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>
This commit is contained in:
David Benjamin
2025-03-15 09:26:53 -07:00
committed by Boringssl LUCI CQ
parent b918bad0f0
commit a71d28876b
5 changed files with 171 additions and 268 deletions
+13 -19
View File
@@ -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,
+27 -61
View File
@@ -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 @@ int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator,
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) {
+59 -75
View File
@@ -167,17 +167,14 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
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 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
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 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
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 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
// 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 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
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 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
}
if (!BN_GENCB_call(cb, 2, 0) || !BN_GENCB_call(cb, 3, 0)) {
goto err;
return 0;
}
// step 6
@@ -291,7 +288,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
for (;;) {
if ((counter != 0) && !BN_GENCB_call(cb, BN_GENCB_GENERATED, counter)) {
goto err;
return 0;
}
// step 7
@@ -307,36 +304,36 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
}
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 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
}
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 @@ int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) {
// 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) {
+53 -84
View File
@@ -147,7 +147,7 @@ int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
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 BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
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 @@ int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
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 @@ int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
// 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 @@ int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
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 @@ int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
// 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 @@ int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder,
// 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 @@ int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder,
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 @@ int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder,
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(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
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(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
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_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) {
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 @@ int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
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_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
}
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) {
+19 -29
View File
@@ -149,57 +149,55 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
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 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
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 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
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 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
// |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,