blob: d9095616909159e4b6062a440cbc042c7d3da22d [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Ard Biesheuvel <ardb@kernel.org>
3Date: Fri, 8 Nov 2019 13:22:34 +0100
4Subject: [PATCH] crypto: curve25519 - implement generic KPP driver
5
6commit ee772cb641135739c1530647391d5a04c39db192 upstream.
7
8Expose the generic Curve25519 library via the crypto API KPP interface.
9
10Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
11Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
12Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
13---
14 crypto/Kconfig | 5 +++
15 crypto/Makefile | 1 +
16 crypto/curve25519-generic.c | 90 +++++++++++++++++++++++++++++++++++++
17 3 files changed, 96 insertions(+)
18 create mode 100644 crypto/curve25519-generic.c
19
20--- a/crypto/Kconfig
21+++ b/crypto/Kconfig
22@@ -264,6 +264,11 @@ config CRYPTO_ECRDSA
23 standard algorithms (called GOST algorithms). Only signature verification
24 is implemented.
25
26+config CRYPTO_CURVE25519
27+ tristate "Curve25519 algorithm"
28+ select CRYPTO_KPP
29+ select CRYPTO_LIB_CURVE25519_GENERIC
30+
31 comment "Authenticated Encryption with Associated Data"
32
33 config CRYPTO_CCM
34--- a/crypto/Makefile
35+++ b/crypto/Makefile
36@@ -167,6 +167,7 @@ obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o
37 obj-$(CONFIG_CRYPTO_OFB) += ofb.o
38 obj-$(CONFIG_CRYPTO_ECC) += ecc.o
39 obj-$(CONFIG_CRYPTO_ESSIV) += essiv.o
40+obj-$(CONFIG_CRYPTO_CURVE25519) += curve25519-generic.o
41
42 ecdh_generic-y += ecdh.o
43 ecdh_generic-y += ecdh_helper.o
44--- /dev/null
45+++ b/crypto/curve25519-generic.c
46@@ -0,0 +1,90 @@
47+// SPDX-License-Identifier: GPL-2.0-or-later
48+
49+#include <crypto/curve25519.h>
50+#include <crypto/internal/kpp.h>
51+#include <crypto/kpp.h>
52+#include <linux/module.h>
53+#include <linux/scatterlist.h>
54+
55+static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
56+ unsigned int len)
57+{
58+ u8 *secret = kpp_tfm_ctx(tfm);
59+
60+ if (!len)
61+ curve25519_generate_secret(secret);
62+ else if (len == CURVE25519_KEY_SIZE &&
63+ crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE))
64+ memcpy(secret, buf, CURVE25519_KEY_SIZE);
65+ else
66+ return -EINVAL;
67+ return 0;
68+}
69+
70+static int curve25519_compute_value(struct kpp_request *req)
71+{
72+ struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
73+ const u8 *secret = kpp_tfm_ctx(tfm);
74+ u8 public_key[CURVE25519_KEY_SIZE];
75+ u8 buf[CURVE25519_KEY_SIZE];
76+ int copied, nbytes;
77+ u8 const *bp;
78+
79+ if (req->src) {
80+ copied = sg_copy_to_buffer(req->src,
81+ sg_nents_for_len(req->src,
82+ CURVE25519_KEY_SIZE),
83+ public_key, CURVE25519_KEY_SIZE);
84+ if (copied != CURVE25519_KEY_SIZE)
85+ return -EINVAL;
86+ bp = public_key;
87+ } else {
88+ bp = curve25519_base_point;
89+ }
90+
91+ curve25519_generic(buf, secret, bp);
92+
93+ /* might want less than we've got */
94+ nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
95+ copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
96+ nbytes),
97+ buf, nbytes);
98+ if (copied != nbytes)
99+ return -EINVAL;
100+ return 0;
101+}
102+
103+static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
104+{
105+ return CURVE25519_KEY_SIZE;
106+}
107+
108+static struct kpp_alg curve25519_alg = {
109+ .base.cra_name = "curve25519",
110+ .base.cra_driver_name = "curve25519-generic",
111+ .base.cra_priority = 100,
112+ .base.cra_module = THIS_MODULE,
113+ .base.cra_ctxsize = CURVE25519_KEY_SIZE,
114+
115+ .set_secret = curve25519_set_secret,
116+ .generate_public_key = curve25519_compute_value,
117+ .compute_shared_secret = curve25519_compute_value,
118+ .max_size = curve25519_max_size,
119+};
120+
121+static int curve25519_init(void)
122+{
123+ return crypto_register_kpp(&curve25519_alg);
124+}
125+
126+static void curve25519_exit(void)
127+{
128+ crypto_unregister_kpp(&curve25519_alg);
129+}
130+
131+subsys_initcall(curve25519_init);
132+module_exit(curve25519_exit);
133+
134+MODULE_ALIAS_CRYPTO("curve25519");
135+MODULE_ALIAS_CRYPTO("curve25519-generic");
136+MODULE_LICENSE("GPL");