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/chacha.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 struct chachapoly_instance_ctx
{
26 struct crypto_skcipher_spawn chacha
;
27 struct crypto_ahash_spawn poly
;
31 struct chachapoly_ctx
{
32 struct crypto_skcipher
*chacha
;
33 struct crypto_ahash
*poly
;
34 /* key bytes we use for the ChaCha20 IV */
40 /* zero byte padding for AD/ciphertext, as needed */
41 u8 pad
[POLY1305_BLOCK_SIZE
];
42 /* tail data with AD/ciphertext lengths */
47 struct scatterlist src
[1];
48 struct ahash_request req
; /* must be last member */
52 u8 iv
[CHACHA_IV_SIZE
];
53 struct scatterlist src
[1];
54 struct skcipher_request req
; /* must be last member */
57 struct chachapoly_req_ctx
{
58 struct scatterlist src
[2];
59 struct scatterlist dst
[2];
60 /* the key we generate for Poly1305 using Chacha20 */
61 u8 key
[POLY1305_KEY_SIZE
];
62 /* calculated Poly1305 tag */
63 u8 tag
[POLY1305_DIGEST_SIZE
];
64 /* length of data to en/decrypt, without ICV */
65 unsigned int cryptlen
;
66 /* Actual AD, excluding IV */
67 unsigned int assoclen
;
70 struct chacha_req chacha
;
74 static inline void async_done_continue(struct aead_request
*req
, int err
,
75 int (*cont
)(struct aead_request
*))
80 if (err
!= -EINPROGRESS
&& err
!= -EBUSY
)
81 aead_request_complete(req
, err
);
84 static void chacha_iv(u8
*iv
, struct aead_request
*req
, u32 icb
)
86 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
87 __le32 leicb
= cpu_to_le32(icb
);
89 memcpy(iv
, &leicb
, sizeof(leicb
));
90 memcpy(iv
+ sizeof(leicb
), ctx
->salt
, ctx
->saltlen
);
91 memcpy(iv
+ sizeof(leicb
) + ctx
->saltlen
, req
->iv
,
92 CHACHA_IV_SIZE
- sizeof(leicb
) - ctx
->saltlen
);
95 static int poly_verify_tag(struct aead_request
*req
)
97 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
98 u8 tag
[sizeof(rctx
->tag
)];
100 scatterwalk_map_and_copy(tag
, req
->src
,
101 req
->assoclen
+ rctx
->cryptlen
,
103 if (crypto_memneq(tag
, rctx
->tag
, sizeof(tag
)))
108 static int poly_copy_tag(struct aead_request
*req
)
110 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
112 scatterwalk_map_and_copy(rctx
->tag
, req
->dst
,
113 req
->assoclen
+ rctx
->cryptlen
,
114 sizeof(rctx
->tag
), 1);
118 static void chacha_decrypt_done(struct crypto_async_request
*areq
, int err
)
120 async_done_continue(areq
->data
, err
, poly_verify_tag
);
123 static int chacha_decrypt(struct aead_request
*req
)
125 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
126 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
127 struct chacha_req
*creq
= &rctx
->u
.chacha
;
128 struct scatterlist
*src
, *dst
;
131 if (rctx
->cryptlen
== 0)
134 chacha_iv(creq
->iv
, req
, 1);
136 sg_init_table(rctx
->src
, 2);
137 src
= scatterwalk_ffwd(rctx
->src
, req
->src
, req
->assoclen
);
140 if (req
->src
!= req
->dst
) {
141 sg_init_table(rctx
->dst
, 2);
142 dst
= scatterwalk_ffwd(rctx
->dst
, req
->dst
, req
->assoclen
);
145 skcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
146 chacha_decrypt_done
, req
);
147 skcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
148 skcipher_request_set_crypt(&creq
->req
, src
, dst
,
149 rctx
->cryptlen
, creq
->iv
);
150 err
= crypto_skcipher_decrypt(&creq
->req
);
155 return poly_verify_tag(req
);
158 static int poly_tail_continue(struct aead_request
*req
)
160 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
162 if (rctx
->cryptlen
== req
->cryptlen
) /* encrypting */
163 return poly_copy_tag(req
);
165 return chacha_decrypt(req
);
168 static void poly_tail_done(struct crypto_async_request
*areq
, int err
)
170 async_done_continue(areq
->data
, err
, poly_tail_continue
);
173 static int poly_tail(struct aead_request
*req
)
175 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
176 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
177 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
178 struct poly_req
*preq
= &rctx
->u
.poly
;
182 sg_init_table(preq
->src
, 1);
183 len
= cpu_to_le64(rctx
->assoclen
);
184 memcpy(&preq
->tail
.assoclen
, &len
, sizeof(len
));
185 len
= cpu_to_le64(rctx
->cryptlen
);
186 memcpy(&preq
->tail
.cryptlen
, &len
, sizeof(len
));
187 sg_set_buf(preq
->src
, &preq
->tail
, sizeof(preq
->tail
));
189 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
190 poly_tail_done
, req
);
191 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
192 ahash_request_set_crypt(&preq
->req
, preq
->src
,
193 rctx
->tag
, sizeof(preq
->tail
));
195 err
= crypto_ahash_finup(&preq
->req
);
199 return poly_tail_continue(req
);
202 static void poly_cipherpad_done(struct crypto_async_request
*areq
, int err
)
204 async_done_continue(areq
->data
, err
, poly_tail
);
207 static int poly_cipherpad(struct aead_request
*req
)
209 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
210 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
211 struct poly_req
*preq
= &rctx
->u
.poly
;
212 unsigned int padlen
, bs
= POLY1305_BLOCK_SIZE
;
215 padlen
= (bs
- (rctx
->cryptlen
% bs
)) % bs
;
216 memset(preq
->pad
, 0, sizeof(preq
->pad
));
217 sg_init_table(preq
->src
, 1);
218 sg_set_buf(preq
->src
, &preq
->pad
, padlen
);
220 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
221 poly_cipherpad_done
, req
);
222 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
223 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, padlen
);
225 err
= crypto_ahash_update(&preq
->req
);
229 return poly_tail(req
);
232 static void poly_cipher_done(struct crypto_async_request
*areq
, int err
)
234 async_done_continue(areq
->data
, err
, poly_cipherpad
);
237 static int poly_cipher(struct aead_request
*req
)
239 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
240 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
241 struct poly_req
*preq
= &rctx
->u
.poly
;
242 struct scatterlist
*crypt
= req
->src
;
245 if (rctx
->cryptlen
== req
->cryptlen
) /* encrypting */
248 sg_init_table(rctx
->src
, 2);
249 crypt
= scatterwalk_ffwd(rctx
->src
, crypt
, req
->assoclen
);
251 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
252 poly_cipher_done
, req
);
253 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
254 ahash_request_set_crypt(&preq
->req
, crypt
, NULL
, rctx
->cryptlen
);
256 err
= crypto_ahash_update(&preq
->req
);
260 return poly_cipherpad(req
);
263 static void poly_adpad_done(struct crypto_async_request
*areq
, int err
)
265 async_done_continue(areq
->data
, err
, poly_cipher
);
268 static int poly_adpad(struct aead_request
*req
)
270 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
271 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
272 struct poly_req
*preq
= &rctx
->u
.poly
;
273 unsigned int padlen
, bs
= POLY1305_BLOCK_SIZE
;
276 padlen
= (bs
- (rctx
->assoclen
% bs
)) % bs
;
277 memset(preq
->pad
, 0, sizeof(preq
->pad
));
278 sg_init_table(preq
->src
, 1);
279 sg_set_buf(preq
->src
, preq
->pad
, padlen
);
281 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
282 poly_adpad_done
, req
);
283 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
284 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, padlen
);
286 err
= crypto_ahash_update(&preq
->req
);
290 return poly_cipher(req
);
293 static void poly_ad_done(struct crypto_async_request
*areq
, int err
)
295 async_done_continue(areq
->data
, err
, poly_adpad
);
298 static int poly_ad(struct aead_request
*req
)
300 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
301 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
302 struct poly_req
*preq
= &rctx
->u
.poly
;
305 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
307 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
308 ahash_request_set_crypt(&preq
->req
, req
->src
, NULL
, rctx
->assoclen
);
310 err
= crypto_ahash_update(&preq
->req
);
314 return poly_adpad(req
);
317 static void poly_setkey_done(struct crypto_async_request
*areq
, int err
)
319 async_done_continue(areq
->data
, err
, poly_ad
);
322 static int poly_setkey(struct aead_request
*req
)
324 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
325 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
326 struct poly_req
*preq
= &rctx
->u
.poly
;
329 sg_init_table(preq
->src
, 1);
330 sg_set_buf(preq
->src
, rctx
->key
, sizeof(rctx
->key
));
332 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
333 poly_setkey_done
, req
);
334 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
335 ahash_request_set_crypt(&preq
->req
, preq
->src
, NULL
, sizeof(rctx
->key
));
337 err
= crypto_ahash_update(&preq
->req
);
344 static void poly_init_done(struct crypto_async_request
*areq
, int err
)
346 async_done_continue(areq
->data
, err
, poly_setkey
);
349 static int poly_init(struct aead_request
*req
)
351 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
352 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
353 struct poly_req
*preq
= &rctx
->u
.poly
;
356 ahash_request_set_callback(&preq
->req
, aead_request_flags(req
),
357 poly_init_done
, req
);
358 ahash_request_set_tfm(&preq
->req
, ctx
->poly
);
360 err
= crypto_ahash_init(&preq
->req
);
364 return poly_setkey(req
);
367 static void poly_genkey_done(struct crypto_async_request
*areq
, int err
)
369 async_done_continue(areq
->data
, err
, poly_init
);
372 static int poly_genkey(struct aead_request
*req
)
374 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
375 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
376 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
377 struct chacha_req
*creq
= &rctx
->u
.chacha
;
380 rctx
->assoclen
= req
->assoclen
;
382 if (crypto_aead_ivsize(tfm
) == 8) {
383 if (rctx
->assoclen
< 8)
388 sg_init_table(creq
->src
, 1);
389 memset(rctx
->key
, 0, sizeof(rctx
->key
));
390 sg_set_buf(creq
->src
, rctx
->key
, sizeof(rctx
->key
));
392 chacha_iv(creq
->iv
, req
, 0);
394 skcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
395 poly_genkey_done
, req
);
396 skcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
397 skcipher_request_set_crypt(&creq
->req
, creq
->src
, creq
->src
,
398 POLY1305_KEY_SIZE
, creq
->iv
);
400 err
= crypto_skcipher_decrypt(&creq
->req
);
404 return poly_init(req
);
407 static void chacha_encrypt_done(struct crypto_async_request
*areq
, int err
)
409 async_done_continue(areq
->data
, err
, poly_genkey
);
412 static int chacha_encrypt(struct aead_request
*req
)
414 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(crypto_aead_reqtfm(req
));
415 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
416 struct chacha_req
*creq
= &rctx
->u
.chacha
;
417 struct scatterlist
*src
, *dst
;
420 if (req
->cryptlen
== 0)
423 chacha_iv(creq
->iv
, req
, 1);
425 sg_init_table(rctx
->src
, 2);
426 src
= scatterwalk_ffwd(rctx
->src
, req
->src
, req
->assoclen
);
429 if (req
->src
!= req
->dst
) {
430 sg_init_table(rctx
->dst
, 2);
431 dst
= scatterwalk_ffwd(rctx
->dst
, req
->dst
, req
->assoclen
);
434 skcipher_request_set_callback(&creq
->req
, aead_request_flags(req
),
435 chacha_encrypt_done
, req
);
436 skcipher_request_set_tfm(&creq
->req
, ctx
->chacha
);
437 skcipher_request_set_crypt(&creq
->req
, src
, dst
,
438 req
->cryptlen
, creq
->iv
);
439 err
= crypto_skcipher_encrypt(&creq
->req
);
444 return poly_genkey(req
);
447 static int chachapoly_encrypt(struct aead_request
*req
)
449 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
451 rctx
->cryptlen
= req
->cryptlen
;
453 /* encrypt call chain:
454 * - chacha_encrypt/done()
455 * - poly_genkey/done()
457 * - poly_setkey/done()
459 * - poly_adpad/done()
460 * - poly_cipher/done()
461 * - poly_cipherpad/done()
462 * - poly_tail/done/continue()
465 return chacha_encrypt(req
);
468 static int chachapoly_decrypt(struct aead_request
*req
)
470 struct chachapoly_req_ctx
*rctx
= aead_request_ctx(req
);
472 rctx
->cryptlen
= req
->cryptlen
- POLY1305_DIGEST_SIZE
;
474 /* decrypt call chain:
475 * - poly_genkey/done()
477 * - poly_setkey/done()
479 * - poly_adpad/done()
480 * - poly_cipher/done()
481 * - poly_cipherpad/done()
482 * - poly_tail/done/continue()
483 * - chacha_decrypt/done()
484 * - poly_verify_tag()
486 return poly_genkey(req
);
489 static int chachapoly_setkey(struct crypto_aead
*aead
, const u8
*key
,
492 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(aead
);
495 if (keylen
!= ctx
->saltlen
+ CHACHA_KEY_SIZE
)
498 keylen
-= ctx
->saltlen
;
499 memcpy(ctx
->salt
, key
+ keylen
, ctx
->saltlen
);
501 crypto_skcipher_clear_flags(ctx
->chacha
, CRYPTO_TFM_REQ_MASK
);
502 crypto_skcipher_set_flags(ctx
->chacha
, crypto_aead_get_flags(aead
) &
503 CRYPTO_TFM_REQ_MASK
);
505 err
= crypto_skcipher_setkey(ctx
->chacha
, key
, keylen
);
506 crypto_aead_set_flags(aead
, crypto_skcipher_get_flags(ctx
->chacha
) &
507 CRYPTO_TFM_RES_MASK
);
511 static int chachapoly_setauthsize(struct crypto_aead
*tfm
,
512 unsigned int authsize
)
514 if (authsize
!= POLY1305_DIGEST_SIZE
)
520 static int chachapoly_init(struct crypto_aead
*tfm
)
522 struct aead_instance
*inst
= aead_alg_instance(tfm
);
523 struct chachapoly_instance_ctx
*ictx
= aead_instance_ctx(inst
);
524 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
525 struct crypto_skcipher
*chacha
;
526 struct crypto_ahash
*poly
;
529 poly
= crypto_spawn_ahash(&ictx
->poly
);
531 return PTR_ERR(poly
);
533 chacha
= crypto_spawn_skcipher(&ictx
->chacha
);
534 if (IS_ERR(chacha
)) {
535 crypto_free_ahash(poly
);
536 return PTR_ERR(chacha
);
539 ctx
->chacha
= chacha
;
541 ctx
->saltlen
= ictx
->saltlen
;
543 align
= crypto_aead_alignmask(tfm
);
544 align
&= ~(crypto_tfm_ctx_alignment() - 1);
545 crypto_aead_set_reqsize(
547 align
+ offsetof(struct chachapoly_req_ctx
, u
) +
548 max(offsetof(struct chacha_req
, req
) +
549 sizeof(struct skcipher_request
) +
550 crypto_skcipher_reqsize(chacha
),
551 offsetof(struct poly_req
, req
) +
552 sizeof(struct ahash_request
) +
553 crypto_ahash_reqsize(poly
)));
558 static void chachapoly_exit(struct crypto_aead
*tfm
)
560 struct chachapoly_ctx
*ctx
= crypto_aead_ctx(tfm
);
562 crypto_free_ahash(ctx
->poly
);
563 crypto_free_skcipher(ctx
->chacha
);
566 static void chachapoly_free(struct aead_instance
*inst
)
568 struct chachapoly_instance_ctx
*ctx
= aead_instance_ctx(inst
);
570 crypto_drop_skcipher(&ctx
->chacha
);
571 crypto_drop_ahash(&ctx
->poly
);
575 static int chachapoly_create(struct crypto_template
*tmpl
, struct rtattr
**tb
,
576 const char *name
, unsigned int ivsize
)
578 struct crypto_attr_type
*algt
;
579 struct aead_instance
*inst
;
580 struct skcipher_alg
*chacha
;
581 struct crypto_alg
*poly
;
582 struct hash_alg_common
*poly_hash
;
583 struct chachapoly_instance_ctx
*ctx
;
584 const char *chacha_name
, *poly_name
;
587 if (ivsize
> CHACHAPOLY_IV_SIZE
)
590 algt
= crypto_get_attr_type(tb
);
592 return PTR_ERR(algt
);
594 if ((algt
->type
^ CRYPTO_ALG_TYPE_AEAD
) & algt
->mask
)
597 chacha_name
= crypto_attr_alg_name(tb
[1]);
598 if (IS_ERR(chacha_name
))
599 return PTR_ERR(chacha_name
);
600 poly_name
= crypto_attr_alg_name(tb
[2]);
601 if (IS_ERR(poly_name
))
602 return PTR_ERR(poly_name
);
604 poly
= crypto_find_alg(poly_name
, &crypto_ahash_type
,
605 CRYPTO_ALG_TYPE_HASH
,
606 CRYPTO_ALG_TYPE_AHASH_MASK
|
607 crypto_requires_sync(algt
->type
,
610 return PTR_ERR(poly
);
611 poly_hash
= __crypto_hash_alg_common(poly
);
614 if (poly_hash
->digestsize
!= POLY1305_DIGEST_SIZE
)
618 inst
= kzalloc(sizeof(*inst
) + sizeof(*ctx
), GFP_KERNEL
);
622 ctx
= aead_instance_ctx(inst
);
623 ctx
->saltlen
= CHACHAPOLY_IV_SIZE
- ivsize
;
624 err
= crypto_init_ahash_spawn(&ctx
->poly
, poly_hash
,
625 aead_crypto_instance(inst
));
629 crypto_set_skcipher_spawn(&ctx
->chacha
, aead_crypto_instance(inst
));
630 err
= crypto_grab_skcipher(&ctx
->chacha
, chacha_name
, 0,
631 crypto_requires_sync(algt
->type
,
636 chacha
= crypto_spawn_skcipher_alg(&ctx
->chacha
);
639 /* Need 16-byte IV size, including Initial Block Counter value */
640 if (crypto_skcipher_alg_ivsize(chacha
) != CHACHA_IV_SIZE
)
641 goto out_drop_chacha
;
642 /* Not a stream cipher? */
643 if (chacha
->base
.cra_blocksize
!= 1)
644 goto out_drop_chacha
;
647 if (snprintf(inst
->alg
.base
.cra_name
, CRYPTO_MAX_ALG_NAME
,
648 "%s(%s,%s)", name
, chacha
->base
.cra_name
,
649 poly
->cra_name
) >= CRYPTO_MAX_ALG_NAME
)
650 goto out_drop_chacha
;
651 if (snprintf(inst
->alg
.base
.cra_driver_name
, CRYPTO_MAX_ALG_NAME
,
652 "%s(%s,%s)", name
, chacha
->base
.cra_driver_name
,
653 poly
->cra_driver_name
) >= CRYPTO_MAX_ALG_NAME
)
654 goto out_drop_chacha
;
656 inst
->alg
.base
.cra_flags
= (chacha
->base
.cra_flags
| poly
->cra_flags
) &
658 inst
->alg
.base
.cra_priority
= (chacha
->base
.cra_priority
+
659 poly
->cra_priority
) / 2;
660 inst
->alg
.base
.cra_blocksize
= 1;
661 inst
->alg
.base
.cra_alignmask
= chacha
->base
.cra_alignmask
|
663 inst
->alg
.base
.cra_ctxsize
= sizeof(struct chachapoly_ctx
) +
665 inst
->alg
.ivsize
= ivsize
;
666 inst
->alg
.chunksize
= crypto_skcipher_alg_chunksize(chacha
);
667 inst
->alg
.maxauthsize
= POLY1305_DIGEST_SIZE
;
668 inst
->alg
.init
= chachapoly_init
;
669 inst
->alg
.exit
= chachapoly_exit
;
670 inst
->alg
.encrypt
= chachapoly_encrypt
;
671 inst
->alg
.decrypt
= chachapoly_decrypt
;
672 inst
->alg
.setkey
= chachapoly_setkey
;
673 inst
->alg
.setauthsize
= chachapoly_setauthsize
;
675 inst
->free
= chachapoly_free
;
677 err
= aead_register_instance(tmpl
, inst
);
679 goto out_drop_chacha
;
682 crypto_mod_put(poly
);
686 crypto_drop_skcipher(&ctx
->chacha
);
688 crypto_drop_ahash(&ctx
->poly
);
694 static int rfc7539_create(struct crypto_template
*tmpl
, struct rtattr
**tb
)
696 return chachapoly_create(tmpl
, tb
, "rfc7539", 12);
699 static int rfc7539esp_create(struct crypto_template
*tmpl
, struct rtattr
**tb
)
701 return chachapoly_create(tmpl
, tb
, "rfc7539esp", 8);
704 static struct crypto_template rfc7539_tmpls
[] = {
707 .create
= rfc7539_create
,
708 .module
= THIS_MODULE
,
710 .name
= "rfc7539esp",
711 .create
= rfc7539esp_create
,
712 .module
= THIS_MODULE
,
716 static int __init
chacha20poly1305_module_init(void)
718 return crypto_register_templates(rfc7539_tmpls
,
719 ARRAY_SIZE(rfc7539_tmpls
));
722 static void __exit
chacha20poly1305_module_exit(void)
724 crypto_unregister_templates(rfc7539_tmpls
,
725 ARRAY_SIZE(rfc7539_tmpls
));
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");