21 #include <linux/kernel.h>
22 #include <linux/module.h>
24 #include <linux/string.h>
56 ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv));
57 ablkcipher_request_set_callback(subreq, req->
creq.base.flags &
59 req->
creq.base.complete,
61 ablkcipher_request_set_crypt(subreq, req->
creq.src, req->
creq.dst,
64 spin_lock_bh(&ctx->
lock);
66 ivsize = crypto_ablkcipher_ivsize(geniv);
71 err = crypto_ablkcipher_encrypt(subreq);
78 spin_unlock_bh(&ctx->
lock);
89 spin_lock_bh(&ctx->
lock);
90 if (crypto_ablkcipher_crt(geniv)->givencrypt !=
91 chainiv_givencrypt_first)
94 crypto_ablkcipher_crt(geniv)->givencrypt = chainiv_givencrypt;
96 crypto_ablkcipher_ivsize(geniv));
99 spin_unlock_bh(&ctx->
lock);
104 return chainiv_givencrypt(req);
107 static int chainiv_init_common(
struct crypto_tfm *tfm)
114 static int chainiv_init(
struct crypto_tfm *tfm)
120 return chainiv_init_common(tfm);
128 if (!ctx->
queue.qlen) {
132 if (!ctx->
queue.qlen ||
150 spin_lock_bh(&ctx->
lock);
151 err = skcipher_enqueue_givcrypt(&ctx->
queue, req);
152 spin_unlock_bh(&ctx->
lock);
158 return async_chainiv_schedule_work(ctx);
166 unsigned int ivsize = crypto_ablkcipher_ivsize(geniv);
171 ctx->
err = crypto_ablkcipher_encrypt(subreq);
178 return async_chainiv_schedule_work(ctx);
187 ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv));
188 ablkcipher_request_set_callback(subreq, req->
creq.base.flags,
189 req->
creq.base.complete,
190 req->
creq.base.data);
191 ablkcipher_request_set_crypt(subreq, req->
creq.src, req->
creq.dst,
197 if (ctx->
queue.qlen) {
202 return async_chainiv_givencrypt_tail(req);
205 return async_chainiv_postpone_request(req);
217 if (crypto_ablkcipher_crt(geniv)->givencrypt !=
218 async_chainiv_givencrypt_first)
221 crypto_ablkcipher_crt(geniv)->givencrypt = async_chainiv_givencrypt;
223 crypto_ablkcipher_ivsize(geniv));
232 return async_chainiv_givencrypt(req);
245 spin_lock_bh(&ctx->
lock);
246 req = skcipher_dequeue_givcrypt(&ctx->
queue);
247 spin_unlock_bh(&ctx->
lock);
250 async_chainiv_schedule_work(ctx);
254 subreq = skcipher_givcrypt_reqctx(req);
257 err = async_chainiv_givencrypt_tail(req);
260 skcipher_givcrypt_complete(req, err);
264 static int async_chainiv_init(
struct crypto_tfm *tfm)
273 return chainiv_init_common(tfm);
276 static void async_chainiv_exit(
struct crypto_tfm *tfm)
306 inst->
alg.cra_ablkcipher.givencrypt = chainiv_givencrypt_first;
308 inst->
alg.cra_init = chainiv_init;
313 if (!crypto_requires_sync(algt->
type, algt->
mask)) {
316 inst->
alg.cra_ablkcipher.givencrypt =
317 async_chainiv_givencrypt_first;
319 inst->
alg.cra_init = async_chainiv_init;
320 inst->
alg.cra_exit = async_chainiv_exit;
325 inst->
alg.cra_ctxsize += inst->
alg.cra_ablkcipher.ivsize;
343 .alloc = chainiv_alloc,
344 .free = chainiv_free,
348 static int __init chainiv_module_init(
void)
353 static void chainiv_module_exit(
void)