Convert most of BN to scopers Change-Id: I7977afe38eb3a6980ecd09eb8069a7603bd673f9 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/78568 Auto-Submit: David Benjamin <davidben@google.com> Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/bn/convert.cc b/crypto/bn/convert.cc index 6f4d4fa..59ea6d4 100644 --- a/crypto/bn/convert.cc +++ b/crypto/bn/convert.cc
@@ -19,6 +19,8 @@ #include <limits.h> #include <stdio.h> +#include <algorithm> + #include <openssl/bio.h> #include <openssl/bytestring.h> #include <openssl/err.h> @@ -196,33 +198,32 @@ char *BN_bn2dec(const BIGNUM *a) { // It is easier to print strings little-endian, so we assemble it in reverse // and fix at the end. - BIGNUM *copy = NULL; - CBB cbb; - if (!CBB_init(&cbb, 16) || // - !CBB_add_u8(&cbb, 0 /* trailing NUL */)) { - goto err; + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 16) || // + !CBB_add_u8(cbb.get(), 0 /* trailing NUL */)) { + return nullptr; } if (BN_is_zero(a)) { - if (!CBB_add_u8(&cbb, '0')) { - goto err; + if (!CBB_add_u8(cbb.get(), '0')) { + return nullptr; } } else { - copy = BN_dup(a); - if (copy == NULL) { - goto err; + bssl::UniquePtr<BIGNUM> copy(BN_dup(a)); + if (copy == nullptr) { + return nullptr; } - while (!BN_is_zero(copy)) { - BN_ULONG word = BN_div_word(copy, BN_DEC_CONV); + while (!BN_is_zero(copy.get())) { + BN_ULONG word = BN_div_word(copy.get(), BN_DEC_CONV); if (word == (BN_ULONG)-1) { - goto err; + return nullptr; } - const int add_leading_zeros = !BN_is_zero(copy); + const int add_leading_zeros = !BN_is_zero(copy.get()); for (int i = 0; i < BN_DEC_NUM && (add_leading_zeros || word != 0); i++) { - if (!CBB_add_u8(&cbb, '0' + word % 10)) { - goto err; + if (!CBB_add_u8(cbb.get(), '0' + word % 10)) { + return nullptr; } word /= 10; } @@ -231,30 +232,18 @@ } if (BN_is_negative(a) && // - !CBB_add_u8(&cbb, '-')) { - goto err; + !CBB_add_u8(cbb.get(), '-')) { + return nullptr; } uint8_t *data; size_t len; - if (!CBB_finish(&cbb, &data, &len)) { - goto err; + if (!CBB_finish(cbb.get(), &data, &len)) { + return nullptr; } - // Reverse the buffer. - for (size_t i = 0; i < len / 2; i++) { - uint8_t tmp = data[i]; - data[i] = data[len - 1 - i]; - data[len - 1 - i] = tmp; - } - - BN_free(copy); - return (char *)data; - -err: - BN_free(copy); - CBB_cleanup(&cbb); - return NULL; + std::reverse(data, data + len); + return reinterpret_cast<char *>(data); } int BN_dec2bn(BIGNUM **outp, const char *in) { @@ -285,33 +274,28 @@ } int BN_print(BIO *bp, const BIGNUM *a) { - int i, j, v, z = 0; - int ret = 0; - if (a->neg && BIO_write(bp, "-", 1) != 1) { - goto end; + return 0; } if (BN_is_zero(a) && BIO_write(bp, "0", 1) != 1) { - goto end; + return 0; } - for (i = bn_minimal_width(a) - 1; i >= 0; i--) { - for (j = BN_BITS2 - 4; j >= 0; j -= 4) { + int z = 0; + for (int i = bn_minimal_width(a) - 1; i >= 0; i--) { + for (int j = BN_BITS2 - 4; j >= 0; j -= 4) { // strip leading zeros - v = ((int)(a->d[i] >> (long)j)) & 0x0f; + int v = ((int)(a->d[i] >> (long)j)) & 0x0f; if (z || v != 0) { if (BIO_write(bp, &hextable[v], 1) != 1) { - goto end; + return 0; } z = 1; } } } - ret = 1; - -end: - return ret; + return 1; } int BN_print_fp(FILE *fp, const BIGNUM *a) {
diff --git a/crypto/bn/exponentiation.cc b/crypto/bn/exponentiation.cc index a6d7d9c..07f9ec6 100644 --- a/crypto/bn/exponentiation.cc +++ b/crypto/bn/exponentiation.cc
@@ -123,62 +123,44 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { - BIGNUM a_bignum; - BN_init(&a_bignum); - - int ret = 0; - // BN_mod_exp_mont requires reduced inputs. if (bn_minimal_width(m) == 1) { a %= m->d[0]; } - if (!BN_set_word(&a_bignum, a)) { + bssl::UniquePtr<BIGNUM> a_bignum(BN_new()); + if (a_bignum == nullptr || !BN_set_word(a_bignum.get(), a)) { OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } - ret = BN_mod_exp_mont(rr, &a_bignum, p, m, ctx, mont); - -err: - BN_free(&a_bignum); - - return ret; + return BN_mod_exp_mont(rr, a_bignum.get(), p, m, ctx, mont); } int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { - BIGNUM tmp; - BN_init(&tmp); - - int ret = 0; - BN_MONT_CTX *new_mont = NULL; - // Allocate a montgomery context if it was not supplied by the caller. - if (mont == NULL) { - new_mont = BN_MONT_CTX_new_for_modulus(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_for_modulus(m, ctx)); + if (new_mont == nullptr) { + return 0; } - mont = new_mont; + mont = new_mont.get(); } // BN_mod_mul_montgomery removes one Montgomery factor, so passing one // Montgomery-encoded and one non-Montgomery-encoded value gives a // non-Montgomery-encoded result. - if (!BN_mod_exp_mont(rr, a1, p1, m, ctx, mont) || - !BN_mod_exp_mont(&tmp, a2, p2, m, ctx, mont) || + bssl::UniquePtr<BIGNUM> tmp(BN_new()); + if (tmp == nullptr || // + !BN_mod_exp_mont(rr, a1, p1, m, ctx, mont) || + !BN_mod_exp_mont(tmp.get(), a2, p2, m, ctx, mont) || !BN_to_montgomery(rr, rr, mont, ctx) || - !BN_mod_mul_montgomery(rr, rr, &tmp, mont, ctx)) { - goto err; + !BN_mod_mul_montgomery(rr, rr, tmp.get(), mont, ctx)) { + return 0; } - ret = 1; - -err: - BN_MONT_CTX_free(new_mont); - BN_free(&tmp); - - return ret; + return 1; }
diff --git a/crypto/fipsmodule/bn/exponentiation.cc.inc b/crypto/fipsmodule/bn/exponentiation.cc.inc index b719bea..205f4b4 100644 --- a/crypto/fipsmodule/bn/exponentiation.cc.inc +++ b/crypto/fipsmodule/bn/exponentiation.cc.inc
@@ -413,7 +413,6 @@ const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { int i, ret = 0, wvalue; - BN_MONT_CTX *new_mont = NULL; void *powerbuf_free = NULL; size_t powerbuf_len = 0; @@ -449,12 +448,13 @@ // Allocate a montgomery context if it was not supplied by the caller. int top, num_powers, window; - if (mont == NULL) { - new_mont = BN_MONT_CTX_new_consttime(m, ctx); - if (new_mont == NULL) { + bssl::UniquePtr<BN_MONT_CTX> new_mont; + if (mont == nullptr) { + new_mont.reset(BN_MONT_CTX_new_consttime(m, ctx)); + if (new_mont == nullptr) { goto err; } - mont = new_mont; + mont = new_mont.get(); } // Use the width in |mont->N|, rather than the copy in |m|. The assembly @@ -731,7 +731,6 @@ ret = 1; err: - BN_MONT_CTX_free(new_mont); if (powerbuf != NULL && powerbuf_free == NULL) { OPENSSL_cleanse(powerbuf, powerbuf_len); }
diff --git a/crypto/fipsmodule/bn/gcd.cc.inc b/crypto/fipsmodule/bn/gcd.cc.inc index 6e3cc06..e876c4d 100644 --- a/crypto/fipsmodule/bn/gcd.cc.inc +++ b/crypto/fipsmodule/bn/gcd.cc.inc
@@ -33,23 +33,20 @@ return 0; } - BIGNUM *A, *B, *X, *Y; - int ret = 0; int sign; - - BN_CTX_start(ctx); - A = BN_CTX_get(ctx); - B = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - Y = BN_CTX_get(ctx); + bssl::BN_CTXScope scope(ctx); + BIGNUM *A = BN_CTX_get(ctx); + BIGNUM *B = BN_CTX_get(ctx); + BIGNUM *X = BN_CTX_get(ctx); + BIGNUM *Y = BN_CTX_get(ctx); BIGNUM *R = out; if (Y == NULL) { - goto err; + return 0; } BN_zero(Y); if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) { - goto err; + return 0; } A->neg = 0; sign = -1; @@ -80,17 +77,17 @@ if (BN_is_odd(X)) { if (!BN_uadd(X, X, n)) { - goto err; + return 0; } } // now X is even, so we can easily divide it by two if (!BN_rshift1(X, X)) { - goto err; + return 0; } } if (shift > 0) { if (!BN_rshift(B, B, shift)) { - goto err; + return 0; } } @@ -102,17 +99,17 @@ if (BN_is_odd(Y)) { if (!BN_uadd(Y, Y, n)) { - goto err; + return 0; } } // now Y is even if (!BN_rshift1(Y, Y)) { - goto err; + return 0; } } if (shift > 0) { if (!BN_rshift(A, A, shift)) { - goto err; + return 0; } } @@ -129,21 +126,21 @@ if (BN_ucmp(B, A) >= 0) { // -sign*(X + Y)*a == B - A (mod |n|) if (!BN_uadd(X, X, Y)) { - goto err; + return 0; } // NB: we could use BN_mod_add_quick(X, X, Y, n), but that // actually makes the algorithm slower if (!BN_usub(B, B, A)) { - goto err; + return 0; } } else { // sign*(X + Y)*a == A - B (mod |n|) if (!BN_uadd(Y, Y, X)) { - goto err; + return 0; } // as above, BN_mod_add_quick(Y, Y, X, n) would slow things down if (!BN_usub(A, A, B)) { - goto err; + return 0; } } } @@ -151,7 +148,7 @@ if (!BN_is_one(A)) { *out_no_inverse = 1; OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); - goto err; + return 0; } // The while loop (Euclid's algorithm) ends when @@ -162,7 +159,7 @@ if (sign < 0) { if (!BN_sub(Y, n, Y)) { - goto err; + return 0; } } // Now Y*a == A (mod |n|). @@ -170,61 +167,49 @@ // Y*a == 1 (mod |n|) if (Y->neg || BN_ucmp(Y, n) >= 0) { if (!BN_nnmod(Y, Y, n, ctx)) { - goto err; + return 0; } } if (!BN_copy(R, Y)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) { - BIGNUM *new_out = NULL; - if (out == NULL) { - new_out = BN_new(); - if (new_out == NULL) { - return NULL; + bssl::UniquePtr<BIGNUM> new_out; + if (out == nullptr) { + new_out.reset(BN_new()); + if (new_out == nullptr) { + return nullptr; } - out = new_out; + out = new_out.get(); } - int ok = 0; - BIGNUM *a_reduced = NULL; + bssl::UniquePtr<BIGNUM> a_reduced; if (a->neg || BN_ucmp(a, n) >= 0) { - a_reduced = BN_dup(a); - if (a_reduced == NULL) { - goto err; + a_reduced.reset(BN_dup(a)); + if (a_reduced == nullptr) { + return nullptr; } - if (!BN_nnmod(a_reduced, a_reduced, n, ctx)) { - goto err; + if (!BN_nnmod(a_reduced.get(), a_reduced.get(), n, ctx)) { + return nullptr; } - a = a_reduced; + a = a_reduced.get(); } int no_inverse; if (!BN_is_odd(n)) { if (!bn_mod_inverse_consttime(out, &no_inverse, a, n, ctx)) { - goto err; + return nullptr; } } else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) { - goto err; + return nullptr; } - ok = 1; - -err: - if (!ok) { - BN_free(new_out); - out = NULL; - } - BN_free(a_reduced); + new_out.release(); // Passed to the caller via |out|. return out; } @@ -240,9 +225,10 @@ return 0; } - int ret = 0; - BIGNUM blinding_factor; - BN_init(&blinding_factor); + bssl::UniquePtr<BIGNUM> blinding_factor(BN_new()); + if (blinding_factor == nullptr) { + return 0; + } // |BN_mod_inverse_odd| is leaky, so generate a secret blinding factor and // blind |a|. This works because (ar)^-1 * r = a^-1, supposing r is @@ -253,12 +239,12 @@ // // TODO(crbug.com/boringssl/677): When the PRNG output is marked secret by // default, the explicit |bn_secret| call can be removed. - if (!BN_rand_range_ex(&blinding_factor, 1, &mont->N)) { - goto err; + if (!BN_rand_range_ex(blinding_factor.get(), 1, &mont->N)) { + return 0; } - bn_secret(&blinding_factor); - if (!BN_mod_mul_montgomery(out, &blinding_factor, a, mont, ctx)) { - goto err; + bn_secret(blinding_factor.get()); + if (!BN_mod_mul_montgomery(out, blinding_factor.get(), a, mont, ctx)) { + return 0; } // Once blinded, |out| is no longer secret, so it may be passed to a leaky @@ -266,35 +252,27 @@ // secret again after multiplying. bn_declassify(out); if (!BN_mod_inverse_odd(out, out_no_inverse, out, &mont->N, ctx) || - !BN_mod_mul_montgomery(out, &blinding_factor, out, mont, ctx)) { - goto err; + !BN_mod_mul_montgomery(out, blinding_factor.get(), out, mont, ctx)) { + return 0; } - ret = 1; - -err: - BN_free(&blinding_factor); - return ret; + return 1; } int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx, const BN_MONT_CTX *mont_p) { - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *p_minus_2 = BN_CTX_get(ctx); - int ok = p_minus_2 != NULL && BN_copy(p_minus_2, p) && - BN_sub_word(p_minus_2, 2) && - BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p); - BN_CTX_end(ctx); - return ok; + return p_minus_2 != nullptr && BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p); } int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx, const BN_MONT_CTX *mont_p) { - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *p_minus_2 = BN_CTX_get(ctx); - int ok = p_minus_2 != NULL && BN_copy(p_minus_2, p) && - BN_sub_word(p_minus_2, 2) && - BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p); - BN_CTX_end(ctx); - return ok; + return p_minus_2 != nullptr && BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p); }
diff --git a/crypto/fipsmodule/bn/gcd_extra.cc.inc b/crypto/fipsmodule/bn/gcd_extra.cc.inc index d8642cd..dc0f072 100644 --- a/crypto/fipsmodule/bn/gcd_extra.cc.inc +++ b/crypto/fipsmodule/bn/gcd_extra.cc.inc
@@ -56,19 +56,18 @@ } // This is a constant-time implementation of Stein's algorithm (binary GCD). - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *u = BN_CTX_get(ctx); BIGNUM *v = BN_CTX_get(ctx); BIGNUM *tmp = BN_CTX_get(ctx); unsigned x_bits, y_bits, num_iters, shift; - if (u == NULL || v == NULL || tmp == NULL || // + if (u == nullptr || v == nullptr || tmp == nullptr || // !BN_copy(u, x) || // !BN_copy(v, y) || // !bn_resize_words(u, width) || // !bn_resize_words(v, width) || // !bn_resize_words(tmp, width)) { - goto err; + return 0; } // Each loop iteration halves at least one of |u| and |v|. Thus we need at @@ -78,7 +77,7 @@ num_iters = x_bits + y_bits; if (num_iters < x_bits) { OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); - goto err; + return 0; } shift = 0; @@ -114,11 +113,7 @@ } *out_shift = shift; - ret = bn_set_words(r, v->d, width); - -err: - BN_CTX_end(ctx); - return ret; + return bn_set_words(r, v->d, width); } int BN_gcd(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { @@ -128,12 +123,11 @@ int bn_is_relatively_prime(int *out_relatively_prime, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); unsigned shift; BIGNUM *gcd = BN_CTX_get(ctx); - if (gcd == NULL || !bn_gcd_consttime(gcd, &shift, x, y, ctx)) { - goto err; + if (gcd == nullptr || !bn_gcd_consttime(gcd, &shift, x, y, ctx)) { + return 0; } // Check that 2^|shift| * |gcd| is one. @@ -146,25 +140,20 @@ } *out_relatively_prime = mask == 0; } - ret = 1; -err: - BN_CTX_end(ctx); - return ret; + return 1; } int bn_lcm_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); unsigned shift; BIGNUM *gcd = BN_CTX_get(ctx); - int ret = gcd != NULL && // - bn_mul_consttime(r, a, b, ctx) && - bn_gcd_consttime(gcd, &shift, a, b, ctx) && - // |gcd| has a secret bit width. - bn_div_consttime(r, NULL, r, gcd, /*divisor_min_bits=*/0, ctx) && - bn_rshift_secret_shift(r, r, shift, ctx); - BN_CTX_end(ctx); - return ret; + return gcd != nullptr && // + bn_mul_consttime(r, a, b, ctx) && + bn_gcd_consttime(gcd, &shift, a, b, ctx) && + // |gcd| has a secret bit width. + bn_div_consttime(r, nullptr, r, gcd, /*divisor_min_bits=*/0, ctx) && + bn_rshift_secret_shift(r, r, shift, ctx); } int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a, @@ -207,8 +196,7 @@ a_width = n_width; } - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *u = BN_CTX_get(ctx); BIGNUM *v = BN_CTX_get(ctx); BIGNUM *A = BN_CTX_get(ctx); @@ -218,14 +206,14 @@ BIGNUM *tmp = BN_CTX_get(ctx); BIGNUM *tmp2 = BN_CTX_get(ctx); size_t a_bits, num_iters, n_bits; - if (u == NULL || // - v == NULL || // - A == NULL || // - B == NULL || // - C == NULL || // - D == NULL || // - tmp == NULL || // - tmp2 == NULL || // + if (u == nullptr || // + v == nullptr || // + A == nullptr || // + B == nullptr || // + C == nullptr || // + D == nullptr || // + tmp == nullptr || // + tmp2 == nullptr || // !BN_copy(u, a) || // !BN_copy(v, n) || // !BN_one(A) || // @@ -242,7 +230,7 @@ // |tmp| and |tmp2| may be used at either size. !bn_resize_words(tmp, n_width) || // !bn_resize_words(tmp2, n_width)) { - goto err; + return 0; } // Each loop iteration halves at least one of |u| and |v|. Thus we need at @@ -254,7 +242,7 @@ num_iters = a_bits + n_bits; if (num_iters < a_bits) { OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); - goto err; + return 0; } // Before and after each loop iteration, the following hold: @@ -328,12 +316,8 @@ if (constant_time_declassify_int(!BN_is_one(u))) { *out_no_inverse = 1; OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); - goto err; + return 0; } - ret = BN_copy(r, A) != NULL; - -err: - BN_CTX_end(ctx); - return ret; + return BN_copy(r, A) != nullptr; }
diff --git a/crypto/fipsmodule/bn/jacobi.cc.inc b/crypto/fipsmodule/bn/jacobi.cc.inc index 0ac6f67..1c1c51f 100644 --- a/crypto/fipsmodule/bn/jacobi.cc.inc +++ b/crypto/fipsmodule/bn/jacobi.cc.inc
@@ -42,32 +42,29 @@ return -2; } - int ret = -2; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *A = BN_CTX_get(ctx); BIGNUM *B = BN_CTX_get(ctx); if (B == NULL) { - goto end; + return -2; } if (!BN_copy(A, a) || !BN_copy(B, b)) { - goto end; + return -2; } // Adapted from logic to compute the Kronecker symbol, originally implemented // according to Henri Cohen, "A Course in Computational Algebraic Number // Theory" (algorithm 1.4.10). - ret = 1; - + int ret = 1; while (1) { // Cohen's step 3: // B is positive and odd if (BN_is_zero(A)) { - ret = BN_is_one(B) ? ret : 0; - goto end; + return BN_is_one(B) ? ret : 0; } // now A is non-zero @@ -76,8 +73,7 @@ i++; } if (!BN_rshift(A, A, i)) { - ret = -2; - goto end; + return -2; } if (i & 1) { // i is odd @@ -93,16 +89,11 @@ // (A, B) := (B mod |A|, |A|) if (!BN_nnmod(B, B, A, ctx)) { - ret = -2; - goto end; + return -2; } BIGNUM *tmp = A; A = B; B = tmp; tmp->neg = 0; } - -end: - BN_CTX_end(ctx); - return ret; }
diff --git a/crypto/fipsmodule/bn/montgomery.cc.inc b/crypto/fipsmodule/bn/montgomery.cc.inc index c0adcca..4bafb11 100644 --- a/crypto/fipsmodule/bn/montgomery.cc.inc +++ b/crypto/fipsmodule/bn/montgomery.cc.inc
@@ -245,21 +245,13 @@ int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mont, BN_CTX *ctx) { - int ret = 0; - BIGNUM *t; - - BN_CTX_start(ctx); - t = BN_CTX_get(ctx); + bssl::BN_CTXScope scope(ctx); + BIGNUM *t = BN_CTX_get(ctx); if (t == NULL || !BN_copy(t, a)) { - goto err; + return 0; } - ret = BN_from_montgomery_word(r, t, mont); - -err: - BN_CTX_end(ctx); - - return ret; + return BN_from_montgomery_word(r, t, mont); } int bn_one_to_montgomery(BIGNUM *r, const BN_MONT_CTX *mont, BN_CTX *ctx) { @@ -286,34 +278,28 @@ const BIGNUM *b, const BN_MONT_CTX *mont, BN_CTX *ctx) { - int ret = 0; - - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); if (tmp == NULL) { - goto err; + return 0; } if (a == b) { if (!bn_sqr_consttime(tmp, a, ctx)) { - goto err; + return 0; } } else { if (!bn_mul_consttime(tmp, a, b, ctx)) { - goto err; + return 0; } } // reduce from aRR to aR if (!BN_from_montgomery_word(r, tmp, mont)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
diff --git a/crypto/fipsmodule/bn/mul.cc.inc b/crypto/fipsmodule/bn/mul.cc.inc index 4d7a919..9f75dde 100644 --- a/crypto/fipsmodule/bn/mul.cc.inc +++ b/crypto/fipsmodule/bn/mul.cc.inc
@@ -137,15 +137,14 @@ int cl = a->width < b->width ? a->width : b->width; int dl = a->width - b->width; int r_len = a->width < b->width ? b->width : a->width; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); - int ok = tmp != NULL && bn_wexpand(r, r_len) && bn_wexpand(tmp, r_len); - if (ok) { - bn_abs_sub_part_words(r->d, a->d, b->d, cl, dl, tmp->d); - r->width = r_len; + if (tmp == nullptr || !bn_wexpand(r, r_len) || !bn_wexpand(tmp, r_len)) { + return 0; } - BN_CTX_end(ctx); - return ok; + bn_abs_sub_part_words(r->d, a->d, b->d, cl, dl, tmp->d); + r->width = r_len; + return 1; } // Karatsuba recursive multiplication algorithm @@ -377,13 +376,13 @@ return 1; } - int ret = 0, i, top; + int i, top; BIGNUM *rr; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); if (r == a || r == b) { rr = BN_CTX_get(ctx); if (rr == NULL) { - goto err; + return 0; } } else { rr = r; @@ -394,7 +393,7 @@ if (i == 0) { if (al == 8) { if (!bn_wexpand(rr, 16)) { - goto err; + return 0; } rr->width = 16; bn_mul_comba8(rr->d, a->d, b->d); @@ -421,7 +420,7 @@ assert(j <= al || j <= bl); BIGNUM *t = BN_CTX_get(ctx); if (t == NULL) { - goto err; + return 0; } if (al > j || bl > j) { // We know |al| and |bl| are at most one from each other, so if al > j, @@ -432,7 +431,7 @@ // https://boringssl-review.googlesource.com/q/I0bd604e2cd6a75c266f64476c23a730ca1721ea6 assert(al >= j && bl >= j); if (!bn_wexpand(t, j * 8) || !bn_wexpand(rr, j * 4)) { - goto err; + return 0; } bn_mul_part_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); } else { @@ -440,7 +439,7 @@ // of al - j or bl - j is zero. The other, by the bound on |i| above, is // zero or -1. Thus, we can use |bn_mul_recursive|. if (!bn_wexpand(t, j * 4) || !bn_wexpand(rr, j * 2)) { - goto err; + return 0; } bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); } @@ -450,20 +449,16 @@ } if (!bn_wexpand(rr, top)) { - goto err; + return 0; } rr->width = top; bn_mul_normal(rr->d, a->d, al, b->d, bl); end: if (r != rr && !BN_copy(r, rr)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { @@ -627,17 +622,16 @@ return 1; } - int ret = 0, max; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *rr = (a != r) ? r : BN_CTX_get(ctx); BIGNUM *tmp = BN_CTX_get(ctx); if (!rr || !tmp) { - goto err; + return 0; } - max = 2 * al; // Non-zero (from above) + int max = 2 * al; // Non-zero (from above) if (!bn_wexpand(rr, max)) { - goto err; + return 0; } if (al == 4) { @@ -658,12 +652,12 @@ // cryptographic primitives. if (al != 0 && (al & (al - 1)) == 0) { if (!bn_wexpand(tmp, al * 4)) { - goto err; + return 0; } bn_sqr_recursive(rr->d, a->d, al, tmp->d); } else { if (!bn_wexpand(tmp, max)) { - goto err; + return 0; } bn_sqr_normal(rr->d, a->d, al, tmp->d); } @@ -674,13 +668,9 @@ rr->width = max; if (rr != r && !BN_copy(r, rr)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) {
diff --git a/crypto/fipsmodule/bn/prime.cc.inc b/crypto/fipsmodule/bn/prime.cc.inc index 0471246..fabb545 100644 --- a/crypto/fipsmodule/bn/prime.cc.inc +++ b/crypto/fipsmodule/bn/prime.cc.inc
@@ -290,9 +290,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) { BIGNUM *t; - int found = 0; int i, j, c1 = 0; - BN_CTX *ctx; int checks = BN_prime_checks_for_size(bits); if (bits < 2) { @@ -305,43 +303,43 @@ return 0; } - 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); - t = BN_CTX_get(ctx); + bssl::BN_CTXScope scope(ctx.get()); + t = BN_CTX_get(ctx.get()); if (!t) { - goto err; + return 0; } loop: // make a random number and set the top and bottom bits if (add == NULL) { if (!probable_prime(ret, bits)) { - goto err; + return 0; } } else { if (safe) { - if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) { - goto err; + if (!probable_prime_dh_safe(ret, bits, add, rem, ctx.get())) { + return 0; } } else { - if (!probable_prime_dh(ret, bits, add, rem, ctx)) { - goto err; + if (!probable_prime_dh(ret, bits, add, rem, ctx.get())) { + return 0; } } } if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, c1++)) { // aborted - goto err; + return 0; } if (!safe) { - i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); + i = BN_is_prime_fasttest_ex(ret, checks, ctx.get(), 0, cb); if (i == -1) { - goto err; + return 0; } else if (i == 0) { goto loop; } @@ -349,7 +347,7 @@ // for "safe prime" generation, check that (p-1)/2 is prime. Since a prime // is odd, We just need to divide by 2 if (!BN_rshift1(t, ret)) { - goto err; + return 0; } // Interleave |ret| and |t|'s primality tests to avoid paying the full @@ -358,37 +356,29 @@ // TODO(davidben): This doesn't quite work because an iteration count of 1 // still runs the blinding mechanism. for (i = 0; i < checks; i++) { - j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, NULL); + j = BN_is_prime_fasttest_ex(ret, 1, ctx.get(), 0, NULL); if (j == -1) { - goto err; + return 0; } else if (j == 0) { goto loop; } - j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, NULL); + j = BN_is_prime_fasttest_ex(t, 1, ctx.get(), 0, NULL); if (j == -1) { - goto err; + return 0; } else if (j == 0) { goto loop; } if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, i)) { - goto err; + return 0; } // We have a safe prime test pass } } // we have a prime :-) - found = 1; - -err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - - return found; + return 1; } static int bn_trial_division(uint16_t *out, const BIGNUM *bn) { @@ -453,8 +443,7 @@ int *out_is_possibly_prime, const BIGNUM *b, const BN_MONT_CTX *mont, BN_CTX *ctx) { // This function corresponds to steps 4.3 through 4.5 of FIPS 186-4, C.3.1. - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); // Step 4.3. We use Montgomery-encoding for better performance and to avoid // timing leaks. @@ -464,7 +453,7 @@ if (z == NULL || !BN_mod_exp_mont_consttime(z, b, miller_rabin->m, w, ctx, mont) || !BN_to_montgomery(z, z, mont, ctx)) { - goto err; + return 0; } // is_possibly_prime is all ones if we have determined |b| is not a composite @@ -493,7 +482,7 @@ // Step 4.5.1. if (!BN_mod_mul_montgomery(z, z, z, mont, ctx)) { - goto err; + return 0; } // Step 4.5.2. If z = w-1 and the loop is not done, this is not a composite @@ -513,11 +502,7 @@ } *out_is_possibly_prime = constant_time_declassify_w(is_possibly_prime) & 1; - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int BN_primality_test(int *out_is_probably_prime, const BIGNUM *w, int checks, @@ -598,26 +583,25 @@ checks = BN_prime_checks_for_size(BN_num_bits(w)); } - BN_CTX *new_ctx = NULL; - if (ctx == NULL) { - new_ctx = BN_CTX_new(); - if (new_ctx == NULL) { + bssl::UniquePtr<BN_CTX> new_ctx; + if (ctx == nullptr) { + new_ctx.reset(BN_CTX_new()); + if (new_ctx == nullptr) { return 0; } - ctx = new_ctx; + ctx = new_ctx.get(); } // See C.3.1 from FIPS 186-4. - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *b = BN_CTX_get(ctx); - BN_MONT_CTX *mont = BN_MONT_CTX_new_consttime(w, ctx); + bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new_consttime(w, ctx)); BN_MILLER_RABIN miller_rabin; crypto_word_t uniform_iterations = 0; - if (b == NULL || mont == NULL || + if (b == nullptr || mont == nullptr || // Steps 1-3. - !bn_miller_rabin_init(&miller_rabin, mont, ctx)) { - goto err; + !bn_miller_rabin_init(&miller_rabin, mont.get(), ctx)) { + return 0; } // The following loop performs in inner iteration of the Miller-Rabin @@ -657,39 +641,32 @@ // Step 4.1-4.2 int is_uniform; if (!bn_rand_secret_range(b, &is_uniform, 2, miller_rabin.w1)) { - goto err; + return 0; } uniform_iterations += is_uniform; // Steps 4.3-4.5 int is_possibly_prime = 0; - if (!bn_miller_rabin_iteration(&miller_rabin, &is_possibly_prime, b, mont, - ctx)) { - goto err; + if (!bn_miller_rabin_iteration(&miller_rabin, &is_possibly_prime, b, + mont.get(), ctx)) { + return 0; } if (!is_possibly_prime) { // Step 4.6. We did not see z = w-1 before z = 1, so w must be composite. *out_is_probably_prime = 0; - ret = 1; - goto err; + return 1; } // Step 4.7 if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, i - 1)) { - goto err; + return 0; } } declassify_assert(uniform_iterations >= (crypto_word_t)checks); *out_is_probably_prime = 1; - ret = 1; - -err: - BN_MONT_CTX_free(mont); - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); - return ret; + return 1; } int BN_is_prime_ex(const BIGNUM *candidate, int checks, BN_CTX *ctx, @@ -720,41 +697,36 @@ checks = BN_prime_checks_for_size(BN_num_bits(w)); } - int ret = 0; - BN_MONT_CTX *mont = NULL; - - BN_CTX_start(ctx); - + bssl::BN_CTXScope scope(ctx); BIGNUM *w1 = BN_CTX_get(ctx); - BIGNUM *b, *g, *z, *x, *x1, *m; - int a; - if (w1 == NULL || !BN_copy(w1, w) || !BN_sub_word(w1, 1)) { - goto err; + if (w1 == nullptr || !BN_copy(w1, w) || !BN_sub_word(w1, 1)) { + return 0; } // Write w1 as m*2^a (Steps 1 and 2). - a = 0; + int a = 0; while (!BN_is_bit_set(w1, a)) { a++; } - m = BN_CTX_get(ctx); - if (m == NULL || !BN_rshift(m, w1, a)) { - goto err; + BIGNUM *m = BN_CTX_get(ctx); + if (m == nullptr || !BN_rshift(m, w1, a)) { + return 0; } - b = BN_CTX_get(ctx); - g = BN_CTX_get(ctx); - z = BN_CTX_get(ctx); - x = BN_CTX_get(ctx); - x1 = BN_CTX_get(ctx); - if (b == NULL || g == NULL || z == NULL || x == NULL || x1 == NULL) { - goto err; + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *g = BN_CTX_get(ctx); + BIGNUM *z = BN_CTX_get(ctx); + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *x1 = BN_CTX_get(ctx); + if (b == nullptr || g == nullptr || z == nullptr || x == nullptr || + x1 == nullptr) { + return 0; } // Montgomery setup for computations mod w - mont = BN_MONT_CTX_new_for_modulus(w, ctx); - if (mont == NULL) { - goto err; + bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new_for_modulus(w, ctx)); + if (mont == nullptr) { + return 0; } // The following loop performs in inner iteration of the Enhanced Miller-Rabin @@ -762,22 +734,21 @@ for (int i = 1; i <= checks; i++) { // Step 4.1-4.2 if (!BN_rand_range_ex(b, 2, w1)) { - goto err; + return 0; } // Step 4.3-4.4 if (!BN_gcd(g, b, w, ctx)) { - goto err; + return 0; } if (BN_cmp_word(g, 1) > 0) { *out_result = bn_composite; - ret = 1; - goto err; + return 1; } // Step 4.5 - if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) { - goto err; + if (!BN_mod_exp_mont(z, b, m, w, ctx, mont.get())) { + return 0; } // Step 4.6 @@ -788,7 +759,7 @@ // Step 4.7 for (int j = 1; j < a; j++) { if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { - goto err; + return 0; } if (BN_cmp(z, w1) == 0) { goto loop; @@ -800,18 +771,18 @@ // Step 4.8-4.9 if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { - goto err; + return 0; } // Step 4.10-4.11 if (!BN_is_one(z) && !BN_copy(x, z)) { - goto err; + return 0; } composite: // Step 4.12-4.14 if (!BN_copy(x1, x) || !BN_sub_word(x1, 1) || !BN_gcd(g, x1, w, ctx)) { - goto err; + return 0; } if (BN_cmp_word(g, 1) > 0) { *out_result = bn_composite; @@ -819,24 +790,17 @@ *out_result = bn_non_prime_power_composite; } - ret = 1; - goto err; + return 1; loop: // Step 4.15 if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, i - 1)) { - goto err; + return 0; } } *out_result = bn_probably_prime; - ret = 1; - -err: - BN_MONT_CTX_free(mont); - BN_CTX_end(ctx); - - return ret; + return 1; } static int probable_prime(BIGNUM *rnd, int bits) { @@ -850,111 +814,99 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) { - int ret = 0; + bssl::BN_CTXScope scope(ctx); BIGNUM *t1; - - BN_CTX_start(ctx); - size_t num_primes; - if ((t1 = BN_CTX_get(ctx)) == NULL) { - goto err; + if ((t1 = BN_CTX_get(ctx)) == nullptr) { + return 0; } if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { - goto err; + return 0; } // we need ((rnd-rem) % add) == 0 - if (!BN_mod(t1, rnd, add, ctx)) { - goto err; + return 0; } if (!BN_sub(rnd, rnd, t1)) { - goto err; + return 0; } - if (rem == NULL) { + if (rem == nullptr) { if (!BN_add_word(rnd, 1)) { - goto err; + return 0; } } else { if (!BN_add(rnd, rnd, rem)) { - goto err; + return 0; } } // we now have a random number 'rand' to test. - num_primes = num_trial_division_primes(rnd); + size_t num_primes = num_trial_division_primes(rnd); loop: for (size_t i = 1; i < num_primes; i++) { // check that rnd is a prime if (bn_mod_u16_consttime(rnd, kPrimes[i]) <= 1) { if (!BN_add(rnd, rnd, add)) { - goto err; + return 0; } goto loop; } } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, const BIGNUM *rem, BN_CTX *ctx) { - int ret = 0; - BIGNUM *t1, *qadd, *q; - bits--; - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - qadd = BN_CTX_get(ctx); - size_t num_primes; + bssl::BN_CTXScope scope(ctx); + BIGNUM *t1 = BN_CTX_get(ctx); + BIGNUM *q = BN_CTX_get(ctx); + BIGNUM *qadd = BN_CTX_get(ctx); if (qadd == NULL) { - goto err; + return 0; } if (!BN_rshift1(qadd, padd)) { - goto err; + return 0; } if (!BN_rand(q, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { - goto err; + return 0; } // we need ((rnd-rem) % add) == 0 if (!BN_mod(t1, q, qadd, ctx)) { - goto err; + return 0; } if (!BN_sub(q, q, t1)) { - goto err; + return 0; } if (rem == NULL) { if (!BN_add_word(q, 1)) { - goto err; + return 0; } } else { if (!BN_rshift1(t1, rem)) { - goto err; + return 0; } if (!BN_add(q, q, t1)) { - goto err; + return 0; } } // we now have a random number 'rand' to test. if (!BN_lshift1(p, q)) { - goto err; + return 0; } if (!BN_add_word(p, 1)) { - goto err; + return 0; } - num_primes = num_trial_division_primes(p); + size_t num_primes = num_trial_division_primes(p); loop: for (size_t i = 1; i < num_primes; i++) { // check that p and q are prime @@ -963,18 +915,14 @@ if (bn_mod_u16_consttime(p, kPrimes[i]) == 0 || bn_mod_u16_consttime(q, kPrimes[i]) == 0) { if (!BN_add(p, p, padd)) { - goto err; + return 0; } if (!BN_add(q, q, qadd)) { - goto err; + return 0; } goto loop; } } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; }
diff --git a/crypto/fipsmodule/bn/shift.cc.inc b/crypto/fipsmodule/bn/shift.cc.inc index 2739c5a..491c796 100644 --- a/crypto/fipsmodule/bn/shift.cc.inc +++ b/crypto/fipsmodule/bn/shift.cc.inc
@@ -129,12 +129,11 @@ int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a, unsigned n, BN_CTX *ctx) { - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); unsigned max_bits; if (tmp == NULL || !BN_copy(r, a) || !bn_wexpand(tmp, r->width)) { - goto err; + return 0; } // Shift conditionally by powers of two. @@ -147,11 +146,7 @@ r->d /* ignore shift */, r->width); } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num) {
diff --git a/crypto/fipsmodule/bn/sqrt.cc.inc b/crypto/fipsmodule/bn/sqrt.cc.inc index cb70f19..df31df5 100644 --- a/crypto/fipsmodule/bn/sqrt.cc.inc +++ b/crypto/fipsmodule/bn/sqrt.cc.inc
@@ -63,7 +63,7 @@ return ret; } - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); A = BN_CTX_get(ctx); b = BN_CTX_get(ctx); q = BN_CTX_get(ctx); @@ -378,7 +378,6 @@ } ret = NULL; } - BN_CTX_end(ctx); return ret; } @@ -395,7 +394,7 @@ return 1; } - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); if (out_sqrt == in) { estimate = BN_CTX_get(ctx); } else { @@ -454,6 +453,5 @@ if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) { ok = 0; } - BN_CTX_end(ctx); return ok; }