2 * ChaCha20-Poly1305 AEAD, RFC7539
4 * Copyright (C) 2015 Martin Willi
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
12 #include <crypto/internal/aead.h>
13 #include <crypto/internal/hash.h>
14 #include <crypto/internal/skcipher.h>
15 #include <crypto/scatterwalk.h>
16 #include <crypto/chacha20.h>
17 #include <crypto/poly1305.h>
18 #include <linux/err.h>
19 #include <linux/init.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
25 #define CHACHAPOLY_IV_SIZE 12
27 struct chachapoly_instance_ctx
{
28 struct crypto_skcipher_spawn chacha
;
29 struct crypto_ahash_spawn poly
;
33 struct chachapoly_ctx
{
34 struct crypto_ablkcipher
*chacha
;
35 struct crypto_ahash
*poly
;
36 /* key bytes we use for the ChaCha20 IV */
42 /* zero byte padding for AD/ciphertext, as needed */
43 u8 pad
[POLY1305_BLOCK_SIZE
];
44 /* tail data with AD/ciphertext lengths */
49 struct scatterlist src
[1];
50 struct ahash_request req
; /* must be last member */
54 u8 iv
[CHACHA20_IV_SIZE
];
55 struct scatterlist src
[1];
56 struct ablkcipher_request req
; /* must be last member */
59 struct chachapoly_req_ctx
{
60 struct scatterlist src
[2];
61 struct scatterlist dst
[2];
62 /* the key we generate for Poly1305 using Chacha20 */
63 u8 key
[POLY1305_KEY_SIZE
];
64 /* calculated Poly1305 tag */
65 u8 tag
[POLY1305_DIGEST_SIZE
];
66 /* length of data to en/decrypt, without ICV */
67 unsigned int cryptlen
;
68 /* Actual AD, excluding IV */
69 unsigned int assoclen
;
72 struct chacha_req chacha
;
76 static inline void async_done_continue(struct aead_request
*req
, int err
,
77 int (*cont
)(struct aead_request
*))
82 if (err
!= -EINPROGRESS
&& err
!= -EBUSY
)
83 aead_request_complete(req
, err
);
86 static void chacha_iv(u8
*iv
, struct aead_request
*req
, u32 icb
)
88 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
89 __le32 leicb
= cpu_to_le32(icb
);
91 memcpy(iv
, &leicb
, sizeof(leicb
));
92 memcpy(iv
+ sizeof(leicb
), ctx
->salt
, ctx
->saltlen
);
93 memcpy(iv
+ sizeof(leicb
) + ctx
->saltlen
, req
->iv
,
94 CHACHA20_IV_SIZE
- sizeof(leicb
) - ctx
->saltlen
);
97 static int poly_verify_tag(struct aead_request
*req
)
99 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
100 u8 tag
[sizeof(rctx
->tag
)];
102 scatterwalk_map_and_copy(tag
, req
->src
,
103 req
->assoclen
+ rctx
->cryptlen
,
105 if (crypto_memneq(tag
, rctx
->tag
, sizeof(tag
)))
110 static int poly_copy_tag(struct aead_request
*req
)
112 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
114 scatterwalk_map_and_copy(rctx
->tag
, req
->dst
,
115 req
->assoclen
+ rctx
->cryptlen
,
116 sizeof(rctx
->tag
), 1);
120 static void chacha_decrypt_done(struct crypto_async_request
*areq
, int err
)
122 async_done_continue(areq
->data
, err
, poly_verify_tag
);
125 static int chacha_decrypt(struct aead_request
*req
)
127 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
128 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
129 struct chacha_req
*creq
= &rctx
->u
.chacha
;
130 struct scatterlist
*src
, *dst
;
133 chacha_iv(creq
->iv
, req
, 1);
135 sg_init_table(rctx
->src
, 2);
136 src
= scatterwalk_ffwd(rctx
->src
, req
->src
, req
->assoclen
);
139 if (req
->src
!= req
->dst
) {
140 sg_init_table(rctx
->dst
, 2);
141 dst
= scatterwalk_ffwd(rctx
->dst
, req
->dst
, req
->assoclen
);
144 ablkcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
145 chacha_decrypt_done
, req
);
146 ablkcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
147 ablkcipher_request_set_crypt(&creq
->req
, src
, dst
,
148 rctx
->cryptlen
, creq
->iv
);
149 err
= crypto_ablkcipher_decrypt(&creq
->req
);
153 return poly_verify_tag(req
);
156 static int poly_tail_continue(struct aead_request
*req
)
158 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
160 if (rctx
->cryptlen
== req
->cryptlen
) /* encrypting */
161 return poly_copy_tag(req
);
163 return chacha_decrypt(req
);
166 static void poly_tail_done(struct crypto_async_request
*areq
, int err
)
168 async_done_continue(areq
->data
, err
, poly_tail_continue
);
171 static int poly_tail(struct aead_request
*req
)
173 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
174 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
175 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
176 struct poly_req
*preq
= &rctx
->u
.poly
;
180 sg_init_table(preq
->src
, 1);
181 len
= cpu_to_le64(rctx
->assoclen
);
182 memcpy(&preq
->tail
.assoclen
, &len
, sizeof(len
));
183 len
= cpu_to_le64(rctx
->cryptlen
);
184 memcpy(&preq
->tail
.cryptlen
, &len
, sizeof(len
));
185 sg_set_buf(preq
->src
, &preq
->tail
, sizeof(preq
->tail
));
187 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
188 poly_tail_done
, req
);
189 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
190 ahash_request_set_crypt(&preq
->req
, preq
->src
,
191 rctx
->tag
, sizeof(preq
->tail
));
193 err
= crypto_ahash_finup(&preq
->req
);
197 return poly_tail_continue(req
);
200 static void poly_cipherpad_done(struct crypto_async_request
*areq
, int err
)
202 async_done_continue(areq
->data
, err
, poly_tail
);
205 static int poly_cipherpad(struct aead_request
*req
)
207 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
208 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
209 struct poly_req
*preq
= &rctx
->u
.poly
;
210 unsigned int padlen
, bs
= POLY1305_BLOCK_SIZE
;
213 padlen
= (bs
- (rctx
->cryptlen
% bs
)) % bs
;
214 memset(preq
->pad
, 0, sizeof(preq
->pad
));
215 sg_init_table(preq
->src
, 1);
216 sg_set_buf(preq
->src
, &preq
->pad
, padlen
);
218 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
219 poly_cipherpad_done
, req
);
220 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
221 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, padlen
);
223 err
= crypto_ahash_update(&preq
->req
);
227 return poly_tail(req
);
230 static void poly_cipher_done(struct crypto_async_request
*areq
, int err
)
232 async_done_continue(areq
->data
, err
, poly_cipherpad
);
235 static int poly_cipher(struct aead_request
*req
)
237 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
238 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
239 struct poly_req
*preq
= &rctx
->u
.poly
;
240 struct scatterlist
*crypt
= req
->src
;
243 if (rctx
->cryptlen
== req
->cryptlen
) /* encrypting */
246 sg_init_table(rctx
->src
, 2);
247 crypt
= scatterwalk_ffwd(rctx
->src
, crypt
, req
->assoclen
);
249 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
250 poly_cipher_done
, req
);
251 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
252 ahash_request_set_crypt(&preq
->req
, crypt
, NULL
, rctx
->cryptlen
);
254 err
= crypto_ahash_update(&preq
->req
);
258 return poly_cipherpad(req
);
261 static void poly_adpad_done(struct crypto_async_request
*areq
, int err
)
263 async_done_continue(areq
->data
, err
, poly_cipher
);
266 static int poly_adpad(struct aead_request
*req
)
268 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
269 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
270 struct poly_req
*preq
= &rctx
->u
.poly
;
271 unsigned int padlen
, bs
= POLY1305_BLOCK_SIZE
;
274 padlen
= (bs
- (rctx
->assoclen
% bs
)) % bs
;
275 memset(preq
->pad
, 0, sizeof(preq
->pad
));
276 sg_init_table(preq
->src
, 1);
277 sg_set_buf(preq
->src
, preq
->pad
, padlen
);
279 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
280 poly_adpad_done
, req
);
281 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
282 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, padlen
);
284 err
= crypto_ahash_update(&preq
->req
);
288 return poly_cipher(req
);
291 static void poly_ad_done(struct crypto_async_request
*areq
, int err
)
293 async_done_continue(areq
->data
, err
, poly_adpad
);
296 static int poly_ad(struct aead_request
*req
)
298 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
299 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
300 struct poly_req
*preq
= &rctx
->u
.poly
;
303 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
305 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
306 ahash_request_set_crypt(&preq
->req
, req
->src
, NULL
, rctx
->assoclen
);
308 err
= crypto_ahash_update(&preq
->req
);
312 return poly_adpad(req
);
315 static void poly_setkey_done(struct crypto_async_request
*areq
, int err
)
317 async_done_continue(areq
->data
, err
, poly_ad
);
320 static int poly_setkey(struct aead_request
*req
)
322 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
323 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
324 struct poly_req
*preq
= &rctx
->u
.poly
;
327 sg_init_table(preq
->src
, 1);
328 sg_set_buf(preq
->src
, rctx
->key
, sizeof(rctx
->key
));
330 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
331 poly_setkey_done
, req
);
332 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
333 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, sizeof(rctx
->key
));
335 err
= crypto_ahash_update(&preq
->req
);
342 static void poly_init_done(struct crypto_async_request
*areq
, int err
)
344 async_done_continue(areq
->data
, err
, poly_setkey
);
347 static int poly_init(struct aead_request
*req
)
349 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
350 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
351 struct poly_req
*preq
= &rctx
->u
.poly
;
354 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
355 poly_init_done
, req
);
356 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
358 err
= crypto_ahash_init(&preq
->req
);
362 return poly_setkey(req
);
365 static void poly_genkey_done(struct crypto_async_request
*areq
, int err
)
367 async_done_continue(areq
->data
, err
, poly_init
);
370 static int poly_genkey(struct aead_request
*req
)
372 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
373 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
374 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
375 struct chacha_req
*creq
= &rctx
->u
.chacha
;
378 rctx
->assoclen
= req
->assoclen
;
380 if (crypto_aead_ivsize(tfm
) == 8) {
381 if (rctx
->assoclen
< 8)
386 sg_init_table(creq
->src
, 1);
387 memset(rctx
->key
, 0, sizeof(rctx
->key
));
388 sg_set_buf(creq
->src
, rctx
->key
, sizeof(rctx
->key
));
390 chacha_iv(creq
->iv
, req
, 0);
392 ablkcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
393 poly_genkey_done
, req
);
394 ablkcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
395 ablkcipher_request_set_crypt(&creq
->req
, creq
->src
, creq
->src
,
396 POLY1305_KEY_SIZE
, creq
->iv
);
398 err
= crypto_ablkcipher_decrypt(&creq
->req
);
402 return poly_init(req
);
405 static void chacha_encrypt_done(struct crypto_async_request
*areq
, int err
)
407 async_done_continue(areq
->data
, err
, poly_genkey
);
410 static int chacha_encrypt(struct aead_request
*req
)
412 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
413 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
414 struct chacha_req
*creq
= &rctx
->u
.chacha
;
415 struct scatterlist
*src
, *dst
;
418 chacha_iv(creq
->iv
, req
, 1);
420 sg_init_table(rctx
->src
, 2);
421 src
= scatterwalk_ffwd(rctx
->src
, req
->src
, req
->assoclen
);
424 if (req
->src
!= req
->dst
) {
425 sg_init_table(rctx
->dst
, 2);
426 dst
= scatterwalk_ffwd(rctx
->dst
, req
->dst
, req
->assoclen
);
429 ablkcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
430 chacha_encrypt_done
, req
);
431 ablkcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
432 ablkcipher_request_set_crypt(&creq
->req
, src
, dst
,
433 req
->cryptlen
, creq
->iv
);
434 err
= crypto_ablkcipher_encrypt(&creq
->req
);
438 return poly_genkey(req
);
441 static int chachapoly_encrypt(struct aead_request
*req
)
443 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
445 rctx
->cryptlen
= req
->cryptlen
;
447 /* encrypt call chain:
448 * - chacha_encrypt/done()
449 * - poly_genkey/done()
451 * - poly_setkey/done()
453 * - poly_adpad/done()
454 * - poly_cipher/done()
455 * - poly_cipherpad/done()
456 * - poly_tail/done/continue()
459 return chacha_encrypt(req
);
462 static int chachapoly_decrypt(struct aead_request
*req
)
464 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
466 rctx
->cryptlen
= req
->cryptlen
- POLY1305_DIGEST_SIZE
;
468 /* decrypt call chain:
469 * - poly_genkey/done()
471 * - poly_setkey/done()
473 * - poly_adpad/done()
474 * - poly_cipher/done()
475 * - poly_cipherpad/done()
476 * - poly_tail/done/continue()
477 * - chacha_decrypt/done()
478 * - poly_verify_tag()
480 return poly_genkey(req
);
483 static int chachapoly_setkey(struct crypto_aead
*aead
, const u8
*key
,
486 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(aead
);
489 if (keylen
!= ctx
->saltlen
+ CHACHA20_KEY_SIZE
)
492 keylen
-= ctx
->saltlen
;
493 memcpy(ctx
->salt
, key
+ keylen
, ctx
->saltlen
);
495 crypto_ablkcipher_clear_flags(ctx
->chacha
, CRYPTO_TFM_REQ_MASK
);
496 crypto_ablkcipher_set_flags(ctx
->chacha
, crypto_aead_get_flags(aead
) &
497 CRYPTO_TFM_REQ_MASK
);
499 err
= crypto_ablkcipher_setkey(ctx
->chacha
, key
, keylen
);
500 crypto_aead_set_flags(aead
, crypto_ablkcipher_get_flags(ctx
->chacha
) &
501 CRYPTO_TFM_RES_MASK
);
505 static int chachapoly_setauthsize(struct crypto_aead
*tfm
,
506 unsigned int authsize
)
508 if (authsize
!= POLY1305_DIGEST_SIZE
)
514 static int chachapoly_init(struct crypto_aead
*tfm
)
516 struct aead_instance
*inst
= aead_alg_instance(tfm
);
517 struct chachapoly_instance_ctx
*ictx
= aead_instance_ctx(inst
);
518 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
519 struct crypto_ablkcipher
*chacha
;
520 struct crypto_ahash
*poly
;
523 poly
= crypto_spawn_ahash(&ictx
->poly
);
525 return PTR_ERR(poly
);
527 chacha
= crypto_spawn_skcipher(&ictx
->chacha
);
528 if (IS_ERR(chacha
)) {
529 crypto_free_ahash(poly
);
530 return PTR_ERR(chacha
);
533 ctx
->chacha
= chacha
;
535 ctx
->saltlen
= ictx
->saltlen
;
537 align
= crypto_aead_alignmask(tfm
);
538 align
&= ~(crypto_tfm_ctx_alignment() - 1);
539 crypto_aead_set_reqsize(
541 align
+ offsetof(struct chachapoly_req_ctx
, u
) +
542 max(offsetof(struct chacha_req
, req
) +
543 sizeof(struct ablkcipher_request
) +
544 crypto_ablkcipher_reqsize(chacha
),
545 offsetof(struct poly_req
, req
) +
546 sizeof(struct ahash_request
) +
547 crypto_ahash_reqsize(poly
)));
552 static void chachapoly_exit(struct crypto_aead
*tfm
)
554 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
556 crypto_free_ahash(ctx
->poly
);
557 crypto_free_ablkcipher(ctx
->chacha
);
560 static void chachapoly_free(struct aead_instance
*inst
)
562 struct chachapoly_instance_ctx
*ctx
= aead_instance_ctx(inst
);
564 crypto_drop_skcipher(&ctx
->chacha
);
565 crypto_drop_ahash(&ctx
->poly
);
569 static int chachapoly_create(struct crypto_template
*tmpl
, struct rtattr
**tb
,
570 const char *name
, unsigned int ivsize
)
572 struct crypto_attr_type
*algt
;
573 struct aead_instance
*inst
;
574 struct crypto_alg
*chacha
;
575 struct crypto_alg
*poly
;
576 struct hash_alg_common
*poly_hash
;
577 struct chachapoly_instance_ctx
*ctx
;
578 const char *chacha_name
, *poly_name
;
581 if (ivsize
> CHACHAPOLY_IV_SIZE
)
584 algt
= crypto_get_attr_type(tb
);
586 return PTR_ERR(algt
);
588 if ((algt
->type
^ CRYPTO_ALG_TYPE_AEAD
) & algt
->mask
)
591 chacha_name
= crypto_attr_alg_name(tb
[1]);
592 if (IS_ERR(chacha_name
))
593 return PTR_ERR(chacha_name
);
594 poly_name
= crypto_attr_alg_name(tb
[2]);
595 if (IS_ERR(poly_name
))
596 return PTR_ERR(poly_name
);
598 poly
= crypto_find_alg(poly_name
, &crypto_ahash_type
,
599 CRYPTO_ALG_TYPE_HASH
,
600 CRYPTO_ALG_TYPE_AHASH_MASK
);
602 return PTR_ERR(poly
);
603 poly_hash
= __crypto_hash_alg_common(poly
);
606 if (poly_hash
->digestsize
!= POLY1305_DIGEST_SIZE
)
610 inst
= kzalloc(sizeof(*inst
) + sizeof(*ctx
), GFP_KERNEL
);
614 ctx
= aead_instance_ctx(inst
);
615 ctx
->saltlen
= CHACHAPOLY_IV_SIZE
- ivsize
;
616 err
= crypto_init_ahash_spawn(&ctx
->poly
, poly_hash
,
617 aead_crypto_instance(inst
));
621 crypto_set_skcipher_spawn(&ctx
->chacha
, aead_crypto_instance(inst
));
622 err
= crypto_grab_skcipher(&ctx
->chacha
, chacha_name
, 0,
623 crypto_requires_sync(algt
->type
,
628 chacha
= crypto_skcipher_spawn_alg(&ctx
->chacha
);
631 /* Need 16-byte IV size, including Initial Block Counter value */
632 if (chacha
->cra_ablkcipher
.ivsize
!= CHACHA20_IV_SIZE
)
633 goto out_drop_chacha
;
634 /* Not a stream cipher? */
635 if (chacha
->cra_blocksize
!= 1)
636 goto out_drop_chacha
;
639 if (snprintf(inst
->alg
.base
.cra_name
, CRYPTO_MAX_ALG_NAME
,
640 "%s(%s,%s)", name
, chacha_name
,
641 poly_name
) >= CRYPTO_MAX_ALG_NAME
)
642 goto out_drop_chacha
;
643 if (snprintf(inst
->alg
.base
.cra_driver_name
, CRYPTO_MAX_ALG_NAME
,
644 "%s(%s,%s)", name
, chacha
->cra_driver_name
,
645 poly
->cra_driver_name
) >= CRYPTO_MAX_ALG_NAME
)
646 goto out_drop_chacha
;
648 inst
->alg
.base
.cra_flags
= (chacha
->cra_flags
| poly
->cra_flags
) &
650 inst
->alg
.base
.cra_priority
= (chacha
->cra_priority
+
651 poly
->cra_priority
) / 2;
652 inst
->alg
.base
.cra_blocksize
= 1;
653 inst
->alg
.base
.cra_alignmask
= chacha
->cra_alignmask
|
655 inst
->alg
.base
.cra_ctxsize
= sizeof(struct chachapoly_ctx
) +
657 inst
->alg
.ivsize
= ivsize
;
658 inst
->alg
.maxauthsize
= POLY1305_DIGEST_SIZE
;
659 inst
->alg
.init
= chachapoly_init
;
660 inst
->alg
.exit
= chachapoly_exit
;
661 inst
->alg
.encrypt
= chachapoly_encrypt
;
662 inst
->alg
.decrypt
= chachapoly_decrypt
;
663 inst
->alg
.setkey
= chachapoly_setkey
;
664 inst
->alg
.setauthsize
= chachapoly_setauthsize
;
666 inst
->free
= chachapoly_free
;
668 err
= aead_register_instance(tmpl
, inst
);
670 goto out_drop_chacha
;
673 crypto_mod_put(poly
);
677 crypto_drop_skcipher(&ctx
->chacha
);
679 crypto_drop_ahash(&ctx
->poly
);
685 static int rfc7539_create(struct crypto_template
*tmpl
, struct rtattr
**tb
)
687 return chachapoly_create(tmpl
, tb
, "rfc7539", 12);
690 static int rfc7539esp_create(struct crypto_template
*tmpl
, struct rtattr
**tb
)
692 return chachapoly_create(tmpl
, tb
, "rfc7539esp", 8);
695 static struct crypto_template rfc7539_tmpl
= {
697 .create
= rfc7539_create
,
698 .module
= THIS_MODULE
,
701 static struct crypto_template rfc7539esp_tmpl
= {
702 .name
= "rfc7539esp",
703 .create
= rfc7539esp_create
,
704 .module
= THIS_MODULE
,
707 static int __init
chacha20poly1305_module_init(void)
711 err
= crypto_register_template(&rfc7539_tmpl
);
715 err
= crypto_register_template(&rfc7539esp_tmpl
);
717 crypto_unregister_template(&rfc7539_tmpl
);
722 static void __exit
chacha20poly1305_module_exit(void)
724 crypto_unregister_template(&rfc7539esp_tmpl
);
725 crypto_unregister_template(&rfc7539_tmpl
);
728 module_init(chacha20poly1305_module_init
);
729 module_exit(chacha20poly1305_module_exit
);
731 MODULE_LICENSE("GPL");
732 MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");
733 MODULE_DESCRIPTION("ChaCha20-Poly1305 AEAD");
734 MODULE_ALIAS_CRYPTO("rfc7539");
735 MODULE_ALIAS_CRYPTO("rfc7539esp");