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 <linux/err.h>
17 #include <linux/init.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
23 #define POLY1305_BLOCK_SIZE 16
24 #define POLY1305_DIGEST_SIZE 16
25 #define POLY1305_KEY_SIZE 32
26 #define CHACHA20_KEY_SIZE 32
27 #define CHACHA20_IV_SIZE 16
28 #define CHACHAPOLY_IV_SIZE 12
30 struct chachapoly_instance_ctx
{
31 struct crypto_skcipher_spawn chacha
;
32 struct crypto_ahash_spawn poly
;
36 struct chachapoly_ctx
{
37 struct crypto_ablkcipher
*chacha
;
38 struct crypto_ahash
*poly
;
39 /* key bytes we use for the ChaCha20 IV */
45 /* zero byte padding for AD/ciphertext, as needed */
46 u8 pad
[POLY1305_BLOCK_SIZE
];
47 /* tail data with AD/ciphertext lengths */
52 struct scatterlist src
[1];
53 struct ahash_request req
; /* must be last member */
57 u8 iv
[CHACHA20_IV_SIZE
];
58 struct scatterlist src
[1];
59 struct ablkcipher_request req
; /* must be last member */
62 struct chachapoly_req_ctx
{
63 /* the key we generate for Poly1305 using Chacha20 */
64 u8 key
[POLY1305_KEY_SIZE
];
65 /* calculated Poly1305 tag */
66 u8 tag
[POLY1305_DIGEST_SIZE
];
67 /* length of data to en/decrypt, without ICV */
68 unsigned int cryptlen
;
71 struct chacha_req chacha
;
75 static inline void async_done_continue(struct aead_request
*req
, int err
,
76 int (*cont
)(struct aead_request
*))
81 if (err
!= -EINPROGRESS
&& err
!= -EBUSY
)
82 aead_request_complete(req
, err
);
85 static void chacha_iv(u8
*iv
, struct aead_request
*req
, u32 icb
)
87 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
88 __le32 leicb
= cpu_to_le32(icb
);
90 memcpy(iv
, &leicb
, sizeof(leicb
));
91 memcpy(iv
+ sizeof(leicb
), ctx
->salt
, ctx
->saltlen
);
92 memcpy(iv
+ sizeof(leicb
) + ctx
->saltlen
, req
->iv
,
93 CHACHA20_IV_SIZE
- sizeof(leicb
) - ctx
->saltlen
);
96 static int poly_verify_tag(struct aead_request
*req
)
98 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
99 u8 tag
[sizeof(rctx
->tag
)];
101 scatterwalk_map_and_copy(tag
, req
->src
, rctx
->cryptlen
, sizeof(tag
), 0);
102 if (crypto_memneq(tag
, rctx
->tag
, sizeof(tag
)))
107 static int poly_copy_tag(struct aead_request
*req
)
109 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
111 scatterwalk_map_and_copy(rctx
->tag
, req
->dst
, rctx
->cryptlen
,
112 sizeof(rctx
->tag
), 1);
116 static void chacha_decrypt_done(struct crypto_async_request
*areq
, int err
)
118 async_done_continue(areq
->data
, err
, poly_verify_tag
);
121 static int chacha_decrypt(struct aead_request
*req
)
123 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
124 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
125 struct chacha_req
*creq
= &rctx
->u
.chacha
;
128 chacha_iv(creq
->iv
, req
, 1);
130 ablkcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
131 chacha_decrypt_done
, req
);
132 ablkcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
133 ablkcipher_request_set_crypt(&creq
->req
, req
->src
, req
->dst
,
134 rctx
->cryptlen
, creq
->iv
);
135 err
= crypto_ablkcipher_decrypt(&creq
->req
);
139 return poly_verify_tag(req
);
142 static int poly_tail_continue(struct aead_request
*req
)
144 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
146 if (rctx
->cryptlen
== req
->cryptlen
) /* encrypting */
147 return poly_copy_tag(req
);
149 return chacha_decrypt(req
);
152 static void poly_tail_done(struct crypto_async_request
*areq
, int err
)
154 async_done_continue(areq
->data
, err
, poly_tail_continue
);
157 static int poly_tail(struct aead_request
*req
)
159 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
160 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
161 struct poly_req
*preq
= &rctx
->u
.poly
;
165 sg_init_table(preq
->src
, 1);
166 len
= cpu_to_le64(req
->assoclen
);
167 memcpy(&preq
->tail
.assoclen
, &len
, sizeof(len
));
168 len
= cpu_to_le64(rctx
->cryptlen
);
169 memcpy(&preq
->tail
.cryptlen
, &len
, sizeof(len
));
170 sg_set_buf(preq
->src
, &preq
->tail
, sizeof(preq
->tail
));
172 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
173 poly_tail_done
, req
);
174 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
175 ahash_request_set_crypt(&preq
->req
, preq
->src
,
176 rctx
->tag
, sizeof(preq
->tail
));
178 err
= crypto_ahash_finup(&preq
->req
);
182 return poly_tail_continue(req
);
185 static void poly_cipherpad_done(struct crypto_async_request
*areq
, int err
)
187 async_done_continue(areq
->data
, err
, poly_tail
);
190 static int poly_cipherpad(struct aead_request
*req
)
192 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
193 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
194 struct poly_req
*preq
= &rctx
->u
.poly
;
195 unsigned int padlen
, bs
= POLY1305_BLOCK_SIZE
;
198 padlen
= (bs
- (rctx
->cryptlen
% bs
)) % bs
;
199 memset(preq
->pad
, 0, sizeof(preq
->pad
));
200 sg_init_table(preq
->src
, 1);
201 sg_set_buf(preq
->src
, &preq
->pad
, padlen
);
203 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
204 poly_cipherpad_done
, req
);
205 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
206 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, padlen
);
208 err
= crypto_ahash_update(&preq
->req
);
212 return poly_tail(req
);
215 static void poly_cipher_done(struct crypto_async_request
*areq
, int err
)
217 async_done_continue(areq
->data
, err
, poly_cipherpad
);
220 static int poly_cipher(struct aead_request
*req
)
222 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
223 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
224 struct poly_req
*preq
= &rctx
->u
.poly
;
225 struct scatterlist
*crypt
= req
->src
;
228 if (rctx
->cryptlen
== req
->cryptlen
) /* encrypting */
231 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
232 poly_cipher_done
, req
);
233 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
234 ahash_request_set_crypt(&preq
->req
, crypt
, NULL
, rctx
->cryptlen
);
236 err
= crypto_ahash_update(&preq
->req
);
240 return poly_cipherpad(req
);
243 static void poly_adpad_done(struct crypto_async_request
*areq
, int err
)
245 async_done_continue(areq
->data
, err
, poly_cipher
);
248 static int poly_adpad(struct aead_request
*req
)
250 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
251 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
252 struct poly_req
*preq
= &rctx
->u
.poly
;
253 unsigned int padlen
, bs
= POLY1305_BLOCK_SIZE
;
256 padlen
= (bs
- (req
->assoclen
% bs
)) % bs
;
257 memset(preq
->pad
, 0, sizeof(preq
->pad
));
258 sg_init_table(preq
->src
, 1);
259 sg_set_buf(preq
->src
, preq
->pad
, padlen
);
261 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
262 poly_adpad_done
, req
);
263 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
264 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, padlen
);
266 err
= crypto_ahash_update(&preq
->req
);
270 return poly_cipher(req
);
273 static void poly_ad_done(struct crypto_async_request
*areq
, int err
)
275 async_done_continue(areq
->data
, err
, poly_adpad
);
278 static int poly_ad(struct aead_request
*req
)
280 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
281 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
282 struct poly_req
*preq
= &rctx
->u
.poly
;
285 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
287 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
288 ahash_request_set_crypt(&preq
->req
, req
->assoc
, NULL
, req
->assoclen
);
290 err
= crypto_ahash_update(&preq
->req
);
294 return poly_adpad(req
);
297 static void poly_setkey_done(struct crypto_async_request
*areq
, int err
)
299 async_done_continue(areq
->data
, err
, poly_ad
);
302 static int poly_setkey(struct aead_request
*req
)
304 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
305 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
306 struct poly_req
*preq
= &rctx
->u
.poly
;
309 sg_init_table(preq
->src
, 1);
310 sg_set_buf(preq
->src
, rctx
->key
, sizeof(rctx
->key
));
312 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
313 poly_setkey_done
, req
);
314 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
315 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, sizeof(rctx
->key
));
317 err
= crypto_ahash_update(&preq
->req
);
324 static void poly_init_done(struct crypto_async_request
*areq
, int err
)
326 async_done_continue(areq
->data
, err
, poly_setkey
);
329 static int poly_init(struct aead_request
*req
)
331 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
332 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
333 struct poly_req
*preq
= &rctx
->u
.poly
;
336 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
337 poly_init_done
, req
);
338 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
340 err
= crypto_ahash_init(&preq
->req
);
344 return poly_setkey(req
);
347 static void poly_genkey_done(struct crypto_async_request
*areq
, int err
)
349 async_done_continue(areq
->data
, err
, poly_init
);
352 static int poly_genkey(struct aead_request
*req
)
354 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
355 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
356 struct chacha_req
*creq
= &rctx
->u
.chacha
;
359 sg_init_table(creq
->src
, 1);
360 memset(rctx
->key
, 0, sizeof(rctx
->key
));
361 sg_set_buf(creq
->src
, rctx
->key
, sizeof(rctx
->key
));
363 chacha_iv(creq
->iv
, req
, 0);
365 ablkcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
366 poly_genkey_done
, req
);
367 ablkcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
368 ablkcipher_request_set_crypt(&creq
->req
, creq
->src
, creq
->src
,
369 POLY1305_KEY_SIZE
, creq
->iv
);
371 err
= crypto_ablkcipher_decrypt(&creq
->req
);
375 return poly_init(req
);
378 static void chacha_encrypt_done(struct crypto_async_request
*areq
, int err
)
380 async_done_continue(areq
->data
, err
, poly_genkey
);
383 static int chacha_encrypt(struct aead_request
*req
)
385 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
386 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
387 struct chacha_req
*creq
= &rctx
->u
.chacha
;
390 chacha_iv(creq
->iv
, req
, 1);
392 ablkcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
393 chacha_encrypt_done
, req
);
394 ablkcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
395 ablkcipher_request_set_crypt(&creq
->req
, req
->src
, req
->dst
,
396 req
->cryptlen
, creq
->iv
);
397 err
= crypto_ablkcipher_encrypt(&creq
->req
);
401 return poly_genkey(req
);
404 static int chachapoly_encrypt(struct aead_request
*req
)
406 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
408 rctx
->cryptlen
= req
->cryptlen
;
410 /* encrypt call chain:
411 * - chacha_encrypt/done()
412 * - poly_genkey/done()
414 * - poly_setkey/done()
416 * - poly_adpad/done()
417 * - poly_cipher/done()
418 * - poly_cipherpad/done()
419 * - poly_tail/done/continue()
422 return chacha_encrypt(req
);
425 static int chachapoly_decrypt(struct aead_request
*req
)
427 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
429 if (req
->cryptlen
< POLY1305_DIGEST_SIZE
)
431 rctx
->cryptlen
= req
->cryptlen
- POLY1305_DIGEST_SIZE
;
433 /* decrypt call chain:
434 * - poly_genkey/done()
436 * - poly_setkey/done()
438 * - poly_adpad/done()
439 * - poly_cipher/done()
440 * - poly_cipherpad/done()
441 * - poly_tail/done/continue()
442 * - chacha_decrypt/done()
443 * - poly_verify_tag()
445 return poly_genkey(req
);
448 static int chachapoly_setkey(struct crypto_aead
*aead
, const u8
*key
,
451 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(aead
);
454 if (keylen
!= ctx
->saltlen
+ CHACHA20_KEY_SIZE
)
457 keylen
-= ctx
->saltlen
;
458 memcpy(ctx
->salt
, key
+ keylen
, ctx
->saltlen
);
460 crypto_ablkcipher_clear_flags(ctx
->chacha
, CRYPTO_TFM_REQ_MASK
);
461 crypto_ablkcipher_set_flags(ctx
->chacha
, crypto_aead_get_flags(aead
) &
462 CRYPTO_TFM_REQ_MASK
);
464 err
= crypto_ablkcipher_setkey(ctx
->chacha
, key
, keylen
);
465 crypto_aead_set_flags(aead
, crypto_ablkcipher_get_flags(ctx
->chacha
) &
466 CRYPTO_TFM_RES_MASK
);
470 static int chachapoly_setauthsize(struct crypto_aead
*tfm
,
471 unsigned int authsize
)
473 if (authsize
!= POLY1305_DIGEST_SIZE
)
479 static int chachapoly_init(struct crypto_tfm
*tfm
)
481 struct crypto_instance
*inst
= (void *)tfm
->__crt_alg
;
482 struct chachapoly_instance_ctx
*ictx
= crypto_instance_ctx(inst
);
483 struct chachapoly_ctx
*ctx
= crypto_tfm_ctx(tfm
);
484 struct crypto_ablkcipher
*chacha
;
485 struct crypto_ahash
*poly
;
488 poly
= crypto_spawn_ahash(&ictx
->poly
);
490 return PTR_ERR(poly
);
492 chacha
= crypto_spawn_skcipher(&ictx
->chacha
);
493 if (IS_ERR(chacha
)) {
494 crypto_free_ahash(poly
);
495 return PTR_ERR(chacha
);
498 ctx
->chacha
= chacha
;
500 ctx
->saltlen
= ictx
->saltlen
;
502 align
= crypto_tfm_alg_alignmask(tfm
);
503 align
&= ~(crypto_tfm_ctx_alignment() - 1);
504 crypto_aead_set_reqsize(__crypto_aead_cast(tfm
),
505 align
+ offsetof(struct chachapoly_req_ctx
, u
) +
506 max(offsetof(struct chacha_req
, req
) +
507 sizeof(struct ablkcipher_request
) +
508 crypto_ablkcipher_reqsize(chacha
),
509 offsetof(struct poly_req
, req
) +
510 sizeof(struct ahash_request
) +
511 crypto_ahash_reqsize(poly
)));
516 static void chachapoly_exit(struct crypto_tfm
*tfm
)
518 struct chachapoly_ctx
*ctx
= crypto_tfm_ctx(tfm
);
520 crypto_free_ahash(ctx
->poly
);
521 crypto_free_ablkcipher(ctx
->chacha
);
524 static struct crypto_instance
*chachapoly_alloc(struct rtattr
**tb
,
528 struct crypto_attr_type
*algt
;
529 struct crypto_instance
*inst
;
530 struct crypto_alg
*chacha
;
531 struct crypto_alg
*poly
;
532 struct ahash_alg
*poly_ahash
;
533 struct chachapoly_instance_ctx
*ctx
;
534 const char *chacha_name
, *poly_name
;
537 if (ivsize
> CHACHAPOLY_IV_SIZE
)
538 return ERR_PTR(-EINVAL
);
540 algt
= crypto_get_attr_type(tb
);
542 return ERR_CAST(algt
);
544 if ((algt
->type
^ CRYPTO_ALG_TYPE_AEAD
) & algt
->mask
)
545 return ERR_PTR(-EINVAL
);
547 chacha_name
= crypto_attr_alg_name(tb
[1]);
548 if (IS_ERR(chacha_name
))
549 return ERR_CAST(chacha_name
);
550 poly_name
= crypto_attr_alg_name(tb
[2]);
551 if (IS_ERR(poly_name
))
552 return ERR_CAST(poly_name
);
554 poly
= crypto_find_alg(poly_name
, &crypto_ahash_type
,
555 CRYPTO_ALG_TYPE_HASH
,
556 CRYPTO_ALG_TYPE_AHASH_MASK
);
558 return ERR_CAST(poly
);
561 inst
= kzalloc(sizeof(*inst
) + sizeof(*ctx
), GFP_KERNEL
);
565 ctx
= crypto_instance_ctx(inst
);
566 ctx
->saltlen
= CHACHAPOLY_IV_SIZE
- ivsize
;
567 poly_ahash
= container_of(poly
, struct ahash_alg
, halg
.base
);
568 err
= crypto_init_ahash_spawn(&ctx
->poly
, &poly_ahash
->halg
, inst
);
572 crypto_set_skcipher_spawn(&ctx
->chacha
, inst
);
573 err
= crypto_grab_skcipher(&ctx
->chacha
, chacha_name
, 0,
574 crypto_requires_sync(algt
->type
,
579 chacha
= crypto_skcipher_spawn_alg(&ctx
->chacha
);
582 /* Need 16-byte IV size, including Initial Block Counter value */
583 if (chacha
->cra_ablkcipher
.ivsize
!= CHACHA20_IV_SIZE
)
584 goto out_drop_chacha
;
585 /* Not a stream cipher? */
586 if (chacha
->cra_blocksize
!= 1)
587 goto out_drop_chacha
;
590 if (snprintf(inst
->alg
.cra_name
, CRYPTO_MAX_ALG_NAME
,
591 "%s(%s,%s)", name
, chacha_name
,
592 poly_name
) >= CRYPTO_MAX_ALG_NAME
)
593 goto out_drop_chacha
;
594 if (snprintf(inst
->alg
.cra_driver_name
, CRYPTO_MAX_ALG_NAME
,
595 "%s(%s,%s)", name
, chacha
->cra_driver_name
,
596 poly
->cra_driver_name
) >= CRYPTO_MAX_ALG_NAME
)
597 goto out_drop_chacha
;
599 inst
->alg
.cra_flags
= CRYPTO_ALG_TYPE_AEAD
;
600 inst
->alg
.cra_flags
|= (chacha
->cra_flags
|
601 poly
->cra_flags
) & CRYPTO_ALG_ASYNC
;
602 inst
->alg
.cra_priority
= (chacha
->cra_priority
+
603 poly
->cra_priority
) / 2;
604 inst
->alg
.cra_blocksize
= 1;
605 inst
->alg
.cra_alignmask
= chacha
->cra_alignmask
| poly
->cra_alignmask
;
606 inst
->alg
.cra_type
= &crypto_nivaead_type
;
607 inst
->alg
.cra_aead
.ivsize
= ivsize
;
608 inst
->alg
.cra_aead
.maxauthsize
= POLY1305_DIGEST_SIZE
;
609 inst
->alg
.cra_ctxsize
= sizeof(struct chachapoly_ctx
) + ctx
->saltlen
;
610 inst
->alg
.cra_init
= chachapoly_init
;
611 inst
->alg
.cra_exit
= chachapoly_exit
;
612 inst
->alg
.cra_aead
.encrypt
= chachapoly_encrypt
;
613 inst
->alg
.cra_aead
.decrypt
= chachapoly_decrypt
;
614 inst
->alg
.cra_aead
.setkey
= chachapoly_setkey
;
615 inst
->alg
.cra_aead
.setauthsize
= chachapoly_setauthsize
;
616 inst
->alg
.cra_aead
.geniv
= "seqiv";
619 crypto_mod_put(poly
);
623 crypto_drop_skcipher(&ctx
->chacha
);
625 crypto_drop_ahash(&ctx
->poly
);
633 static struct crypto_instance
*rfc7539_alloc(struct rtattr
**tb
)
635 return chachapoly_alloc(tb
, "rfc7539", 12);
638 static struct crypto_instance
*rfc7539esp_alloc(struct rtattr
**tb
)
640 return chachapoly_alloc(tb
, "rfc7539esp", 8);
643 static void chachapoly_free(struct crypto_instance
*inst
)
645 struct chachapoly_instance_ctx
*ctx
= crypto_instance_ctx(inst
);
647 crypto_drop_skcipher(&ctx
->chacha
);
648 crypto_drop_ahash(&ctx
->poly
);
652 static struct crypto_template rfc7539_tmpl
= {
654 .alloc
= rfc7539_alloc
,
655 .free
= chachapoly_free
,
656 .module
= THIS_MODULE
,
659 static struct crypto_template rfc7539esp_tmpl
= {
660 .name
= "rfc7539esp",
661 .alloc
= rfc7539esp_alloc
,
662 .free
= chachapoly_free
,
663 .module
= THIS_MODULE
,
666 static int __init
chacha20poly1305_module_init(void)
670 err
= crypto_register_template(&rfc7539_tmpl
);
674 err
= crypto_register_template(&rfc7539esp_tmpl
);
676 crypto_unregister_template(&rfc7539_tmpl
);
681 static void __exit
chacha20poly1305_module_exit(void)
683 crypto_unregister_template(&rfc7539esp_tmpl
);
684 crypto_unregister_template(&rfc7539_tmpl
);
687 module_init(chacha20poly1305_module_init
);
688 module_exit(chacha20poly1305_module_exit
);
690 MODULE_LICENSE("GPL");
691 MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");
692 MODULE_DESCRIPTION("ChaCha20-Poly1305 AEAD");
693 MODULE_ALIAS_CRYPTO("chacha20poly1305");
694 MODULE_ALIAS_CRYPTO("rfc7539");
695 MODULE_ALIAS_CRYPTO("rfc7539esp");