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:
committed by
Boringssl LUCI CQ
parent
b918bad0f0
commit
a71d28876b
+13
-19
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user