diff options
author | tb <> | 2023-07-28 09:28:37 +0000 |
---|---|---|
committer | tb <> | 2023-07-28 09:28:37 +0000 |
commit | 33dbb14462f6ae315b78289dc98d9434aff69e79 (patch) | |
tree | 7caeb4b66ea3545dbbf75224b3b77f6e29ea4f22 /src/lib | |
parent | cf0c598c9887e5bc98b6596c5e1e0dda9848b88d (diff) | |
download | openbsd-33dbb14462f6ae315b78289dc98d9434aff69e79.tar.gz openbsd-33dbb14462f6ae315b78289dc98d9434aff69e79.tar.bz2 openbsd-33dbb14462f6ae315b78289dc98d9434aff69e79.zip |
Move KDF handling to ECDH_compute_key()
In OpenSSL e2285d87, the KDF handling was moved from the compute_key()
method into the public API. A consequence of this change is that the
ECDH_compute_key() API no longer returns -1 for some errors. Existing
checks for <= 0 are safe as are those checking for the exact length as
return value, which is all what the ecosystem seems to be doing.
ok jsing
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/ec/ec.h | 11 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_err.c | 3 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_kmeth.c | 10 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_local.h | 10 | ||||
-rw-r--r-- | src/lib/libcrypto/ecdh/ecdh.c | 86 |
5 files changed, 73 insertions, 47 deletions
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h index 686f018a9d..85951f0b97 100644 --- a/src/lib/libcrypto/ec/ec.h +++ b/src/lib/libcrypto/ec/ec.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec.h,v 1.44 2023/07/28 09:25:12 tb Exp $ */ | 1 | /* $OpenBSD: ec.h,v 1.45 2023/07/28 09:28:37 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Originally written by Bodo Moeller for the OpenSSL project. | 3 | * Originally written by Bodo Moeller for the OpenSSL project. |
4 | */ | 4 | */ |
@@ -368,8 +368,8 @@ void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, | |||
368 | void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, | 368 | void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, |
369 | int (*keygen)(EC_KEY *key)); | 369 | int (*keygen)(EC_KEY *key)); |
370 | void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, | 370 | void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, |
371 | int (*ckey)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, | 371 | int (*ckey)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, |
372 | void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))); | 372 | const EC_KEY *ecdh)); |
373 | void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, | 373 | void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, |
374 | int (*sign)(int type, const unsigned char *digest, int digest_len, | 374 | int (*sign)(int type, const unsigned char *digest, int digest_len, |
375 | unsigned char *signature, unsigned int *signature_len, | 375 | unsigned char *signature, unsigned int *signature_len, |
@@ -392,8 +392,8 @@ void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth, | |||
392 | void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, | 392 | void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, |
393 | int (**pkeygen)(EC_KEY *key)); | 393 | int (**pkeygen)(EC_KEY *key)); |
394 | void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, | 394 | void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, |
395 | int (**pck)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, | 395 | int (**pck)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, |
396 | void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))); | 396 | const EC_KEY *ecdh)); |
397 | void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, | 397 | void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, |
398 | int (**psign)(int type, const unsigned char *digest, int digest_len, | 398 | int (**psign)(int type, const unsigned char *digest, int digest_len, |
399 | unsigned char *signature, unsigned int *signature_len, | 399 | unsigned char *signature, unsigned int *signature_len, |
@@ -684,6 +684,7 @@ void ERR_load_EC_strings(void); | |||
684 | #define EC_R_INVALID_FORM 104 | 684 | #define EC_R_INVALID_FORM 104 |
685 | #define EC_R_INVALID_GROUP_ORDER 122 | 685 | #define EC_R_INVALID_GROUP_ORDER 122 |
686 | #define EC_R_INVALID_KEY 165 | 686 | #define EC_R_INVALID_KEY 165 |
687 | #define EC_R_INVALID_OUTPUT_LENGTH 171 | ||
687 | #define EC_R_INVALID_PEER_KEY 152 | 688 | #define EC_R_INVALID_PEER_KEY 152 |
688 | #define EC_R_INVALID_PENTANOMIAL_BASIS 132 | 689 | #define EC_R_INVALID_PENTANOMIAL_BASIS 132 |
689 | #define EC_R_INVALID_PRIVATE_KEY 123 | 690 | #define EC_R_INVALID_PRIVATE_KEY 123 |
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c index d797b937c2..9f2253dddd 100644 --- a/src/lib/libcrypto/ec/ec_err.c +++ b/src/lib/libcrypto/ec/ec_err.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_err.c,v 1.17 2023/07/07 13:54:45 beck Exp $ */ | 1 | /* $OpenBSD: ec_err.c,v 1.18 2023/07/28 09:28:37 tb Exp $ */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
@@ -98,6 +98,7 @@ static ERR_STRING_DATA EC_str_reasons[] = | |||
98 | {ERR_REASON(EC_R_INVALID_FORM), "invalid form"}, | 98 | {ERR_REASON(EC_R_INVALID_FORM), "invalid form"}, |
99 | {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"}, | 99 | {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"}, |
100 | {ERR_REASON(EC_R_INVALID_KEY), "invalid key"}, | 100 | {ERR_REASON(EC_R_INVALID_KEY), "invalid key"}, |
101 | {ERR_REASON(EC_R_INVALID_OUTPUT_LENGTH), "invalid output length"}, | ||
101 | {ERR_REASON(EC_R_INVALID_PEER_KEY), "invalid peer key"}, | 102 | {ERR_REASON(EC_R_INVALID_PEER_KEY), "invalid peer key"}, |
102 | {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, | 103 | {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, |
103 | {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, | 104 | {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, |
diff --git a/src/lib/libcrypto/ec/ec_kmeth.c b/src/lib/libcrypto/ec/ec_kmeth.c index 3e997f8a5e..38aca0028e 100644 --- a/src/lib/libcrypto/ec/ec_kmeth.c +++ b/src/lib/libcrypto/ec/ec_kmeth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_kmeth.c,v 1.11 2023/07/07 13:54:45 beck Exp $ */ | 1 | /* $OpenBSD: ec_kmeth.c,v 1.12 2023/07/28 09:28:37 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 3 | * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
4 | * project. | 4 | * project. |
@@ -238,8 +238,8 @@ LCRYPTO_ALIAS(EC_KEY_METHOD_set_keygen); | |||
238 | 238 | ||
239 | void | 239 | void |
240 | EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, | 240 | EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, |
241 | int (*ckey)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, | 241 | int (*ckey)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, |
242 | void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))) | 242 | const EC_KEY *ecdh)) |
243 | { | 243 | { |
244 | meth->compute_key = ckey; | 244 | meth->compute_key = ckey; |
245 | } | 245 | } |
@@ -310,8 +310,8 @@ LCRYPTO_ALIAS(EC_KEY_METHOD_get_keygen); | |||
310 | 310 | ||
311 | void | 311 | void |
312 | EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, | 312 | EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, |
313 | int (**pck)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, | 313 | int (**pck)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, |
314 | void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))) | 314 | const EC_KEY *ecdh)) |
315 | { | 315 | { |
316 | if (pck != NULL) | 316 | if (pck != NULL) |
317 | *pck = meth->compute_key; | 317 | *pck = meth->compute_key; |
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h index 7a1f90886d..8153d4a96a 100644 --- a/src/lib/libcrypto/ec/ec_local.h +++ b/src/lib/libcrypto/ec/ec_local.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_local.h,v 1.24 2023/07/05 08:39:40 tb Exp $ */ | 1 | /* $OpenBSD: ec_local.h,v 1.25 2023/07/28 09:28:37 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Originally written by Bodo Moeller for the OpenSSL project. | 3 | * Originally written by Bodo Moeller for the OpenSSL project. |
4 | */ | 4 | */ |
@@ -323,8 +323,8 @@ struct ec_key_method_st { | |||
323 | int (*set_private)(EC_KEY *key, const BIGNUM *priv_key); | 323 | int (*set_private)(EC_KEY *key, const BIGNUM *priv_key); |
324 | int (*set_public)(EC_KEY *key, const EC_POINT *pub_key); | 324 | int (*set_public)(EC_KEY *key, const EC_POINT *pub_key); |
325 | int (*keygen)(EC_KEY *key); | 325 | int (*keygen)(EC_KEY *key); |
326 | int (*compute_key)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, | 326 | int (*compute_key)(unsigned char **out, size_t *out_len, |
327 | void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen)); | 327 | const EC_POINT *pub_key, const EC_KEY *ecdh); |
328 | int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char | 328 | int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char |
329 | *sig, unsigned int *siglen, const BIGNUM *kinv, | 329 | *sig, unsigned int *siglen, const BIGNUM *kinv, |
330 | const BIGNUM *r, EC_KEY *eckey); | 330 | const BIGNUM *r, EC_KEY *eckey); |
@@ -342,8 +342,8 @@ struct ec_key_method_st { | |||
342 | #define EC_KEY_METHOD_DYNAMIC 1 | 342 | #define EC_KEY_METHOD_DYNAMIC 1 |
343 | 343 | ||
344 | int ec_key_gen(EC_KEY *eckey); | 344 | int ec_key_gen(EC_KEY *eckey); |
345 | int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, | 345 | int ecdh_compute_key(unsigned char **out, size_t *out_len, |
346 | void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen)); | 346 | const EC_POINT *pub_key, const EC_KEY *ecdh); |
347 | int ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, | 347 | int ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, |
348 | const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); | 348 | const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); |
349 | int ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, | 349 | int ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, |
diff --git a/src/lib/libcrypto/ecdh/ecdh.c b/src/lib/libcrypto/ecdh/ecdh.c index 6ab4ff8382..034bd84a49 100644 --- a/src/lib/libcrypto/ecdh/ecdh.c +++ b/src/lib/libcrypto/ecdh/ecdh.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ecdh.c,v 1.6 2023/07/24 17:08:53 tb Exp $ */ | 1 | /* $OpenBSD: ecdh.c,v 1.7 2023/07/28 09:28:37 tb Exp $ */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | 3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. |
4 | * | 4 | * |
@@ -145,10 +145,9 @@ ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z, | |||
145 | /* | 145 | /* |
146 | * Based on the ECKAS-DH1 and ECSVDP-DH primitives in the IEEE 1363 standard. | 146 | * Based on the ECKAS-DH1 and ECSVDP-DH primitives in the IEEE 1363 standard. |
147 | */ | 147 | */ |
148 | /* XXX - KDF handling moved to ECDH_compute_key(). See OpenSSL e2285d87. */ | ||
149 | int | 148 | int |
150 | ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, | 149 | ecdh_compute_key(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, |
151 | void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)) | 150 | const EC_KEY *ecdh) |
152 | { | 151 | { |
153 | BN_CTX *ctx; | 152 | BN_CTX *ctx; |
154 | BIGNUM *x; | 153 | BIGNUM *x; |
@@ -157,13 +156,10 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh | |||
157 | EC_POINT *point = NULL; | 156 | EC_POINT *point = NULL; |
158 | unsigned char *buf = NULL; | 157 | unsigned char *buf = NULL; |
159 | int buflen; | 158 | int buflen; |
160 | int ret = -1; | 159 | int ret = 0; |
161 | 160 | ||
162 | if (outlen > INT_MAX) { | 161 | *out = NULL; |
163 | /* Sort of, anyway. */ | 162 | *out_len = 0; |
164 | ECerror(ERR_R_MALLOC_FAILURE); | ||
165 | return -1; | ||
166 | } | ||
167 | 163 | ||
168 | if ((ctx = BN_CTX_new()) == NULL) | 164 | if ((ctx = BN_CTX_new()) == NULL) |
169 | goto err; | 165 | goto err; |
@@ -203,11 +199,6 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh | |||
203 | ECerror(ERR_R_INTERNAL_ERROR); | 199 | ECerror(ERR_R_INTERNAL_ERROR); |
204 | goto err; | 200 | goto err; |
205 | } | 201 | } |
206 | if (KDF == NULL && outlen < buflen) { | ||
207 | /* The resulting key would be truncated. */ | ||
208 | ECerror(EC_R_KEY_TRUNCATION); | ||
209 | goto err; | ||
210 | } | ||
211 | if ((buf = malloc(buflen)) == NULL) { | 202 | if ((buf = malloc(buflen)) == NULL) { |
212 | ECerror(ERR_R_MALLOC_FAILURE); | 203 | ECerror(ERR_R_MALLOC_FAILURE); |
213 | goto err; | 204 | goto err; |
@@ -217,19 +208,12 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh | |||
217 | goto err; | 208 | goto err; |
218 | } | 209 | } |
219 | 210 | ||
220 | if (KDF != NULL) { | 211 | *out = buf; |
221 | if (KDF(buf, buflen, out, &outlen) == NULL) { | 212 | *out_len = buflen; |
222 | ECerror(EC_R_KDF_FAILED); | 213 | buf = NULL; |
223 | goto err; | 214 | |
224 | } | 215 | ret = 1; |
225 | } else { | ||
226 | memset(out, 0, outlen); | ||
227 | if (outlen > buflen) | ||
228 | outlen = buflen; | ||
229 | memcpy(out, buf, outlen); | ||
230 | } | ||
231 | 216 | ||
232 | ret = outlen; | ||
233 | err: | 217 | err: |
234 | EC_POINT_free(point); | 218 | EC_POINT_free(point); |
235 | BN_CTX_end(ctx); | 219 | BN_CTX_end(ctx); |
@@ -240,15 +224,55 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh | |||
240 | } | 224 | } |
241 | 225 | ||
242 | int | 226 | int |
243 | ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, | 227 | ECDH_compute_key(void *out, size_t out_len, const EC_POINT *pub_key, |
244 | EC_KEY *eckey, | 228 | EC_KEY *eckey, |
245 | void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)) | 229 | void *(*KDF)(const void *in, size_t inlen, void *out, size_t *out_len)) |
246 | { | 230 | { |
231 | unsigned char *secret = NULL; | ||
232 | size_t secret_len = 0; | ||
233 | int ret = 0; | ||
234 | |||
247 | if (eckey->meth->compute_key == NULL) { | 235 | if (eckey->meth->compute_key == NULL) { |
248 | ECerror(EC_R_NOT_IMPLEMENTED); | 236 | ECerror(EC_R_NOT_IMPLEMENTED); |
249 | return 0; | 237 | goto err; |
238 | } | ||
239 | |||
240 | if (out_len > INT_MAX) { | ||
241 | ECerror(EC_R_INVALID_OUTPUT_LENGTH); | ||
242 | goto err; | ||
243 | } | ||
244 | |||
245 | if (!eckey->meth->compute_key(&secret, &secret_len, pub_key, eckey)) | ||
246 | goto err; | ||
247 | |||
248 | if (KDF != NULL) { | ||
249 | if (KDF(secret, secret_len, out, &out_len) == NULL) { | ||
250 | ECerror(EC_R_KDF_FAILED); | ||
251 | goto err; | ||
252 | } | ||
253 | } else { | ||
254 | memset(out, 0, out_len); | ||
255 | if (out_len < secret_len) { | ||
256 | /* The resulting key would be truncated. */ | ||
257 | ECerror(EC_R_KEY_TRUNCATION); | ||
258 | goto err; | ||
259 | } | ||
260 | if (out_len > secret_len) | ||
261 | out_len = secret_len; | ||
262 | memcpy(out, secret, out_len); | ||
250 | } | 263 | } |
251 | return eckey->meth->compute_key(out, outlen, pub_key, eckey, KDF); | 264 | |
265 | if (out_len > INT_MAX) { | ||
266 | ECerror(EC_R_INVALID_OUTPUT_LENGTH); | ||
267 | goto err; | ||
268 | } | ||
269 | |||
270 | ret = out_len; | ||
271 | |||
272 | err: | ||
273 | freezero(secret, secret_len); | ||
274 | |||
275 | return ret; | ||
252 | } | 276 | } |
253 | LCRYPTO_ALIAS(ECDH_compute_key); | 277 | LCRYPTO_ALIAS(ECDH_compute_key); |
254 | 278 | ||