Convert a few more things to scopers Also simplify DH_generate_parameters_ex a bit. Any function that does BN_CTX_new + BN_CTX_get isn't getting anything out of the BN_CTX-owned BIGNUMs. BN_CTX is only useful when your function gets called multiple times. Change-Id: I8c3988a9c3d0939b9f3ac9fc36fcd0fe3d92a33c Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/77547 Reviewed-by: Bob Beck <bbe@google.com> Auto-Submit: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/bn/exponentiation.cc b/crypto/bn/exponentiation.cc index 9942986..a6d7d9c 100644 --- a/crypto/bn/exponentiation.cc +++ b/crypto/bn/exponentiation.cc
@@ -22,55 +22,49 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { - int i, bits, ret = 0; - BIGNUM *v, *rr; - - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); + BIGNUM *rr; if (r == a || r == p) { rr = BN_CTX_get(ctx); } else { rr = r; } - v = BN_CTX_get(ctx); + BIGNUM *v = BN_CTX_get(ctx); if (rr == NULL || v == NULL) { - goto err; + return 0; } if (BN_copy(v, a) == NULL) { - goto err; + return 0; } - bits = BN_num_bits(p); + int bits = BN_num_bits(p); if (BN_is_odd(p)) { if (BN_copy(rr, a) == NULL) { - goto err; + return 0; } } else { if (!BN_one(rr)) { - goto err; + return 0; } } - for (i = 1; i < bits; i++) { + for (int i = 1; i < bits; i++) { if (!BN_sqr(v, v, ctx)) { - goto err; + return 0; } if (BN_is_bit_set(p, i)) { if (!BN_mul(rr, rr, v, ctx)) { - goto err; + return 0; } } } if (r != rr && !BN_copy(r, rr)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } static int mod_exp_even(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
diff --git a/crypto/dh/params.cc b/crypto/dh/params.cc index 18c585e..115505f 100644 --- a/crypto/dh/params.cc +++ b/crypto/dh/params.cc
@@ -22,7 +22,8 @@ #include "../fipsmodule/dh/internal.h" -static BIGNUM *get_params(BIGNUM *ret, const BN_ULONG *words, size_t num_words) { +static BIGNUM *get_params(BIGNUM *ret, const BN_ULONG *words, + size_t num_words) { BIGNUM *alloc = NULL; if (ret == NULL) { alloc = BN_new(); @@ -304,92 +305,57 @@ return 0; } - BIGNUM *t1, *t2; - int g, ok = 0; - BN_CTX *ctx = NULL; - - ctx = BN_CTX_new(); - if (ctx == NULL) { - goto err; - } - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - t2 = BN_CTX_get(ctx); - if (t1 == NULL || t2 == NULL) { - goto err; - } - // Make sure |dh| has the necessary elements if (dh->p == NULL) { dh->p = BN_new(); if (dh->p == NULL) { - goto err; + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + return 0; } } if (dh->g == NULL) { dh->g = BN_new(); if (dh->g == NULL) { - goto err; + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + return 0; } } + BN_ULONG t1, t2, g; if (generator <= 1) { OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR); - goto err; + return 0; } if (generator == DH_GENERATOR_2) { - if (!BN_set_word(t1, 24)) { - goto err; - } - if (!BN_set_word(t2, 11)) { - goto err; - } + t1 = 24; + t2 = 11; g = 2; } else if (generator == DH_GENERATOR_5) { - if (!BN_set_word(t1, 10)) { - goto err; - } - if (!BN_set_word(t2, 3)) { - goto err; - } - // BN_set_word(t3,7); just have to miss - // out on these ones :-( + t1 = 10; + t2 = 3; g = 5; } else { - // in the general case, don't worry if 'generator' is a - // generator or not: since we are using safe primes, - // it will generate either an order-q or an order-2q group, - // which both is OK - if (!BN_set_word(t1, 2)) { - goto err; - } - if (!BN_set_word(t2, 1)) { - goto err; - } + // In the general case, don't worry if 'generator' is a generator or not: + // since we are using safe primes, it will generate either an order-q or an + // order-2q group, which both is OK. + t1 = 2; + t2 = 1; g = generator; } - if (!BN_generate_prime_ex(dh->p, prime_bits, 1, t1, t2, cb)) { - goto err; - } - if (!BN_GENCB_call(cb, 3, 0)) { - goto err; - } - if (!BN_set_word(dh->g, g)) { - goto err; - } - ok = 1; - -err: - if (!ok) { + bssl::UniquePtr<BIGNUM> t1_bn(BN_new()), t2_bn(BN_new()); + if (t1_bn == nullptr || t2_bn == nullptr || + !BN_set_word(t1_bn.get(), t1) || // + !BN_set_word(t2_bn.get(), t2) || // + !BN_generate_prime_ex(dh->p, prime_bits, 1, t1_bn.get(), t2_bn.get(), + cb) || + !BN_GENCB_call(cb, 3, 0) || // + !BN_set_word(dh->g, g)) { OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + return 0; } - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return ok; + return 1; } static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) {
diff --git a/crypto/dsa/dsa.cc b/crypto/dsa/dsa.cc index d1bfdf0..958be93 100644 --- a/crypto/dsa/dsa.cc +++ b/crypto/dsa/dsa.cc
@@ -167,17 +167,14 @@ return 0; } - int ok = 0; unsigned char seed[SHA256_DIGEST_LENGTH]; unsigned char md[SHA256_DIGEST_LENGTH]; unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; BIGNUM *r0, *W, *X, *c, *test; BIGNUM *g = NULL, *q = NULL, *p = NULL; - BN_MONT_CTX *mont = NULL; int k, n = 0, m = 0; int counter = 0; int r = 0; - BN_CTX *ctx = NULL; unsigned int h = 2; const EVP_MD *evpmd; @@ -201,23 +198,23 @@ OPENSSL_memcpy(seed, seed_in, seed_len); } - ctx = BN_CTX_new(); - if (ctx == NULL) { - goto err; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + if (ctx == nullptr) { + return 0; } - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx.get()); - r0 = BN_CTX_get(ctx); - g = BN_CTX_get(ctx); - W = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - c = BN_CTX_get(ctx); - p = BN_CTX_get(ctx); - test = BN_CTX_get(ctx); + r0 = BN_CTX_get(ctx.get()); + g = BN_CTX_get(ctx.get()); + W = BN_CTX_get(ctx.get()); + q = BN_CTX_get(ctx.get()); + X = BN_CTX_get(ctx.get()); + c = BN_CTX_get(ctx.get()); + p = BN_CTX_get(ctx.get()); + test = BN_CTX_get(ctx.get()); if (test == NULL || !BN_lshift(test, BN_value_one(), bits - 1)) { - goto err; + return 0; } for (;;) { @@ -225,13 +222,13 @@ for (;;) { // step 1 if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, m++)) { - goto err; + return 0; } int use_random_seed = (seed_in == NULL); if (use_random_seed) { if (!RAND_bytes(seed, qsize)) { - goto err; + return 0; } // DSA parameters are public. CONSTTIME_DECLASSIFY(seed, qsize); @@ -252,7 +249,7 @@ // step 2 if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) || !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) { - goto err; + return 0; } for (size_t i = 0; i < qsize; i++) { md[i] ^= buf2[i]; @@ -262,17 +259,17 @@ md[0] |= 0x80; md[qsize - 1] |= 0x01; if (!BN_bin2bn(md, qsize, q)) { - goto err; + return 0; } // step 4 - r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, use_random_seed, - cb); + r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx.get(), + use_random_seed, cb); if (r > 0) { break; } if (r != 0) { - goto err; + return 0; } // do a callback call @@ -280,7 +277,7 @@ } if (!BN_GENCB_call(cb, 2, 0) || !BN_GENCB_call(cb, 3, 0)) { - goto err; + return 0; } // step 6 @@ -291,7 +288,7 @@ for (;;) { if ((counter != 0) && !BN_GENCB_call(cb, BN_GENCB_GENERATED, counter)) { - goto err; + return 0; } // step 7 @@ -307,36 +304,36 @@ } if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) { - goto err; + return 0; } // step 8 if (!BN_bin2bn(md, qsize, r0) || !BN_lshift(r0, r0, (qsize << 3) * k) || !BN_add(W, W, r0)) { - goto err; + return 0; } } // more of step 8 if (!BN_mask_bits(W, bits - 1) || !BN_copy(X, W) || !BN_add(X, X, test)) { - goto err; + return 0; } // step 9 - if (!BN_lshift1(r0, q) || !BN_mod(c, X, r0, ctx) || + if (!BN_lshift1(r0, q) || !BN_mod(c, X, r0, ctx.get()) || !BN_sub(r0, c, BN_value_one()) || !BN_sub(p, X, r0)) { - goto err; + return 0; } // step 10 if (BN_cmp(p, test) >= 0) { // step 11 - r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); + r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx.get(), 1, cb); if (r > 0) { goto end; // found it } if (r != 0) { - goto err; + return 0; } } @@ -352,68 +349,56 @@ } end: if (!BN_GENCB_call(cb, 2, 1)) { - goto err; + return 0; } // We now need to generate g // Set r0=(p-1)/q - if (!BN_sub(test, p, BN_value_one()) || !BN_div(r0, NULL, test, q, ctx)) { - goto err; + if (!BN_sub(test, p, BN_value_one()) || + !BN_div(r0, NULL, test, q, ctx.get())) { + return 0; } - mont = BN_MONT_CTX_new_for_modulus(p, ctx); - if (mont == NULL || !BN_set_word(test, h)) { - goto err; + bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new_for_modulus(p, ctx.get())); + if (mont == nullptr || !BN_set_word(test, h)) { + return 0; } for (;;) { // g=test^r0%p - if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) { - goto err; + if (!BN_mod_exp_mont(g, test, r0, p, ctx.get(), mont.get())) { + return 0; } if (!BN_is_one(g)) { break; } if (!BN_add(test, test, BN_value_one())) { - goto err; + return 0; } h++; } if (!BN_GENCB_call(cb, 3, 1)) { - goto err; + return 0; } - ok = 1; - -err: - if (ok) { - BN_free(dsa->p); - BN_free(dsa->q); - BN_free(dsa->g); - dsa->p = BN_dup(p); - dsa->q = BN_dup(q); - dsa->g = BN_dup(g); - if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { - ok = 0; - goto err; - } - if (out_counter != NULL) { - *out_counter = counter; - } - if (out_h != NULL) { - *out_h = h; - } + BN_free(dsa->p); + BN_free(dsa->q); + BN_free(dsa->g); + dsa->p = BN_dup(p); + dsa->q = BN_dup(q); + dsa->g = BN_dup(g); + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + return 0; + } + if (out_counter != NULL) { + *out_counter = counter; + } + if (out_h != NULL) { + *out_h = h; } - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - - BN_MONT_CTX_free(mont); - - return ok; + return 1; } DSA *DSAparams_dup(const DSA *dsa) { @@ -529,14 +514,13 @@ // neither inputs nor outputs are in Montgomery form. static int mod_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BN_MONT_CTX *mont, BN_CTX *ctx) { - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); // |BN_mod_mul_montgomery| removes a factor of R, so we cancel it with a // single |BN_to_montgomery| which adds one factor of R. - int ok = tmp != NULL && BN_to_montgomery(tmp, a, mont, ctx) && - BN_mod_mul_montgomery(r, tmp, b, mont, ctx); - BN_CTX_end(ctx); - return ok; + return tmp != nullptr && // + BN_to_montgomery(tmp, a, mont, ctx) && + BN_mod_mul_montgomery(r, tmp, b, mont, ctx); } DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) {
diff --git a/crypto/fipsmodule/bn/div.cc.inc b/crypto/fipsmodule/bn/div.cc.inc index b09f9fe..72ac926 100644 --- a/crypto/fipsmodule/bn/div.cc.inc +++ b/crypto/fipsmodule/bn/div.cc.inc
@@ -147,7 +147,7 @@ return 0; } - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); BIGNUM *snum = BN_CTX_get(ctx); BIGNUM *sdiv = BN_CTX_get(ctx); @@ -155,7 +155,7 @@ int norm_shift, num_n, loop, div_n; BN_ULONG d0, d1; if (tmp == NULL || snum == NULL || sdiv == NULL || res == NULL) { - goto err; + return 0; } // Knuth step D1: Normalise the numbers such that the divisor's MSB is set. @@ -164,7 +164,7 @@ norm_shift = BN_BITS2 - (BN_num_bits(divisor) % BN_BITS2); if (!BN_lshift(sdiv, divisor, norm_shift) || !BN_lshift(snum, numerator, norm_shift)) { - goto err; + return 0; } // This algorithm relies on |sdiv| being minimal width. We do not use this @@ -184,7 +184,7 @@ // digit in Knuth step D1.) num_n = snum->width <= div_n ? div_n + 1 : snum->width + 1; if (!bn_resize_words(snum, num_n)) { - goto err; + return 0; } // Knuth step D2: The quotient's width is the difference between numerator and @@ -193,7 +193,7 @@ res->neg = snum->neg ^ sdiv->neg; if (!bn_wexpand(res, loop) || // !bn_wexpand(tmp, div_n + 1)) { - goto err; + return 0; } res->width = loop; @@ -312,15 +312,10 @@ // Knuth step D8: Unnormalize. snum now contains the remainder. if (rem != NULL && !BN_rshift(rem, snum, norm_shift)) { - goto err; + return 0; } - BN_CTX_end(ctx); return 1; - -err: - BN_CTX_end(ctx); - return 0; } int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) { @@ -396,8 +391,7 @@ // but it is simple, easy to make constant-time, and performant enough for RSA // key generation. - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *q = quotient, *r = remainder; if (quotient == NULL || quotient == numerator || quotient == divisor) { q = BN_CTX_get(ctx); @@ -410,7 +404,7 @@ if (q == NULL || r == NULL || tmp == NULL || !bn_wexpand(q, numerator->width) || !bn_wexpand(r, divisor->width) || !bn_wexpand(tmp, divisor->width)) { - goto err; + return 0; } OPENSSL_memset(q->d, 0, numerator->width * sizeof(BN_ULONG)); @@ -461,14 +455,10 @@ if ((quotient != NULL && !BN_copy(quotient, q)) || (remainder != NULL && !BN_copy(remainder, r))) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } static BIGNUM *bn_scratch_space_from_ctx(size_t width, BN_CTX *ctx) { @@ -510,26 +500,24 @@ int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) { - BN_CTX *ctx = BN_CTX_new(); - int ok = ctx != NULL && bn_mod_add_consttime(r, a, b, m, ctx); - BN_CTX_free(ctx); - return ok; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + return ctx != nullptr && bn_mod_add_consttime(r, a, b, m, ctx.get()); } int bn_mod_add_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) { - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); a = bn_resized_from_ctx(a, m->width, ctx); b = bn_resized_from_ctx(b, m->width, ctx); BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); - int ok = a != NULL && b != NULL && tmp != NULL && bn_wexpand(r, m->width); - if (ok) { - bn_mod_add_words(r->d, a->d, b->d, m->d, tmp->d, m->width); - r->width = m->width; - r->neg = 0; + if (a == nullptr || b == nullptr || tmp == nullptr || + !bn_wexpand(r, m->width)) { + return 0; } - BN_CTX_end(ctx); - return ok; + bn_mod_add_words(r->d, a->d, b->d, m->d, tmp->d, m->width); + r->width = m->width; + r->neg = 0; + return 1; } int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, @@ -542,58 +530,49 @@ int bn_mod_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) { - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); a = bn_resized_from_ctx(a, m->width, ctx); b = bn_resized_from_ctx(b, m->width, ctx); BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); - int ok = a != NULL && b != NULL && tmp != NULL && bn_wexpand(r, m->width); - if (ok) { - bn_mod_sub_words(r->d, a->d, b->d, m->d, tmp->d, m->width); - r->width = m->width; - r->neg = 0; + if (a == nullptr || b == nullptr || tmp == nullptr || + !bn_wexpand(r, m->width)) { + return 0; } - BN_CTX_end(ctx); - return ok; + bn_mod_sub_words(r->d, a->d, b->d, m->d, tmp->d, m->width); + r->width = m->width; + r->neg = 0; + return 1; } int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) { - BN_CTX *ctx = BN_CTX_new(); - int ok = ctx != NULL && bn_mod_sub_consttime(r, a, b, m, ctx); - BN_CTX_free(ctx); - return ok; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + return ctx != nullptr && bn_mod_sub_consttime(r, a, b, m, ctx.get()); } int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) { - BIGNUM *t; - int ret = 0; - - BN_CTX_start(ctx); - t = BN_CTX_get(ctx); + bssl::BN_CTXScope scope(ctx); + BIGNUM *t = BN_CTX_get(ctx); if (t == NULL) { - goto err; + return 0; } if (a == b) { if (!BN_sqr(t, a, ctx)) { - goto err; + return 0; } } else { if (!BN_mul(t, a, b, ctx)) { - goto err; + return 0; } } if (!BN_nnmod(r, t, m, ctx)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) { @@ -607,25 +586,20 @@ int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx) { - BIGNUM *abs_m = NULL; - int ret; - if (!BN_nnmod(r, a, m, ctx)) { return 0; } + bssl::UniquePtr<BIGNUM> abs_m; if (m->neg) { - abs_m = BN_dup(m); - if (abs_m == NULL) { + abs_m.reset(BN_dup(m)); + if (abs_m == nullptr) { return 0; } abs_m->neg = 0; } - ret = bn_mod_lshift_consttime(r, r, n, (abs_m ? abs_m : m), ctx); - - BN_free(abs_m); - return ret; + return bn_mod_lshift_consttime(r, r, n, (abs_m ? abs_m.get() : m), ctx); } int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, @@ -634,24 +608,21 @@ return 0; } - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); - int ok = tmp != NULL; - if (ok) { - for (int i = 0; i < n; i++) { - bn_mod_add_words(r->d, r->d, r->d, m->d, tmp->d, m->width); - } - r->neg = 0; + if (tmp == nullptr) { + return 0; } - BN_CTX_end(ctx); - return ok; + for (int i = 0; i < n; i++) { + bn_mod_add_words(r->d, r->d, r->d, m->d, tmp->d, m->width); + } + r->neg = 0; + return 1; } int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) { - BN_CTX *ctx = BN_CTX_new(); - int ok = ctx != NULL && bn_mod_lshift_consttime(r, a, n, m, ctx); - BN_CTX_free(ctx); - return ok; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + return ctx != nullptr && bn_mod_lshift_consttime(r, a, n, m, ctx.get()); } int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) { @@ -668,10 +639,8 @@ } int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) { - BN_CTX *ctx = BN_CTX_new(); - int ok = ctx != NULL && bn_mod_lshift1_consttime(r, a, m, ctx); - BN_CTX_free(ctx); - return ok; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + return ctx != nullptr && bn_mod_lshift1_consttime(r, a, m, ctx.get()); } BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
diff --git a/crypto/fipsmodule/bn/exponentiation.cc.inc b/crypto/fipsmodule/bn/exponentiation.cc.inc index bcf88e5..b719bea 100644 --- a/crypto/fipsmodule/bn/exponentiation.cc.inc +++ b/crypto/fipsmodule/bn/exponentiation.cc.inc
@@ -149,57 +149,55 @@ return BN_one(rr); } - int ret = 0; BIGNUM *val[TABLE_SIZE]; - BN_MONT_CTX *new_mont = NULL; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *r = BN_CTX_get(ctx); val[0] = BN_CTX_get(ctx); - int window, r_is_one, wstart; if (r == NULL || val[0] == NULL) { - goto err; + return 0; } // Allocate a montgomery context if it was not supplied by the caller. - if (mont == NULL) { - new_mont = BN_MONT_CTX_new_consttime(m, ctx); - if (new_mont == NULL) { - goto err; + bssl::UniquePtr<BN_MONT_CTX> new_mont; + if (mont == nullptr) { + new_mont.reset(BN_MONT_CTX_new_consttime(m, ctx)); + if (new_mont == nullptr) { + return 0; } - mont = new_mont; + mont = new_mont.get(); } // We exponentiate by looking at sliding windows of the exponent and // precomputing powers of |a|. Windows may be shifted so they always end on a // set bit, so only precompute odd powers. We compute val[i] = a^(2*i + 1) // for i = 0 to 2^(window-1), all in Montgomery form. - window = BN_window_bits_for_exponent_size(bits); + int window = BN_window_bits_for_exponent_size(bits); if (!BN_to_montgomery(val[0], a, mont, ctx)) { - goto err; + return 0; } if (window > 1) { BIGNUM *d = BN_CTX_get(ctx); if (d == NULL || !BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) { - goto err; + return 0; } for (int i = 1; i < 1 << (window - 1); i++) { val[i] = BN_CTX_get(ctx); if (val[i] == NULL || !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx)) { - goto err; + return 0; } } } // |p| is non-zero, so at least one window is non-zero. To save some // multiplications, defer initializing |r| until then. - r_is_one = 1; - wstart = bits - 1; // The top bit of the window. + int r_is_one = 1; + int wstart = bits - 1; // The top bit of the window. for (;;) { if (!BN_is_bit_set(p, wstart)) { if (!r_is_one && !BN_mod_mul_montgomery(r, r, r, mont, ctx)) { - goto err; + return 0; } if (wstart == 0) { break; @@ -223,7 +221,7 @@ if (!r_is_one) { for (int i = 0; i < wsize + 1; i++) { if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) { - goto err; + return 0; } } } @@ -232,10 +230,10 @@ assert(wvalue < (1 << window)); if (r_is_one) { if (!BN_copy(r, val[wvalue >> 1])) { - goto err; + return 0; } } else if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) { - goto err; + return 0; } r_is_one = 0; @@ -248,15 +246,7 @@ // |p| is non-zero, so |r_is_one| must be cleared at some point. assert(!r_is_one); - if (!BN_from_montgomery(rr, r, mont, ctx)) { - goto err; - } - ret = 1; - -err: - BN_MONT_CTX_free(new_mont); - BN_CTX_end(ctx); - return ret; + return BN_from_montgomery(rr, r, mont, ctx); } void bn_mod_exp_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num,