hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/crypto/rsa-pkcs1pad.c
....@@ -1,22 +1,20 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * RSA padding templates.
34 *
45 * Copyright (c) 2015 Intel Corporation
5
- *
6
- * This program is free software; you can redistribute it and/or modify it
7
- * under the terms of the GNU General Public License as published by the Free
8
- * Software Foundation; either version 2 of the License, or (at your option)
9
- * any later version.
106 */
117
128 #include <crypto/algapi.h>
139 #include <crypto/akcipher.h>
1410 #include <crypto/internal/akcipher.h>
11
+#include <crypto/internal/rsa.h>
1512 #include <linux/err.h>
1613 #include <linux/init.h>
1714 #include <linux/kernel.h>
1815 #include <linux/module.h>
1916 #include <linux/random.h>
17
+#include <linux/scatterlist.h>
2018
2119 /*
2220 * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
....@@ -202,7 +200,7 @@
202200 sg_copy_from_buffer(req->dst,
203201 sg_nents_for_len(req->dst, ctx->key_size),
204202 out_buf, ctx->key_size);
205
- kzfree(out_buf);
203
+ kfree_sensitive(out_buf);
206204
207205 out:
208206 req->dst_len = ctx->key_size;
....@@ -216,16 +214,14 @@
216214 struct crypto_async_request *child_async_req, int err)
217215 {
218216 struct akcipher_request *req = child_async_req->data;
219
- struct crypto_async_request async_req;
220217
221218 if (err == -EINPROGRESS)
222
- return;
219
+ goto out;
223220
224
- async_req.data = req->base.data;
225
- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
226
- async_req.flags = child_async_req->flags;
227
- req->base.complete(&async_req,
228
- pkcs1pad_encrypt_sign_complete(req, err));
221
+ err = pkcs1pad_encrypt_sign_complete(req, err);
222
+
223
+out:
224
+ akcipher_request_complete(req, err);
229225 }
230226
231227 static int pkcs1pad_encrypt(struct akcipher_request *req)
....@@ -325,7 +321,7 @@
325321 out_buf + pos, req->dst_len);
326322
327323 done:
328
- kzfree(req_ctx->out_buf);
324
+ kfree_sensitive(req_ctx->out_buf);
329325
330326 return err;
331327 }
....@@ -334,15 +330,14 @@
334330 struct crypto_async_request *child_async_req, int err)
335331 {
336332 struct akcipher_request *req = child_async_req->data;
337
- struct crypto_async_request async_req;
338333
339334 if (err == -EINPROGRESS)
340
- return;
335
+ goto out;
341336
342
- async_req.data = req->base.data;
343
- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
344
- async_req.flags = child_async_req->flags;
345
- req->base.complete(&async_req, pkcs1pad_decrypt_complete(req, err));
337
+ err = pkcs1pad_decrypt_complete(req, err);
338
+
339
+out:
340
+ akcipher_request_complete(req, err);
346341 }
347342
348343 static int pkcs1pad_decrypt(struct akcipher_request *req)
....@@ -392,7 +387,8 @@
392387 if (!ctx->key_size)
393388 return -EINVAL;
394389
395
- digest_size = digest_info->size;
390
+ if (digest_info)
391
+ digest_size = digest_info->size;
396392
397393 if (req->src_len + digest_size > ctx->key_size - 11)
398394 return -EOVERFLOW;
....@@ -412,8 +408,9 @@
412408 memset(req_ctx->in_buf + 1, 0xff, ps_end - 1);
413409 req_ctx->in_buf[ps_end] = 0x00;
414410
415
- memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data,
416
- digest_info->size);
411
+ if (digest_info)
412
+ memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data,
413
+ digest_info->size);
417414
418415 pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
419416 ctx->key_size - 1 - req->src_len, req->src);
....@@ -426,7 +423,7 @@
426423 akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg,
427424 req->dst, ctx->key_size - 1, req->dst_len);
428425
429
- err = crypto_akcipher_sign(&req_ctx->child_req);
426
+ err = crypto_akcipher_decrypt(&req_ctx->child_req);
430427 if (err != -EINPROGRESS && err != -EBUSY)
431428 return pkcs1pad_encrypt_sign_complete(req, err);
432429
....@@ -475,23 +472,35 @@
475472 goto done;
476473 pos++;
477474
478
- if (crypto_memneq(out_buf + pos, digest_info->data, digest_info->size))
479
- goto done;
475
+ if (digest_info) {
476
+ if (digest_info->size > dst_len - pos)
477
+ goto done;
478
+ if (crypto_memneq(out_buf + pos, digest_info->data,
479
+ digest_info->size))
480
+ goto done;
480481
481
- pos += digest_info->size;
482
+ pos += digest_info->size;
483
+ }
482484
483485 err = 0;
484486
485
- if (req->dst_len < dst_len - pos)
486
- err = -EOVERFLOW;
487
- req->dst_len = dst_len - pos;
488
-
489
- if (!err)
490
- sg_copy_from_buffer(req->dst,
491
- sg_nents_for_len(req->dst, req->dst_len),
492
- out_buf + pos, req->dst_len);
487
+ if (req->dst_len != dst_len - pos) {
488
+ err = -EKEYREJECTED;
489
+ req->dst_len = dst_len - pos;
490
+ goto done;
491
+ }
492
+ /* Extract appended digest. */
493
+ sg_pcopy_to_buffer(req->src,
494
+ sg_nents_for_len(req->src,
495
+ req->src_len + req->dst_len),
496
+ req_ctx->out_buf + ctx->key_size,
497
+ req->dst_len, req->src_len);
498
+ /* Do the actual verification step. */
499
+ if (memcmp(req_ctx->out_buf + ctx->key_size, out_buf + pos,
500
+ req->dst_len) != 0)
501
+ err = -EKEYREJECTED;
493502 done:
494
- kzfree(req_ctx->out_buf);
503
+ kfree_sensitive(req_ctx->out_buf);
495504
496505 return err;
497506 }
....@@ -500,15 +509,14 @@
500509 struct crypto_async_request *child_async_req, int err)
501510 {
502511 struct akcipher_request *req = child_async_req->data;
503
- struct crypto_async_request async_req;
504512
505513 if (err == -EINPROGRESS)
506
- return;
514
+ goto out;
507515
508
- async_req.data = req->base.data;
509
- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
510
- async_req.flags = child_async_req->flags;
511
- req->base.complete(&async_req, pkcs1pad_verify_complete(req, err));
516
+ err = pkcs1pad_verify_complete(req, err);
517
+
518
+out:
519
+ akcipher_request_complete(req, err);
512520 }
513521
514522 /*
....@@ -526,10 +534,12 @@
526534 struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
527535 int err;
528536
529
- if (!ctx->key_size || req->src_len < ctx->key_size)
537
+ if (WARN_ON(req->dst) ||
538
+ WARN_ON(!req->dst_len) ||
539
+ !ctx->key_size || req->src_len != ctx->key_size)
530540 return -EINVAL;
531541
532
- req_ctx->out_buf = kmalloc(ctx->key_size, GFP_KERNEL);
542
+ req_ctx->out_buf = kmalloc(ctx->key_size + req->dst_len, GFP_KERNEL);
533543 if (!req_ctx->out_buf)
534544 return -ENOMEM;
535545
....@@ -545,7 +555,7 @@
545555 req_ctx->out_sg, req->src_len,
546556 ctx->key_size);
547557
548
- err = crypto_akcipher_verify(&req_ctx->child_req);
558
+ err = crypto_akcipher_encrypt(&req_ctx->child_req);
549559 if (err != -EINPROGRESS && err != -EBUSY)
550560 return pkcs1pad_verify_complete(req, err);
551561
....@@ -585,63 +595,67 @@
585595
586596 static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
587597 {
588
- const struct rsa_asn1_template *digest_info;
589
- struct crypto_attr_type *algt;
598
+ u32 mask;
590599 struct akcipher_instance *inst;
591600 struct pkcs1pad_inst_ctx *ctx;
592
- struct crypto_akcipher_spawn *spawn;
593601 struct akcipher_alg *rsa_alg;
594
- const char *rsa_alg_name;
595602 const char *hash_name;
596603 int err;
597604
598
- algt = crypto_get_attr_type(tb);
599
- if (IS_ERR(algt))
600
- return PTR_ERR(algt);
601
-
602
- if ((algt->type ^ CRYPTO_ALG_TYPE_AKCIPHER) & algt->mask)
603
- return -EINVAL;
604
-
605
- rsa_alg_name = crypto_attr_alg_name(tb[1]);
606
- if (IS_ERR(rsa_alg_name))
607
- return PTR_ERR(rsa_alg_name);
608
-
609
- hash_name = crypto_attr_alg_name(tb[2]);
610
- if (IS_ERR(hash_name))
611
- return PTR_ERR(hash_name);
612
-
613
- digest_info = rsa_lookup_asn1(hash_name);
614
- if (!digest_info)
615
- return -EINVAL;
605
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AKCIPHER, &mask);
606
+ if (err)
607
+ return err;
616608
617609 inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
618610 if (!inst)
619611 return -ENOMEM;
620612
621613 ctx = akcipher_instance_ctx(inst);
622
- spawn = &ctx->spawn;
623
- ctx->digest_info = digest_info;
624614
625
- crypto_set_spawn(&spawn->base, akcipher_crypto_instance(inst));
626
- err = crypto_grab_akcipher(spawn, rsa_alg_name, 0,
627
- crypto_requires_sync(algt->type, algt->mask));
615
+ err = crypto_grab_akcipher(&ctx->spawn, akcipher_crypto_instance(inst),
616
+ crypto_attr_alg_name(tb[1]), 0, mask);
628617 if (err)
629
- goto out_free_inst;
618
+ goto err_free_inst;
630619
631
- rsa_alg = crypto_spawn_akcipher_alg(spawn);
620
+ rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn);
621
+
622
+ if (strcmp(rsa_alg->base.cra_name, "rsa") != 0) {
623
+ err = -EINVAL;
624
+ goto err_free_inst;
625
+ }
632626
633627 err = -ENAMETOOLONG;
628
+ hash_name = crypto_attr_alg_name(tb[2]);
629
+ if (IS_ERR(hash_name)) {
630
+ if (snprintf(inst->alg.base.cra_name,
631
+ CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)",
632
+ rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
633
+ goto err_free_inst;
634634
635
- if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
636
- "pkcs1pad(%s,%s)", rsa_alg->base.cra_name, hash_name) >=
637
- CRYPTO_MAX_ALG_NAME ||
638
- snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
639
- "pkcs1pad(%s,%s)",
640
- rsa_alg->base.cra_driver_name, hash_name) >=
641
- CRYPTO_MAX_ALG_NAME)
642
- goto out_drop_alg;
635
+ if (snprintf(inst->alg.base.cra_driver_name,
636
+ CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)",
637
+ rsa_alg->base.cra_driver_name) >=
638
+ CRYPTO_MAX_ALG_NAME)
639
+ goto err_free_inst;
640
+ } else {
641
+ ctx->digest_info = rsa_lookup_asn1(hash_name);
642
+ if (!ctx->digest_info) {
643
+ err = -EINVAL;
644
+ goto err_free_inst;
645
+ }
643646
644
- inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC;
647
+ if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
648
+ "pkcs1pad(%s,%s)", rsa_alg->base.cra_name,
649
+ hash_name) >= CRYPTO_MAX_ALG_NAME)
650
+ goto err_free_inst;
651
+
652
+ if (snprintf(inst->alg.base.cra_driver_name,
653
+ CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)",
654
+ rsa_alg->base.cra_driver_name,
655
+ hash_name) >= CRYPTO_MAX_ALG_NAME)
656
+ goto err_free_inst;
657
+ }
658
+
645659 inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
646660 inst->alg.base.cra_ctxsize = sizeof(struct pkcs1pad_ctx);
647661
....@@ -660,15 +674,10 @@
660674 inst->free = pkcs1pad_free;
661675
662676 err = akcipher_register_instance(tmpl, inst);
663
- if (err)
664
- goto out_drop_alg;
665
-
666
- return 0;
667
-
668
-out_drop_alg:
669
- crypto_drop_akcipher(spawn);
670
-out_free_inst:
671
- kfree(inst);
677
+ if (err) {
678
+err_free_inst:
679
+ pkcs1pad_free(inst);
680
+ }
672681 return err;
673682 }
674683