From: tb Date: Thu, 3 Aug 2023 18:53:55 +0000 (+0000) Subject: Make the bn_rand_interval() API a bit more ergonomic X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=12347e819a161ea252d407d10e9bab13ecdbe9e2;p=openbsd Make the bn_rand_interval() API a bit more ergonomic Provide bn_rand_in_range() which is a slightly tweaked version of what was previously called bn_rand_range(). The way bn_rand_range() is called in libcrypto, the lower bound is always expressible as a word. In fact, most of the time it is 1, the DH code uses a 2, the MR tests in BPSW use 3 and an exceptinally high number appears in the Tonelli-Shanks implementation where we use 32. Converting these lower bounds to BIGNUMs on the call site is annoying so let bn_rand_interval() do that internally and route that through bn_rand_in_range(). This way we can avoid using BN_sub_word(). Adjust the bn_isqrt() test to use bn_rand_in_range() since that's the only caller that uses actual BIGNUMs as lower bounds. ok jsing --- diff --git a/lib/libcrypto/bn/bn_bpsw.c b/lib/libcrypto/bn/bn_bpsw.c index 82a4e871461..14f2800ad37 100644 --- a/lib/libcrypto/bn/bn_bpsw.c +++ b/lib/libcrypto/bn/bn_bpsw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_bpsw.c,v 1.10 2023/05/10 21:05:24 tb Exp $ */ +/* $OpenBSD: bn_bpsw.c,v 1.11 2023/08/03 18:53:55 tb Exp $ */ /* * Copyright (c) 2022 Martin Grenouilloux * Copyright (c) 2022 Theo Buehler @@ -385,7 +385,7 @@ bn_miller_rabin(int *is_pseudoprime, const BIGNUM *n, BN_CTX *ctx, size_t rounds) { BN_MONT_CTX *mctx = NULL; - BIGNUM *base, *k, *n_minus_one, *three; + BIGNUM *base, *k, *n_minus_one; size_t i; int s; int ret = 0; @@ -398,8 +398,6 @@ bn_miller_rabin(int *is_pseudoprime, const BIGNUM *n, BN_CTX *ctx, goto err; if ((n_minus_one = BN_CTX_get(ctx)) == NULL) goto err; - if ((three = BN_CTX_get(ctx)) == NULL) - goto err; if (BN_is_word(n, 2) || BN_is_word(n, 3)) { *is_pseudoprime = 1; @@ -451,11 +449,8 @@ bn_miller_rabin(int *is_pseudoprime, const BIGNUM *n, BN_CTX *ctx, * risk of false positives in BPSW. */ - if (!BN_set_word(three, 3)) - goto err; - for (i = 0; i < rounds; i++) { - if (!bn_rand_interval(base, three, n_minus_one)) + if (!bn_rand_interval(base, 3, n_minus_one)) goto err; if (!bn_fermat(is_pseudoprime, n, n_minus_one, k, s, base, ctx, diff --git a/lib/libcrypto/bn/bn_local.h b/lib/libcrypto/bn/bn_local.h index 9447ed4f4c2..5b7e852d705 100644 --- a/lib/libcrypto/bn/bn_local.h +++ b/lib/libcrypto/bn/bn_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_local.h,v 1.32 2023/08/02 08:44:38 tb Exp $ */ +/* $OpenBSD: bn_local.h,v 1.33 2023/08/03 18:53:55 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -274,7 +274,8 @@ void bn_div_rem_words(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q, BN_ULONG *out_r); int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); -int bn_rand_interval(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc); +int bn_rand_in_range(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc); +int bn_rand_interval(BIGNUM *rnd, BN_ULONG lower_word, const BIGNUM *upper_exc); void BN_init(BIGNUM *); diff --git a/lib/libcrypto/bn/bn_mod_sqrt.c b/lib/libcrypto/bn/bn_mod_sqrt.c index bdd5b2cdba0..280002cc48d 100644 --- a/lib/libcrypto/bn/bn_mod_sqrt.c +++ b/lib/libcrypto/bn/bn_mod_sqrt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_mod_sqrt.c,v 1.2 2023/07/08 12:21:58 beck Exp $ */ +/* $OpenBSD: bn_mod_sqrt.c,v 1.3 2023/08/03 18:53:55 tb Exp $ */ /* * Copyright (c) 2022 Theo Buehler @@ -237,7 +237,7 @@ static int bn_mod_sqrt_find_sylow_generator(BIGNUM *out_generator, const BIGNUM *p, const BIGNUM *q, BN_CTX *ctx) { - BIGNUM *n, *p_abs, *thirty_two; + BIGNUM *n, *p_abs; int i, is_non_residue; int ret = 0; @@ -245,8 +245,6 @@ bn_mod_sqrt_find_sylow_generator(BIGNUM *out_generator, const BIGNUM *p, if ((n = BN_CTX_get(ctx)) == NULL) goto err; - if ((thirty_two = BN_CTX_get(ctx)) == NULL) - goto err; if ((p_abs = BN_CTX_get(ctx)) == NULL) goto err; @@ -259,14 +257,12 @@ bn_mod_sqrt_find_sylow_generator(BIGNUM *out_generator, const BIGNUM *p, goto found; } - if (!BN_set_word(thirty_two, 32)) - goto err; if (!bn_copy(p_abs, p)) goto err; BN_set_negative(p_abs, 0); for (i = 0; i < 128; i++) { - if (!bn_rand_interval(n, thirty_two, p_abs)) + if (!bn_rand_interval(n, 32, p_abs)) goto err; if (!bn_mod_sqrt_n_is_non_residue(&is_non_residue, n, p, ctx)) goto err; diff --git a/lib/libcrypto/bn/bn_rand.c b/lib/libcrypto/bn/bn_rand.c index f68913473f4..a5b163c8202 100644 --- a/lib/libcrypto/bn/bn_rand.c +++ b/lib/libcrypto/bn/bn_rand.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_rand.c,v 1.28 2023/07/08 12:21:58 beck Exp $ */ +/* $OpenBSD: bn_rand.c,v 1.29 2023/08/03 18:53:55 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -284,29 +284,46 @@ BN_rand_range(BIGNUM *r, const BIGNUM *range) LCRYPTO_ALIAS(BN_rand_range); int -bn_rand_interval(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc) +bn_rand_in_range(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc) { - BIGNUM *len = NULL; + BIGNUM *len; int ret = 0; - if (BN_cmp(lower_inc, upper_exc) >= 0) - goto err; - if ((len = BN_new()) == NULL) goto err; - if (!BN_sub(len, upper_exc, lower_inc)) goto err; - - if (!bn_rand_range(0, rnd, len)) + if (!BN_rand_range(rnd, len)) goto err; - if (!BN_add(rnd, rnd, lower_inc)) goto err; ret = 1; + err: BN_free(len); + + return ret; +} + +int +bn_rand_interval(BIGNUM *rnd, BN_ULONG lower_word, const BIGNUM *upper_exc) +{ + BIGNUM *lower_inc = NULL; + int ret = 0; + + if ((lower_inc = BN_new()) == NULL) + goto err; + if (!BN_set_word(lower_inc, lower_word)) + goto err; + if (!bn_rand_in_range(rnd, lower_inc, upper_exc)) + goto err; + + ret = 1; + + err: + BN_free(lower_inc); + return ret; } diff --git a/lib/libcrypto/dh/dh_key.c b/lib/libcrypto/dh/dh_key.c index a4bd6894836..050d1143f8f 100644 --- a/lib/libcrypto/dh/dh_key.c +++ b/lib/libcrypto/dh/dh_key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh_key.c,v 1.39 2023/07/08 15:29:03 beck Exp $ */ +/* $OpenBSD: dh_key.c,v 1.40 2023/08/03 18:53:55 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -109,7 +109,7 @@ generate_key(DH *dh) unsigned l; BN_CTX *ctx; BN_MONT_CTX *mont = NULL; - BIGNUM *pub_key = NULL, *priv_key = NULL, *two = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { DHerror(DH_R_MODULUS_TOO_LARGE); @@ -139,11 +139,7 @@ generate_key(DH *dh) if (dh->priv_key == NULL) { if (dh->q) { - if ((two = BN_new()) == NULL) - goto err; - if (!BN_add(two, BN_value_one(), BN_value_one())) - goto err; - if (!bn_rand_interval(priv_key, two, dh->q)) + if (!bn_rand_interval(priv_key, 2, dh->q)) goto err; } else { /* secret exponent length */ @@ -169,7 +165,7 @@ generate_key(DH *dh) if (dh->priv_key == NULL) BN_free(priv_key); BN_CTX_free(ctx); - BN_free(two); + return ok; } diff --git a/lib/libcrypto/dsa/dsa_key.c b/lib/libcrypto/dsa/dsa_key.c index c378707e367..431748ab75f 100644 --- a/lib/libcrypto/dsa/dsa_key.c +++ b/lib/libcrypto/dsa/dsa_key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsa_key.c,v 1.34 2023/07/08 14:28:15 beck Exp $ */ +/* $OpenBSD: dsa_key.c,v 1.35 2023/08/03 18:53:55 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -95,7 +95,7 @@ dsa_builtin_keygen(DSA *dsa) if ((ctx = BN_CTX_new()) == NULL) goto err; - if (!bn_rand_interval(priv_key, BN_value_one(), dsa->q)) + if (!bn_rand_interval(priv_key, 1, dsa->q)) goto err; if (!BN_mod_exp_ct(pub_key, dsa->g, priv_key, dsa->p, ctx)) goto err; diff --git a/lib/libcrypto/dsa/dsa_ossl.c b/lib/libcrypto/dsa/dsa_ossl.c index 36b2a63462e..b92d0b8cee4 100644 --- a/lib/libcrypto/dsa/dsa_ossl.c +++ b/lib/libcrypto/dsa/dsa_ossl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsa_ossl.c,v 1.52 2023/07/08 14:28:15 beck Exp $ */ +/* $OpenBSD: dsa_ossl.c,v 1.53 2023/08/03 18:53:55 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -172,7 +172,7 @@ dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) * * Where b is a random value in the range [1, q). */ - if (!bn_rand_interval(b, BN_value_one(), dsa->q)) + if (!bn_rand_interval(b, 1, dsa->q)) goto err; if (BN_mod_inverse_ct(binv, b, dsa->q, ctx) == NULL) goto err; @@ -261,7 +261,7 @@ dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) !BN_set_bit(m, q_bits)) goto err; - if (!bn_rand_interval(k, BN_value_one(), dsa->q)) + if (!bn_rand_interval(k, 1, dsa->q)) goto err; BN_set_flags(k, BN_FLG_CONSTTIME); diff --git a/lib/libcrypto/ec/ec_key.c b/lib/libcrypto/ec/ec_key.c index e5ff1898034..d9ddd5d7973 100644 --- a/lib/libcrypto/ec/ec_key.c +++ b/lib/libcrypto/ec/ec_key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec_key.c,v 1.36 2023/07/07 13:54:45 beck Exp $ */ +/* $OpenBSD: ec_key.c,v 1.37 2023/08/03 18:53:56 tb Exp $ */ /* * Written by Nils Larsch for the OpenSSL project. */ @@ -269,7 +269,7 @@ ec_key_gen(EC_KEY *eckey) if ((order = EC_GROUP_get0_order(eckey->group)) == NULL) goto err; - if (!bn_rand_interval(priv_key, BN_value_one(), order)) + if (!bn_rand_interval(priv_key, 1, order)) goto err; if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, NULL)) goto err; diff --git a/lib/libcrypto/ec/ecp_smpl.c b/lib/libcrypto/ec/ecp_smpl.c index de1f9a3472a..018aedfd4e5 100644 --- a/lib/libcrypto/ec/ecp_smpl.c +++ b/lib/libcrypto/ec/ecp_smpl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecp_smpl.c,v 1.55 2023/07/26 17:15:25 tb Exp $ */ +/* $OpenBSD: ecp_smpl.c,v 1.56 2023/08/03 18:53:56 tb Exp $ */ /* Includes code written by Lenka Fibikova * for the OpenSSL project. * Includes code written by Bodo Moeller for the OpenSSL project. @@ -1227,7 +1227,7 @@ ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) goto err; /* Generate lambda in [1, group->field). */ - if (!bn_rand_interval(lambda, BN_value_one(), &group->field)) + if (!bn_rand_interval(lambda, 1, &group->field)) goto err; if (group->meth->field_encode != NULL && diff --git a/lib/libcrypto/ecdsa/ecdsa.c b/lib/libcrypto/ecdsa/ecdsa.c index 1252ab2a43c..8160014b3b2 100644 --- a/lib/libcrypto/ecdsa/ecdsa.c +++ b/lib/libcrypto/ecdsa/ecdsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecdsa.c,v 1.16 2023/07/28 09:18:10 tb Exp $ */ +/* $OpenBSD: ecdsa.c,v 1.17 2023/08/03 18:53:56 tb Exp $ */ /* ==================================================================== * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. * @@ -338,7 +338,7 @@ ecdsa_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv, BIGNUM **out_r) /* Step 11: repeat until r != 0. */ do { /* Step 3: generate random k. */ - if (!bn_rand_interval(k, BN_value_one(), order)) + if (!bn_rand_interval(k, 1, order)) goto err; /* @@ -472,7 +472,7 @@ ecdsa_compute_s(BIGNUM **out_s, const BIGNUM *e, const BIGNUM *kinv, goto err; } - if (!bn_rand_interval(b, BN_value_one(), order)) { + if (!bn_rand_interval(b, 1, order)) { ECerror(ERR_R_BN_LIB); goto err; } diff --git a/regress/lib/libcrypto/bn/bn_isqrt.c b/regress/lib/libcrypto/bn/bn_isqrt.c index 2663bb74e94..d8a2d2755f9 100644 --- a/regress/lib/libcrypto/bn/bn_isqrt.c +++ b/regress/lib/libcrypto/bn/bn_isqrt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_isqrt.c,v 1.3 2023/03/08 06:28:08 tb Exp $ */ +/* $OpenBSD: bn_isqrt.c,v 1.4 2023/08/03 18:53:56 tb Exp $ */ /* * Copyright (c) 2022 Theo Buehler * @@ -194,8 +194,8 @@ isqrt_test(void) if (!BN_set_bit(upper, UPPER_BITS)) errx(1, "BN_set_bit(upper, %d)", UPPER_BITS); - if (!bn_rand_interval(n, lower, upper)) - errx(1, "bn_rand_interval n"); + if (!bn_rand_in_range(n, lower, upper)) + errx(1, "bn_rand_in_range n"); /* n_sqr = n^2 */ if (!BN_sqr(n_sqr, n, ctx)) @@ -246,8 +246,8 @@ isqrt_test(void) */ for (i = 0; i < N_TESTS; i++) { - if (!bn_rand_interval(testcase, n_sqr, upper)) - errx(1, "bn_rand_interval testcase"); + if (!bn_rand_in_range(testcase, n_sqr, upper)) + errx(1, "bn_rand_in_range testcase"); if (!bn_isqrt(isqrt, &is_perfect_square, testcase, ctx)) errx(1, "bn_isqrt testcase");