mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-29 10:08:59 +00:00
137 lines
3.7 KiB
Diff
137 lines
3.7 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Ard Biesheuvel <ardb@kernel.org>
|
||
|
Date: Fri, 8 Nov 2019 13:22:34 +0100
|
||
|
Subject: [PATCH] crypto: curve25519 - implement generic KPP driver
|
||
|
|
||
|
commit ee772cb641135739c1530647391d5a04c39db192 upstream.
|
||
|
|
||
|
Expose the generic Curve25519 library via the crypto API KPP interface.
|
||
|
|
||
|
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
|
||
|
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||
|
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||
|
---
|
||
|
crypto/Kconfig | 5 +++
|
||
|
crypto/Makefile | 1 +
|
||
|
crypto/curve25519-generic.c | 90 +++++++++++++++++++++++++++++++++++++
|
||
|
3 files changed, 96 insertions(+)
|
||
|
create mode 100644 crypto/curve25519-generic.c
|
||
|
|
||
|
--- a/crypto/Kconfig
|
||
|
+++ b/crypto/Kconfig
|
||
|
@@ -264,6 +264,11 @@ config CRYPTO_ECRDSA
|
||
|
standard algorithms (called GOST algorithms). Only signature verification
|
||
|
is implemented.
|
||
|
|
||
|
+config CRYPTO_CURVE25519
|
||
|
+ tristate "Curve25519 algorithm"
|
||
|
+ select CRYPTO_KPP
|
||
|
+ select CRYPTO_LIB_CURVE25519_GENERIC
|
||
|
+
|
||
|
comment "Authenticated Encryption with Associated Data"
|
||
|
|
||
|
config CRYPTO_CCM
|
||
|
--- a/crypto/Makefile
|
||
|
+++ b/crypto/Makefile
|
||
|
@@ -167,6 +167,7 @@ obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o
|
||
|
obj-$(CONFIG_CRYPTO_OFB) += ofb.o
|
||
|
obj-$(CONFIG_CRYPTO_ECC) += ecc.o
|
||
|
obj-$(CONFIG_CRYPTO_ESSIV) += essiv.o
|
||
|
+obj-$(CONFIG_CRYPTO_CURVE25519) += curve25519-generic.o
|
||
|
|
||
|
ecdh_generic-y += ecdh.o
|
||
|
ecdh_generic-y += ecdh_helper.o
|
||
|
--- /dev/null
|
||
|
+++ b/crypto/curve25519-generic.c
|
||
|
@@ -0,0 +1,90 @@
|
||
|
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||
|
+
|
||
|
+#include <crypto/curve25519.h>
|
||
|
+#include <crypto/internal/kpp.h>
|
||
|
+#include <crypto/kpp.h>
|
||
|
+#include <linux/module.h>
|
||
|
+#include <linux/scatterlist.h>
|
||
|
+
|
||
|
+static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
|
||
|
+ unsigned int len)
|
||
|
+{
|
||
|
+ u8 *secret = kpp_tfm_ctx(tfm);
|
||
|
+
|
||
|
+ if (!len)
|
||
|
+ curve25519_generate_secret(secret);
|
||
|
+ else if (len == CURVE25519_KEY_SIZE &&
|
||
|
+ crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE))
|
||
|
+ memcpy(secret, buf, CURVE25519_KEY_SIZE);
|
||
|
+ else
|
||
|
+ return -EINVAL;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int curve25519_compute_value(struct kpp_request *req)
|
||
|
+{
|
||
|
+ struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
|
||
|
+ const u8 *secret = kpp_tfm_ctx(tfm);
|
||
|
+ u8 public_key[CURVE25519_KEY_SIZE];
|
||
|
+ u8 buf[CURVE25519_KEY_SIZE];
|
||
|
+ int copied, nbytes;
|
||
|
+ u8 const *bp;
|
||
|
+
|
||
|
+ if (req->src) {
|
||
|
+ copied = sg_copy_to_buffer(req->src,
|
||
|
+ sg_nents_for_len(req->src,
|
||
|
+ CURVE25519_KEY_SIZE),
|
||
|
+ public_key, CURVE25519_KEY_SIZE);
|
||
|
+ if (copied != CURVE25519_KEY_SIZE)
|
||
|
+ return -EINVAL;
|
||
|
+ bp = public_key;
|
||
|
+ } else {
|
||
|
+ bp = curve25519_base_point;
|
||
|
+ }
|
||
|
+
|
||
|
+ curve25519_generic(buf, secret, bp);
|
||
|
+
|
||
|
+ /* might want less than we've got */
|
||
|
+ nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
|
||
|
+ copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
|
||
|
+ nbytes),
|
||
|
+ buf, nbytes);
|
||
|
+ if (copied != nbytes)
|
||
|
+ return -EINVAL;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
|
||
|
+{
|
||
|
+ return CURVE25519_KEY_SIZE;
|
||
|
+}
|
||
|
+
|
||
|
+static struct kpp_alg curve25519_alg = {
|
||
|
+ .base.cra_name = "curve25519",
|
||
|
+ .base.cra_driver_name = "curve25519-generic",
|
||
|
+ .base.cra_priority = 100,
|
||
|
+ .base.cra_module = THIS_MODULE,
|
||
|
+ .base.cra_ctxsize = CURVE25519_KEY_SIZE,
|
||
|
+
|
||
|
+ .set_secret = curve25519_set_secret,
|
||
|
+ .generate_public_key = curve25519_compute_value,
|
||
|
+ .compute_shared_secret = curve25519_compute_value,
|
||
|
+ .max_size = curve25519_max_size,
|
||
|
+};
|
||
|
+
|
||
|
+static int curve25519_init(void)
|
||
|
+{
|
||
|
+ return crypto_register_kpp(&curve25519_alg);
|
||
|
+}
|
||
|
+
|
||
|
+static void curve25519_exit(void)
|
||
|
+{
|
||
|
+ crypto_unregister_kpp(&curve25519_alg);
|
||
|
+}
|
||
|
+
|
||
|
+subsys_initcall(curve25519_init);
|
||
|
+module_exit(curve25519_exit);
|
||
|
+
|
||
|
+MODULE_ALIAS_CRYPTO("curve25519");
|
||
|
+MODULE_ALIAS_CRYPTO("curve25519-generic");
|
||
|
+MODULE_LICENSE("GPL");
|