mirror of
https://github.com/openeuler-riscv/boringssl.git
synced 2026-05-13 07:33:34 +00:00
Convert more things to scopers
This was just focused around BN_CTX right now. Change-Id: I9a8bf0b3d6d5b92901fc0afe8162e2e690ebe25c Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/78571 Auto-Submit: David Benjamin <davidben@google.com> Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
committed by
Boringssl LUCI CQ
parent
13a1db17c6
commit
eac08c808f
@@ -55,13 +55,11 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
|
||||
if (ctx == NULL) {
|
||||
return 0;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
int ok = 0;
|
||||
bssl::BN_CTXScope scope(ctx.get());
|
||||
|
||||
// Check |pub_key| is greater than 1.
|
||||
if (BN_cmp(pub_key, BN_value_one()) <= 0) {
|
||||
@@ -69,11 +67,11 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) {
|
||||
}
|
||||
|
||||
// Check |pub_key| is less than |dh->p| - 1.
|
||||
BIGNUM *tmp = BN_CTX_get(ctx);
|
||||
BIGNUM *tmp = BN_CTX_get(ctx.get());
|
||||
if (tmp == NULL ||
|
||||
!BN_copy(tmp, dh->p) ||
|
||||
!BN_sub_word(tmp, 1)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (BN_cmp(pub_key, tmp) >= 0) {
|
||||
*out_flags |= DH_CHECK_PUBKEY_TOO_LARGE;
|
||||
@@ -83,23 +81,17 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) {
|
||||
// Check |pub_key|^|dh->q| is 1 mod |dh->p|. This is necessary for RFC 5114
|
||||
// groups which are not safe primes but pick a generator on a prime-order
|
||||
// subgroup of size |dh->q|.
|
||||
if (!BN_mod_exp_mont(tmp, pub_key, dh->q, dh->p, ctx, NULL)) {
|
||||
goto err;
|
||||
if (!BN_mod_exp_mont(tmp, pub_key, dh->q, dh->p, ctx.get(), NULL)) {
|
||||
return 0;
|
||||
}
|
||||
if (!BN_is_one(tmp)) {
|
||||
*out_flags |= DH_CHECK_PUBKEY_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int DH_check(const DH *dh, int *out_flags) {
|
||||
*out_flags = 0;
|
||||
if (!dh_check_params_fast(dh)) {
|
||||
@@ -112,23 +104,18 @@ int DH_check(const DH *dh, int *out_flags) {
|
||||
// for 3, p mod 12 == 5
|
||||
// for 5, p mod 10 == 3 or 7
|
||||
// should hold.
|
||||
int ok = 0, r;
|
||||
BN_CTX *ctx = NULL;
|
||||
BN_ULONG l;
|
||||
BIGNUM *t1 = NULL, *t2 = NULL;
|
||||
|
||||
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);
|
||||
t1 = BN_CTX_get(ctx);
|
||||
if (t1 == NULL) {
|
||||
goto err;
|
||||
bssl::BN_CTXScope scope(ctx.get());
|
||||
BIGNUM *t1 = BN_CTX_get(ctx.get());
|
||||
if (t1 == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
t2 = BN_CTX_get(ctx);
|
||||
if (t2 == NULL) {
|
||||
goto err;
|
||||
BIGNUM *t2 = BN_CTX_get(ctx.get());
|
||||
if (t2 == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dh->q) {
|
||||
@@ -138,39 +125,40 @@ int DH_check(const DH *dh, int *out_flags) {
|
||||
*out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
|
||||
} else {
|
||||
// Check g^q == 1 mod p
|
||||
if (!BN_mod_exp_mont(t1, dh->g, dh->q, dh->p, ctx, NULL)) {
|
||||
goto err;
|
||||
if (!BN_mod_exp_mont(t1, dh->g, dh->q, dh->p, ctx.get(), nullptr)) {
|
||||
return 0;
|
||||
}
|
||||
if (!BN_is_one(t1)) {
|
||||
*out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
|
||||
}
|
||||
}
|
||||
r = BN_is_prime_ex(dh->q, BN_prime_checks_for_validation, ctx, NULL);
|
||||
int r = BN_is_prime_ex(dh->q, BN_prime_checks_for_validation, ctx.get(),
|
||||
nullptr);
|
||||
if (r < 0) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (!r) {
|
||||
*out_flags |= DH_CHECK_Q_NOT_PRIME;
|
||||
}
|
||||
// Check p == 1 mod q i.e. q divides p - 1
|
||||
if (!BN_div(t1, t2, dh->p, dh->q, ctx)) {
|
||||
goto err;
|
||||
if (!BN_div(t1, t2, dh->p, dh->q, ctx.get())) {
|
||||
return 0;
|
||||
}
|
||||
if (!BN_is_one(t2)) {
|
||||
*out_flags |= DH_CHECK_INVALID_Q_VALUE;
|
||||
}
|
||||
} else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
|
||||
l = BN_mod_word(dh->p, 24);
|
||||
BN_ULONG l = BN_mod_word(dh->p, 24);
|
||||
if (l == (BN_ULONG)-1) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (l != 11) {
|
||||
*out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
|
||||
}
|
||||
} else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
|
||||
l = BN_mod_word(dh->p, 10);
|
||||
BN_ULONG l = BN_mod_word(dh->p, 10);
|
||||
if (l == (BN_ULONG)-1) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (l != 3 && l != 7) {
|
||||
*out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
|
||||
@@ -179,30 +167,24 @@ int DH_check(const DH *dh, int *out_flags) {
|
||||
*out_flags |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR;
|
||||
}
|
||||
|
||||
r = BN_is_prime_ex(dh->p, BN_prime_checks_for_validation, ctx, NULL);
|
||||
int r =
|
||||
BN_is_prime_ex(dh->p, BN_prime_checks_for_validation, ctx.get(), nullptr);
|
||||
if (r < 0) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (!r) {
|
||||
*out_flags |= DH_CHECK_P_NOT_PRIME;
|
||||
} else if (!dh->q) {
|
||||
if (!BN_rshift1(t1, dh->p)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
r = BN_is_prime_ex(t1, BN_prime_checks_for_validation, ctx, NULL);
|
||||
r = BN_is_prime_ex(t1, BN_prime_checks_for_validation, ctx.get(), nullptr);
|
||||
if (r < 0) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (!r) {
|
||||
*out_flags |= DH_CHECK_P_NOT_SAFE_PRIME;
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
return ok;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -147,28 +147,27 @@ int DH_generate_key(DH *dh) {
|
||||
}
|
||||
|
||||
int ok = 0;
|
||||
int generate_new_key = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *pub_key = NULL, *priv_key = NULL, *priv_key_limit = NULL;
|
||||
bool generate_new_key = false;
|
||||
BIGNUM *pub_key = nullptr, *priv_key = nullptr;
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
|
||||
if (ctx == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (dh->priv_key == NULL) {
|
||||
if (dh->priv_key == nullptr) {
|
||||
priv_key = BN_new();
|
||||
if (priv_key == NULL) {
|
||||
if (priv_key == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
generate_new_key = 1;
|
||||
generate_new_key = true;
|
||||
} else {
|
||||
priv_key = dh->priv_key;
|
||||
}
|
||||
|
||||
if (dh->pub_key == NULL) {
|
||||
if (dh->pub_key == nullptr) {
|
||||
pub_key = BN_new();
|
||||
if (pub_key == NULL) {
|
||||
if (pub_key == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
@@ -176,7 +175,7 @@ int DH_generate_key(DH *dh) {
|
||||
}
|
||||
|
||||
if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
|
||||
dh->p, ctx)) {
|
||||
dh->p, ctx.get())) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -202,30 +201,30 @@ int DH_generate_key(DH *dh) {
|
||||
// clamp |dh->priv_length| before invoking the algorithm.
|
||||
|
||||
// Compute M = min(2^N, q).
|
||||
priv_key_limit = BN_new();
|
||||
if (priv_key_limit == NULL) {
|
||||
bssl::UniquePtr<BIGNUM> priv_key_limit(BN_new());
|
||||
if (priv_key_limit == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
if (dh->priv_length == 0 || dh->priv_length >= BN_num_bits(dh->p) - 1) {
|
||||
// M = q = (p - 1) / 2.
|
||||
if (!BN_rshift1(priv_key_limit, dh->p)) {
|
||||
if (!BN_rshift1(priv_key_limit.get(), dh->p)) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
// M = 2^N.
|
||||
if (!BN_set_bit(priv_key_limit, dh->priv_length)) {
|
||||
if (!BN_set_bit(priv_key_limit.get(), dh->priv_length)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
// Choose a private key uniformly from [1, M-1].
|
||||
if (!BN_rand_range_ex(priv_key, 1, priv_key_limit)) {
|
||||
if (!BN_rand_range_ex(priv_key, 1, priv_key_limit.get())) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx,
|
||||
if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx.get(),
|
||||
dh->method_mont_p)) {
|
||||
goto err;
|
||||
}
|
||||
@@ -239,14 +238,12 @@ err:
|
||||
OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
|
||||
}
|
||||
|
||||
if (dh->pub_key == NULL) {
|
||||
if (dh->pub_key == nullptr) {
|
||||
BN_free(pub_key);
|
||||
}
|
||||
if (dh->priv_key == NULL) {
|
||||
if (dh->priv_key == nullptr) {
|
||||
BN_free(priv_key);
|
||||
}
|
||||
BN_free(priv_key_limit);
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -267,56 +264,46 @@ static int dh_compute_key(DH *dh, BIGNUM *out_shared_key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
BN_CTX_start(ctx);
|
||||
bssl::BN_CTXScope scope(ctx);
|
||||
BIGNUM *p_minus_1 = BN_CTX_get(ctx);
|
||||
|
||||
if (!p_minus_1 ||
|
||||
!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
|
||||
dh->p, ctx)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BN_mod_exp_mont_consttime(out_shared_key, peers_key, dh->priv_key, dh->p,
|
||||
ctx, dh->method_mont_p) ||
|
||||
!BN_copy(p_minus_1, dh->p) || !BN_sub_word(p_minus_1, 1)) {
|
||||
OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This performs the check required by SP 800-56Ar3 section 5.7.1.1 step two.
|
||||
if (BN_cmp_word(out_shared_key, 1) <= 0 ||
|
||||
BN_cmp(out_shared_key, p_minus_1) == 0) {
|
||||
OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dh_compute_key_padded_no_self_test(unsigned char *out,
|
||||
const BIGNUM *peers_key, DH *dh) {
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
|
||||
if (ctx == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
bssl::BN_CTXScope scope(ctx.get());
|
||||
int dh_size = DH_size(dh);
|
||||
int ret = -1;
|
||||
BIGNUM *shared_key = BN_CTX_get(ctx);
|
||||
if (shared_key && dh_compute_key(dh, shared_key, peers_key, ctx) &&
|
||||
BN_bn2bin_padded(out, dh_size, shared_key)) {
|
||||
ret = dh_size;
|
||||
BIGNUM *shared_key = BN_CTX_get(ctx.get());
|
||||
if (shared_key == nullptr ||
|
||||
!dh_compute_key(dh, shared_key, peers_key, ctx.get()) ||
|
||||
!BN_bn2bin_padded(out, dh_size, shared_key)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ret;
|
||||
return dh_size;
|
||||
}
|
||||
|
||||
int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
|
||||
@@ -328,22 +315,18 @@ int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
|
||||
int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
|
||||
boringssl_ensure_ffdh_self_test();
|
||||
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
|
||||
if (ctx == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
int ret = -1;
|
||||
BIGNUM *shared_key = BN_CTX_get(ctx);
|
||||
if (shared_key && dh_compute_key(dh, shared_key, peers_key, ctx)) {
|
||||
// A |BIGNUM|'s byte count fits in |int|.
|
||||
ret = (int)BN_bn2bin(shared_key, out);
|
||||
bssl::BN_CTXScope scope(ctx.get());
|
||||
BIGNUM *shared_key = BN_CTX_get(ctx.get());
|
||||
if (shared_key == nullptr ||
|
||||
!dh_compute_key(dh, shared_key, peers_key, ctx.get())) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ret;
|
||||
// A |BIGNUM|'s byte count fits in |int|.
|
||||
return static_cast<int>(BN_bn2bin(shared_key, out));
|
||||
}
|
||||
|
||||
int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len,
|
||||
@@ -415,29 +398,27 @@ DH *DH_get_rfc7919_2048(void) {
|
||||
TOBN(0xadf85458, 0xa2bb4a9a), TOBN(0xffffffff, 0xffffffff),
|
||||
};
|
||||
|
||||
BIGNUM *const ffdhe2048_p = BN_new();
|
||||
BIGNUM *const ffdhe2048_q = BN_new();
|
||||
BIGNUM *const ffdhe2048_g = BN_new();
|
||||
DH *const dh = DH_new();
|
||||
|
||||
bssl::UniquePtr<BIGNUM> ffdhe2048_p(BN_new());
|
||||
bssl::UniquePtr<BIGNUM> ffdhe2048_q(BN_new());
|
||||
bssl::UniquePtr<BIGNUM> ffdhe2048_g(BN_new());
|
||||
bssl::UniquePtr<DH> dh(DH_new());
|
||||
if (!ffdhe2048_p || !ffdhe2048_q || !ffdhe2048_g || !dh) {
|
||||
goto err;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bn_set_static_words(ffdhe2048_p, kFFDHE2048Data,
|
||||
bn_set_static_words(ffdhe2048_p.get(), kFFDHE2048Data,
|
||||
OPENSSL_ARRAY_SIZE(kFFDHE2048Data));
|
||||
|
||||
if (!BN_rshift1(ffdhe2048_q, ffdhe2048_p) || !BN_set_word(ffdhe2048_g, 2) ||
|
||||
!DH_set0_pqg(dh, ffdhe2048_p, ffdhe2048_q, ffdhe2048_g)) {
|
||||
goto err;
|
||||
if (!BN_rshift1(ffdhe2048_q.get(), ffdhe2048_p.get()) ||
|
||||
!BN_set_word(ffdhe2048_g.get(), 2) ||
|
||||
!DH_set0_pqg(dh.get(), ffdhe2048_p.get(), ffdhe2048_q.get(),
|
||||
ffdhe2048_g.get())) {
|
||||
return nullptr;
|
||||
}
|
||||
// |DH_set0_pqg| takes ownership on success.
|
||||
ffdhe2048_p.release();
|
||||
ffdhe2048_q.release();
|
||||
ffdhe2048_g.release();
|
||||
|
||||
return dh;
|
||||
|
||||
err:
|
||||
BN_free(ffdhe2048_p);
|
||||
BN_free(ffdhe2048_q);
|
||||
BN_free(ffdhe2048_g);
|
||||
DH_free(dh);
|
||||
return NULL;
|
||||
return dh.release();
|
||||
}
|
||||
|
||||
@@ -655,12 +655,10 @@ static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
|
||||
ERR_clear_error();
|
||||
|
||||
// This is an unusual input, so we do not guarantee constant-time processing.
|
||||
BN_CTX_start(ctx);
|
||||
bssl::BN_CTXScope scope(ctx);
|
||||
BIGNUM *tmp = BN_CTX_get(ctx);
|
||||
int ok = tmp != NULL && BN_nnmod(tmp, in, EC_GROUP_get0_order(group), ctx) &&
|
||||
ec_bignum_to_scalar(group, out, tmp);
|
||||
BN_CTX_end(ctx);
|
||||
return ok;
|
||||
return tmp != nullptr && BN_nnmod(tmp, in, EC_GROUP_get0_order(group), ctx) &&
|
||||
ec_bignum_to_scalar(group, out, tmp);
|
||||
}
|
||||
|
||||
int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r,
|
||||
|
||||
@@ -718,15 +718,15 @@ static int check_mod_inverse(int *out_ok, const BIGNUM *a, const BIGNUM *ainv,
|
||||
// Note |bn_mul_consttime| and |bn_div_consttime| do not scale linearly, but
|
||||
// checking |ainv| is in range bounds the running time, assuming |m|'s bounds
|
||||
// were checked by the caller.
|
||||
BN_CTX_start(ctx);
|
||||
bssl::BN_CTXScope scope(ctx);
|
||||
BIGNUM *tmp = BN_CTX_get(ctx);
|
||||
int ret = tmp != NULL && bn_mul_consttime(tmp, a, ainv, ctx) &&
|
||||
bn_div_consttime(NULL, tmp, tmp, m, m_min_bits, ctx);
|
||||
if (ret) {
|
||||
*out_ok = constant_time_declassify_int(BN_is_one(tmp));
|
||||
if (tmp == nullptr || //
|
||||
!bn_mul_consttime(tmp, a, ainv, ctx) ||
|
||||
!bn_div_consttime(NULL, tmp, tmp, m, m_min_bits, ctx)) {
|
||||
return 0;
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
*out_ok = constant_time_declassify_int(BN_is_one(tmp));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RSA_check_key(const RSA *key) {
|
||||
|
||||
@@ -446,8 +446,6 @@ int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out,
|
||||
}
|
||||
|
||||
const unsigned rsa_size = RSA_size(rsa);
|
||||
BIGNUM *f, *result;
|
||||
|
||||
if (max_out < rsa_size) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
@@ -458,18 +456,17 @@ int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out,
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
|
||||
if (ctx == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
uint8_t *buf = NULL;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
f = BN_CTX_get(ctx);
|
||||
result = BN_CTX_get(ctx);
|
||||
if (f == NULL || result == NULL) {
|
||||
uint8_t *buf = nullptr;
|
||||
bssl::BN_CTXScope scope(ctx.get());
|
||||
BIGNUM *f = BN_CTX_get(ctx.get());
|
||||
BIGNUM *result = BN_CTX_get(ctx.get());
|
||||
if (f == nullptr || result == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -478,12 +475,12 @@ int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out,
|
||||
} else {
|
||||
// Allocate a temporary buffer to hold the padded plaintext.
|
||||
buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(rsa_size));
|
||||
if (buf == NULL) {
|
||||
if (buf == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (BN_bin2bn(in, in_len, f) == NULL) {
|
||||
if (BN_bin2bn(in, in_len, f) == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -492,8 +489,9 @@ int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ||
|
||||
!BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) {
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx.get()) ||
|
||||
!BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx.get(),
|
||||
rsa->mont_n)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -522,8 +520,6 @@ int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out,
|
||||
}
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
if (buf != out) {
|
||||
OPENSSL_free(buf);
|
||||
}
|
||||
@@ -539,32 +535,28 @@ int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
|
||||
|
||||
int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
|
||||
size_t len) {
|
||||
if (rsa->n == NULL || rsa->d == NULL) {
|
||||
if (rsa->n == nullptr || rsa->d == nullptr) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIGNUM *f, *result;
|
||||
BN_CTX *ctx = NULL;
|
||||
size_t blinding_index = 0;
|
||||
BN_BLINDING *blinding = NULL;
|
||||
int ret = 0, do_blinding;
|
||||
|
||||
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);
|
||||
f = BN_CTX_get(ctx);
|
||||
result = BN_CTX_get(ctx);
|
||||
|
||||
if (f == NULL || result == NULL) {
|
||||
size_t blinding_index = 0;
|
||||
BN_BLINDING *blinding = nullptr;
|
||||
int ret = 0, do_blinding;
|
||||
bssl::BN_CTXScope scope(ctx.get());
|
||||
BIGNUM *f = BN_CTX_get(ctx.get());
|
||||
BIGNUM *result = BN_CTX_get(ctx.get());
|
||||
if (f == nullptr || result == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// The caller should have ensured this.
|
||||
assert(len == BN_num_bytes(rsa->n));
|
||||
if (BN_bin2bn(in, len, f) == NULL) {
|
||||
if (BN_bin2bn(in, len, f) == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -576,7 +568,7 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!freeze_private_key(rsa, ctx)) {
|
||||
if (!freeze_private_key(rsa, ctx.get())) {
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
@@ -584,7 +576,7 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
|
||||
do_blinding =
|
||||
(rsa->flags & (RSA_FLAG_NO_BLINDING | RSA_FLAG_NO_PUBLIC_EXPONENT)) == 0;
|
||||
|
||||
if (rsa->e == NULL && do_blinding) {
|
||||
if (rsa->e == nullptr && do_blinding) {
|
||||
// We cannot do blinding or verification without |e|, and continuing without
|
||||
// those countermeasures is dangerous. However, the Java/Android RSA API
|
||||
// requires support for keys where only |d| and |n| (and not |e|) are known.
|
||||
@@ -598,29 +590,29 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
|
||||
}
|
||||
|
||||
if (do_blinding) {
|
||||
blinding = rsa_blinding_get(rsa, &blinding_index, ctx);
|
||||
if (blinding == NULL) {
|
||||
blinding = rsa_blinding_get(rsa, &blinding_index, ctx.get());
|
||||
if (blinding == nullptr) {
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) {
|
||||
if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx.get())) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (rsa->p != NULL && rsa->q != NULL && rsa->e != NULL && rsa->dmp1 != NULL &&
|
||||
rsa->dmq1 != NULL && rsa->iqmp != NULL &&
|
||||
if (rsa->p != nullptr && rsa->q != nullptr && rsa->e != nullptr &&
|
||||
rsa->dmp1 != nullptr && rsa->dmq1 != nullptr && rsa->iqmp != nullptr &&
|
||||
// Require that we can reduce |f| by |rsa->p| and |rsa->q| in constant
|
||||
// time, which requires primes be the same size, rounded to the Montgomery
|
||||
// coefficient. (See |mod_montgomery|.) This is not required by RFC 8017,
|
||||
// but it is true for keys generated by us and all common implementations.
|
||||
bn_less_than_montgomery_R(rsa->q, rsa->mont_p) &&
|
||||
bn_less_than_montgomery_R(rsa->p, rsa->mont_q)) {
|
||||
if (!rsa_mod_exp_crt(result, f, rsa, ctx)) {
|
||||
if (!rsa_mod_exp_crt(result, f, rsa, ctx.get())) {
|
||||
goto err;
|
||||
}
|
||||
} else if (!BN_mod_exp_mont_consttime(result, f, rsa->d_fixed, rsa->n, ctx,
|
||||
rsa->mont_n)) {
|
||||
} else if (!BN_mod_exp_mont_consttime(result, f, rsa->d_fixed, rsa->n,
|
||||
ctx.get(), rsa->mont_n)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -634,17 +626,19 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
|
||||
//
|
||||
// This check is cheap assuming |e| is small, which we require in
|
||||
// |rsa_check_public_key|.
|
||||
if (rsa->e != NULL) {
|
||||
BIGNUM *vrfy = BN_CTX_get(ctx);
|
||||
if (vrfy == NULL ||
|
||||
!BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx, rsa->mont_n) ||
|
||||
if (rsa->e != nullptr) {
|
||||
BIGNUM *vrfy = BN_CTX_get(ctx.get());
|
||||
if (vrfy == nullptr ||
|
||||
!BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx.get(),
|
||||
rsa->mont_n) ||
|
||||
!constant_time_declassify_int(BN_equal_consttime(vrfy, f))) {
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_blinding && !BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx)) {
|
||||
if (do_blinding &&
|
||||
!BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx.get())) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -663,11 +657,7 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
if (blinding != NULL) {
|
||||
if (blinding != nullptr) {
|
||||
rsa_blinding_release(rsa, blinding, blinding_index);
|
||||
}
|
||||
|
||||
@@ -717,23 +707,19 @@ static int rsa_mod_exp_crt(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
|
||||
assert(rsa->dmq1 != NULL);
|
||||
assert(rsa->iqmp != NULL);
|
||||
|
||||
BIGNUM *r1, *m1;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
r1 = BN_CTX_get(ctx);
|
||||
m1 = BN_CTX_get(ctx);
|
||||
BIGNUM *n, *p, *q;
|
||||
bssl::BN_CTXScope scope(ctx);
|
||||
BIGNUM *r1 = BN_CTX_get(ctx);
|
||||
BIGNUM *m1 = BN_CTX_get(ctx);
|
||||
if (r1 == NULL || m1 == NULL) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Use the minimal-width versions of |n|, |p|, and |q|. Either works, but if
|
||||
// someone gives us non-minimal values, these will be slightly more efficient
|
||||
// on the non-Montgomery operations.
|
||||
n = &rsa->mont_n->N;
|
||||
p = &rsa->mont_p->N;
|
||||
q = &rsa->mont_q->N;
|
||||
BIGNUM *n = &rsa->mont_n->N;
|
||||
BIGNUM *p = &rsa->mont_p->N;
|
||||
BIGNUM *q = &rsa->mont_q->N;
|
||||
|
||||
// This is a pre-condition for |mod_montgomery|. It was already checked by the
|
||||
// caller.
|
||||
@@ -766,7 +752,7 @@ static int rsa_mod_exp_crt(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
|
||||
// [0, n).
|
||||
!bn_mul_consttime(r0, r0, q, ctx) || //
|
||||
!bn_uadd_consttime(r0, r0, m1)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The result should be bounded by |n|, but fixed-width operations may
|
||||
@@ -776,14 +762,10 @@ static int rsa_mod_exp_crt(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
|
||||
declassify_assert(BN_cmp(r0, n) < 0);
|
||||
bn_assert_fits_in_bytes(r0, BN_num_bytes(n));
|
||||
if (!bn_resize_words(r0, n->width)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ensure_bignum(BIGNUM **out) {
|
||||
@@ -914,11 +896,11 @@ static int generate_prime(BIGNUM *out, int bits, const BIGNUM *e,
|
||||
}
|
||||
int limit = BN_is_word(e, 3) ? bits * 8 : bits * 5;
|
||||
|
||||
int ret = 0, tries = 0, rand_tries = 0;
|
||||
BN_CTX_start(ctx);
|
||||
int tries = 0, rand_tries = 0;
|
||||
bssl::BN_CTXScope scope(ctx);
|
||||
BIGNUM *tmp = BN_CTX_get(ctx);
|
||||
if (tmp == NULL) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
@@ -927,13 +909,13 @@ static int generate_prime(BIGNUM *out, int bits, const BIGNUM *e,
|
||||
// bound checked below in steps 4.4 and 5.5).
|
||||
if (!BN_rand(out, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD) ||
|
||||
!BN_GENCB_call(cb, BN_GENCB_GENERATED, rand_tries++)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p != NULL) {
|
||||
// If |p| and |out| are too close, try again (step 5.4).
|
||||
if (!bn_abs_sub_consttime(tmp, out, p, ctx)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (BN_cmp(tmp, pow2_bits_100) <= 0) {
|
||||
continue;
|
||||
@@ -963,18 +945,17 @@ static int generate_prime(BIGNUM *out, int bits, const BIGNUM *e,
|
||||
int relatively_prime;
|
||||
if (!bn_usub_consttime(tmp, out, BN_value_one()) ||
|
||||
!bn_is_relatively_prime(&relatively_prime, tmp, e, ctx)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (constant_time_declassify_int(relatively_prime)) {
|
||||
// Test |out| for primality (steps 4.5.1 and 5.6.1).
|
||||
int is_probable_prime;
|
||||
if (!BN_primality_test(&is_probable_prime, out,
|
||||
BN_prime_checks_for_generation, ctx, 0, cb)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (is_probable_prime) {
|
||||
ret = 1;
|
||||
goto err;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -984,16 +965,12 @@ static int generate_prime(BIGNUM *out, int bits, const BIGNUM *e,
|
||||
tries++;
|
||||
if (tries >= limit) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (!BN_GENCB_call(cb, 2, tries)) {
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// rsa_generate_key_impl generates an RSA key using a generalized version of
|
||||
@@ -1029,29 +1006,31 @@ static int rsa_generate_key_impl(RSA *rsa, int bits, const BIGNUM *e_value,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
int prime_bits = bits / 2;
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
BIGNUM *totient, *pm1, *qm1, *sqrt2, *pow2_prime_bits_100, *pow2_prime_bits;
|
||||
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
|
||||
int sqrt2_bits;
|
||||
if (ctx == NULL) {
|
||||
goto bn_err;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
totient = BN_CTX_get(ctx);
|
||||
pm1 = BN_CTX_get(ctx);
|
||||
qm1 = BN_CTX_get(ctx);
|
||||
sqrt2 = BN_CTX_get(ctx);
|
||||
pow2_prime_bits_100 = BN_CTX_get(ctx);
|
||||
pow2_prime_bits = BN_CTX_get(ctx);
|
||||
if (totient == NULL || pm1 == NULL || qm1 == NULL || sqrt2 == NULL ||
|
||||
pow2_prime_bits_100 == NULL || pow2_prime_bits == NULL ||
|
||||
!BN_set_bit(pow2_prime_bits_100, prime_bits - 100) ||
|
||||
!BN_set_bit(pow2_prime_bits, prime_bits)) {
|
||||
goto bn_err;
|
||||
if (ctx == nullptr) {
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We need the RSA components non-NULL.
|
||||
int prime_bits = bits / 2;
|
||||
bssl::BN_CTXScope scope(ctx.get());
|
||||
BIGNUM *totient = BN_CTX_get(ctx.get());
|
||||
BIGNUM *pm1 = BN_CTX_get(ctx.get());
|
||||
BIGNUM *qm1 = BN_CTX_get(ctx.get());
|
||||
BIGNUM *sqrt2 = BN_CTX_get(ctx.get());
|
||||
BIGNUM *pow2_prime_bits_100 = BN_CTX_get(ctx.get());
|
||||
BIGNUM *pow2_prime_bits = BN_CTX_get(ctx.get());
|
||||
if (totient == nullptr || pm1 == nullptr || qm1 == nullptr ||
|
||||
sqrt2 == nullptr || pow2_prime_bits_100 == nullptr ||
|
||||
pow2_prime_bits == nullptr ||
|
||||
!BN_set_bit(pow2_prime_bits_100, prime_bits - 100) ||
|
||||
!BN_set_bit(pow2_prime_bits, prime_bits)) {
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We need the RSA components non-null.
|
||||
if (!ensure_bignum(&rsa->n) || //
|
||||
!ensure_bignum(&rsa->d) || //
|
||||
!ensure_bignum(&rsa->e) || //
|
||||
@@ -1060,16 +1039,19 @@ static int rsa_generate_key_impl(RSA *rsa, int bits, const BIGNUM *e_value,
|
||||
!ensure_bignum(&rsa->dmp1) || //
|
||||
!ensure_bignum(&rsa->dmq1) || //
|
||||
!ensure_bignum(&rsa->iqmp)) {
|
||||
goto bn_err;
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BN_copy(rsa->e, e_value)) {
|
||||
goto bn_err;
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Compute sqrt2 >= ⌊2^(prime_bits-1)×√2⌋.
|
||||
if (!bn_set_words(sqrt2, kBoringSSLRSASqrtTwo, kBoringSSLRSASqrtTwoLen)) {
|
||||
goto bn_err;
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
sqrt2_bits = kBoringSSLRSASqrtTwoLen * BN_BITS2;
|
||||
assert(sqrt2_bits == (int)BN_num_bits(sqrt2));
|
||||
@@ -1077,14 +1059,16 @@ static int rsa_generate_key_impl(RSA *rsa, int bits, const BIGNUM *e_value,
|
||||
// For key sizes up to 4096 (prime_bits = 2048), this is exactly
|
||||
// ⌊2^(prime_bits-1)×√2⌋.
|
||||
if (!BN_rshift(sqrt2, sqrt2, sqrt2_bits - prime_bits)) {
|
||||
goto bn_err;
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
} else if (prime_bits > sqrt2_bits) {
|
||||
// For key sizes beyond 4096, this is approximate. We err towards retrying
|
||||
// to ensure our key is the right size and round up.
|
||||
if (!BN_add_word(sqrt2, 1) ||
|
||||
!BN_lshift(sqrt2, sqrt2, prime_bits - sqrt2_bits)) {
|
||||
goto bn_err;
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
assert(prime_bits == (int)BN_num_bits(sqrt2));
|
||||
@@ -1095,13 +1079,14 @@ static int rsa_generate_key_impl(RSA *rsa, int bits, const BIGNUM *e_value,
|
||||
//
|
||||
// Each call to |generate_prime| fails with probability p = 2^-21. The
|
||||
// probability that either call fails is 1 - (1-p)^2, which is around 2^-20.
|
||||
if (!generate_prime(rsa->p, prime_bits, rsa->e, NULL, sqrt2,
|
||||
pow2_prime_bits_100, ctx, cb) ||
|
||||
if (!generate_prime(rsa->p, prime_bits, rsa->e, nullptr, sqrt2,
|
||||
pow2_prime_bits_100, ctx.get(), cb) ||
|
||||
!BN_GENCB_call(cb, 3, 0) ||
|
||||
!generate_prime(rsa->q, prime_bits, rsa->e, rsa->p, sqrt2,
|
||||
pow2_prime_bits_100, ctx, cb) ||
|
||||
pow2_prime_bits_100, ctx.get(), cb) ||
|
||||
!BN_GENCB_call(cb, 3, 1)) {
|
||||
goto bn_err;
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BN_cmp(rsa->p, rsa->q) < 0) {
|
||||
@@ -1120,9 +1105,11 @@ static int rsa_generate_key_impl(RSA *rsa, int bits, const BIGNUM *e_value,
|
||||
int no_inverse;
|
||||
if (!bn_usub_consttime(pm1, rsa->p, BN_value_one()) ||
|
||||
!bn_usub_consttime(qm1, rsa->q, BN_value_one()) ||
|
||||
!bn_lcm_consttime(totient, pm1, qm1, ctx) ||
|
||||
!bn_mod_inverse_consttime(rsa->d, &no_inverse, rsa->e, totient, ctx)) {
|
||||
goto bn_err;
|
||||
!bn_lcm_consttime(totient, pm1, qm1, ctx.get()) ||
|
||||
!bn_mod_inverse_consttime(rsa->d, &no_inverse, rsa->e, totient,
|
||||
ctx.get())) {
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Retry if |rsa->d| <= 2^|prime_bits|. See appendix B.3.1's guidance on
|
||||
@@ -1133,12 +1120,15 @@ static int rsa_generate_key_impl(RSA *rsa, int bits, const BIGNUM *e_value,
|
||||
assert(BN_num_bits(pm1) == (unsigned)prime_bits);
|
||||
assert(BN_num_bits(qm1) == (unsigned)prime_bits);
|
||||
if ( // Calculate n.
|
||||
!bn_mul_consttime(rsa->n, rsa->p, rsa->q, ctx) ||
|
||||
!bn_mul_consttime(rsa->n, rsa->p, rsa->q, ctx.get()) ||
|
||||
// Calculate d mod (p-1).
|
||||
!bn_div_consttime(NULL, rsa->dmp1, rsa->d, pm1, prime_bits, ctx) ||
|
||||
!bn_div_consttime(nullptr, rsa->dmp1, rsa->d, pm1, prime_bits,
|
||||
ctx.get()) ||
|
||||
// Calculate d mod (q-1)
|
||||
!bn_div_consttime(NULL, rsa->dmq1, rsa->d, qm1, prime_bits, ctx)) {
|
||||
goto bn_err;
|
||||
!bn_div_consttime(nullptr, rsa->dmq1, rsa->d, qm1, prime_bits,
|
||||
ctx.get())) {
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
bn_set_minimal_width(rsa->n);
|
||||
|
||||
@@ -1146,41 +1136,30 @@ static int rsa_generate_key_impl(RSA *rsa, int bits, const BIGNUM *e_value,
|
||||
bn_declassify(rsa->n);
|
||||
|
||||
// Calculate q^-1 mod p.
|
||||
rsa->mont_p = BN_MONT_CTX_new_consttime(rsa->p, ctx);
|
||||
if (rsa->mont_p == NULL || //
|
||||
!bn_mod_inverse_secret_prime(rsa->iqmp, rsa->q, rsa->p, ctx,
|
||||
rsa->mont_p = BN_MONT_CTX_new_consttime(rsa->p, ctx.get());
|
||||
if (rsa->mont_p == nullptr || //
|
||||
!bn_mod_inverse_secret_prime(rsa->iqmp, rsa->q, rsa->p, ctx.get(),
|
||||
rsa->mont_p)) {
|
||||
goto bn_err;
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sanity-check that |rsa->n| has the specified size. This is implied by
|
||||
// |generate_prime|'s bounds.
|
||||
if (BN_num_bits(rsa->n) != (unsigned)bits) {
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The key generation process is complex and thus error-prone. It could be
|
||||
// disastrous to generate and then use a bad key so double-check that the key
|
||||
// makes sense. Also, while |rsa| is mutable, fill in the cached components.
|
||||
if (!RSA_check_key(rsa) ||
|
||||
!freeze_private_key(rsa, ctx)) {
|
||||
if (!RSA_check_key(rsa) || !freeze_private_key(rsa, ctx.get())) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
bn_err:
|
||||
if (!ret) {
|
||||
OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
|
||||
}
|
||||
err:
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void replace_bignum(BIGNUM **out, BIGNUM **in) {
|
||||
|
||||
@@ -349,25 +349,21 @@ int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
|
||||
}
|
||||
|
||||
const unsigned rsa_size = RSA_size(rsa);
|
||||
BIGNUM *f, *result;
|
||||
uint8_t *buf = NULL;
|
||||
BN_CTX *ctx = NULL;
|
||||
int i, ret = 0;
|
||||
|
||||
if (max_out < rsa_size) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
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);
|
||||
f = BN_CTX_get(ctx);
|
||||
result = BN_CTX_get(ctx);
|
||||
buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(rsa_size));
|
||||
bssl::BN_CTXScope scope(ctx.get());
|
||||
BIGNUM *f = BN_CTX_get(ctx.get());
|
||||
BIGNUM *result = BN_CTX_get(ctx.get());
|
||||
uint8_t *buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(rsa_size));
|
||||
int i, ret = 0;
|
||||
if (!f || !result || !buf) {
|
||||
goto err;
|
||||
}
|
||||
@@ -378,8 +374,8 @@ int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
|
||||
break;
|
||||
case RSA_PKCS1_OAEP_PADDING:
|
||||
// Use the default parameters: SHA-1 for both hashes and no label.
|
||||
i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, NULL, 0,
|
||||
NULL, NULL);
|
||||
i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
break;
|
||||
case RSA_NO_PADDING:
|
||||
i = RSA_padding_add_none(buf, rsa_size, in, in_len);
|
||||
@@ -393,7 +389,7 @@ int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_bin2bn(buf, rsa_size, f) == NULL) {
|
||||
if (BN_bin2bn(buf, rsa_size, f) == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -403,8 +399,9 @@ int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ||
|
||||
!BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) {
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx.get()) ||
|
||||
!BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx.get(),
|
||||
rsa->mont_n)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -419,12 +416,7 @@ int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
OPENSSL_free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user