Blame view
crypto/ecdh.c
4.02 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
3c4b23901 crypto: ecdh - Ad... |
2 3 4 5 |
/* ECDH key-agreement protocol * * Copyright (c) 2016, Intel Corporation * Authors: Salvator Benedetto <salvatore.benedetto@intel.com> |
3c4b23901 crypto: ecdh - Ad... |
6 7 8 9 10 11 12 13 14 15 16 17 18 |
*/ #include <linux/module.h> #include <crypto/internal/kpp.h> #include <crypto/kpp.h> #include <crypto/ecdh.h> #include <linux/scatterlist.h> #include "ecc.h" struct ecdh_ctx { unsigned int curve_id; unsigned int ndigits; u64 private_key[ECC_MAX_DIGITS]; |
3c4b23901 crypto: ecdh - Ad... |
19 20 21 22 23 24 25 26 27 28 |
}; static inline struct ecdh_ctx *ecdh_get_ctx(struct crypto_kpp *tfm) { return kpp_tfm_ctx(tfm); } static unsigned int ecdh_supported_curve(unsigned int curve_id) { switch (curve_id) { |
d5c3b1789 crypto: ecc - Act... |
29 30 |
case ECC_CURVE_NIST_P192: return ECC_CURVE_NIST_P192_DIGITS; case ECC_CURVE_NIST_P256: return ECC_CURVE_NIST_P256_DIGITS; |
3c4b23901 crypto: ecdh - Ad... |
31 32 33 |
default: return 0; } } |
5527dfb6d crypto: kpp - con... |
34 35 |
static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf, unsigned int len) |
3c4b23901 crypto: ecdh - Ad... |
36 37 38 39 |
{ struct ecdh_ctx *ctx = ecdh_get_ctx(tfm); struct ecdh params; unsigned int ndigits; |
3f20005ab crypto: ecdh - av... |
40 41 |
if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0 || params.key_size > sizeof(ctx->private_key)) |
3c4b23901 crypto: ecdh - Ad... |
42 43 44 45 46 47 48 49 |
return -EINVAL; ndigits = ecdh_supported_curve(params.curve_id); if (!ndigits) return -EINVAL; ctx->curve_id = params.curve_id; ctx->ndigits = ndigits; |
6755fd269 crypto: ecdh - ad... |
50 51 52 |
if (!params.key || !params.key_size) return ecc_gen_privkey(ctx->curve_id, ctx->ndigits, ctx->private_key); |
3c4b23901 crypto: ecdh - Ad... |
53 |
memcpy(ctx->private_key, params.key, params.key_size); |
c49bfdb52 crypto: ecdh - av... |
54 55 56 57 58 |
if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits, ctx->private_key, params.key_size) < 0) { memzero_explicit(ctx->private_key, params.key_size); return -EINVAL; } |
3c4b23901 crypto: ecdh - Ad... |
59 60 61 62 63 |
return 0; } static int ecdh_compute_value(struct kpp_request *req) { |
3c4b23901 crypto: ecdh - Ad... |
64 65 |
struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); struct ecdh_ctx *ctx = ecdh_get_ctx(tfm); |
952035bae crypto: ecdh - fi... |
66 67 |
u64 *public_key; u64 *shared_secret = NULL; |
3c4b23901 crypto: ecdh - Ad... |
68 |
void *buf; |
952035bae crypto: ecdh - fi... |
69 70 |
size_t copied, nbytes, public_key_sz; int ret = -ENOMEM; |
3c4b23901 crypto: ecdh - Ad... |
71 72 |
nbytes = ctx->ndigits << ECC_DIGITS_TO_BYTES_SHIFT; |
952035bae crypto: ecdh - fi... |
73 74 75 76 77 78 |
/* Public part is a point thus it has both coordinates */ public_key_sz = 2 * nbytes; public_key = kmalloc(public_key_sz, GFP_KERNEL); if (!public_key) return -ENOMEM; |
3c4b23901 crypto: ecdh - Ad... |
79 80 |
if (req->src) { |
952035bae crypto: ecdh - fi... |
81 82 83 |
shared_secret = kmalloc(nbytes, GFP_KERNEL); if (!shared_secret) goto free_pubkey; |
95ec01ba1 crypto: ecdh - fi... |
84 85 86 87 88 89 90 91 92 93 94 95 |
/* from here on it's invalid parameters */ ret = -EINVAL; /* must have exactly two points to be on the curve */ if (public_key_sz != req->src_len) goto free_all; copied = sg_copy_to_buffer(req->src, sg_nents_for_len(req->src, public_key_sz), public_key, public_key_sz); if (copied != public_key_sz) |
952035bae crypto: ecdh - fi... |
96 |
goto free_all; |
3c4b23901 crypto: ecdh - Ad... |
97 |
|
8f44df154 crypto: ecdh - ma... |
98 |
ret = crypto_ecdh_shared_secret(ctx->curve_id, ctx->ndigits, |
952035bae crypto: ecdh - fi... |
99 100 |
ctx->private_key, public_key, shared_secret); |
3c4b23901 crypto: ecdh - Ad... |
101 |
|
952035bae crypto: ecdh - fi... |
102 |
buf = shared_secret; |
3c4b23901 crypto: ecdh - Ad... |
103 |
} else { |
7380c56d2 crypto: ecc - ren... |
104 |
ret = ecc_make_pub_key(ctx->curve_id, ctx->ndigits, |
952035bae crypto: ecdh - fi... |
105 106 107 |
ctx->private_key, public_key); buf = public_key; nbytes = public_key_sz; |
3c4b23901 crypto: ecdh - Ad... |
108 109 110 |
} if (ret < 0) |
952035bae crypto: ecdh - fi... |
111 |
goto free_all; |
3c4b23901 crypto: ecdh - Ad... |
112 |
|
95ec01ba1 crypto: ecdh - fi... |
113 114 115 116 117 |
/* might want less than we've got */ nbytes = min_t(size_t, nbytes, req->dst_len); copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, nbytes), buf, nbytes); |
3c4b23901 crypto: ecdh - Ad... |
118 |
if (copied != nbytes) |
952035bae crypto: ecdh - fi... |
119 |
ret = -EINVAL; |
3c4b23901 crypto: ecdh - Ad... |
120 |
|
952035bae crypto: ecdh - fi... |
121 122 |
/* fall through */ free_all: |
453431a54 mm, treewide: ren... |
123 |
kfree_sensitive(shared_secret); |
952035bae crypto: ecdh - fi... |
124 125 |
free_pubkey: kfree(public_key); |
3c4b23901 crypto: ecdh - Ad... |
126 127 |
return ret; } |
d0efb48b8 crypto: ecdh - co... |
128 |
static unsigned int ecdh_max_size(struct crypto_kpp *tfm) |
3c4b23901 crypto: ecdh - Ad... |
129 130 |
{ struct ecdh_ctx *ctx = ecdh_get_ctx(tfm); |
3c4b23901 crypto: ecdh - Ad... |
131 |
|
d0efb48b8 crypto: ecdh - co... |
132 133 |
/* Public key is made of two coordinates, add one to the left shift */ return ctx->ndigits << (ECC_DIGITS_TO_BYTES_SHIFT + 1); |
3c4b23901 crypto: ecdh - Ad... |
134 |
} |
3c4b23901 crypto: ecdh - Ad... |
135 136 137 138 139 |
static struct kpp_alg ecdh = { .set_secret = ecdh_set_secret, .generate_public_key = ecdh_compute_value, .compute_shared_secret = ecdh_compute_value, .max_size = ecdh_max_size, |
3c4b23901 crypto: ecdh - Ad... |
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
.base = { .cra_name = "ecdh", .cra_driver_name = "ecdh-generic", .cra_priority = 100, .cra_module = THIS_MODULE, .cra_ctxsize = sizeof(struct ecdh_ctx), }, }; static int ecdh_init(void) { return crypto_register_kpp(&ecdh); } static void ecdh_exit(void) { crypto_unregister_kpp(&ecdh); } |
c4741b230 crypto: run initc... |
158 |
subsys_initcall(ecdh_init); |
3c4b23901 crypto: ecdh - Ad... |
159 160 161 162 |
module_exit(ecdh_exit); MODULE_ALIAS_CRYPTO("ecdh"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("ECDH generic algorithm"); |