summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authortb <>2023-07-03 13:53:54 +0000
committertb <>2023-07-03 13:53:54 +0000
commit556ac59e012f4b9c05b4a8fec4d7245bbd9dc1a3 (patch)
treebb803a62b99b495c15378d923d6ca6a16564b1c0 /src/lib
parent15bf5c4650c5014c8ea5f866385d01d28022cff4 (diff)
downloadopenbsd-556ac59e012f4b9c05b4a8fec4d7245bbd9dc1a3.tar.gz
openbsd-556ac59e012f4b9c05b4a8fec4d7245bbd9dc1a3.tar.bz2
openbsd-556ac59e012f4b9c05b4a8fec4d7245bbd9dc1a3.zip
Rework the logic in ECDSA sign_sig()
If the caller supplied both kinv and r, we don't loop but rather throw an undocumented error code that no one uses, which is intended to tell the caller to run ECDSA_sign_setup() and try again. Use a boolean that indicates this situation so that the logic becomes a bit more transparent. ok jsing
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_ossl.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c
index 1dce05c35f..d935d237ba 100644
--- a/src/lib/libcrypto/ecdsa/ecs_ossl.c
+++ b/src/lib/libcrypto/ecdsa/ecs_ossl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecs_ossl.c,v 1.59 2023/07/03 11:10:28 tb Exp $ */ 1/* $OpenBSD: ecs_ossl.c,v 1.60 2023/07/03 13:53:54 tb Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project 3 * Written by Nils Larsch for the OpenSSL project
4 */ 4 */
@@ -275,6 +275,7 @@ ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
275 BIGNUM *kinv = NULL, *r = NULL, *s = NULL; 275 BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
276 BIGNUM *b, *binv, *bm, *bxr, *m; 276 BIGNUM *b, *binv, *bm, *bxr, *m;
277 const BIGNUM *ckinv, *order, *priv_key; 277 const BIGNUM *ckinv, *order, *priv_key;
278 int caller_supplied_values = 0;
278 int attempts = 0; 279 int attempts = 0;
279 ECDSA_SIG *sig = NULL; 280 ECDSA_SIG *sig = NULL;
280 281
@@ -322,19 +323,28 @@ ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
322 if (!ecdsa_prepare_digest(dgst, dgst_len, order, m)) 323 if (!ecdsa_prepare_digest(dgst, dgst_len, order, m))
323 goto err; 324 goto err;
324 325
326 if (in_kinv != NULL && in_r != NULL) {
327 /*
328 * Use the caller's kinv and r. Don't call ECDSA_sign_setup().
329 * If we're unable to compute a valid signature, the caller
330 * must provide new values.
331 */
332 caller_supplied_values = 1;
333
334 ckinv = in_kinv;
335 if (!bn_copy(r, in_r)) {
336 ECDSAerror(ERR_R_MALLOC_FAILURE);
337 goto err;
338 }
339 }
340
325 do { 341 do {
326 if (in_kinv == NULL || in_r == NULL) { 342 if (!caller_supplied_values) {
327 if (!ECDSA_sign_setup(eckey, ctx, &kinv, &r)) { 343 if (!ECDSA_sign_setup(eckey, ctx, &kinv, &r)) {
328 ECDSAerror(ERR_R_ECDSA_LIB); 344 ECDSAerror(ERR_R_ECDSA_LIB);
329 goto err; 345 goto err;
330 } 346 }
331 ckinv = kinv; 347 ckinv = kinv;
332 } else {
333 ckinv = in_kinv;
334 if (!bn_copy(r, in_r)) {
335 ECDSAerror(ERR_R_MALLOC_FAILURE);
336 goto err;
337 }
338 } 348 }
339 349
340 /* 350 /*
@@ -385,23 +395,19 @@ ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
385 goto err; 395 goto err;
386 } 396 }
387 397
388 if (BN_is_zero(s)) { 398 /* If s is non-zero, we have a valid signature. */
389 /* 399 if (!BN_is_zero(s))
390 * If kinv and r have been supplied by the caller,
391 * don't generate new kinv and r values
392 */
393 if (in_kinv != NULL && in_r != NULL) {
394 ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES);
395 goto err;
396 }
397
398 if (++attempts > ECDSA_MAX_SIGN_ITERATIONS) {
399 ECDSAerror(EC_R_WRONG_CURVE_PARAMETERS);
400 goto err;
401 }
402 } else
403 /* s != 0 => we have a valid signature */
404 break; 400 break;
401
402 if (caller_supplied_values) {
403 ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES);
404 goto err;
405 }
406
407 if (++attempts > ECDSA_MAX_SIGN_ITERATIONS) {
408 ECDSAerror(EC_R_WRONG_CURVE_PARAMETERS);
409 goto err;
410 }
405 } while (1); 411 } while (1);
406 412
407 if ((sig = ECDSA_SIG_new()) == NULL) { 413 if ((sig = ECDSA_SIG_new()) == NULL) {