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_skcipher
*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 skcipher_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 if (rctx
->cryptlen
== 0)
136 chacha_iv(creq
->iv
, req
, 1);
138 sg_init_table(rctx
->src
, 2);
139 src
= scatterwalk_ffwd(rctx
->src
, req
->src
, req
->assoclen
);
142 if (req
->src
!= req
->dst
) {
143 sg_init_table(rctx
->dst
, 2);
144 dst
= scatterwalk_ffwd(rctx
->dst
, req
->dst
, req
->assoclen
);
147 skcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
148 chacha_decrypt_done
, req
);
149 skcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
150 skcipher_request_set_crypt(&creq
->req
, src
, dst
,
151 rctx
->cryptlen
, creq
->iv
);
152 err
= crypto_skcipher_decrypt(&creq
->req
);
157 return poly_verify_tag(req
);
160 static int poly_tail_continue(struct aead_request
*req
)
162 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
164 if (rctx
->cryptlen
== req
->cryptlen
) /* encrypting */
165 return poly_copy_tag(req
);
167 return chacha_decrypt(req
);
170 static void poly_tail_done(struct crypto_async_request
*areq
, int err
)
172 async_done_continue(areq
->data
, err
, poly_tail_continue
);
175 static int poly_tail(struct aead_request
*req
)
177 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
178 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
179 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
180 struct poly_req
*preq
= &rctx
->u
.poly
;
184 sg_init_table(preq
->src
, 1);
185 len
= cpu_to_le64(rctx
->assoclen
);
186 memcpy(&preq
->tail
.assoclen
, &len
, sizeof(len
));
187 len
= cpu_to_le64(rctx
->cryptlen
);
188 memcpy(&preq
->tail
.cryptlen
, &len
, sizeof(len
));
189 sg_set_buf(preq
->src
, &preq
->tail
, sizeof(preq
->tail
));
191 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
192 poly_tail_done
, req
);
193 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
194 ahash_request_set_crypt(&preq
->req
, preq
->src
,
195 rctx
->tag
, sizeof(preq
->tail
));
197 err
= crypto_ahash_finup(&preq
->req
);
201 return poly_tail_continue(req
);
204 static void poly_cipherpad_done(struct crypto_async_request
*areq
, int err
)
206 async_done_continue(areq
->data
, err
, poly_tail
);
209 static int poly_cipherpad(struct aead_request
*req
)
211 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
212 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
213 struct poly_req
*preq
= &rctx
->u
.poly
;
214 unsigned int padlen
, bs
= POLY1305_BLOCK_SIZE
;
217 padlen
= (bs
- (rctx
->cryptlen
% bs
)) % bs
;
218 memset(preq
->pad
, 0, sizeof(preq
->pad
));
219 sg_init_table(preq
->src
, 1);
220 sg_set_buf(preq
->src
, &preq
->pad
, padlen
);
222 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
223 poly_cipherpad_done
, req
);
224 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
225 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, padlen
);
227 err
= crypto_ahash_update(&preq
->req
);
231 return poly_tail(req
);
234 static void poly_cipher_done(struct crypto_async_request
*areq
, int err
)
236 async_done_continue(areq
->data
, err
, poly_cipherpad
);
239 static int poly_cipher(struct aead_request
*req
)
241 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
242 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
243 struct poly_req
*preq
= &rctx
->u
.poly
;
244 struct scatterlist
*crypt
= req
->src
;
247 if (rctx
->cryptlen
== req
->cryptlen
) /* encrypting */
250 sg_init_table(rctx
->src
, 2);
251 crypt
= scatterwalk_ffwd(rctx
->src
, crypt
, req
->assoclen
);
253 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
254 poly_cipher_done
, req
);
255 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
256 ahash_request_set_crypt(&preq
->req
, crypt
, NULL
, rctx
->cryptlen
);
258 err
= crypto_ahash_update(&preq
->req
);
262 return poly_cipherpad(req
);
265 static void poly_adpad_done(struct crypto_async_request
*areq
, int err
)
267 async_done_continue(areq
->data
, err
, poly_cipher
);
270 static int poly_adpad(struct aead_request
*req
)
272 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
273 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
274 struct poly_req
*preq
= &rctx
->u
.poly
;
275 unsigned int padlen
, bs
= POLY1305_BLOCK_SIZE
;
278 padlen
= (bs
- (rctx
->assoclen
% bs
)) % bs
;
279 memset(preq
->pad
, 0, sizeof(preq
->pad
));
280 sg_init_table(preq
->src
, 1);
281 sg_set_buf(preq
->src
, preq
->pad
, padlen
);
283 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
284 poly_adpad_done
, req
);
285 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
286 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, padlen
);
288 err
= crypto_ahash_update(&preq
->req
);
292 return poly_cipher(req
);
295 static void poly_ad_done(struct crypto_async_request
*areq
, int err
)
297 async_done_continue(areq
->data
, err
, poly_adpad
);
300 static int poly_ad(struct aead_request
*req
)
302 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
303 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
304 struct poly_req
*preq
= &rctx
->u
.poly
;
307 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
309 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
310 ahash_request_set_crypt(&preq
->req
, req
->src
, NULL
, rctx
->assoclen
);
312 err
= crypto_ahash_update(&preq
->req
);
316 return poly_adpad(req
);
319 static void poly_setkey_done(struct crypto_async_request
*areq
, int err
)
321 async_done_continue(areq
->data
, err
, poly_ad
);
324 static int poly_setkey(struct aead_request
*req
)
326 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
327 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
328 struct poly_req
*preq
= &rctx
->u
.poly
;
331 sg_init_table(preq
->src
, 1);
332 sg_set_buf(preq
->src
, rctx
->key
, sizeof(rctx
->key
));
334 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
335 poly_setkey_done
, req
);
336 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
337 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, sizeof(rctx
->key
));
339 err
= crypto_ahash_update(&preq
->req
);
346 static void poly_init_done(struct crypto_async_request
*areq
, int err
)
348 async_done_continue(areq
->data
, err
, poly_setkey
);
351 static int poly_init(struct aead_request
*req
)
353 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
354 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
355 struct poly_req
*preq
= &rctx
->u
.poly
;
358 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
359 poly_init_done
, req
);
360 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
362 err
= crypto_ahash_init(&preq
->req
);
366 return poly_setkey(req
);
369 static void poly_genkey_done(struct crypto_async_request
*areq
, int err
)
371 async_done_continue(areq
->data
, err
, poly_init
);
374 static int poly_genkey(struct aead_request
*req
)
376 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
377 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
378 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
379 struct chacha_req
*creq
= &rctx
->u
.chacha
;
382 rctx
->assoclen
= req
->assoclen
;
384 if (crypto_aead_ivsize(tfm
) == 8) {
385 if (rctx
->assoclen
< 8)
390 sg_init_table(creq
->src
, 1);
391 memset(rctx
->key
, 0, sizeof(rctx
->key
));
392 sg_set_buf(creq
->src
, rctx
->key
, sizeof(rctx
->key
));
394 chacha_iv(creq
->iv
, req
, 0);
396 skcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
397 poly_genkey_done
, req
);
398 skcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
399 skcipher_request_set_crypt(&creq
->req
, creq
->src
, creq
->src
,
400 POLY1305_KEY_SIZE
, creq
->iv
);
402 err
= crypto_skcipher_decrypt(&creq
->req
);
406 return poly_init(req
);
409 static void chacha_encrypt_done(struct crypto_async_request
*areq
, int err
)
411 async_done_continue(areq
->data
, err
, poly_genkey
);
414 static int chacha_encrypt(struct aead_request
*req
)
416 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
417 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
418 struct chacha_req
*creq
= &rctx
->u
.chacha
;
419 struct scatterlist
*src
, *dst
;
422 if (req
->cryptlen
== 0)
425 chacha_iv(creq
->iv
, req
, 1);
427 sg_init_table(rctx
->src
, 2);
428 src
= scatterwalk_ffwd(rctx
->src
, req
->src
, req
->assoclen
);
431 if (req
->src
!= req
->dst
) {
432 sg_init_table(rctx
->dst
, 2);
433 dst
= scatterwalk_ffwd(rctx
->dst
, req
->dst
, req
->assoclen
);
436 skcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
437 chacha_encrypt_done
, req
);
438 skcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
439 skcipher_request_set_crypt(&creq
->req
, src
, dst
,
440 req
->cryptlen
, creq
->iv
);
441 err
= crypto_skcipher_encrypt(&creq
->req
);
446 return poly_genkey(req
);
449 static int chachapoly_encrypt(struct aead_request
*req
)
451 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
453 rctx
->cryptlen
= req
->cryptlen
;
455 /* encrypt call chain:
456 * - chacha_encrypt/done()
457 * - poly_genkey/done()
459 * - poly_setkey/done()
461 * - poly_adpad/done()
462 * - poly_cipher/done()
463 * - poly_cipherpad/done()
464 * - poly_tail/done/continue()
467 return chacha_encrypt(req
);
470 static int chachapoly_decrypt(struct aead_request
*req
)
472 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
474 rctx
->cryptlen
= req
->cryptlen
- POLY1305_DIGEST_SIZE
;
476 /* decrypt call chain:
477 * - poly_genkey/done()
479 * - poly_setkey/done()
481 * - poly_adpad/done()
482 * - poly_cipher/done()
483 * - poly_cipherpad/done()
484 * - poly_tail/done/continue()
485 * - chacha_decrypt/done()
486 * - poly_verify_tag()
488 return poly_genkey(req
);
491 static int chachapoly_setkey(struct crypto_aead
*aead
, const u8
*key
,
494 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(aead
);
497 if (keylen
!= ctx
->saltlen
+ CHACHA20_KEY_SIZE
)
500 keylen
-= ctx
->saltlen
;
501 memcpy(ctx
->salt
, key
+ keylen
, ctx
->saltlen
);
503 crypto_skcipher_clear_flags(ctx
->chacha
, CRYPTO_TFM_REQ_MASK
);
504 crypto_skcipher_set_flags(ctx
->chacha
, crypto_aead_get_flags(aead
) &
505 CRYPTO_TFM_REQ_MASK
);
507 err
= crypto_skcipher_setkey(ctx
->chacha
, key
, keylen
);
508 crypto_aead_set_flags(aead
, crypto_skcipher_get_flags(ctx
->chacha
) &
509 CRYPTO_TFM_RES_MASK
);
513 static int chachapoly_setauthsize(struct crypto_aead
*tfm
,
514 unsigned int authsize
)
516 if (authsize
!= POLY1305_DIGEST_SIZE
)
522 static int chachapoly_init(struct crypto_aead
*tfm
)
524 struct aead_instance
*inst
= aead_alg_instance(tfm
);
525 struct chachapoly_instance_ctx
*ictx
= aead_instance_ctx(inst
);
526 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
527 struct crypto_skcipher
*chacha
;
528 struct crypto_ahash
*poly
;
531 poly
= crypto_spawn_ahash(&ictx
->poly
);
533 return PTR_ERR(poly
);
535 chacha
= crypto_spawn_skcipher(&ictx
->chacha
);
536 if (IS_ERR(chacha
)) {
537 crypto_free_ahash(poly
);
538 return PTR_ERR(chacha
);
541 ctx
->chacha
= chacha
;
543 ctx
->saltlen
= ictx
->saltlen
;
545 align
= crypto_aead_alignmask(tfm
);
546 align
&= ~(crypto_tfm_ctx_alignment() - 1);
547 crypto_aead_set_reqsize(
549 align
+ offsetof(struct chachapoly_req_ctx
, u
) +
550 max(offsetof(struct chacha_req
, req
) +
551 sizeof(struct skcipher_request
) +
552 crypto_skcipher_reqsize(chacha
),
553 offsetof(struct poly_req
, req
) +
554 sizeof(struct ahash_request
) +
555 crypto_ahash_reqsize(poly
)));
560 static void chachapoly_exit(struct crypto_aead
*tfm
)
562 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
564 crypto_free_ahash(ctx
->poly
);
565 crypto_free_skcipher(ctx
->chacha
);
568 static void chachapoly_free(struct aead_instance
*inst
)
570 struct chachapoly_instance_ctx
*ctx
= aead_instance_ctx(inst
);
572 crypto_drop_skcipher(&ctx
->chacha
);
573 crypto_drop_ahash(&ctx
->poly
);
577 static int chachapoly_create(struct crypto_template
*tmpl
, struct rtattr
**tb
,
578 const char *name
, unsigned int ivsize
)
580 struct crypto_attr_type
*algt
;
581 struct aead_instance
*inst
;
582 struct skcipher_alg
*chacha
;
583 struct crypto_alg
*poly
;
584 struct hash_alg_common
*poly_hash
;
585 struct chachapoly_instance_ctx
*ctx
;
586 const char *chacha_name
, *poly_name
;
589 if (ivsize
> CHACHAPOLY_IV_SIZE
)
592 algt
= crypto_get_attr_type(tb
);
594 return PTR_ERR(algt
);
596 if ((algt
->type
^ CRYPTO_ALG_TYPE_AEAD
) & algt
->mask
)
599 chacha_name
= crypto_attr_alg_name(tb
[1]);
600 if (IS_ERR(chacha_name
))
601 return PTR_ERR(chacha_name
);
602 poly_name
= crypto_attr_alg_name(tb
[2]);
603 if (IS_ERR(poly_name
))
604 return PTR_ERR(poly_name
);
606 poly
= crypto_find_alg(poly_name
, &crypto_ahash_type
,
607 CRYPTO_ALG_TYPE_HASH
,
608 CRYPTO_ALG_TYPE_AHASH_MASK
|
609 crypto_requires_sync(algt
->type
,
612 return PTR_ERR(poly
);
615 inst
= kzalloc(sizeof(*inst
) + sizeof(*ctx
), GFP_KERNEL
);
619 ctx
= aead_instance_ctx(inst
);
620 ctx
->saltlen
= CHACHAPOLY_IV_SIZE
- ivsize
;
621 poly_hash
= __crypto_hash_alg_common(poly
);
622 err
= crypto_init_ahash_spawn(&ctx
->poly
, poly_hash
,
623 aead_crypto_instance(inst
));
627 crypto_set_skcipher_spawn(&ctx
->chacha
, aead_crypto_instance(inst
));
628 err
= crypto_grab_skcipher(&ctx
->chacha
, chacha_name
, 0,
629 crypto_requires_sync(algt
->type
,
634 chacha
= crypto_spawn_skcipher_alg(&ctx
->chacha
);
637 /* Need 16-byte IV size, including Initial Block Counter value */
638 if (crypto_skcipher_alg_ivsize(chacha
) != CHACHA20_IV_SIZE
)
639 goto out_drop_chacha
;
640 /* Not a stream cipher? */
641 if (chacha
->base
.cra_blocksize
!= 1)
642 goto out_drop_chacha
;
645 if (snprintf(inst
->alg
.base
.cra_name
, CRYPTO_MAX_ALG_NAME
,
646 "%s(%s,%s)", name
, chacha_name
,
647 poly_name
) >= CRYPTO_MAX_ALG_NAME
)
648 goto out_drop_chacha
;
649 if (snprintf(inst
->alg
.base
.cra_driver_name
, CRYPTO_MAX_ALG_NAME
,
650 "%s(%s,%s)", name
, chacha
->base
.cra_driver_name
,
651 poly
->cra_driver_name
) >= CRYPTO_MAX_ALG_NAME
)
652 goto out_drop_chacha
;
654 inst
->alg
.base
.cra_flags
= (chacha
->base
.cra_flags
| poly
->cra_flags
) &
656 inst
->alg
.base
.cra_priority
= (chacha
->base
.cra_priority
+
657 poly
->cra_priority
) / 2;
658 inst
->alg
.base
.cra_blocksize
= 1;
659 inst
->alg
.base
.cra_alignmask
= chacha
->base
.cra_alignmask
|
661 inst
->alg
.base
.cra_ctxsize
= sizeof(struct chachapoly_ctx
) +
663 inst
->alg
.ivsize
= ivsize
;
664 inst
->alg
.chunksize
= crypto_skcipher_alg_chunksize(chacha
);
665 inst
->alg
.maxauthsize
= POLY1305_DIGEST_SIZE
;
666 inst
->alg
.init
= chachapoly_init
;
667 inst
->alg
.exit
= chachapoly_exit
;
668 inst
->alg
.encrypt
= chachapoly_encrypt
;
669 inst
->alg
.decrypt
= chachapoly_decrypt
;
670 inst
->alg
.setkey
= chachapoly_setkey
;
671 inst
->alg
.setauthsize
= chachapoly_setauthsize
;
673 inst
->free
= chachapoly_free
;
675 err
= aead_register_instance(tmpl
, inst
);
677 goto out_drop_chacha
;
680 crypto_mod_put(poly
);
684 crypto_drop_skcipher(&ctx
->chacha
);
686 crypto_drop_ahash(&ctx
->poly
);
692 static int rfc7539_create(struct crypto_template
*tmpl
, struct rtattr
**tb
)
694 return chachapoly_create(tmpl
, tb
, "rfc7539", 12);
697 static int rfc7539esp_create(struct crypto_template
*tmpl
, struct rtattr
**tb
)
699 return chachapoly_create(tmpl
, tb
, "rfc7539esp", 8);
702 static struct crypto_template rfc7539_tmpl
= {
704 .create
= rfc7539_create
,
705 .module
= THIS_MODULE
,
708 static struct crypto_template rfc7539esp_tmpl
= {
709 .name
= "rfc7539esp",
710 .create
= rfc7539esp_create
,
711 .module
= THIS_MODULE
,
714 static int __init
chacha20poly1305_module_init(void)
718 err
= crypto_register_template(&rfc7539_tmpl
);
722 err
= crypto_register_template(&rfc7539esp_tmpl
);
724 crypto_unregister_template(&rfc7539_tmpl
);
729 static void __exit
chacha20poly1305_module_exit(void)
731 crypto_unregister_template(&rfc7539esp_tmpl
);
732 crypto_unregister_template(&rfc7539_tmpl
);
735 module_init(chacha20poly1305_module_init
);
736 module_exit(chacha20poly1305_module_exit
);
738 MODULE_LICENSE("GPL");
739 MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");
740 MODULE_DESCRIPTION("ChaCha20-Poly1305 AEAD");
741 MODULE_ALIAS_CRYPTO("rfc7539");
742 MODULE_ALIAS_CRYPTO("rfc7539esp");