2 * Authenc: Simple AEAD wrapper for IPsec
4 * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
13 #include <crypto/aead.h>
14 #include <crypto/internal/hash.h>
15 #include <crypto/internal/skcipher.h>
16 #include <crypto/authenc.h>
17 #include <crypto/scatterwalk.h>
18 #include <linux/err.h>
19 #include <linux/init.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/rtnetlink.h>
23 #include <linux/slab.h>
24 #include <linux/spinlock.h>
26 struct authenc_instance_ctx
{
27 struct crypto_spawn auth
;
28 struct crypto_skcipher_spawn enc
;
31 struct crypto_authenc_ctx
{
33 struct crypto_hash
*auth
;
34 struct crypto_ablkcipher
*enc
;
37 static int crypto_authenc_setkey(struct crypto_aead
*authenc
, const u8
*key
,
40 unsigned int authkeylen
;
41 unsigned int enckeylen
;
42 struct crypto_authenc_ctx
*ctx
= crypto_aead_ctx(authenc
);
43 struct crypto_hash
*auth
= ctx
->auth
;
44 struct crypto_ablkcipher
*enc
= ctx
->enc
;
45 struct rtattr
*rta
= (void *)key
;
46 struct crypto_authenc_key_param
*param
;
49 if (!RTA_OK(rta
, keylen
))
51 if (rta
->rta_type
!= CRYPTO_AUTHENC_KEYA_PARAM
)
53 if (RTA_PAYLOAD(rta
) < sizeof(*param
))
56 param
= RTA_DATA(rta
);
57 enckeylen
= be32_to_cpu(param
->enckeylen
);
59 key
+= RTA_ALIGN(rta
->rta_len
);
60 keylen
-= RTA_ALIGN(rta
->rta_len
);
62 if (keylen
< enckeylen
)
65 authkeylen
= keylen
- enckeylen
;
67 crypto_hash_clear_flags(auth
, CRYPTO_TFM_REQ_MASK
);
68 crypto_hash_set_flags(auth
, crypto_aead_get_flags(authenc
) &
70 err
= crypto_hash_setkey(auth
, key
, authkeylen
);
71 crypto_aead_set_flags(authenc
, crypto_hash_get_flags(auth
) &
77 crypto_ablkcipher_clear_flags(enc
, CRYPTO_TFM_REQ_MASK
);
78 crypto_ablkcipher_set_flags(enc
, crypto_aead_get_flags(authenc
) &
80 err
= crypto_ablkcipher_setkey(enc
, key
+ authkeylen
, enckeylen
);
81 crypto_aead_set_flags(authenc
, crypto_ablkcipher_get_flags(enc
) &
88 crypto_aead_set_flags(authenc
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
92 static void authenc_chain(struct scatterlist
*head
, struct scatterlist
*sg
,
96 head
->length
+= sg
->length
;
97 sg
= scatterwalk_sg_next(sg
);
101 scatterwalk_sg_chain(head
, 2, sg
);
106 static u8
*crypto_authenc_hash(struct aead_request
*req
, unsigned int flags
,
107 struct scatterlist
*cipher
,
108 unsigned int cryptlen
)
110 struct crypto_aead
*authenc
= crypto_aead_reqtfm(req
);
111 struct crypto_authenc_ctx
*ctx
= crypto_aead_ctx(authenc
);
112 struct crypto_hash
*auth
= ctx
->auth
;
113 struct hash_desc desc
= {
115 .flags
= aead_request_flags(req
) & flags
,
117 u8
*hash
= aead_request_ctx(req
);
120 hash
= (u8
*)ALIGN((unsigned long)hash
+ crypto_hash_alignmask(auth
),
121 crypto_hash_alignmask(auth
) + 1);
123 spin_lock_bh(&ctx
->auth_lock
);
124 err
= crypto_hash_init(&desc
);
128 err
= crypto_hash_update(&desc
, req
->assoc
, req
->assoclen
);
132 err
= crypto_hash_update(&desc
, cipher
, cryptlen
);
136 err
= crypto_hash_final(&desc
, hash
);
138 spin_unlock_bh(&ctx
->auth_lock
);
146 static int crypto_authenc_genicv(struct aead_request
*req
, u8
*iv
,
149 struct crypto_aead
*authenc
= crypto_aead_reqtfm(req
);
150 struct scatterlist
*dst
= req
->dst
;
151 struct scatterlist cipher
[2];
153 unsigned int ivsize
= crypto_aead_ivsize(authenc
);
154 unsigned int cryptlen
;
159 vdst
= PageHighMem(dstp
) ? NULL
: page_address(dstp
) + dst
->offset
;
161 sg_init_table(cipher
, 2);
162 sg_set_buf(cipher
, iv
, ivsize
);
163 authenc_chain(cipher
, dst
, vdst
== iv
+ ivsize
);
165 cryptlen
= req
->cryptlen
+ ivsize
;
166 hash
= crypto_authenc_hash(req
, flags
, cipher
, cryptlen
);
168 return PTR_ERR(hash
);
170 scatterwalk_map_and_copy(hash
, cipher
, cryptlen
,
171 crypto_aead_authsize(authenc
), 1);
175 static void crypto_authenc_encrypt_done(struct crypto_async_request
*req
,
178 struct aead_request
*areq
= req
->data
;
181 struct crypto_aead
*authenc
= crypto_aead_reqtfm(areq
);
182 struct crypto_authenc_ctx
*ctx
= crypto_aead_ctx(authenc
);
183 struct ablkcipher_request
*abreq
= aead_request_ctx(areq
);
184 u8
*iv
= (u8
*)(abreq
+ 1) +
185 crypto_ablkcipher_reqsize(ctx
->enc
);
187 err
= crypto_authenc_genicv(areq
, iv
, 0);
190 aead_request_complete(areq
, err
);
193 static int crypto_authenc_encrypt(struct aead_request
*req
)
195 struct crypto_aead
*authenc
= crypto_aead_reqtfm(req
);
196 struct crypto_authenc_ctx
*ctx
= crypto_aead_ctx(authenc
);
197 struct ablkcipher_request
*abreq
= aead_request_ctx(req
);
198 struct crypto_ablkcipher
*enc
= ctx
->enc
;
199 struct scatterlist
*dst
= req
->dst
;
200 unsigned int cryptlen
= req
->cryptlen
;
201 u8
*iv
= (u8
*)(abreq
+ 1) + crypto_ablkcipher_reqsize(enc
);
204 ablkcipher_request_set_tfm(abreq
, enc
);
205 ablkcipher_request_set_callback(abreq
, aead_request_flags(req
),
206 crypto_authenc_encrypt_done
, req
);
207 ablkcipher_request_set_crypt(abreq
, req
->src
, dst
, cryptlen
, req
->iv
);
209 memcpy(iv
, req
->iv
, crypto_aead_ivsize(authenc
));
211 err
= crypto_ablkcipher_encrypt(abreq
);
215 return crypto_authenc_genicv(req
, iv
, CRYPTO_TFM_REQ_MAY_SLEEP
);
218 static void crypto_authenc_givencrypt_done(struct crypto_async_request
*req
,
221 struct aead_request
*areq
= req
->data
;
224 struct skcipher_givcrypt_request
*greq
= aead_request_ctx(areq
);
226 err
= crypto_authenc_genicv(areq
, greq
->giv
, 0);
229 aead_request_complete(areq
, err
);
232 static int crypto_authenc_givencrypt(struct aead_givcrypt_request
*req
)
234 struct crypto_aead
*authenc
= aead_givcrypt_reqtfm(req
);
235 struct crypto_authenc_ctx
*ctx
= crypto_aead_ctx(authenc
);
236 struct aead_request
*areq
= &req
->areq
;
237 struct skcipher_givcrypt_request
*greq
= aead_request_ctx(areq
);
241 skcipher_givcrypt_set_tfm(greq
, ctx
->enc
);
242 skcipher_givcrypt_set_callback(greq
, aead_request_flags(areq
),
243 crypto_authenc_givencrypt_done
, areq
);
244 skcipher_givcrypt_set_crypt(greq
, areq
->src
, areq
->dst
, areq
->cryptlen
,
246 skcipher_givcrypt_set_giv(greq
, iv
, req
->seq
);
248 err
= crypto_skcipher_givencrypt(greq
);
252 return crypto_authenc_genicv(areq
, iv
, CRYPTO_TFM_REQ_MAY_SLEEP
);
255 static int crypto_authenc_verify(struct aead_request
*req
,
256 struct scatterlist
*cipher
,
257 unsigned int cryptlen
)
259 struct crypto_aead
*authenc
= crypto_aead_reqtfm(req
);
262 unsigned int authsize
;
264 ohash
= crypto_authenc_hash(req
, CRYPTO_TFM_REQ_MAY_SLEEP
, cipher
,
267 return PTR_ERR(ohash
);
269 authsize
= crypto_aead_authsize(authenc
);
270 ihash
= ohash
+ authsize
;
271 scatterwalk_map_and_copy(ihash
, cipher
, cryptlen
, authsize
, 0);
272 return memcmp(ihash
, ohash
, authsize
) ? -EBADMSG
: 0;
275 static int crypto_authenc_iverify(struct aead_request
*req
, u8
*iv
,
276 unsigned int cryptlen
)
278 struct crypto_aead
*authenc
= crypto_aead_reqtfm(req
);
279 struct scatterlist
*src
= req
->src
;
280 struct scatterlist cipher
[2];
282 unsigned int ivsize
= crypto_aead_ivsize(authenc
);
286 vsrc
= PageHighMem(srcp
) ? NULL
: page_address(srcp
) + src
->offset
;
288 sg_init_table(cipher
, 2);
289 sg_set_buf(cipher
, iv
, ivsize
);
290 authenc_chain(cipher
, src
, vsrc
== iv
+ ivsize
);
292 return crypto_authenc_verify(req
, cipher
, cryptlen
+ ivsize
);
295 static int crypto_authenc_decrypt(struct aead_request
*req
)
297 struct crypto_aead
*authenc
= crypto_aead_reqtfm(req
);
298 struct crypto_authenc_ctx
*ctx
= crypto_aead_ctx(authenc
);
299 struct ablkcipher_request
*abreq
= aead_request_ctx(req
);
300 unsigned int cryptlen
= req
->cryptlen
;
301 unsigned int authsize
= crypto_aead_authsize(authenc
);
305 if (cryptlen
< authsize
)
307 cryptlen
-= authsize
;
309 err
= crypto_authenc_iverify(req
, iv
, cryptlen
);
313 ablkcipher_request_set_tfm(abreq
, ctx
->enc
);
314 ablkcipher_request_set_callback(abreq
, aead_request_flags(req
),
315 req
->base
.complete
, req
->base
.data
);
316 ablkcipher_request_set_crypt(abreq
, req
->src
, req
->dst
, cryptlen
, iv
);
318 return crypto_ablkcipher_decrypt(abreq
);
321 static int crypto_authenc_init_tfm(struct crypto_tfm
*tfm
)
323 struct crypto_instance
*inst
= (void *)tfm
->__crt_alg
;
324 struct authenc_instance_ctx
*ictx
= crypto_instance_ctx(inst
);
325 struct crypto_authenc_ctx
*ctx
= crypto_tfm_ctx(tfm
);
326 struct crypto_hash
*auth
;
327 struct crypto_ablkcipher
*enc
;
330 auth
= crypto_spawn_hash(&ictx
->auth
);
332 return PTR_ERR(auth
);
334 enc
= crypto_spawn_skcipher(&ictx
->enc
);
341 tfm
->crt_aead
.reqsize
= max_t(unsigned int,
342 (crypto_hash_alignmask(auth
) &
343 ~(crypto_tfm_ctx_alignment() - 1)) +
344 crypto_hash_digestsize(auth
) * 2,
345 sizeof(struct skcipher_givcrypt_request
) +
346 crypto_ablkcipher_reqsize(enc
) +
347 crypto_ablkcipher_ivsize(enc
));
349 spin_lock_init(&ctx
->auth_lock
);
354 crypto_free_hash(auth
);
358 static void crypto_authenc_exit_tfm(struct crypto_tfm
*tfm
)
360 struct crypto_authenc_ctx
*ctx
= crypto_tfm_ctx(tfm
);
362 crypto_free_hash(ctx
->auth
);
363 crypto_free_ablkcipher(ctx
->enc
);
366 static struct crypto_instance
*crypto_authenc_alloc(struct rtattr
**tb
)
368 struct crypto_attr_type
*algt
;
369 struct crypto_instance
*inst
;
370 struct crypto_alg
*auth
;
371 struct crypto_alg
*enc
;
372 struct authenc_instance_ctx
*ctx
;
373 const char *enc_name
;
376 algt
= crypto_get_attr_type(tb
);
381 if ((algt
->type
^ CRYPTO_ALG_TYPE_AEAD
) & algt
->mask
)
382 return ERR_PTR(-EINVAL
);
384 auth
= crypto_attr_alg(tb
[1], CRYPTO_ALG_TYPE_HASH
,
385 CRYPTO_ALG_TYPE_HASH_MASK
);
387 return ERR_PTR(PTR_ERR(auth
));
389 enc_name
= crypto_attr_alg_name(tb
[2]);
390 err
= PTR_ERR(enc_name
);
391 if (IS_ERR(enc_name
))
394 inst
= kzalloc(sizeof(*inst
) + sizeof(*ctx
), GFP_KERNEL
);
399 ctx
= crypto_instance_ctx(inst
);
401 err
= crypto_init_spawn(&ctx
->auth
, auth
, inst
, CRYPTO_ALG_TYPE_MASK
);
405 crypto_set_skcipher_spawn(&ctx
->enc
, inst
);
406 err
= crypto_grab_skcipher(&ctx
->enc
, enc_name
, 0,
407 crypto_requires_sync(algt
->type
,
412 enc
= crypto_skcipher_spawn_alg(&ctx
->enc
);
415 if (snprintf(inst
->alg
.cra_name
, CRYPTO_MAX_ALG_NAME
,
416 "authenc(%s,%s)", auth
->cra_name
, enc
->cra_name
) >=
420 if (snprintf(inst
->alg
.cra_driver_name
, CRYPTO_MAX_ALG_NAME
,
421 "authenc(%s,%s)", auth
->cra_driver_name
,
422 enc
->cra_driver_name
) >= CRYPTO_MAX_ALG_NAME
)
425 inst
->alg
.cra_flags
= CRYPTO_ALG_TYPE_AEAD
;
426 inst
->alg
.cra_flags
|= enc
->cra_flags
& CRYPTO_ALG_ASYNC
;
427 inst
->alg
.cra_priority
= enc
->cra_priority
* 10 + auth
->cra_priority
;
428 inst
->alg
.cra_blocksize
= enc
->cra_blocksize
;
429 inst
->alg
.cra_alignmask
= auth
->cra_alignmask
| enc
->cra_alignmask
;
430 inst
->alg
.cra_type
= &crypto_aead_type
;
432 inst
->alg
.cra_aead
.ivsize
= enc
->cra_ablkcipher
.ivsize
;
433 inst
->alg
.cra_aead
.maxauthsize
= auth
->cra_type
== &crypto_hash_type
?
434 auth
->cra_hash
.digestsize
:
436 __crypto_shash_alg(auth
)->digestsize
:
437 auth
->cra_digest
.dia_digestsize
;
439 inst
->alg
.cra_ctxsize
= sizeof(struct crypto_authenc_ctx
);
441 inst
->alg
.cra_init
= crypto_authenc_init_tfm
;
442 inst
->alg
.cra_exit
= crypto_authenc_exit_tfm
;
444 inst
->alg
.cra_aead
.setkey
= crypto_authenc_setkey
;
445 inst
->alg
.cra_aead
.encrypt
= crypto_authenc_encrypt
;
446 inst
->alg
.cra_aead
.decrypt
= crypto_authenc_decrypt
;
447 inst
->alg
.cra_aead
.givencrypt
= crypto_authenc_givencrypt
;
450 crypto_mod_put(auth
);
454 crypto_drop_skcipher(&ctx
->enc
);
456 crypto_drop_spawn(&ctx
->auth
);
464 static void crypto_authenc_free(struct crypto_instance
*inst
)
466 struct authenc_instance_ctx
*ctx
= crypto_instance_ctx(inst
);
468 crypto_drop_skcipher(&ctx
->enc
);
469 crypto_drop_spawn(&ctx
->auth
);
473 static struct crypto_template crypto_authenc_tmpl
= {
475 .alloc
= crypto_authenc_alloc
,
476 .free
= crypto_authenc_free
,
477 .module
= THIS_MODULE
,
480 static int __init
crypto_authenc_module_init(void)
482 return crypto_register_template(&crypto_authenc_tmpl
);
485 static void __exit
crypto_authenc_module_exit(void)
487 crypto_unregister_template(&crypto_authenc_tmpl
);
490 module_init(crypto_authenc_module_init
);
491 module_exit(crypto_authenc_module_exit
);
493 MODULE_LICENSE("GPL");
494 MODULE_DESCRIPTION("Simple AEAD wrapper for IPsec");