curve25519-generic.c (2233B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2 3#include <crypto/curve25519.h> 4#include <crypto/internal/kpp.h> 5#include <crypto/kpp.h> 6#include <linux/module.h> 7#include <linux/scatterlist.h> 8 9static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf, 10 unsigned int len) 11{ 12 u8 *secret = kpp_tfm_ctx(tfm); 13 14 if (!len) 15 curve25519_generate_secret(secret); 16 else if (len == CURVE25519_KEY_SIZE && 17 crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE)) 18 memcpy(secret, buf, CURVE25519_KEY_SIZE); 19 else 20 return -EINVAL; 21 return 0; 22} 23 24static int curve25519_compute_value(struct kpp_request *req) 25{ 26 struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); 27 const u8 *secret = kpp_tfm_ctx(tfm); 28 u8 public_key[CURVE25519_KEY_SIZE]; 29 u8 buf[CURVE25519_KEY_SIZE]; 30 int copied, nbytes; 31 u8 const *bp; 32 33 if (req->src) { 34 copied = sg_copy_to_buffer(req->src, 35 sg_nents_for_len(req->src, 36 CURVE25519_KEY_SIZE), 37 public_key, CURVE25519_KEY_SIZE); 38 if (copied != CURVE25519_KEY_SIZE) 39 return -EINVAL; 40 bp = public_key; 41 } else { 42 bp = curve25519_base_point; 43 } 44 45 curve25519_generic(buf, secret, bp); 46 47 /* might want less than we've got */ 48 nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len); 49 copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, 50 nbytes), 51 buf, nbytes); 52 if (copied != nbytes) 53 return -EINVAL; 54 return 0; 55} 56 57static unsigned int curve25519_max_size(struct crypto_kpp *tfm) 58{ 59 return CURVE25519_KEY_SIZE; 60} 61 62static struct kpp_alg curve25519_alg = { 63 .base.cra_name = "curve25519", 64 .base.cra_driver_name = "curve25519-generic", 65 .base.cra_priority = 100, 66 .base.cra_module = THIS_MODULE, 67 .base.cra_ctxsize = CURVE25519_KEY_SIZE, 68 69 .set_secret = curve25519_set_secret, 70 .generate_public_key = curve25519_compute_value, 71 .compute_shared_secret = curve25519_compute_value, 72 .max_size = curve25519_max_size, 73}; 74 75static int curve25519_init(void) 76{ 77 return crypto_register_kpp(&curve25519_alg); 78} 79 80static void curve25519_exit(void) 81{ 82 crypto_unregister_kpp(&curve25519_alg); 83} 84 85subsys_initcall(curve25519_init); 86module_exit(curve25519_exit); 87 88MODULE_ALIAS_CRYPTO("curve25519"); 89MODULE_ALIAS_CRYPTO("curve25519-generic"); 90MODULE_LICENSE("GPL");