hc
2024-05-10 ee930fffee469d076998274a2ca55e13dc1efb67
kernel/crypto/chacha20poly1305.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * ChaCha20-Poly1305 AEAD, RFC7539
34 *
45 * 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.
106 */
117
128 #include <crypto/internal/aead.h>
....@@ -19,10 +15,6 @@
1915 #include <linux/init.h>
2016 #include <linux/kernel.h>
2117 #include <linux/module.h>
22
-
23
-#include "internal.h"
24
-
25
-#define CHACHAPOLY_IV_SIZE 12
2618
2719 struct chachapoly_instance_ctx {
2820 struct crypto_skcipher_spawn chacha;
....@@ -141,14 +133,10 @@
141133
142134 chacha_iv(creq->iv, req, 1);
143135
144
- sg_init_table(rctx->src, 2);
145136 src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen);
146137 dst = src;
147
-
148
- if (req->src != req->dst) {
149
- sg_init_table(rctx->dst, 2);
138
+ if (req->src != req->dst)
150139 dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen);
151
- }
152140
153141 skcipher_request_set_callback(&creq->req, rctx->flags,
154142 chacha_decrypt_done, req);
....@@ -184,15 +172,11 @@
184172 struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm);
185173 struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
186174 struct poly_req *preq = &rctx->u.poly;
187
- __le64 len;
188175 int err;
189176
190
- sg_init_table(preq->src, 1);
191
- len = cpu_to_le64(rctx->assoclen);
192
- memcpy(&preq->tail.assoclen, &len, sizeof(len));
193
- len = cpu_to_le64(rctx->cryptlen);
194
- memcpy(&preq->tail.cryptlen, &len, sizeof(len));
195
- sg_set_buf(preq->src, &preq->tail, sizeof(preq->tail));
177
+ preq->tail.assoclen = cpu_to_le64(rctx->assoclen);
178
+ preq->tail.cryptlen = cpu_to_le64(rctx->cryptlen);
179
+ sg_init_one(preq->src, &preq->tail, sizeof(preq->tail));
196180
197181 ahash_request_set_callback(&preq->req, rctx->flags,
198182 poly_tail_done, req);
....@@ -217,13 +201,12 @@
217201 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
218202 struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
219203 struct poly_req *preq = &rctx->u.poly;
220
- unsigned int padlen, bs = POLY1305_BLOCK_SIZE;
204
+ unsigned int padlen;
221205 int err;
222206
223
- padlen = (bs - (rctx->cryptlen % bs)) % bs;
207
+ padlen = -rctx->cryptlen % POLY1305_BLOCK_SIZE;
224208 memset(preq->pad, 0, sizeof(preq->pad));
225
- sg_init_table(preq->src, 1);
226
- sg_set_buf(preq->src, &preq->pad, padlen);
209
+ sg_init_one(preq->src, preq->pad, padlen);
227210
228211 ahash_request_set_callback(&preq->req, rctx->flags,
229212 poly_cipherpad_done, req);
....@@ -253,7 +236,6 @@
253236 if (rctx->cryptlen == req->cryptlen) /* encrypting */
254237 crypt = req->dst;
255238
256
- sg_init_table(rctx->src, 2);
257239 crypt = scatterwalk_ffwd(rctx->src, crypt, req->assoclen);
258240
259241 ahash_request_set_callback(&preq->req, rctx->flags,
....@@ -278,13 +260,12 @@
278260 struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
279261 struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
280262 struct poly_req *preq = &rctx->u.poly;
281
- unsigned int padlen, bs = POLY1305_BLOCK_SIZE;
263
+ unsigned int padlen;
282264 int err;
283265
284
- padlen = (bs - (rctx->assoclen % bs)) % bs;
266
+ padlen = -rctx->assoclen % POLY1305_BLOCK_SIZE;
285267 memset(preq->pad, 0, sizeof(preq->pad));
286
- sg_init_table(preq->src, 1);
287
- sg_set_buf(preq->src, preq->pad, padlen);
268
+ sg_init_one(preq->src, preq->pad, padlen);
288269
289270 ahash_request_set_callback(&preq->req, rctx->flags,
290271 poly_adpad_done, req);
....@@ -334,8 +315,7 @@
334315 struct poly_req *preq = &rctx->u.poly;
335316 int err;
336317
337
- sg_init_table(preq->src, 1);
338
- sg_set_buf(preq->src, rctx->key, sizeof(rctx->key));
318
+ sg_init_one(preq->src, rctx->key, sizeof(rctx->key));
339319
340320 ahash_request_set_callback(&preq->req, rctx->flags,
341321 poly_setkey_done, req);
....@@ -393,9 +373,8 @@
393373 rctx->assoclen -= 8;
394374 }
395375
396
- sg_init_table(creq->src, 1);
397376 memset(rctx->key, 0, sizeof(rctx->key));
398
- sg_set_buf(creq->src, rctx->key, sizeof(rctx->key));
377
+ sg_init_one(creq->src, rctx->key, sizeof(rctx->key));
399378
400379 chacha_iv(creq->iv, req, 0);
401380
....@@ -430,14 +409,10 @@
430409
431410 chacha_iv(creq->iv, req, 1);
432411
433
- sg_init_table(rctx->src, 2);
434412 src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen);
435413 dst = src;
436
-
437
- if (req->src != req->dst) {
438
- sg_init_table(rctx->dst, 2);
414
+ if (req->src != req->dst)
439415 dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen);
440
- }
441416
442417 skcipher_request_set_callback(&creq->req, rctx->flags,
443418 chacha_encrypt_done, req);
....@@ -500,7 +475,6 @@
500475 unsigned int keylen)
501476 {
502477 struct chachapoly_ctx *ctx = crypto_aead_ctx(aead);
503
- int err;
504478
505479 if (keylen != ctx->saltlen + CHACHA_KEY_SIZE)
506480 return -EINVAL;
....@@ -511,11 +485,7 @@
511485 crypto_skcipher_clear_flags(ctx->chacha, CRYPTO_TFM_REQ_MASK);
512486 crypto_skcipher_set_flags(ctx->chacha, crypto_aead_get_flags(aead) &
513487 CRYPTO_TFM_REQ_MASK);
514
-
515
- err = crypto_skcipher_setkey(ctx->chacha, key, keylen);
516
- crypto_aead_set_flags(aead, crypto_skcipher_get_flags(ctx->chacha) &
517
- CRYPTO_TFM_RES_MASK);
518
- return err;
488
+ return crypto_skcipher_setkey(ctx->chacha, key, keylen);
519489 }
520490
521491 static int chachapoly_setauthsize(struct crypto_aead *tfm,
....@@ -585,91 +555,63 @@
585555 static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
586556 const char *name, unsigned int ivsize)
587557 {
588
- struct crypto_attr_type *algt;
558
+ u32 mask;
589559 struct aead_instance *inst;
590
- struct skcipher_alg *chacha;
591
- struct crypto_alg *poly;
592
- struct hash_alg_common *poly_hash;
593560 struct chachapoly_instance_ctx *ctx;
594
- const char *chacha_name, *poly_name;
561
+ struct skcipher_alg *chacha;
562
+ struct hash_alg_common *poly;
595563 int err;
596564
597565 if (ivsize > CHACHAPOLY_IV_SIZE)
598566 return -EINVAL;
599567
600
- algt = crypto_get_attr_type(tb);
601
- if (IS_ERR(algt))
602
- return PTR_ERR(algt);
568
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
569
+ if (err)
570
+ return err;
603571
604
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
605
- return -EINVAL;
606
-
607
- chacha_name = crypto_attr_alg_name(tb[1]);
608
- if (IS_ERR(chacha_name))
609
- return PTR_ERR(chacha_name);
610
- poly_name = crypto_attr_alg_name(tb[2]);
611
- if (IS_ERR(poly_name))
612
- return PTR_ERR(poly_name);
613
-
614
- poly = crypto_find_alg(poly_name, &crypto_ahash_type,
615
- CRYPTO_ALG_TYPE_HASH,
616
- CRYPTO_ALG_TYPE_AHASH_MASK |
617
- crypto_requires_sync(algt->type,
618
- algt->mask));
619
- if (IS_ERR(poly))
620
- return PTR_ERR(poly);
621
- poly_hash = __crypto_hash_alg_common(poly);
622
-
623
- err = -EINVAL;
624
- if (poly_hash->digestsize != POLY1305_DIGEST_SIZE)
625
- goto out_put_poly;
626
-
627
- err = -ENOMEM;
628572 inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
629573 if (!inst)
630
- goto out_put_poly;
631
-
574
+ return -ENOMEM;
632575 ctx = aead_instance_ctx(inst);
633576 ctx->saltlen = CHACHAPOLY_IV_SIZE - ivsize;
634
- err = crypto_init_ahash_spawn(&ctx->poly, poly_hash,
635
- aead_crypto_instance(inst));
577
+
578
+ err = crypto_grab_skcipher(&ctx->chacha, aead_crypto_instance(inst),
579
+ crypto_attr_alg_name(tb[1]), 0, mask);
636580 if (err)
637581 goto err_free_inst;
638
-
639
- crypto_set_skcipher_spawn(&ctx->chacha, aead_crypto_instance(inst));
640
- err = crypto_grab_skcipher(&ctx->chacha, chacha_name, 0,
641
- crypto_requires_sync(algt->type,
642
- algt->mask));
643
- if (err)
644
- goto err_drop_poly;
645
-
646582 chacha = crypto_spawn_skcipher_alg(&ctx->chacha);
647583
584
+ err = crypto_grab_ahash(&ctx->poly, aead_crypto_instance(inst),
585
+ crypto_attr_alg_name(tb[2]), 0, mask);
586
+ if (err)
587
+ goto err_free_inst;
588
+ poly = crypto_spawn_ahash_alg(&ctx->poly);
589
+
648590 err = -EINVAL;
591
+ if (poly->digestsize != POLY1305_DIGEST_SIZE)
592
+ goto err_free_inst;
649593 /* Need 16-byte IV size, including Initial Block Counter value */
650594 if (crypto_skcipher_alg_ivsize(chacha) != CHACHA_IV_SIZE)
651
- goto out_drop_chacha;
595
+ goto err_free_inst;
652596 /* Not a stream cipher? */
653597 if (chacha->base.cra_blocksize != 1)
654
- goto out_drop_chacha;
598
+ goto err_free_inst;
655599
656600 err = -ENAMETOOLONG;
657601 if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
658602 "%s(%s,%s)", name, chacha->base.cra_name,
659
- poly->cra_name) >= CRYPTO_MAX_ALG_NAME)
660
- goto out_drop_chacha;
603
+ poly->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
604
+ goto err_free_inst;
661605 if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
662606 "%s(%s,%s)", name, chacha->base.cra_driver_name,
663
- poly->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
664
- goto out_drop_chacha;
607
+ poly->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
608
+ goto err_free_inst;
665609
666
- inst->alg.base.cra_flags = (chacha->base.cra_flags | poly->cra_flags) &
667
- CRYPTO_ALG_ASYNC;
668610 inst->alg.base.cra_priority = (chacha->base.cra_priority +
669
- poly->cra_priority) / 2;
611
+ poly->base.cra_priority) / 2;
670612 inst->alg.base.cra_blocksize = 1;
671613 inst->alg.base.cra_alignmask = chacha->base.cra_alignmask |
672
- poly->cra_alignmask;
614
+ poly->base.cra_alignmask;
673615 inst->alg.base.cra_ctxsize = sizeof(struct chachapoly_ctx) +
674616 ctx->saltlen;
675617 inst->alg.ivsize = ivsize;
....@@ -685,20 +627,11 @@
685627 inst->free = chachapoly_free;
686628
687629 err = aead_register_instance(tmpl, inst);
688
- if (err)
689
- goto out_drop_chacha;
690
-
691
-out_put_poly:
692
- crypto_mod_put(poly);
693
- return err;
694
-
695
-out_drop_chacha:
696
- crypto_drop_skcipher(&ctx->chacha);
697
-err_drop_poly:
698
- crypto_drop_ahash(&ctx->poly);
630
+ if (err) {
699631 err_free_inst:
700
- kfree(inst);
701
- goto out_put_poly;
632
+ chachapoly_free(inst);
633
+ }
634
+ return err;
702635 }
703636
704637 static int rfc7539_create(struct crypto_template *tmpl, struct rtattr **tb)
....@@ -711,40 +644,31 @@
711644 return chachapoly_create(tmpl, tb, "rfc7539esp", 8);
712645 }
713646
714
-static struct crypto_template rfc7539_tmpl = {
715
- .name = "rfc7539",
716
- .create = rfc7539_create,
717
- .module = THIS_MODULE,
718
-};
719
-
720
-static struct crypto_template rfc7539esp_tmpl = {
721
- .name = "rfc7539esp",
722
- .create = rfc7539esp_create,
723
- .module = THIS_MODULE,
647
+static struct crypto_template rfc7539_tmpls[] = {
648
+ {
649
+ .name = "rfc7539",
650
+ .create = rfc7539_create,
651
+ .module = THIS_MODULE,
652
+ }, {
653
+ .name = "rfc7539esp",
654
+ .create = rfc7539esp_create,
655
+ .module = THIS_MODULE,
656
+ },
724657 };
725658
726659 static int __init chacha20poly1305_module_init(void)
727660 {
728
- int err;
729
-
730
- err = crypto_register_template(&rfc7539_tmpl);
731
- if (err)
732
- return err;
733
-
734
- err = crypto_register_template(&rfc7539esp_tmpl);
735
- if (err)
736
- crypto_unregister_template(&rfc7539_tmpl);
737
-
738
- return err;
661
+ return crypto_register_templates(rfc7539_tmpls,
662
+ ARRAY_SIZE(rfc7539_tmpls));
739663 }
740664
741665 static void __exit chacha20poly1305_module_exit(void)
742666 {
743
- crypto_unregister_template(&rfc7539esp_tmpl);
744
- crypto_unregister_template(&rfc7539_tmpl);
667
+ crypto_unregister_templates(rfc7539_tmpls,
668
+ ARRAY_SIZE(rfc7539_tmpls));
745669 }
746670
747
-module_init(chacha20poly1305_module_init);
671
+subsys_initcall(chacha20poly1305_module_init);
748672 module_exit(chacha20poly1305_module_exit);
749673
750674 MODULE_LICENSE("GPL");