Skip to content

Commit c402d7b

Browse files
authored
Merge pull request #8729 from philljj/linuxkm_ecdh_decode_secret
Linuxkm ecdh decode secret
2 parents d5cca9d + 68682f1 commit c402d7b

1 file changed

Lines changed: 57 additions & 2 deletions

File tree

linuxkm/lkcapi_ecdh_glue.c

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,61 @@ static struct kpp_alg ecdh_nist_p384 = {
133133
.exit = km_ecdh_exit,
134134
};
135135

136+
/* The ecdh secret is passed in this format:
137+
* __________________________________________________________
138+
* | secret hdr | key_size | key |
139+
* | (struct kpp_secret) | (int) | (curve_len, if present) |
140+
* ----------------------------------------------------------
141+
*
142+
* - the key_size field is mandatory, but may be 0 value.
143+
* - the key is optional.
144+
*
145+
* If key_size is 0, then key pair should be generated.
146+
* */
147+
#define ECDH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + sizeof(short))
148+
149+
static int km_ecdh_decode_secret(const u8 * buf, unsigned int len,
150+
struct ecdh * params)
151+
{
152+
struct kpp_secret secret;
153+
const u8 * ptr = NULL;
154+
size_t expected_len = 0;
155+
156+
if (unlikely(!buf || len < ECDH_KPP_SECRET_MIN_SIZE || !params)) {
157+
return -EINVAL;
158+
}
159+
160+
/* the type of secret should be the first byte. */
161+
ptr = buf;
162+
memcpy(&secret, ptr, sizeof(secret));
163+
ptr += sizeof(secret);
164+
if (secret.type != CRYPTO_KPP_SECRET_TYPE_ECDH) {
165+
return -EINVAL;
166+
}
167+
168+
/* the key_size field will be present */
169+
memcpy(&params->key_size, ptr, sizeof(params->key_size));
170+
ptr += sizeof(params->key_size);
171+
172+
/* Calculate expected len. Verify we got expected data. */
173+
expected_len = ECDH_KPP_SECRET_MIN_SIZE + params->key_size;
174+
175+
if (secret.len != expected_len) {
176+
#ifdef WOLFKM_DEBUG_ECDH
177+
pr_err("%s: km_ecdh_decode_secret: got %d, expected %zu",
178+
WOLFKM_ECDH_DRIVER, secret.len, expected_len);
179+
#endif /* WOLFKM_DEBUG_ECDH */
180+
return -EINVAL;
181+
}
182+
183+
/* Only set the key if it was provided. */
184+
if (params->key_size) {
185+
params->key = (void *)ptr;
186+
}
187+
188+
return 0;
189+
}
190+
136191
/*
137192
* Set the secret. Kernel crypto expects secret is passed with
138193
* struct kpp_secret as header, followed by secret data as payload.
@@ -150,6 +205,7 @@ static int km_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
150205
struct ecdh params;
151206

152207
ctx = kpp_tfm_ctx(tfm);
208+
memset(&params, 0, sizeof(params));
153209

154210
switch (ctx->curve_len) {
155211
#if defined(LINUXKM_ECC192)
@@ -166,8 +222,7 @@ static int km_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
166222
return -EINVAL;
167223
}
168224

169-
/* use decode key helper so we observe the same format. */
170-
if (crypto_ecdh_decode_key(buf, len, &params) < 0) {
225+
if (km_ecdh_decode_secret(buf, len, &params) < 0) {
171226
#ifdef WOLFKM_DEBUG_ECDH
172227
pr_err("%s: ecdh_set_secret: decode secret failed: %d",
173228
WOLFKM_ECDH_DRIVER, params.key_size);

0 commit comments

Comments
 (0)