1 From 54bdc995d525de6ae20f74af36d079f8b79e52fa Mon Sep 17 00:00:00 2001
2 From: Ard Biesheuvel <ardb@kernel.org>
3 Date: Fri, 8 Nov 2019 13:22:34 +0100
4 Subject: [PATCH 027/124] crypto: curve25519 - implement generic KPP driver
6 commit ee772cb641135739c1530647391d5a04c39db192 upstream.
8 Expose the generic Curve25519 library via the crypto API KPP interface.
10 Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
11 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
12 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
14 crypto/Kconfig | 5 +++
16 crypto/curve25519-generic.c | 90 +++++++++++++++++++++++++++++++++++++
17 3 files changed, 96 insertions(+)
18 create mode 100644 crypto/curve25519-generic.c
22 @@ -264,6 +264,11 @@ config CRYPTO_ECRDSA
23 standard algorithms (called GOST algorithms). Only signature verification
26 +config CRYPTO_CURVE25519
27 + tristate "Curve25519 algorithm"
29 + select CRYPTO_LIB_CURVE25519_GENERIC
31 comment "Authenticated Encryption with Associated Data"
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
42 ecdh_generic-y += ecdh.o
43 ecdh_generic-y += ecdh_helper.o
45 +++ b/crypto/curve25519-generic.c
47 +// SPDX-License-Identifier: GPL-2.0-or-later
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>
55 +static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
58 + u8 *secret = kpp_tfm_ctx(tfm);
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);
70 +static int curve25519_compute_value(struct kpp_request *req)
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];
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)
88 + bp = curve25519_base_point;
91 + curve25519_generic(buf, secret, bp);
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,
98 + if (copied != nbytes)
103 +static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
105 + return CURVE25519_KEY_SIZE;
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,
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,
121 +static int curve25519_init(void)
123 + return crypto_register_kpp(&curve25519_alg);
126 +static void curve25519_exit(void)
128 + crypto_unregister_kpp(&curve25519_alg);
131 +subsys_initcall(curve25519_init);
132 +module_exit(curve25519_exit);
134 +MODULE_ALIAS_CRYPTO("curve25519");
135 +MODULE_ALIAS_CRYPTO("curve25519-generic");
136 +MODULE_LICENSE("GPL");