int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type)
{
unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL;
int Slen, Plen, Ilen, Ijlen;
int i, j, u, v;
int ret = 0;
BIGNUM *Ij = NULL, *Bpl1 = NULL; /* These hold Ij and B + 1 */
EVP_MD_CTX *ctx = NULL;
#ifdef OPENSSL_DEBUG_KEYGEN
unsigned char *tmpout = out;
int tmpn = n;
#endif
ctx = EVP_MD_CTX_new();
if (ctx == NULL)
goto err;
#ifdef OPENSSL_DEBUG_KEYGEN
fprintf(stderr, "KEYGEN DEBUG\n");
fprintf(stderr, "ID %d, ITER %d\n", id, iter);
fprintf(stderr, "Password (length %d):\n", passlen);
h__dump(pass, passlen);
fprintf(stderr, "Salt (length %d):\n", saltlen);
h__dump(salt, saltlen);
#endif
v = EVP_MD_block_size(md_type);
u = EVP_MD_size(md_type);
if (u < 0 || v <= 0)
goto err;
D = OPENSSL_malloc(v);
Ai = OPENSSL_malloc(u);
B = OPENSSL_malloc(v + 1);
Slen = v * ((saltlen + v - 1) / v);
if (passlen)
Plen = v * ((passlen + v - 1) / v);
else
Plen = 0;
Ilen = Slen + Plen;
I = OPENSSL_malloc(Ilen);
Ij = BN_new();
Bpl1 = BN_new();
if (D == NULL || Ai == NULL || B == NULL || I == NULL || Ij == NULL
|| Bpl1 == NULL)
goto err;
for (i = 0; i < v; i++)
D[i] = id;
p = I;
for (i = 0; i < Slen; i++)
*p++ = salt[i % saltlen];
for (i = 0; i < Plen; i++)
*p++ = pass[i % passlen];
for (;;) {
if (!EVP_DigestInit_ex(ctx, md_type, NULL)
|| !EVP_DigestUpdate(ctx, D, v)
|| !EVP_DigestUpdate(ctx, I, Ilen)
|| !EVP_DigestFinal_ex(ctx, Ai, NULL))
goto err;
for (j = 1; j < iter; j++) {
if (!EVP_DigestInit_ex(ctx, md_type, NULL)
|| !EVP_DigestUpdate(ctx, Ai, u)
|| !EVP_DigestFinal_ex(ctx, Ai, NULL))
goto err;
}
memcpy(out, Ai, min(n, u));
if (u >= n) {
#ifdef OPENSSL_DEBUG_KEYGEN
fprintf(stderr, "Output KEY (length %d)\n", tmpn);
h__dump(tmpout, tmpn);
#endif
ret = 1;
goto end;
}
n -= u;
out += u;
for (j = 0; j < v; j++)
B[j] = Ai[j % u];
/* Work out B + 1 first then can use B as tmp space */
if (!BN_bin2bn(B, v, Bpl1))
goto err;
if (!BN_add_word(Bpl1, 1))
goto err;
for (j = 0; j < Ilen; j += v) {
if (!BN_bin2bn(I + j, v, Ij))
goto err;
if (!BN_add(Ij, Ij, Bpl1))
goto err;
if (!BN_bn2bin(Ij, B))
goto err;
Ijlen = BN_num_bytes(Ij);
/* If more than 2^(v*8) - 1 cut off MSB */
if (Ijlen > v) {
if (!BN_bn2bin(Ij, B))
goto err;
memcpy(I + j, B + 1, v);
#ifndef PKCS12_BROKEN_KEYGEN
/* If less than v bytes pad with zeroes */
} else if (Ijlen < v) {
memset(I + j, 0, v - Ijlen);
//.........这里部分代码省略.........
int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
const BIGNUM *Xp, const BIGNUM *Xp1,
const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
BN_GENCB *cb)
{
int ret = 0;
BIGNUM *t, *p1p2, *pm1;
/* Only even e supported */
if (!BN_is_odd(e))
return 0;
BN_CTX_start(ctx);
if (!p1)
p1 = BN_CTX_get(ctx);
if (!p2)
p2 = BN_CTX_get(ctx);
t = BN_CTX_get(ctx);
p1p2 = BN_CTX_get(ctx);
pm1 = BN_CTX_get(ctx);
if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
goto err;
if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
goto err;
if (!BN_mul(p1p2, p1, p2, ctx))
goto err;
/* First set p to value of Rp */
if (!BN_mod_inverse(p, p2, p1, ctx))
goto err;
if (!BN_mul(p, p, p2, ctx))
goto err;
if (!BN_mod_inverse(t, p1, p2, ctx))
goto err;
if (!BN_mul(t, t, p1, ctx))
goto err;
if (!BN_sub(p, p, t))
goto err;
if (p->neg && !BN_add(p, p, p1p2))
goto err;
/* p now equals Rp */
if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
goto err;
if (!BN_add(p, p, Xp))
goto err;
/* p now equals Yp0 */
for (;;) {
int i = 1;
BN_GENCB_call(cb, 0, i++);
if (!BN_copy(pm1, p))
goto err;
if (!BN_sub_word(pm1, 1))
goto err;
if (!BN_gcd(t, pm1, e, ctx))
goto err;
if (BN_is_one(t)
/*
* X9.31 specifies 8 MR and 1 Lucas test or any prime test
* offering similar or better guarantees 50 MR is considerably
* better.
*/
&& BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
break;
if (!BN_add(p, p, p1p2))
goto err;
}
BN_GENCB_call(cb, 3, 0);
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
int
PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n, unsigned char *out,
const EVP_MD *md_type)
{
unsigned char *B, *D, *I, *p, *Ai;
int Slen, Plen, Ilen, Ijlen;
int i, j, u, v;
int ret = 0;
BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */
EVP_MD_CTX ctx;
#if 0
if (!pass) {
PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
#endif
EVP_MD_CTX_init(&ctx);
v = EVP_MD_block_size(md_type);
u = EVP_MD_size(md_type);
if (u < 0)
return 0;
D = malloc(v);
Ai = malloc(u);
B = malloc(v + 1);
Slen = v * ((saltlen + v - 1) / v);
if (passlen)
Plen = v * ((passlen + v - 1)/v);
else
Plen = 0;
Ilen = Slen + Plen;
I = malloc(Ilen);
Ij = BN_new();
Bpl1 = BN_new();
if (!D || !Ai || !B || !I || !Ij || !Bpl1)
goto err;
for (i = 0; i < v; i++)
D[i] = id;
p = I;
for (i = 0; i < Slen; i++)
*p++ = salt[i % saltlen];
for (i = 0; i < Plen; i++)
*p++ = pass[i % passlen];
for (;;) {
if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
!EVP_DigestUpdate(&ctx, D, v) ||
!EVP_DigestUpdate(&ctx, I, Ilen) ||
!EVP_DigestFinal_ex(&ctx, Ai, NULL))
goto err;
for (j = 1; j < iter; j++) {
if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
!EVP_DigestUpdate(&ctx, Ai, u) ||
!EVP_DigestFinal_ex(&ctx, Ai, NULL))
goto err;
}
memcpy (out, Ai, min (n, u));
if (u >= n) {
ret = 1;
goto end;
}
n -= u;
out += u;
for (j = 0; j < v; j++)
B[j] = Ai[j % u];
/* Work out B + 1 first then can use B as tmp space */
if (!BN_bin2bn (B, v, Bpl1))
goto err;
if (!BN_add_word (Bpl1, 1))
goto err;
for (j = 0; j < Ilen; j += v) {
if (!BN_bin2bn(I + j, v, Ij))
goto err;
if (!BN_add(Ij, Ij, Bpl1))
goto err;
if (!BN_bn2bin(Ij, B))
goto err;
Ijlen = BN_num_bytes (Ij);
/* If more than 2^(v*8) - 1 cut off MSB */
if (Ijlen > v) {
if (!BN_bn2bin (Ij, B))
goto err;
memcpy (I + j, B + 1, v);
#ifndef PKCS12_BROKEN_KEYGEN
/* If less than v bytes pad with zeroes */
} else if (Ijlen < v) {
memset(I + j, 0, v - Ijlen);
if (!BN_bn2bin(Ij, I + j + v - Ijlen))
goto err;
#endif
} else if (!BN_bn2bin (Ij, I + j))
goto err;
}
}
err:
PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE);
end:
//.........这里部分代码省略.........
static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
const BIGNUM *rem, BN_CTX *ctx) {
int i, 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);
if (qadd == NULL) {
goto err;
}
if (!BN_rshift1(qadd, padd)) {
goto err;
}
if (!BN_rand(q, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) {
goto err;
}
/* we need ((rnd-rem) % add) == 0 */
if (!BN_mod(t1, q, qadd, ctx)) {
goto err;
}
if (!BN_sub(q, q, t1)) {
goto err;
}
if (rem == NULL) {
if (!BN_add_word(q, 1)) {
goto err;
}
} else {
if (!BN_rshift1(t1, rem)) {
goto err;
}
if (!BN_add(q, q, t1)) {
goto err;
}
}
/* we now have a random number 'rand' to test. */
if (!BN_lshift1(p, q)) {
goto err;
}
if (!BN_add_word(p, 1)) {
goto err;
}
loop:
for (i = 1; i < NUMPRIMES; i++) {
/* check that p and q are prime */
/* check that for p and q
* gcd(p-1,primes) == 1 (except for 2) */
BN_ULONG pmod = BN_mod_word(p, (BN_ULONG)primes[i]);
BN_ULONG qmod = BN_mod_word(q, (BN_ULONG)primes[i]);
if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1) {
goto err;
}
if (pmod == 0 || qmod == 0) {
if (!BN_add(p, p, padd)) {
goto err;
}
if (!BN_add(q, q, qadd)) {
goto err;
}
goto loop;
}
}
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
BIGNUM **kinvp, BIGNUM **rp,
const unsigned char *dgst, int dlen)
{
BN_CTX *ctx = NULL;
BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
EC_POINT *tmp_point=NULL;
const EC_GROUP *group;
int ret = 0;
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (ctx_in == NULL)
{
if ((ctx = BN_CTX_new()) == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
return 0;
}
}
else
ctx = ctx_in;
k = BN_new(); /* this value is later returned in *kinvp */
r = BN_new(); /* this value is later returned in *rp */
order = BN_new();
X = BN_new();
if (!k || !r || !order || !X)
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
goto err;
}
if ((tmp_point = EC_POINT_new(group)) == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
do
{
/* get random k */
do
#ifndef OPENSSL_NO_SHA512
if (dgst != NULL)
{
if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
dgst, dlen, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
}
else
#endif
{
if (!BN_rand_range(k, order))
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
}
while (BN_is_zero(k));
/* We do not want timing information to leak the length of k,
* so we compute G*k using an equivalent scalar of fixed
* bit-length. */
if (!BN_add(k, k, order)) goto err;
if (BN_num_bits(k) <= BN_num_bits(order))
if (!BN_add(k, k, order)) goto err;
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
{
if (!EC_POINT_get_affine_coordinates_GFp(group,
tmp_point, X, NULL, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
goto err;
}
}
#ifndef OPENSSL_NO_EC2M
else /* NID_X9_62_characteristic_two_field */
{
//.........这里部分代码省略.........
static int
ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
BN_CTX *ctx = NULL;
BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
EC_POINT *tmp_point = NULL;
const EC_GROUP *group;
int ret = 0;
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
ECDSAerror(ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (ctx_in == NULL) {
if ((ctx = BN_CTX_new()) == NULL) {
ECDSAerror(ERR_R_MALLOC_FAILURE);
return 0;
}
} else
ctx = ctx_in;
k = BN_new(); /* this value is later returned in *kinvp */
r = BN_new(); /* this value is later returned in *rp */
order = BN_new();
X = BN_new();
if (!k || !r || !order || !X) {
ECDSAerror(ERR_R_MALLOC_FAILURE);
goto err;
}
if ((tmp_point = EC_POINT_new(group)) == NULL) {
ECDSAerror(ERR_R_EC_LIB);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
ECDSAerror(ERR_R_EC_LIB);
goto err;
}
do {
/* get random k */
do
if (!BN_rand_range(k, order)) {
ECDSAerror(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
while (BN_is_zero(k));
/* We do not want timing information to leak the length of k,
* so we compute G*k using an equivalent scalar of fixed
* bit-length. */
if (!BN_add(k, k, order))
goto err;
if (BN_num_bits(k) <= BN_num_bits(order))
if (!BN_add(k, k, order))
goto err;
BN_set_flags(k, BN_FLG_CONSTTIME);
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
ECDSAerror(ERR_R_EC_LIB);
goto err;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(group,
tmp_point, X, NULL, ctx)) {
ECDSAerror(ERR_R_EC_LIB);
goto err;
}
}
#ifndef OPENSSL_NO_EC2M
else /* NID_X9_62_characteristic_two_field */
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
tmp_point, X, NULL, ctx)) {
ECDSAerror(ERR_R_EC_LIB);
goto err;
}
}
#endif
if (!BN_nnmod(r, X, order, ctx)) {
ECDSAerror(ERR_R_BN_LIB);
goto err;
}
} while (BN_is_zero(r));
/* compute the inverse of k */
if (!BN_mod_inverse_ct(k, k, order, ctx)) {
ECDSAerror(ERR_R_BN_LIB);
goto err;
}
/* clear old values if necessary */
BN_clear_free(*rp);
BN_clear_free(*kinvp);
/* save the pre-computed values */
*rp = r;
*kinvp = k;
ret = 1;
//.........这里部分代码省略.........
static int ecdsa_sign_setup(const EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp, const uint8_t *digest,
size_t digest_len) {
BN_CTX *ctx = NULL;
BIGNUM *k = NULL, *kinv = NULL, *r = NULL, *tmp = NULL;
EC_POINT *tmp_point = NULL;
const EC_GROUP *group;
int ret = 0;
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (ctx_in == NULL) {
if ((ctx = BN_CTX_new()) == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
ctx = ctx_in;
}
k = BN_new();
kinv = BN_new(); // this value is later returned in *kinvp
r = BN_new(); // this value is later returned in *rp
tmp = BN_new();
if (k == NULL || kinv == NULL || r == NULL || tmp == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
tmp_point = EC_POINT_new(group);
if (tmp_point == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
const BIGNUM *order = EC_GROUP_get0_order(group);
// Check that the size of the group order is FIPS compliant (FIPS 186-4
// B.5.2).
if (BN_num_bits(order) < 160) {
OPENSSL_PUT_ERROR(ECDSA, EC_R_INVALID_GROUP_ORDER);
goto err;
}
do {
// If possible, we'll include the private key and message digest in the k
// generation. The |digest| argument is only empty if |ECDSA_sign_setup| is
// being used.
if (eckey->fixed_k != NULL) {
if (!BN_copy(k, eckey->fixed_k)) {
goto err;
}
} else if (digest_len > 0) {
do {
if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
digest, digest_len, ctx)) {
OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
} while (BN_is_zero(k));
} else if (!BN_rand_range_ex(k, 1, order)) {
OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
// Compute the inverse of k. The order is a prime, so use Fermat's Little
// Theorem. Note |ec_group_get_order_mont| may return NULL but
// |bn_mod_inverse_prime| allows this.
if (!bn_mod_inverse_prime(kinv, k, order, ctx,
ec_group_get_order_mont(group))) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
// We do not want timing information to leak the length of k,
// so we compute G*k using an equivalent scalar of fixed
// bit-length.
if (!BN_add(k, k, order)) {
goto err;
}
if (BN_num_bits(k) <= BN_num_bits(order)) {
if (!BN_add(k, k, order)) {
goto err;
}
}
// compute r the x-coordinate of generator * k
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, tmp, NULL,
ctx)) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
//.........这里部分代码省略.........
static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
{
BIGNUM *r1,*m1,*vrfy;
BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
BIGNUM *dmp1,*dmq1,*c,*pr1;
int ret=0;
BN_CTX_start(ctx);
r1 = BN_CTX_get(ctx);
m1 = BN_CTX_get(ctx);
vrfy = BN_CTX_get(ctx);
{
BIGNUM local_p, local_q;
BIGNUM *p = NULL, *q = NULL;
/* Make sure BN_mod_inverse in Montgomery intialization uses the
* BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set)
*/
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
BN_init(&local_p);
p = &local_p;
BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
BN_init(&local_q);
q = &local_q;
BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
}
else
{
p = rsa->p;
q = rsa->q;
}
if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
{
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
goto err;
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
goto err;
}
}
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
goto err;
/* compute I mod q */
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
c = &local_c;
BN_with_flags(c, I, BN_FLG_CONSTTIME);
if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
}
else
{
if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
}
/* compute r1^dmq1 mod q */
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
dmq1 = &local_dmq1;
BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
}
else
dmq1 = rsa->dmq1;
if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
rsa->_method_mod_q)) goto err;
/* compute I mod p */
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
c = &local_c;
BN_with_flags(c, I, BN_FLG_CONSTTIME);
if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
}
else
{
if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
}
/* compute r1^dmp1 mod p */
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
dmp1 = &local_dmp1;
BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
}
else
dmp1 = rsa->dmp1;
if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
rsa->_method_mod_p)) goto err;
if (!BN_sub(r0,r0,m1)) goto err;
/* This will help stop the size of r0 increasing, which does
* affect the multiply if it optimised for a power of 2 size */
if (BN_is_negative(r0))
if (!BN_add(r0,r0,rsa->p)) goto err;
//.........这里部分代码省略.........
请发表评论