]> git.karo-electronics.de Git - linux-beck.git/blob - crypto/chacha20poly1305.c
crypto: chacha20 - Export common ChaCha20 helpers
[linux-beck.git] / crypto / chacha20poly1305.c
1 /*
2  * ChaCha20-Poly1305 AEAD, RFC7539
3  *
4  * Copyright (C) 2015 Martin Willi
5  *
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.
10  */
11
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 <linux/err.h>
18 #include <linux/init.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21
22 #include "internal.h"
23
24 #define POLY1305_BLOCK_SIZE     16
25 #define POLY1305_DIGEST_SIZE    16
26 #define POLY1305_KEY_SIZE       32
27 #define CHACHAPOLY_IV_SIZE      12
28
29 struct chachapoly_instance_ctx {
30         struct crypto_skcipher_spawn chacha;
31         struct crypto_ahash_spawn poly;
32         unsigned int saltlen;
33 };
34
35 struct chachapoly_ctx {
36         struct crypto_ablkcipher *chacha;
37         struct crypto_ahash *poly;
38         /* key bytes we use for the ChaCha20 IV */
39         unsigned int saltlen;
40         u8 salt[];
41 };
42
43 struct poly_req {
44         /* zero byte padding for AD/ciphertext, as needed */
45         u8 pad[POLY1305_BLOCK_SIZE];
46         /* tail data with AD/ciphertext lengths */
47         struct {
48                 __le64 assoclen;
49                 __le64 cryptlen;
50         } tail;
51         struct scatterlist src[1];
52         struct ahash_request req; /* must be last member */
53 };
54
55 struct chacha_req {
56         u8 iv[CHACHA20_IV_SIZE];
57         struct scatterlist src[1];
58         struct ablkcipher_request req; /* must be last member */
59 };
60
61 struct chachapoly_req_ctx {
62         struct scatterlist src[2];
63         struct scatterlist dst[2];
64         /* the key we generate for Poly1305 using Chacha20 */
65         u8 key[POLY1305_KEY_SIZE];
66         /* calculated Poly1305 tag */
67         u8 tag[POLY1305_DIGEST_SIZE];
68         /* length of data to en/decrypt, without ICV */
69         unsigned int cryptlen;
70         /* Actual AD, excluding IV */
71         unsigned int assoclen;
72         union {
73                 struct poly_req poly;
74                 struct chacha_req chacha;
75         } u;
76 };
77
78 static inline void async_done_continue(struct aead_request *req, int err,
79                                        int (*cont)(struct aead_request *))
80 {
81         if (!err)
82                 err = cont(req);
83
84         if (err != -EINPROGRESS && err != -EBUSY)
85                 aead_request_complete(req, err);
86 }
87
88 static void chacha_iv(u8 *iv, struct aead_request *req, u32 icb)
89 {
90         struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
91         __le32 leicb = cpu_to_le32(icb);
92
93         memcpy(iv, &leicb, sizeof(leicb));
94         memcpy(iv + sizeof(leicb), ctx->salt, ctx->saltlen);
95         memcpy(iv + sizeof(leicb) + ctx->saltlen, req->iv,
96                CHACHA20_IV_SIZE - sizeof(leicb) - ctx->saltlen);
97 }
98
99 static int poly_verify_tag(struct aead_request *req)
100 {
101         struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
102         u8 tag[sizeof(rctx->tag)];
103
104         scatterwalk_map_and_copy(tag, req->src,
105                                  req->assoclen + rctx->cryptlen,
106                                  sizeof(tag), 0);
107         if (crypto_memneq(tag, rctx->tag, sizeof(tag)))
108                 return -EBADMSG;
109         return 0;
110 }
111
112 static int poly_copy_tag(struct aead_request *req)
113 {
114         struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
115
116         scatterwalk_map_and_copy(rctx->tag, req->dst,
117                                  req->assoclen + rctx->cryptlen,
118                                  sizeof(rctx->tag), 1);
119         return 0;
120 }
121
122 static void chacha_decrypt_done(struct crypto_async_request *areq, int err)
123 {
124         async_done_continue(areq->data, err, poly_verify_tag);
125 }
126
127 static int chacha_decrypt(struct aead_request *req)
128 {
129         struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
130         struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
131         struct chacha_req *creq = &rctx->u.chacha;
132         struct scatterlist *src, *dst;
133         int err;
134
135         chacha_iv(creq->iv, req, 1);
136
137         sg_init_table(rctx->src, 2);
138         src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen);
139         dst = src;
140
141         if (req->src != req->dst) {
142                 sg_init_table(rctx->dst, 2);
143                 dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen);
144         }
145
146         ablkcipher_request_set_callback(&creq->req, aead_request_flags(req),
147                                         chacha_decrypt_done, req);
148         ablkcipher_request_set_tfm(&creq->req, ctx->chacha);
149         ablkcipher_request_set_crypt(&creq->req, src, dst,
150                                      rctx->cryptlen, creq->iv);
151         err = crypto_ablkcipher_decrypt(&creq->req);
152         if (err)
153                 return err;
154
155         return poly_verify_tag(req);
156 }
157
158 static int poly_tail_continue(struct aead_request *req)
159 {
160         struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
161
162         if (rctx->cryptlen == req->cryptlen) /* encrypting */
163                 return poly_copy_tag(req);
164
165         return chacha_decrypt(req);
166 }
167
168 static void poly_tail_done(struct crypto_async_request *areq, int err)
169 {
170         async_done_continue(areq->data, err, poly_tail_continue);
171 }
172
173 static int poly_tail(struct aead_request *req)
174 {
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;
179         __le64 len;
180         int err;
181
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));
188
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));
194
195         err = crypto_ahash_finup(&preq->req);
196         if (err)
197                 return err;
198
199         return poly_tail_continue(req);
200 }
201
202 static void poly_cipherpad_done(struct crypto_async_request *areq, int err)
203 {
204         async_done_continue(areq->data, err, poly_tail);
205 }
206
207 static int poly_cipherpad(struct aead_request *req)
208 {
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;
213         int err;
214
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);
219
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);
224
225         err = crypto_ahash_update(&preq->req);
226         if (err)
227                 return err;
228
229         return poly_tail(req);
230 }
231
232 static void poly_cipher_done(struct crypto_async_request *areq, int err)
233 {
234         async_done_continue(areq->data, err, poly_cipherpad);
235 }
236
237 static int poly_cipher(struct aead_request *req)
238 {
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;
243         int err;
244
245         if (rctx->cryptlen == req->cryptlen) /* encrypting */
246                 crypt = req->dst;
247
248         sg_init_table(rctx->src, 2);
249         crypt = scatterwalk_ffwd(rctx->src, crypt, req->assoclen);
250
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);
255
256         err = crypto_ahash_update(&preq->req);
257         if (err)
258                 return err;
259
260         return poly_cipherpad(req);
261 }
262
263 static void poly_adpad_done(struct crypto_async_request *areq, int err)
264 {
265         async_done_continue(areq->data, err, poly_cipher);
266 }
267
268 static int poly_adpad(struct aead_request *req)
269 {
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;
274         int err;
275
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);
280
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);
285
286         err = crypto_ahash_update(&preq->req);
287         if (err)
288                 return err;
289
290         return poly_cipher(req);
291 }
292
293 static void poly_ad_done(struct crypto_async_request *areq, int err)
294 {
295         async_done_continue(areq->data, err, poly_adpad);
296 }
297
298 static int poly_ad(struct aead_request *req)
299 {
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;
303         int err;
304
305         ahash_request_set_callback(&preq->req, aead_request_flags(req),
306                                    poly_ad_done, req);
307         ahash_request_set_tfm(&preq->req, ctx->poly);
308         ahash_request_set_crypt(&preq->req, req->src, NULL, rctx->assoclen);
309
310         err = crypto_ahash_update(&preq->req);
311         if (err)
312                 return err;
313
314         return poly_adpad(req);
315 }
316
317 static void poly_setkey_done(struct crypto_async_request *areq, int err)
318 {
319         async_done_continue(areq->data, err, poly_ad);
320 }
321
322 static int poly_setkey(struct aead_request *req)
323 {
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;
327         int err;
328
329         sg_init_table(preq->src, 1);
330         sg_set_buf(preq->src, rctx->key, sizeof(rctx->key));
331
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));
336
337         err = crypto_ahash_update(&preq->req);
338         if (err)
339                 return err;
340
341         return poly_ad(req);
342 }
343
344 static void poly_init_done(struct crypto_async_request *areq, int err)
345 {
346         async_done_continue(areq->data, err, poly_setkey);
347 }
348
349 static int poly_init(struct aead_request *req)
350 {
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;
354         int err;
355
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);
359
360         err = crypto_ahash_init(&preq->req);
361         if (err)
362                 return err;
363
364         return poly_setkey(req);
365 }
366
367 static void poly_genkey_done(struct crypto_async_request *areq, int err)
368 {
369         async_done_continue(areq->data, err, poly_init);
370 }
371
372 static int poly_genkey(struct aead_request *req)
373 {
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;
378         int err;
379
380         rctx->assoclen = req->assoclen;
381
382         if (crypto_aead_ivsize(tfm) == 8) {
383                 if (rctx->assoclen < 8)
384                         return -EINVAL;
385                 rctx->assoclen -= 8;
386         }
387
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));
391
392         chacha_iv(creq->iv, req, 0);
393
394         ablkcipher_request_set_callback(&creq->req, aead_request_flags(req),
395                                         poly_genkey_done, req);
396         ablkcipher_request_set_tfm(&creq->req, ctx->chacha);
397         ablkcipher_request_set_crypt(&creq->req, creq->src, creq->src,
398                                      POLY1305_KEY_SIZE, creq->iv);
399
400         err = crypto_ablkcipher_decrypt(&creq->req);
401         if (err)
402                 return err;
403
404         return poly_init(req);
405 }
406
407 static void chacha_encrypt_done(struct crypto_async_request *areq, int err)
408 {
409         async_done_continue(areq->data, err, poly_genkey);
410 }
411
412 static int chacha_encrypt(struct aead_request *req)
413 {
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;
418         int err;
419
420         chacha_iv(creq->iv, req, 1);
421
422         sg_init_table(rctx->src, 2);
423         src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen);
424         dst = src;
425
426         if (req->src != req->dst) {
427                 sg_init_table(rctx->dst, 2);
428                 dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen);
429         }
430
431         ablkcipher_request_set_callback(&creq->req, aead_request_flags(req),
432                                         chacha_encrypt_done, req);
433         ablkcipher_request_set_tfm(&creq->req, ctx->chacha);
434         ablkcipher_request_set_crypt(&creq->req, src, dst,
435                                      req->cryptlen, creq->iv);
436         err = crypto_ablkcipher_encrypt(&creq->req);
437         if (err)
438                 return err;
439
440         return poly_genkey(req);
441 }
442
443 static int chachapoly_encrypt(struct aead_request *req)
444 {
445         struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
446
447         rctx->cryptlen = req->cryptlen;
448
449         /* encrypt call chain:
450          * - chacha_encrypt/done()
451          * - poly_genkey/done()
452          * - poly_init/done()
453          * - poly_setkey/done()
454          * - poly_ad/done()
455          * - poly_adpad/done()
456          * - poly_cipher/done()
457          * - poly_cipherpad/done()
458          * - poly_tail/done/continue()
459          * - poly_copy_tag()
460          */
461         return chacha_encrypt(req);
462 }
463
464 static int chachapoly_decrypt(struct aead_request *req)
465 {
466         struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
467
468         rctx->cryptlen = req->cryptlen - POLY1305_DIGEST_SIZE;
469
470         /* decrypt call chain:
471          * - poly_genkey/done()
472          * - poly_init/done()
473          * - poly_setkey/done()
474          * - poly_ad/done()
475          * - poly_adpad/done()
476          * - poly_cipher/done()
477          * - poly_cipherpad/done()
478          * - poly_tail/done/continue()
479          * - chacha_decrypt/done()
480          * - poly_verify_tag()
481          */
482         return poly_genkey(req);
483 }
484
485 static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
486                              unsigned int keylen)
487 {
488         struct chachapoly_ctx *ctx = crypto_aead_ctx(aead);
489         int err;
490
491         if (keylen != ctx->saltlen + CHACHA20_KEY_SIZE)
492                 return -EINVAL;
493
494         keylen -= ctx->saltlen;
495         memcpy(ctx->salt, key + keylen, ctx->saltlen);
496
497         crypto_ablkcipher_clear_flags(ctx->chacha, CRYPTO_TFM_REQ_MASK);
498         crypto_ablkcipher_set_flags(ctx->chacha, crypto_aead_get_flags(aead) &
499                                     CRYPTO_TFM_REQ_MASK);
500
501         err = crypto_ablkcipher_setkey(ctx->chacha, key, keylen);
502         crypto_aead_set_flags(aead, crypto_ablkcipher_get_flags(ctx->chacha) &
503                               CRYPTO_TFM_RES_MASK);
504         return err;
505 }
506
507 static int chachapoly_setauthsize(struct crypto_aead *tfm,
508                                   unsigned int authsize)
509 {
510         if (authsize != POLY1305_DIGEST_SIZE)
511                 return -EINVAL;
512
513         return 0;
514 }
515
516 static int chachapoly_init(struct crypto_aead *tfm)
517 {
518         struct aead_instance *inst = aead_alg_instance(tfm);
519         struct chachapoly_instance_ctx *ictx = aead_instance_ctx(inst);
520         struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm);
521         struct crypto_ablkcipher *chacha;
522         struct crypto_ahash *poly;
523         unsigned long align;
524
525         poly = crypto_spawn_ahash(&ictx->poly);
526         if (IS_ERR(poly))
527                 return PTR_ERR(poly);
528
529         chacha = crypto_spawn_skcipher(&ictx->chacha);
530         if (IS_ERR(chacha)) {
531                 crypto_free_ahash(poly);
532                 return PTR_ERR(chacha);
533         }
534
535         ctx->chacha = chacha;
536         ctx->poly = poly;
537         ctx->saltlen = ictx->saltlen;
538
539         align = crypto_aead_alignmask(tfm);
540         align &= ~(crypto_tfm_ctx_alignment() - 1);
541         crypto_aead_set_reqsize(
542                 tfm,
543                 align + offsetof(struct chachapoly_req_ctx, u) +
544                 max(offsetof(struct chacha_req, req) +
545                     sizeof(struct ablkcipher_request) +
546                     crypto_ablkcipher_reqsize(chacha),
547                     offsetof(struct poly_req, req) +
548                     sizeof(struct ahash_request) +
549                     crypto_ahash_reqsize(poly)));
550
551         return 0;
552 }
553
554 static void chachapoly_exit(struct crypto_aead *tfm)
555 {
556         struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm);
557
558         crypto_free_ahash(ctx->poly);
559         crypto_free_ablkcipher(ctx->chacha);
560 }
561
562 static void chachapoly_free(struct aead_instance *inst)
563 {
564         struct chachapoly_instance_ctx *ctx = aead_instance_ctx(inst);
565
566         crypto_drop_skcipher(&ctx->chacha);
567         crypto_drop_ahash(&ctx->poly);
568         kfree(inst);
569 }
570
571 static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
572                              const char *name, unsigned int ivsize)
573 {
574         struct crypto_attr_type *algt;
575         struct aead_instance *inst;
576         struct crypto_alg *chacha;
577         struct crypto_alg *poly;
578         struct hash_alg_common *poly_hash;
579         struct chachapoly_instance_ctx *ctx;
580         const char *chacha_name, *poly_name;
581         int err;
582
583         if (ivsize > CHACHAPOLY_IV_SIZE)
584                 return -EINVAL;
585
586         algt = crypto_get_attr_type(tb);
587         if (IS_ERR(algt))
588                 return PTR_ERR(algt);
589
590         if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_AEAD_NEW)) &
591             algt->mask)
592                 return -EINVAL;
593
594         chacha_name = crypto_attr_alg_name(tb[1]);
595         if (IS_ERR(chacha_name))
596                 return PTR_ERR(chacha_name);
597         poly_name = crypto_attr_alg_name(tb[2]);
598         if (IS_ERR(poly_name))
599                 return PTR_ERR(poly_name);
600
601         poly = crypto_find_alg(poly_name, &crypto_ahash_type,
602                                CRYPTO_ALG_TYPE_HASH,
603                                CRYPTO_ALG_TYPE_AHASH_MASK);
604         if (IS_ERR(poly))
605                 return PTR_ERR(poly);
606
607         err = -ENOMEM;
608         inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
609         if (!inst)
610                 goto out_put_poly;
611
612         ctx = aead_instance_ctx(inst);
613         ctx->saltlen = CHACHAPOLY_IV_SIZE - ivsize;
614         poly_hash = __crypto_hash_alg_common(poly);
615         err = crypto_init_ahash_spawn(&ctx->poly, poly_hash,
616                                       aead_crypto_instance(inst));
617         if (err)
618                 goto err_free_inst;
619
620         crypto_set_skcipher_spawn(&ctx->chacha, aead_crypto_instance(inst));
621         err = crypto_grab_skcipher(&ctx->chacha, chacha_name, 0,
622                                    crypto_requires_sync(algt->type,
623                                                         algt->mask));
624         if (err)
625                 goto err_drop_poly;
626
627         chacha = crypto_skcipher_spawn_alg(&ctx->chacha);
628
629         err = -EINVAL;
630         /* Need 16-byte IV size, including Initial Block Counter value */
631         if (chacha->cra_ablkcipher.ivsize != CHACHA20_IV_SIZE)
632                 goto out_drop_chacha;
633         /* Not a stream cipher? */
634         if (chacha->cra_blocksize != 1)
635                 goto out_drop_chacha;
636
637         err = -ENAMETOOLONG;
638         if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
639                      "%s(%s,%s)", name, chacha_name,
640                      poly_name) >= CRYPTO_MAX_ALG_NAME)
641                 goto out_drop_chacha;
642         if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
643                      "%s(%s,%s)", name, chacha->cra_driver_name,
644                      poly->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
645                 goto out_drop_chacha;
646
647         inst->alg.base.cra_flags = (chacha->cra_flags | poly->cra_flags) &
648                                    CRYPTO_ALG_ASYNC;
649         inst->alg.base.cra_flags |= CRYPTO_ALG_AEAD_NEW;
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 |
654                                        poly->cra_alignmask;
655         inst->alg.base.cra_ctxsize = sizeof(struct chachapoly_ctx) +
656                                      ctx->saltlen;
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;
665
666         inst->free = chachapoly_free;
667
668         err = aead_register_instance(tmpl, inst);
669         if (err)
670                 goto out_drop_chacha;
671
672 out_put_poly:
673         crypto_mod_put(poly);
674         return err;
675
676 out_drop_chacha:
677         crypto_drop_skcipher(&ctx->chacha);
678 err_drop_poly:
679         crypto_drop_ahash(&ctx->poly);
680 err_free_inst:
681         kfree(inst);
682         goto out_put_poly;
683 }
684
685 static int rfc7539_create(struct crypto_template *tmpl, struct rtattr **tb)
686 {
687         return chachapoly_create(tmpl, tb, "rfc7539", 12);
688 }
689
690 static int rfc7539esp_create(struct crypto_template *tmpl, struct rtattr **tb)
691 {
692         return chachapoly_create(tmpl, tb, "rfc7539esp", 8);
693 }
694
695 static struct crypto_template rfc7539_tmpl = {
696         .name = "rfc7539",
697         .create = rfc7539_create,
698         .module = THIS_MODULE,
699 };
700
701 static struct crypto_template rfc7539esp_tmpl = {
702         .name = "rfc7539esp",
703         .create = rfc7539esp_create,
704         .module = THIS_MODULE,
705 };
706
707 static int __init chacha20poly1305_module_init(void)
708 {
709         int err;
710
711         err = crypto_register_template(&rfc7539_tmpl);
712         if (err)
713                 return err;
714
715         err = crypto_register_template(&rfc7539esp_tmpl);
716         if (err)
717                 crypto_unregister_template(&rfc7539_tmpl);
718
719         return err;
720 }
721
722 static void __exit chacha20poly1305_module_exit(void)
723 {
724         crypto_unregister_template(&rfc7539esp_tmpl);
725         crypto_unregister_template(&rfc7539_tmpl);
726 }
727
728 module_init(chacha20poly1305_module_init);
729 module_exit(chacha20poly1305_module_exit);
730
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");