BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) { BIGNUM local_n; BIGNUM *e,*n; BN_CTX *ctx; BN_BLINDING *ret = NULL; if (in_ctx == NULL) { if ((ctx = BN_CTX_new()) == NULL) return 0; } else ctx = in_ctx; BN_CTX_start(ctx); e = BN_CTX_get(ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); goto err; } if (rsa->e == NULL) { e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); goto err; } } else e = rsa->e; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { /* Set BN_FLG_CONSTTIME flag */ n = &local_n; BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); } else n = rsa->n; ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp, rsa->_method_mod_n); if (ret == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); goto err; } CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); err: BN_CTX_end(ctx); if (in_ctx == NULL) BN_CTX_free(ctx); if(rsa->e == NULL) BN_free(e); return ret; }
BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx) { BIGNUM local_n; BIGNUM *e, *n; BN_CTX *ctx; BN_BLINDING *ret = NULL; BN_MONT_CTX *mont_ctx = NULL; if (in_ctx == NULL) { ctx = BN_CTX_new(); if (ctx == NULL) { return 0; } } else { ctx = in_ctx; } BN_CTX_start(ctx); e = BN_CTX_get(ctx); if (e == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (rsa->e == NULL) { e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); if (e == NULL) { OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT); goto err; } } else { e = rsa->e; } n = &local_n; BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { mont_ctx = BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx); if (mont_ctx == NULL) { goto err; } } ret = BN_BLINDING_create_param(NULL, e, n, ctx, mont_ctx); if (ret == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB); goto err; } err: BN_CTX_end(ctx); if (in_ctx == NULL) { BN_CTX_free(ctx); } if (rsa->e == NULL) { BN_free(e); } return ret; }
BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) { BIGNUM local_n; BIGNUM *e, *n; BN_CTX *ctx; BN_BLINDING *ret = NULL; if (in_ctx == NULL) { if ((ctx = BN_CTX_new()) == NULL) return 0; } else ctx = in_ctx; BN_CTX_start(ctx); e = BN_CTX_get(ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); goto err; } if (rsa->e == NULL) { e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); goto err; } } else e = rsa->e; if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) { /* * if PRNG is not properly seeded, resort to secret exponent as * unpredictable seed */ RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0); } if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { /* Set BN_FLG_CONSTTIME flag */ n = &local_n; BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); } else n = rsa->n; ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp, rsa->_method_mod_n); if (ret == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); goto err; } CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); err: BN_CTX_end(ctx); if (in_ctx == NULL) BN_CTX_free(ctx); if (rsa->e == NULL) BN_free(e); return ret; }
BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) { BIGNUM *e; BN_CTX *ctx; BN_BLINDING *ret = NULL; if (in_ctx == NULL) { if ((ctx = BN_CTX_new()) == NULL) return 0; } else ctx = in_ctx; BN_CTX_start(ctx); e = BN_CTX_get(ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); goto err; } if (rsa->e == NULL) { e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); goto err; } } else e = rsa->e; { BIGNUM *n = BN_new(); if (n == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp, rsa->_method_mod_n); /* We MUST free n before any further use of rsa->n */ BN_free(n); } if (ret == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); goto err; } BN_BLINDING_set_current_thread(ret); err: BN_CTX_end(ctx); if (ctx != in_ctx) BN_CTX_free(ctx); if (e != rsa->e) BN_free(e); return ret; }
static int dsa_builtin_keygen(DSA *dsa) { int ok = 0; BN_CTX *ctx = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; if ((ctx = BN_CTX_new()) == NULL) goto err; if (dsa->priv_key == NULL) { if ((priv_key = BN_secure_new()) == NULL) goto err; } else priv_key = dsa->priv_key; do if (!BN_rand_range(priv_key, dsa->q)) goto err; while (BN_is_zero(priv_key)) ; if (dsa->pub_key == NULL) { if ((pub_key = BN_new()) == NULL) goto err; } else pub_key = dsa->pub_key; { BIGNUM *local_prk = NULL; BIGNUM *prk; if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { local_prk = prk = BN_new(); if (!local_prk) goto err; BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); } else prk = priv_key; if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) { BN_free(local_prk); goto err; } BN_free(local_prk); } dsa->priv_key = priv_key; dsa->pub_key = pub_key; ok = 1; err: if (pub_key != dsa->pub_key) BN_free(pub_key); if (priv_key != dsa->priv_key) BN_free(priv_key); BN_CTX_free(ctx); return (ok); }
int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { BIGNUM *f, *result; BN_CTX *ctx = NULL; unsigned blinding_index = 0; BN_BLINDING *blinding = NULL; int ret = 0; ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); f = BN_CTX_get(ctx); result = BN_CTX_get(ctx); if (f == NULL || result == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (BN_bin2bn(in, len, f) == NULL) { goto err; } if (BN_ucmp(f, rsa->n) >= 0) { /* Usually the padding functions would catch this. */ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } /* 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. * The callers that require that bad behavior set |RSA_FLAG_NO_BLINDING|. */ int disable_security = (rsa->flags & RSA_FLAG_NO_BLINDING) && rsa->e == NULL; if (!disable_security) { /* Keys without public exponents must have blinding explicitly disabled to * be used. */ if (rsa->e == NULL) { OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT); goto err; } blinding = rsa_blinding_get(rsa, &blinding_index, ctx); if (blinding == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) { goto err; } } if (rsa->p != NULL && rsa->q != NULL && rsa->e != NULL && rsa->dmp1 != NULL && rsa->dmq1 != NULL && rsa->iqmp != NULL) { if (!mod_exp(result, f, rsa, ctx)) { goto err; } } else { BIGNUM local_d; BIGNUM *d = NULL; BN_init(&local_d); d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (!BN_mod_exp_mont_consttime(result, f, d, rsa->n, ctx, rsa->mont_n)) { goto err; } } /* Verify the result to protect against fault attacks as described in the * 1997 paper "On the Importance of Checking Cryptographic Protocols for * Faults" by Dan Boneh, Richard A. DeMillo, and Richard J. Lipton. Some * implementations do this only when the CRT is used, but we do it in all * cases. Section 6 of the aforementioned paper describes an attack that * works when the CRT isn't used. That attack is much less likely to succeed * than the CRT attack, but there have likely been improvements since 1997. * * This check is cheap assuming |e| is small; it almost always is. */ if (!disable_security) { BIGNUM *vrfy = BN_CTX_get(ctx); if (vrfy == NULL || !BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx, rsa->mont_n) || !BN_equal_consttime(vrfy, f)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } if (!BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx)) { goto err; } } if (!BN_bn2bin_padded(out, len, result)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } ret = 1; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (blinding != NULL) { rsa_blinding_release(rsa, blinding, blinding_index); } return ret; }
static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { assert(ctx != NULL); assert(rsa->n != NULL); assert(rsa->e != NULL); assert(rsa->d != NULL); assert(rsa->p != NULL); assert(rsa->q != NULL); assert(rsa->dmp1 != NULL); assert(rsa->dmq1 != NULL); assert(rsa->iqmp != NULL); BIGNUM *r1, *m1, *vrfy; BIGNUM local_dmp1, local_dmq1, local_c, local_r1; BIGNUM *dmp1, *dmq1, *c, *pr1; int ret = 0; size_t i, num_additional_primes = 0; if (rsa->additional_primes != NULL) { num_additional_primes = sk_RSA_additional_prime_num(rsa->additional_primes); } BN_CTX_start(ctx); r1 = BN_CTX_get(ctx); m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); if (r1 == NULL || m1 == NULL || vrfy == NULL) { goto err; } { BIGNUM local_p, local_q; BIGNUM *p = NULL, *q = NULL; /* Make sure BN_mod in Montgomery initialization uses BN_FLG_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); if (!BN_MONT_CTX_set_locked(&rsa->mont_p, &rsa->lock, p, ctx) || !BN_MONT_CTX_set_locked(&rsa->mont_q, &rsa->lock, q, ctx)) { goto err; } } if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx)) { goto err; } /* compute I mod q */ c = &local_c; BN_with_flags(c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, c, rsa->q, ctx)) { goto err; } /* compute r1^dmq1 mod q */ dmq1 = &local_dmq1; BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); if (!BN_mod_exp_mont_consttime(m1, r1, dmq1, rsa->q, ctx, rsa->mont_q)) { goto err; } /* compute I mod p */ c = &local_c; BN_with_flags(c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, c, rsa->p, ctx)) { goto err; } /* compute r1^dmp1 mod p */ dmp1 = &local_dmp1; BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); if (!BN_mod_exp_mont_consttime(r0, r1, dmp1, rsa->p, ctx, rsa->mont_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; } } if (!BN_mul(r1, r0, rsa->iqmp, ctx)) { goto err; } /* Turn BN_FLG_CONSTTIME flag on before division operation */ pr1 = &local_r1; BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); if (!BN_mod(r0, pr1, rsa->p, ctx)) { goto err; } /* If p < q it is occasionally possible for the correction of * adding 'p' if r0 is negative above to leave the result still * negative. This can break the private key operations: the following * second correction should *always* correct this rare occurrence. * This will *never* happen with OpenSSL generated keys because * they ensure p > q [steve] */ if (BN_is_negative(r0)) { if (!BN_add(r0, r0, rsa->p)) { goto err; } } if (!BN_mul(r1, r0, rsa->q, ctx)) { goto err; } if (!BN_add(r0, r1, m1)) { goto err; } for (i = 0; i < num_additional_primes; i++) { /* multi-prime RSA. */ BIGNUM local_exp, local_prime; BIGNUM *exp = &local_exp, *prime = &local_prime; RSA_additional_prime *ap = sk_RSA_additional_prime_value(rsa->additional_primes, i); BN_with_flags(exp, ap->exp, BN_FLG_CONSTTIME); BN_with_flags(prime, ap->prime, BN_FLG_CONSTTIME); /* c will already point to a BIGNUM with the correct flags. */ if (!BN_mod(r1, c, prime, ctx)) { goto err; } if (!BN_MONT_CTX_set_locked(&ap->mont, &rsa->lock, prime, ctx) || !BN_mod_exp_mont_consttime(m1, r1, exp, prime, ctx, ap->mont)) { goto err; } BN_set_flags(m1, BN_FLG_CONSTTIME); if (!BN_sub(m1, m1, r0) || !BN_mul(m1, m1, ap->coeff, ctx) || !BN_mod(m1, m1, prime, ctx) || (BN_is_negative(m1) && !BN_add(m1, m1, prime)) || !BN_mul(m1, m1, ap->r, ctx) || !BN_add(r0, r0, m1)) { goto err; } } ret = 1; err: BN_CTX_end(ctx); return ret; }
static int eay_dh_generate_key(DH *dh) { int ok = 0; int generate_new_key = 0; unsigned l; BN_CTX *ctx; #if 0 BN_MONT_CTX *mont = NULL; #endif BIGNUM *pub_key = NULL, *priv_key = NULL; ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } if (dh->priv_key == NULL) { priv_key = BN_new(); if (priv_key == NULL) { goto err; } generate_new_key = 1; } else{ priv_key = dh->priv_key; } if (dh->pub_key == NULL) { pub_key = BN_new(); if (pub_key == NULL) { goto err; } } else{ pub_key = dh->pub_key; } #if 0 if (dh->flags & DH_FLAG_CACHE_MONT_P) { mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, CRYPTO_LOCK_DH, dh->p, ctx); if (!mont) { goto err; } } #endif if (generate_new_key) { l = dh->length ? dh->length : BN_num_bits(dh->p) - 1; /* secret exponent length */ if (!BN_rand(priv_key, l, 0, 0)) { goto err; } } { BIGNUM local_prk; BIGNUM *prk; #if 0 if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { BN_init(&local_prk); prk = &local_prk; BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); } else #endif prk = priv_key; if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx /* , mont */)) { goto err; } } dh->pub_key = pub_key; dh->priv_key = priv_key; ok = 1; err: /* * if (ok != 1) * DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB); */ if ((pub_key != NULL) && (dh->pub_key == NULL)) { BN_clear_free(pub_key); } if ((priv_key != NULL) && (dh->priv_key == NULL)) { BN_clear_free(priv_key); } BN_CTX_free(ctx); return (ok); }
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; if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err; /* Turn BN_FLG_CONSTTIME flag on before division operation */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { pr1 = &local_r1; BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); } else pr1 = r1; if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err; /* If p < q it is occasionally possible for the correction of * adding 'p' if r0 is negative above to leave the result still * negative. This can break the private key operations: the following * second correction should *always* correct this rare occurrence. * This will *never* happen with OpenSSL generated keys because * they ensure p > q [steve] */ if (BN_is_negative(r0)) if (!BN_add(r0,r0,rsa->p)) goto err; if (!BN_mul(r1,r0,rsa->q,ctx)) goto err; if (!BN_add(r0,r1,m1)) goto err; if (rsa->e && rsa->n) { if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err; /* If 'I' was greater than (or equal to) rsa->n, the operation * will be equivalent to using 'I mod n'. However, the result of * the verify will *always* be less than 'n' so we don't check * for absolute equality, just congruency. */ if (!BN_sub(vrfy, vrfy, I)) goto err; if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; if (BN_is_negative(vrfy)) if (!BN_add(vrfy, vrfy, rsa->n)) goto err; if (!BN_is_zero(vrfy)) { /* 'I' and 'vrfy' aren't congruent mod n. Don't leak * miscalculated CRT output, just do a raw (slower) * mod_exp and return that instead. */ BIGNUM local_d; BIGNUM *d = NULL; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; } } ret=1; err: BN_CTX_end(ctx); return(ret); }
static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { BIGNUM *r1, *m1, *vrfy, *r2, *m[RSA_MAX_PRIME_NUM - 2]; int ret = 0, i, ex_primes = 0, smooth = 0; RSA_PRIME_INFO *pinfo; BN_CTX_start(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); if (vrfy == NULL) goto err; if (rsa->version == RSA_ASN1_VERSION_MULTI && ((ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) <= 0 || ex_primes > RSA_MAX_PRIME_NUM - 2)) goto err; if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { BIGNUM *factor = BN_new(); if (factor == NULL) goto err; /* * Make sure BN_mod_inverse in Montgomery initialization uses the * BN_FLG_CONSTTIME flag */ if (!(BN_with_flags(factor, rsa->p, BN_FLG_CONSTTIME), BN_MONT_CTX_set_locked(&rsa->_method_mod_p, rsa->lock, factor, ctx)) || !(BN_with_flags(factor, rsa->q, BN_FLG_CONSTTIME), BN_MONT_CTX_set_locked(&rsa->_method_mod_q, rsa->lock, factor, ctx))) { BN_free(factor); goto err; } for (i = 0; i < ex_primes; i++) { pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); BN_with_flags(factor, pinfo->r, BN_FLG_CONSTTIME); if (!BN_MONT_CTX_set_locked(&pinfo->m, rsa->lock, factor, ctx)) { BN_free(factor); goto err; } } /* * We MUST free |factor| before any further use of the prime factors */ BN_free(factor); smooth = (ex_primes == 0) && (rsa->meth->bn_mod_exp == BN_mod_exp_mont) && (BN_num_bits(rsa->q) == BN_num_bits(rsa->p)); } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) goto err; if (smooth) { /* * Conversion from Montgomery domain, a.k.a. Montgomery reduction, * accepts values in [0-m*2^w) range. w is m's bit width rounded up * to limb width. So that at the very least if |I| is fully reduced, * i.e. less than p*q, we can count on from-to round to perform * below modulo operations on |I|. Unlike BN_mod it's constant time. */ if (/* m1 = I moq q */ !bn_from_mont_fixed_top(m1, I, rsa->_method_mod_q, ctx) || !bn_to_mont_fixed_top(m1, m1, rsa->_method_mod_q, ctx) /* m1 = m1^dmq1 mod q */ || !BN_mod_exp_mont_consttime(m1, m1, rsa->dmq1, rsa->q, ctx, rsa->_method_mod_q) /* r1 = I mod p */ || !bn_from_mont_fixed_top(r1, I, rsa->_method_mod_p, ctx) || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) /* r1 = r1^dmp1 mod p */ || !BN_mod_exp_mont_consttime(r1, r1, rsa->dmp1, rsa->p, ctx, rsa->_method_mod_p) /* r1 = (r1 - m1) mod p */ /* * bn_mod_sub_fixed_top is not regular modular subtraction, * it can tolerate subtrahend to be larger than modulus, but * not bit-wise wider. This makes up for uncommon q>p case, * when |m1| can be larger than |rsa->p|. */ || !bn_mod_sub_fixed_top(r1, r1, m1, rsa->p) /* r1 = r1 * iqmp mod p */ || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) || !bn_mul_mont_fixed_top(r1, r1, rsa->iqmp, rsa->_method_mod_p, ctx) /* r0 = r1 * q + m1 */ || !bn_mul_fixed_top(r0, r1, rsa->q, ctx) || !bn_mod_add_fixed_top(r0, r0, m1, rsa->n)) goto err; goto tail; } /* compute I mod q */ { BIGNUM *c = BN_new(); if (c == NULL) goto err; BN_with_flags(c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, c, rsa->q, ctx)) { BN_free(c); goto err; } { BIGNUM *dmq1 = BN_new(); if (dmq1 == NULL) { BN_free(c); goto err; } BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); /* compute r1^dmq1 mod q */ if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) { BN_free(c); BN_free(dmq1); goto err; } /* We MUST free dmq1 before any further use of rsa->dmq1 */ BN_free(dmq1); } /* compute I mod p */ if (!BN_mod(r1, c, rsa->p, ctx)) { BN_free(c); goto err; } /* We MUST free c before any further use of I */ BN_free(c); } { BIGNUM *dmp1 = BN_new(); if (dmp1 == NULL) goto err; BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); /* compute r1^dmp1 mod p */ if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p)) { BN_free(dmp1); goto err; } /* We MUST free dmp1 before any further use of rsa->dmp1 */ BN_free(dmp1); } /* * calculate m_i in multi-prime case * * TODO: * 1. squash the following two loops and calculate |m_i| there. * 2. remove cc and reuse |c|. * 3. remove |dmq1| and |dmp1| in previous block and use |di|. * * If these things are done, the code will be more readable. */ if (ex_primes > 0) { BIGNUM *di = BN_new(), *cc = BN_new(); if (cc == NULL || di == NULL) { BN_free(cc); BN_free(di); goto err; } for (i = 0; i < ex_primes; i++) { /* prepare m_i */ if ((m[i] = BN_CTX_get(ctx)) == NULL) { BN_free(cc); BN_free(di); goto err; } pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); /* prepare c and d_i */ BN_with_flags(cc, I, BN_FLG_CONSTTIME); BN_with_flags(di, pinfo->d, BN_FLG_CONSTTIME); if (!BN_mod(r1, cc, pinfo->r, ctx)) { BN_free(cc); BN_free(di); goto err; } /* compute r1 ^ d_i mod r_i */ if (!rsa->meth->bn_mod_exp(m[i], r1, di, pinfo->r, ctx, pinfo->m)) { BN_free(cc); BN_free(di); goto err; } } BN_free(cc); BN_free(di); } 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; if (!BN_mul(r1, r0, rsa->iqmp, ctx)) goto err; { BIGNUM *pr1 = BN_new(); if (pr1 == NULL) goto err; BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); if (!BN_mod(r0, pr1, rsa->p, ctx)) { BN_free(pr1); goto err; } /* We MUST free pr1 before any further use of r1 */ BN_free(pr1); } /* * If p < q it is occasionally possible for the correction of adding 'p' * if r0 is negative above to leave the result still negative. This can * break the private key operations: the following second correction * should *always* correct this rare occurrence. This will *never* happen * with OpenSSL generated keys because they ensure p > q [steve] */ if (BN_is_negative(r0)) if (!BN_add(r0, r0, rsa->p)) goto err; if (!BN_mul(r1, r0, rsa->q, ctx)) goto err; if (!BN_add(r0, r1, m1)) goto err; /* add m_i to m in multi-prime case */ if (ex_primes > 0) { BIGNUM *pr2 = BN_new(); if (pr2 == NULL) goto err; for (i = 0; i < ex_primes; i++) { pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); if (!BN_sub(r1, m[i], r0)) { BN_free(pr2); goto err; } if (!BN_mul(r2, r1, pinfo->t, ctx)) { BN_free(pr2); goto err; } BN_with_flags(pr2, r2, BN_FLG_CONSTTIME); if (!BN_mod(r1, pr2, pinfo->r, ctx)) { BN_free(pr2); goto err; } if (BN_is_negative(r1)) if (!BN_add(r1, r1, pinfo->r)) { BN_free(pr2); goto err; } if (!BN_mul(r1, r1, pinfo->pp, ctx)) { BN_free(pr2); goto err; } if (!BN_add(r0, r0, r1)) { BN_free(pr2); goto err; } } BN_free(pr2); } tail: if (rsa->e && rsa->n) { if (rsa->meth->bn_mod_exp == BN_mod_exp_mont) { if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) goto err; } else { bn_correct_top(r0); if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) goto err; } /* * If 'I' was greater than (or equal to) rsa->n, the operation will * be equivalent to using 'I mod n'. However, the result of the * verify will *always* be less than 'n' so we don't check for * absolute equality, just congruency. */ if (!BN_sub(vrfy, vrfy, I)) goto err; if (BN_is_zero(vrfy)) { bn_correct_top(r0); ret = 1; goto err; /* not actually error */ } if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; if (BN_is_negative(vrfy)) if (!BN_add(vrfy, vrfy, rsa->n)) goto err; if (!BN_is_zero(vrfy)) { /* * 'I' and 'vrfy' aren't congruent mod n. Don't leak * miscalculated CRT output, just do a raw (slower) mod_exp and * return that instead. */ BIGNUM *d = BN_new(); if (d == NULL) goto err; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(d); goto err; } /* We MUST free d before any further use of rsa->d */ BN_free(d); } } /* * It's unfortunate that we have to bn_correct_top(r0). What hopefully * saves the day is that correction is highly unlike, and private key * operations are customarily performed on blinded message. Which means * that attacker won't observe correlation with chosen plaintext. * Secondly, remaining code would still handle it in same computational * time and even conceal memory access pattern around corrected top. */ bn_correct_top(r0); ret = 1; err: BN_CTX_end(ctx); return ret; }
static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { BIGNUM *r1, *m1, *vrfy; 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); if (r1 == NULL || m1 == NULL || vrfy == NULL) { RSAerr(RSA_F_RSA_EAY_MOD_EXP, ERR_R_MALLOC_FAILURE); goto err; } { BIGNUM p, q; /* * Make sure BN_mod_inverse in Montgomery intialization uses the * BN_FLG_CONSTTIME flag */ BN_init(&p); BN_init(&q); BN_with_flags(&p, rsa->p, BN_FLG_CONSTTIME); BN_with_flags(&q, rsa->q, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, &p, ctx) || !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 */ BN_init(&c); BN_with_flags(&c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, &c, rsa->q, ctx)) goto err; /* compute r1^dmq1 mod q */ BN_init(&dmq1); BN_with_flags(&dmq1, rsa->dmq1, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(m1, r1, &dmq1, rsa->q, ctx, rsa->_method_mod_q)) goto err; /* compute I mod p */ BN_with_flags(&c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, &c, rsa->p, ctx)) goto err; /* compute r1^dmp1 mod p */ BN_init(&dmp1); BN_with_flags(&dmp1, rsa->dmp1, BN_FLG_CONSTTIME); 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; if (!BN_mul(r1, r0, rsa->iqmp, ctx)) goto err; /* Turn BN_FLG_CONSTTIME flag on before division operation */ BN_init(&pr1); BN_with_flags(&pr1, r1, BN_FLG_CONSTTIME); if (!BN_mod(r0, &pr1, rsa->p, ctx)) goto err; /* * If p < q it is occasionally possible for the correction of * adding 'p' if r0 is negative above to leave the result still * negative. This can break the private key operations: the following * second correction should *always* correct this rare occurrence. * This will *never* happen with OpenSSL generated keys because * they ensure p > q [steve] */ if (BN_is_negative(r0)) if (!BN_add(r0, r0, rsa->p)) goto err; if (!BN_mul(r1, r0, rsa->q, ctx)) goto err; if (!BN_add(r0, r1, m1)) goto err; if (rsa->e && rsa->n) { if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) goto err; /* * If 'I' was greater than (or equal to) rsa->n, the operation * will be equivalent to using 'I mod n'. However, the result of * the verify will *always* be less than 'n' so we don't check * for absolute equality, just congruency. */ if (!BN_sub(vrfy, vrfy, I)) goto err; if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; if (BN_is_negative(vrfy)) if (!BN_add(vrfy, vrfy, rsa->n)) goto err; if (!BN_is_zero(vrfy)) { /* * 'I' and 'vrfy' aren't congruent mod n. Don't leak * miscalculated CRT output, just do a raw (slower) * mod_exp and return that instead. */ BIGNUM d; BN_init(&d); BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(r0, I, &d, rsa->n, ctx, rsa->_method_mod_n)) { goto err; } } } ret = 1; err: BN_CTX_end(ctx); return ret; }
static int RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret, *br; int j,num=0,r= -1; unsigned char *p; unsigned char *buf=NULL; BN_CTX *ctx=NULL; int local_blinding = 0; BN_BLINDING *blinding = NULL; if((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); br = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if(!f || !ret || !buf) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); goto err; } /* This check was for equality but PGP does evil things * and chops off the top '0' bytes */ if (flen > num) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } /* make data into a big number */ if (BN_bin2bn(from,(int)flen,f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) goto err; /* do the decrypt */ if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL)) ) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM local_d; BIGNUM *d = NULL; if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME); } else d = rsa->d; MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; } if (blinding) if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) goto err; p=buf; j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */ switch (padding) { case RSA_PKCS1_PADDING: r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num); break; #ifndef OPENSSL_NO_SHA case RSA_PKCS1_OAEP_PADDING: r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0); break; #endif case RSA_SSLV23_PADDING: r=RSA_padding_check_SSLv23(to,num,buf,j,num); break; case RSA_NO_PADDING: r=RSA_padding_check_none(to,num,buf,j,num); break; default: RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (buf != NULL) { OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); }
/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. * It does not contain branches that may leak sensitive information. */ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) { BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL; BIGNUM local_A, local_B; BIGNUM *pA, *pB; BIGNUM *ret=NULL; int sign; bn_check_top(a); bn_check_top(n); BN_CTX_start(ctx); A = BN_CTX_get(ctx); B = BN_CTX_get(ctx); X = BN_CTX_get(ctx); D = BN_CTX_get(ctx); M = BN_CTX_get(ctx); Y = BN_CTX_get(ctx); T = BN_CTX_get(ctx); if (T == NULL) goto err; if (in == NULL) R=BN_new(); else R=in; if (R == NULL) goto err; BN_one(X); BN_zero(Y); if (BN_copy(B,a) == NULL) goto err; if (BN_copy(A,n) == NULL) goto err; A->neg = 0; if (B->neg || (BN_ucmp(B, A) >= 0)) { /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, * BN_div_no_branch will be called eventually. */ pB = &local_B; BN_with_flags(pB, B, BN_FLG_CONSTTIME); if (!BN_nnmod(B, pB, A, ctx)) goto err; } sign = -1; /* From B = a mod |n|, A = |n| it follows that * * 0 <= B < A, * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). */ while (!BN_is_zero(B)) { BIGNUM *tmp; /* * 0 < B < A, * (*) -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|) */ /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, * BN_div_no_branch will be called eventually. */ pA = &local_A; BN_with_flags(pA, A, BN_FLG_CONSTTIME); /* (D, M) := (A/B, A%B) ... */ if (!BN_div(D,M,pA,B,ctx)) goto err; /* Now * A = D*B + M; * thus we have * (**) sign*Y*a == D*B + M (mod |n|). */ tmp=A; /* keep the BIGNUM object, the value does not matter */ /* (A, B) := (B, A mod B) ... */ A=B; B=M; /* ... so we have 0 <= B < A again */ /* Since the former M is now B and the former B is now A, * (**) translates into * sign*Y*a == D*A + B (mod |n|), * i.e. * sign*Y*a - D*A == B (mod |n|). * Similarly, (*) translates into * -sign*X*a == A (mod |n|). * * Thus, * sign*Y*a + D*sign*X*a == B (mod |n|), * i.e. * sign*(Y + D*X)*a == B (mod |n|). * * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). * Note that X and Y stay non-negative all the time. */ if (!BN_mul(tmp,D,X,ctx)) goto err; if (!BN_add(tmp,tmp,Y)) goto err; M=Y; /* keep the BIGNUM object, the value does not matter */ Y=X; X=tmp; sign = -sign; } /* * The while loop (Euclid's algorithm) ends when * A == gcd(a,n); * we have * sign*Y*a == A (mod |n|), * where Y is non-negative. */ if (sign < 0) { if (!BN_sub(Y,n,Y)) goto err; } /* Now Y*a == A (mod |n|). */ if (BN_is_one(A)) { /* Y*a == 1 (mod |n|) */ if (!Y->neg && BN_ucmp(Y,n) < 0) { if (!BN_copy(R,Y)) goto err; } else { if (!BN_nnmod(R,Y,n,ctx)) goto err; } } else { BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH,BN_R_NO_INVERSE); goto err; } ret=R; err: if ((ret == NULL) && (in == NULL)) BN_free(R); BN_CTX_end(ctx); bn_check_top(ret); return(ret); }
int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; BIGNUM local_r0, local_d, local_p; BIGNUM *pr0, *d, *p; int prime_bits, ok = -1, n = 0, i, j; BN_CTX *ctx = NULL; STACK_OF(RSA_additional_prime) *additional_primes = NULL; if (num_primes < 2) { ok = 0; /* we set our own err */ OPENSSL_PUT_ERROR(RSA, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES); goto err; } ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); r3 = BN_CTX_get(ctx); if (r0 == NULL || r1 == NULL || r2 == NULL || r3 == NULL) { goto err; } if (num_primes > 2) { additional_primes = sk_RSA_additional_prime_new_null(); if (additional_primes == NULL) { goto err; } } for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime)); if (ap == NULL) { goto err; } memset(ap, 0, sizeof(RSA_additional_prime)); ap->prime = BN_new(); ap->exp = BN_new(); ap->coeff = BN_new(); ap->r = BN_new(); if (ap->prime == NULL || ap->exp == NULL || ap->coeff == NULL || ap->r == NULL || !sk_RSA_additional_prime_push(additional_primes, ap)) { RSA_additional_prime_free(ap); goto err; } } /* We need the RSA components non-NULL */ if (!rsa->n && ((rsa->n = BN_new()) == NULL)) { goto err; } if (!rsa->d && ((rsa->d = BN_new()) == NULL)) { goto err; } if (!rsa->e && ((rsa->e = BN_new()) == NULL)) { goto err; } if (!rsa->p && ((rsa->p = BN_new()) == NULL)) { goto err; } if (!rsa->q && ((rsa->q = BN_new()) == NULL)) { goto err; } if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) { goto err; } if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) { goto err; } if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) { goto err; } if (!BN_copy(rsa->e, e_value)) { goto err; } /* generate p and q */ prime_bits = (bits + (num_primes - 1)) / num_primes; for (;;) { if (!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb) || !BN_sub(r2, rsa->p, BN_value_one()) || !BN_gcd(r1, r2, rsa->e, ctx)) { goto err; } if (BN_is_one(r1)) { break; } if (!BN_GENCB_call(cb, 2, n++)) { goto err; } } if (!BN_GENCB_call(cb, 3, 0)) { goto err; } prime_bits = ((bits - prime_bits) + (num_primes - 2)) / (num_primes - 1); for (;;) { /* When generating ridiculously small keys, we can get stuck * continually regenerating the same prime values. Check for * this and bail if it happens 3 times. */ unsigned int degenerate = 0; do { if (!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb)) { goto err; } } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); if (degenerate == 3) { ok = 0; /* we set our own err */ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); goto err; } if (!BN_sub(r2, rsa->q, BN_value_one()) || !BN_gcd(r1, r2, rsa->e, ctx)) { goto err; } if (BN_is_one(r1)) { break; } if (!BN_GENCB_call(cb, 2, n++)) { goto err; } } if (!BN_GENCB_call(cb, 3, 1) || !BN_mul(rsa->n, rsa->p, rsa->q, ctx)) { goto err; } for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); prime_bits = ((bits - BN_num_bits(rsa->n)) + (num_primes - (i + 1))) / (num_primes - i); for (;;) { if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb)) { goto err; } if (BN_cmp(rsa->p, ap->prime) == 0 || BN_cmp(rsa->q, ap->prime) == 0) { continue; } for (j = 0; j < i - 2; j++) { if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime, ap->prime) == 0) { break; } } if (j != i - 2) { continue; } if (!BN_sub(r2, ap->prime, BN_value_one()) || !BN_gcd(r1, r2, rsa->e, ctx)) { goto err; } if (!BN_is_one(r1)) { continue; } if (i != num_primes - 1) { break; } /* For the last prime we'll check that it makes n large enough. In the * two prime case this isn't a problem because we generate primes with * the top two bits set and so the product is always of the expected * size. In the multi prime case, this doesn't follow. */ if (!BN_mul(r1, rsa->n, ap->prime, ctx)) { goto err; } if (BN_num_bits(r1) == (unsigned) bits) { break; } if (!BN_GENCB_call(cb, 2, n++)) { goto err; } } /* ap->r is is the product of all the primes prior to the current one * (including p and q). */ if (!BN_copy(ap->r, rsa->n)) { goto err; } if (i == num_primes - 1) { /* In the case of the last prime, we calculated n as |r1| in the loop * above. */ if (!BN_copy(rsa->n, r1)) { goto err; } } else if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx)) { goto err; } if (!BN_GENCB_call(cb, 3, 1)) { goto err; } } if (BN_cmp(rsa->p, rsa->q) < 0) { tmp = rsa->p; rsa->p = rsa->q; rsa->q = tmp; } /* calculate d */ if (!BN_sub(r1, rsa->p, BN_value_one())) { goto err; /* p-1 */ } if (!BN_sub(r2, rsa->q, BN_value_one())) { goto err; /* q-1 */ } if (!BN_mul(r0, r1, r2, ctx)) { goto err; /* (p-1)(q-1) */ } for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); if (!BN_sub(r3, ap->prime, BN_value_one()) || !BN_mul(r0, r0, r3, ctx)) { goto err; } } pr0 = &local_r0; BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) { goto err; /* d */ } /* set up d for correct BN_FLG_CONSTTIME flag */ d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); /* calculate d mod (p-1) */ if (!BN_mod(rsa->dmp1, d, r1, ctx)) { goto err; } /* calculate d mod (q-1) */ if (!BN_mod(rsa->dmq1, d, r2, ctx)) { goto err; } /* calculate inverse of q mod p */ p = &local_p; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) { goto err; } for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); if (!BN_sub(ap->exp, ap->prime, BN_value_one()) || !BN_mod(ap->exp, rsa->d, ap->exp, ctx) || !BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx)) { goto err; } } ok = 1; rsa->additional_primes = additional_primes; additional_primes = NULL; err: if (ok == -1) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); ok = 0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } sk_RSA_additional_prime_pop_free(additional_primes, RSA_additional_prime_free); return ok; }
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; BIGNUM local_r0,local_d,local_p; BIGNUM *pr0,*d,*p; int bitsp,bitsq,ok= -1,n=0; BN_CTX *ctx=NULL; ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); r3 = BN_CTX_get(ctx); if (r3 == NULL) goto err; bitsp=(bits+1)/2; bitsq=bits-bitsp; /* We need the RSA components non-NULL */ if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err; if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err; if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err; if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err; if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err; if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err; if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err; if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err; BN_copy(rsa->e, e_value); /* generate p and q */ for (;;) { if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) goto err; if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 0)) goto err; for (;;) { /* When generating ridiculously small keys, we can get stuck * continually regenerating the same prime values. Check for * this and bail if it happens 3 times. */ unsigned int degenerate = 0; do { if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) goto err; } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); if(degenerate == 3) { ok = 0; /* we set our own err */ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL); goto err; } if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 1)) goto err; if (BN_cmp(rsa->p,rsa->q) < 0) { tmp=rsa->p; rsa->p=rsa->q; rsa->q=tmp; } /* calculate n */ if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; /* calculate d */ if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { pr0 = &local_r0; BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); } else pr0 = r0; if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */ /* set up d for correct BN_FLG_CONSTTIME flag */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; /* calculate d mod (p-1) */ if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; /* calculate d mod (q-1) */ if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; /* calculate inverse of q mod p */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { p = &local_p; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); } else p = rsa->p; if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; ok=1; err: if (ok == -1) { RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN); ok=0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ok; }
static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { BIGNUM *r1, *m1, *vrfy, *r2, *m[RSA_MAX_PRIME_NUM - 2]; int ret = 0, i, ex_primes = 0; RSA_PRIME_INFO *pinfo; BN_CTX_start(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); if (vrfy == NULL) goto err; if (rsa->version == RSA_ASN1_VERSION_MULTI && ((ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) <= 0 || ex_primes > RSA_MAX_PRIME_NUM - 2)) goto err; { BIGNUM *p = BN_new(), *q = BN_new(); /* * Make sure BN_mod_inverse in Montgomery initialization uses the * BN_FLG_CONSTTIME flag */ if (p == NULL || q == NULL) { BN_free(p); BN_free(q); goto err; } BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { if (!BN_MONT_CTX_set_locked (&rsa->_method_mod_p, rsa->lock, p, ctx) || !BN_MONT_CTX_set_locked(&rsa->_method_mod_q, rsa->lock, q, ctx)) { BN_free(p); BN_free(q); goto err; } if (ex_primes > 0) { /* cache BN_MONT_CTX for other primes */ BIGNUM *r = BN_new(); if (r == NULL) { BN_free(p); BN_free(q); goto err; } for (i = 0; i < ex_primes; i++) { pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); BN_with_flags(r, pinfo->r, BN_FLG_CONSTTIME); if (!BN_MONT_CTX_set_locked(&pinfo->m, rsa->lock, r, ctx)) { BN_free(p); BN_free(q); BN_free(r); goto err; } } BN_free(r); } } /* * We MUST free p and q before any further use of rsa->p and rsa->q */ BN_free(p); BN_free(q); } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) goto err; /* compute I mod q */ { BIGNUM *c = BN_new(); if (c == NULL) goto err; BN_with_flags(c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, c, rsa->q, ctx)) { BN_free(c); goto err; } { BIGNUM *dmq1 = BN_new(); if (dmq1 == NULL) { BN_free(c); goto err; } BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); /* compute r1^dmq1 mod q */ if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) { BN_free(c); BN_free(dmq1); goto err; } /* We MUST free dmq1 before any further use of rsa->dmq1 */ BN_free(dmq1); } /* compute I mod p */ if (!BN_mod(r1, c, rsa->p, ctx)) { BN_free(c); goto err; } /* We MUST free c before any further use of I */ BN_free(c); } { BIGNUM *dmp1 = BN_new(); if (dmp1 == NULL) goto err; BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); /* compute r1^dmp1 mod p */ if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p)) { BN_free(dmp1); goto err; } /* We MUST free dmp1 before any further use of rsa->dmp1 */ BN_free(dmp1); } /* * calculate m_i in multi-prime case * * TODO: * 1. squash the following two loops and calculate |m_i| there. * 2. remove cc and reuse |c|. * 3. remove |dmq1| and |dmp1| in previous block and use |di|. * * If these things are done, the code will be more readable. */ if (ex_primes > 0) { BIGNUM *di = BN_new(), *cc = BN_new(); if (cc == NULL || di == NULL) { BN_free(cc); BN_free(di); goto err; } for (i = 0; i < ex_primes; i++) { /* prepare m_i */ if ((m[i] = BN_CTX_get(ctx)) == NULL) { BN_free(cc); BN_free(di); goto err; } pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); /* prepare c and d_i */ BN_with_flags(cc, I, BN_FLG_CONSTTIME); BN_with_flags(di, pinfo->d, BN_FLG_CONSTTIME); if (!BN_mod(r1, cc, pinfo->r, ctx)) { BN_free(cc); BN_free(di); goto err; } /* compute r1 ^ d_i mod r_i */ if (!rsa->meth->bn_mod_exp(m[i], r1, di, pinfo->r, ctx, pinfo->m)) { BN_free(cc); BN_free(di); goto err; } } BN_free(cc); BN_free(di); } 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; if (!BN_mul(r1, r0, rsa->iqmp, ctx)) goto err; { BIGNUM *pr1 = BN_new(); if (pr1 == NULL) goto err; BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); if (!BN_mod(r0, pr1, rsa->p, ctx)) { BN_free(pr1); goto err; } /* We MUST free pr1 before any further use of r1 */ BN_free(pr1); } /* * If p < q it is occasionally possible for the correction of adding 'p' * if r0 is negative above to leave the result still negative. This can * break the private key operations: the following second correction * should *always* correct this rare occurrence. This will *never* happen * with OpenSSL generated keys because they ensure p > q [steve] */ if (BN_is_negative(r0)) if (!BN_add(r0, r0, rsa->p)) goto err; if (!BN_mul(r1, r0, rsa->q, ctx)) goto err; if (!BN_add(r0, r1, m1)) goto err; /* add m_i to m in multi-prime case */ if (ex_primes > 0) { BIGNUM *pr2 = BN_new(); if (pr2 == NULL) goto err; for (i = 0; i < ex_primes; i++) { pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); if (!BN_sub(r1, m[i], r0)) { BN_free(pr2); goto err; } if (!BN_mul(r2, r1, pinfo->t, ctx)) { BN_free(pr2); goto err; } BN_with_flags(pr2, r2, BN_FLG_CONSTTIME); if (!BN_mod(r1, pr2, pinfo->r, ctx)) { BN_free(pr2); goto err; } if (BN_is_negative(r1)) if (!BN_add(r1, r1, pinfo->r)) { BN_free(pr2); goto err; } if (!BN_mul(r1, r1, pinfo->pp, ctx)) { BN_free(pr2); goto err; } if (!BN_add(r0, r0, r1)) { BN_free(pr2); goto err; } } BN_free(pr2); } if (rsa->e && rsa->n) { if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) goto err; /* * If 'I' was greater than (or equal to) rsa->n, the operation will * be equivalent to using 'I mod n'. However, the result of the * verify will *always* be less than 'n' so we don't check for * absolute equality, just congruency. */ if (!BN_sub(vrfy, vrfy, I)) goto err; if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; if (BN_is_negative(vrfy)) if (!BN_add(vrfy, vrfy, rsa->n)) goto err; if (!BN_is_zero(vrfy)) { /* * 'I' and 'vrfy' aren't congruent mod n. Don't leak * miscalculated CRT output, just do a raw (slower) mod_exp and * return that instead. */ BIGNUM *d = BN_new(); if (d == NULL) goto err; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(d); goto err; } /* We MUST free d before any further use of rsa->d */ BN_free(d); } } ret = 1; err: BN_CTX_end(ctx); return ret; }
static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret; int j, num = 0, r = -1; unsigned char *p; unsigned char *buf = NULL; BN_CTX *ctx = NULL; int local_blinding = 0; /* * Used only if the blinding structure is shared. A non-NULL unblind * instructs rsa_blinding_convert() and rsa_blinding_invert() to store * the unblinding factor outside the blinding structure. */ BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } /* * This check was for equality but PGP does evil things and chops off the * top '0' bytes */ if (flen > num) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } /* make data into a big number */ if (BN_bin2bn(from, (int)flen, f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) goto err; } /* do the decrypt */ if ((rsa->flags & RSA_FLAG_EXT_PKEY) || (rsa->version == RSA_ASN1_VERSION_MULTI) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM *d = BN_new(); if (d == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) { BN_free(d); goto err; } if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(d); goto err; } /* We MUST free d before any further use of rsa->d */ BN_free(d); } if (blinding) if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; p = buf; j = BN_bn2bin(ret, p); /* j is only used with no-padding mode */ switch (padding) { case RSA_PKCS1_PADDING: r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); break; case RSA_PKCS1_OAEP_PADDING: r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); break; case RSA_SSLV23_PADDING: r = RSA_padding_check_SSLv23(to, num, buf, j, num); break; case RSA_NO_PADDING: r = RSA_padding_check_none(to, num, buf, j, num); break; default: RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_clear_free(buf, num); return r; }
/* signing */ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret, *res; int i, j, k, num = 0, r = -1; unsigned char *buf = NULL; BN_CTX *ctx = NULL; int local_blinding = 0; /* * Used only if the blinding structure is shared. A non-NULL unblind * instructs rsa_blinding_convert() and rsa_blinding_invert() to store * the unblinding factor outside the blinding structure. */ BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); break; case RSA_X931_PADDING: i = RSA_padding_add_X931(buf, num, from, flen); break; case RSA_NO_PADDING: i = RSA_padding_add_none(buf, num, from, flen); break; case RSA_SSLV23_PADDING: default: RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) goto err; if (BN_bin2bn(buf, num, f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) goto err; } if ((rsa->flags & RSA_FLAG_EXT_PKEY) || (rsa->version == RSA_ASN1_VERSION_MULTI) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM *d = BN_new(); if (d == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) { BN_free(d); goto err; } if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(d); goto err; } /* We MUST free d before any further use of rsa->d */ BN_free(d); } if (blinding) if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; if (padding == RSA_X931_PADDING) { BN_sub(f, rsa->n, ret); if (BN_cmp(ret, f) > 0) res = f; else res = ret; } else { res = ret; } /* * put in leading 0 bytes if the number is less than the length of the * modulus */ j = BN_num_bytes(res); i = BN_bn2bin(res, &(to[num - j])); for (k = 0; k < (num - i); k++) to[k] = 0; r = num; err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_clear_free(buf, num); return r; }
static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { BIGNUM *r1, *m1, *vrfy; 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 = NULL, *local_q = NULL; BIGNUM *p = NULL, *q = NULL; /* * Make sure BN_mod_inverse in Montgomery initialization uses the * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { local_p = p = BN_new(); if (p == NULL) goto err; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); local_q = q = BN_new(); if (q == NULL) { BN_free(local_p); goto err; } 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) || !BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx)) { BN_free(local_p); BN_free(local_q); goto err; } } /* * We MUST free local_p and local_q before any further use of rsa->p and * rsa->q */ BN_free(local_p); BN_free(local_q); } 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 */ { BIGNUM *local_c = NULL; const BIGNUM *c; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { local_c = BN_new(); if (local_c == NULL) goto err; BN_with_flags(local_c, I, BN_FLG_CONSTTIME); c = local_c; } else { c = I; } if (!BN_mod(r1, c, rsa->q, ctx)) { BN_free(local_c); goto err; } { BIGNUM *local_dmq1 = NULL, *dmq1; /* compute r1^dmq1 mod q */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { dmq1 = local_dmq1 = BN_new(); if (local_dmq1 == NULL) { BN_free(local_c); goto err; } 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)) { BN_free(local_c); BN_free(local_dmq1); goto err; } /* We MUST free local_dmq1 before any further use of rsa->dmq1 */ BN_free(local_dmq1); } /* compute I mod p */ if (!BN_mod(r1, c, rsa->p, ctx)) { BN_free(local_c); goto err; } /* We MUST free local_c before any further use of I */ BN_free(local_c); } { BIGNUM *local_dmp1 = NULL, *dmp1; /* compute r1^dmp1 mod p */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { dmp1 = local_dmp1 = BN_new(); if (local_dmp1 == NULL) goto err; 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)) { BN_free(local_dmp1); goto err; } /* We MUST free local_dmp1 before any further use of rsa->dmp1 */ BN_free(local_dmp1); } 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; if (!BN_mul(r1, r0, rsa->iqmp, ctx)) goto err; { BIGNUM *local_r1 = NULL, *pr1; /* Turn BN_FLG_CONSTTIME flag on before division operation */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { pr1 = local_r1 = BN_new(); if (local_r1 == NULL) goto err; BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); } else { pr1 = r1; } if (!BN_mod(r0, pr1, rsa->p, ctx)) { BN_free(local_r1); goto err; } /* We MUST free local_r1 before any further use of r1 */ BN_free(local_r1); } /* * If p < q it is occasionally possible for the correction of adding 'p' * if r0 is negative above to leave the result still negative. This can * break the private key operations: the following second correction * should *always* correct this rare occurrence. This will *never* happen * with OpenSSL generated keys because they ensure p > q [steve] */ if (BN_is_negative(r0)) if (!BN_add(r0, r0, rsa->p)) goto err; if (!BN_mul(r1, r0, rsa->q, ctx)) goto err; if (!BN_add(r0, r1, m1)) goto err; if (rsa->e && rsa->n) { if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) goto err; /* * If 'I' was greater than (or equal to) rsa->n, the operation will * be equivalent to using 'I mod n'. However, the result of the * verify will *always* be less than 'n' so we don't check for * absolute equality, just congruency. */ if (!BN_sub(vrfy, vrfy, I)) goto err; if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; if (BN_is_negative(vrfy)) if (!BN_add(vrfy, vrfy, rsa->n)) goto err; if (!BN_is_zero(vrfy)) { /* * 'I' and 'vrfy' aren't congruent mod n. Don't leak * miscalculated CRT output, just do a raw (slower) mod_exp and * return that instead. */ BIGNUM *local_d = NULL; BIGNUM *d = NULL; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { local_d = d = BN_new(); if (d == NULL) goto err; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else { d = rsa->d; } if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(local_d); goto err; } /* We MUST free local_d before any further use of rsa->d */ BN_free(local_d); } } ret = 1; err: BN_CTX_end(ctx); return (ret); }
static int dsa_builtin_keygen(DSA *dsa) { int ok = 0; BN_CTX *ctx = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL); goto err; } if ((ctx = BN_CTX_new()) == NULL) goto err; if (dsa->priv_key == NULL) { if ((priv_key = BN_new()) == NULL) goto err; } else priv_key = dsa->priv_key; do if (!BN_rand_range(priv_key, dsa->q)) goto err; while (BN_is_zero(priv_key)) ; if (dsa->pub_key == NULL) { if ((pub_key = BN_new()) == NULL) goto err; } else pub_key = dsa->pub_key; { BIGNUM local_prk; BIGNUM *prk; if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { BN_init(&local_prk); prk = &local_prk; BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); } else prk = priv_key; if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) goto err; } dsa->priv_key = priv_key; dsa->pub_key = pub_key; if (fips_dsa_pairwise_fail) BN_add_word(dsa->pub_key, 1); if (!fips_check_dsa(dsa)) goto err; ok = 1; err: if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key); if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key); if (ctx != NULL) BN_CTX_free(ctx); return (ok); }
static int generate_key(DH *dh) { int ok = 0; int generate_new_key = 0; unsigned l; BN_CTX *ctx; BN_MONT_CTX *mont = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; ctx = BN_CTX_new(); if (ctx == NULL) goto err; if (dh->priv_key == NULL) { priv_key = BN_new(); if (priv_key == NULL) goto err; generate_new_key = 1; } else priv_key = dh->priv_key; if (dh->pub_key == NULL) { pub_key = BN_new(); if (pub_key == NULL) goto err; } else pub_key = dh->pub_key; if (dh->flags & DH_FLAG_CACHE_MONT_P) { mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, CRYPTO_LOCK_DH, dh->p, ctx); if (!mont) goto err; } if (generate_new_key) { if (dh->q) { do { if (!BN_rand_range(priv_key, dh->q)) goto err; } while (BN_is_zero(priv_key) || BN_is_one(priv_key)); } else { /* secret exponent length */ l = dh->length ? dh->length : BN_num_bits(dh->p) - 1; if (!BN_rand(priv_key, l, 0, 0)) goto err; } } { BIGNUM local_prk; BIGNUM *prk; if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { BN_init(&local_prk); prk = &local_prk; BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); } else prk = priv_key; if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err; } dh->pub_key = pub_key; dh->priv_key = priv_key; ok = 1; err: if (ok != 1) DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB); if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); BN_CTX_free(ctx); return (ok); }
static int rsa_builtin_multi_prime_keygen(RSA *rsa, int bits, int num_primes, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; BIGNUM local_r0,local_d,local_p; BIGNUM *pr0,*d,*p; int prime_bits, ok= -1,n=0,i,j; BN_CTX *ctx=NULL; #ifdef OPENSSL_CRYPTOCOP static int cryptocop_count; #endif STACK_OF(RSA_additional_prime) *additional_primes = NULL; if (num_primes < 2) { ok = 0; /* we set our own err */ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES); goto err; } ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); r3 = BN_CTX_get(ctx); if (r3 == NULL) goto err; if (num_primes > 2) { if ((additional_primes = sk_RSA_additional_prime_new_null()) == NULL) goto err; } #ifdef OPENSSL_CRYPTOCOP if(bits < CRYPTOCOP_MIN_RSA_BITS && cryptocop_count < CRYPTOCOP_COUNT_MAX) { syslog(LOG_ERR, "RSA key generation with %d bits " CRYPTOCOP_INFO, bits); cryptocop_count++; } #endif for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime)); if (ap == NULL) goto err; memset(ap, 0, sizeof(RSA_additional_prime)); if ((ap->prime = BN_new()) == NULL) goto err; if ((ap->exp = BN_new()) == NULL) goto err; if ((ap->coeff = BN_new()) == NULL) goto err; if ((ap->r = BN_new()) == NULL) goto err; if (!sk_RSA_additional_prime_push(additional_primes, ap)) goto err; } /* We need the RSA components non-NULL */ if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err; if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err; if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err; if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err; if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err; if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err; if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err; if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err; BN_copy(rsa->e, e_value); /* generate p and q. */ prime_bits = (bits+(num_primes-1))/num_primes; for (;;) { if(!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb)) goto err; if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 0)) goto err; prime_bits = ((bits-prime_bits) + (num_primes-2))/(num_primes-1); for (;;) { /* When generating ridiculously small keys, we can get stuck * continually regenerating the same prime values. Check for * this and bail if it happens 3 times. */ unsigned int degenerate = 0; do { if(!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb)) goto err; } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); if(degenerate == 3) { ok = 0; /* we set our own err */ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL); goto err; } if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 1)) goto err; if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); prime_bits = ((bits - BN_num_bits(rsa->n))+(num_primes-(i+1)))/(num_primes-i); for (;;) { if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb)) goto err; if (BN_cmp(rsa->p, ap->prime) == 0) continue; if (BN_cmp(rsa->q, ap->prime) == 0) continue; for (j = 0; j < i - 2; j++) { if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime, ap->prime) == 0) break; } if (j != i - 2) continue; if (!BN_sub(r2, ap->prime, BN_value_one())) goto err; if (!BN_gcd(r1, r2, rsa->e, ctx)) goto err; if (!BN_is_one(r1)) continue; if (i != num_primes - 1) break; /* For the last prime we'll check that it makes * n large enough. In the two prime case this isn't a * problem because we generate primes with the top two * bits set and so the product is always of the * expected size. In the multi prime case, this doesn't * follow. */ if (!BN_mul(r1, rsa->n, ap->prime, ctx)) goto err; if (BN_num_bits(r1) == bits) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } /* ap->r is is the product of all the primes prior to the * current one (including p and q). */ if (!BN_copy(ap->r, rsa->n)) goto err; if (i == num_primes - 1) { /* In the case of the last prime, we calculated n in r1 * in the loop above. */ if (!BN_copy(rsa->n, r1)) goto err; } else { if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx)) goto err; } if(!BN_GENCB_call(cb, 3, 1)) goto err; } if (BN_cmp(rsa->p,rsa->q) < 0) { tmp=rsa->p; rsa->p=rsa->q; rsa->q=tmp; } /* calculate d */ if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); if (!BN_sub(r3, ap->prime, BN_value_one())) goto err; if (!BN_mul(r0, r0, r3, ctx)) goto err; } if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { pr0 = &local_r0; BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); } else pr0 = r0; if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */ /* set up d for correct BN_FLG_CONSTTIME flag */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; /* calculate d mod (p-1) */ if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; /* calculate d mod (q-1) */ if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; /* calculate inverse of q mod p */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { p = &local_p; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); } else p = rsa->p; if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); if (!BN_sub(ap->exp, ap->prime, BN_value_one())) goto err; if (!BN_mod(ap->exp, rsa->d, ap->exp, ctx)) goto err; if (!BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx)) goto err; } ok=1; rsa->additional_primes = additional_primes; additional_primes = NULL; err: if (ok == -1) { RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN); ok=0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (additional_primes != NULL) { for (i = 0; i < sk_RSA_additional_prime_num(additional_primes); i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i); if (ap->prime != NULL) BN_clear_free(ap->prime); if (ap->exp != NULL) BN_clear_free(ap->exp); if (ap->coeff != NULL) BN_clear_free(ap->coeff); if (ap->r != NULL) BN_clear_free(ap->r); } sk_RSA_additional_prime_pop_free(additional_primes, int_rsa_free_additional_prime); } return ok; }
/* signing */ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret, *br, *res; int i,j,k,num=0,r= -1; unsigned char *buf=NULL; BN_CTX *ctx=NULL; int local_blinding = 0; BN_BLINDING *blinding = NULL; if ((ctx=BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); br = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if(!f || !ret || !buf) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen); break; case RSA_X931_PADDING: i=RSA_padding_add_X931(buf,num,from,flen); break; case RSA_NO_PADDING: i=RSA_padding_add_none(buf,num,from,flen); break; case RSA_SSLV23_PADDING: default: RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) goto err; if (BN_bin2bn(buf,num,f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) goto err; if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL)) ) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM local_d; BIGNUM *d = NULL; if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) { BN_init(&local_d); d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME); } else d = rsa->d; MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; } if (blinding) if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) goto err; if (padding == RSA_X931_PADDING) { BN_sub(f, rsa->n, ret); if (BN_cmp(ret, f)) res = f; else res = ret; } else res = ret; /* put in leading 0 bytes if the number is less than the * length of the modulus */ j=BN_num_bytes(res); i=BN_bn2bin(res,&(to[num-j])); for (k=0; k<(num-i); k++) to[k]=0; r=num; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (buf != NULL) { OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); }
static int generate_key(DH *dh) { int ok=0; int generate_new_key=0; unsigned l; BN_CTX *ctx; BN_MONT_CTX *mont=NULL; BIGNUM *pub_key=NULL,*priv_key=NULL; if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) { DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL); return 0; } ctx = BN_CTX_new(); if (ctx == NULL) goto err; if (dh->priv_key == NULL) { priv_key=BN_new(); if (priv_key == NULL) goto err; generate_new_key=1; } else priv_key=dh->priv_key; if (dh->pub_key == NULL) { pub_key=BN_new(); if (pub_key == NULL) goto err; } else pub_key=dh->pub_key; if (dh->flags & DH_FLAG_CACHE_MONT_P) { mont = BN_MONT_CTX_set_locked( (BN_MONT_CTX **)&dh->method_mont_p, CRYPTO_LOCK_DH, dh->p, ctx); if (!mont) goto err; } if (generate_new_key) { l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */ if (!BN_rand(priv_key, l, 0, 0)) goto err; } { BIGNUM local_prk; BIGNUM *prk; if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { BN_init(&local_prk); prk = &local_prk; BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); } else prk = priv_key; if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err; } dh->pub_key=pub_key; dh->priv_key=priv_key; ok=1; err: if (ok != 1) DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB); if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); BN_CTX_free(ctx); return(ok); }
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; BIGNUM *dmp1, *dmq1; int ret=0; BN_CTX_start(ctx); r1 = BN_CTX_get(ctx); m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!BN_mod(r1,I,rsa->q,ctx)) goto err; if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) { dmq1 = &local_dmq1; BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME); } else dmq1 = rsa->dmq1; if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx, rsa->_method_mod_q)) goto err; if (!BN_mod(r1,I,rsa->p,ctx)) goto err; if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) { dmp1 = &local_dmp1; BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_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; if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err; if (!BN_mod(r0,r1,rsa->p,ctx)) goto err; /* If p < q it is occasionally possible for the correction of * adding 'p' if r0 is negative above to leave the result still * negative. This can break the private key operations: the following * second correction should *always* correct this rare occurrence. * This will *never* happen with OpenSSL generated keys because * they ensure p > q [steve] */ if (BN_is_negative(r0)) if (!BN_add(r0,r0,rsa->p)) goto err; if (!BN_mul(r1,r0,rsa->q,ctx)) goto err; if (!BN_add(r0,r1,m1)) goto err; if (rsa->e && rsa->n) { if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err; /* If 'I' was greater than (or equal to) rsa->n, the operation * will be equivalent to using 'I mod n'. However, the result of * the verify will *always* be less than 'n' so we don't check * for absolute equality, just congruency. */ if (!BN_sub(vrfy, vrfy, I)) goto err; if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; if (BN_is_negative(vrfy)) if (!BN_add(vrfy, vrfy, rsa->n)) goto err; if (!BN_is_zero(vrfy)) { /* 'I' and 'vrfy' aren't congruent mod n. Don't leak * miscalculated CRT output, just do a raw (slower) * mod_exp and return that instead. */ BIGNUM local_d; BIGNUM *d = NULL; if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME); } else d = rsa->d; if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; } } ret=1; err: BN_CTX_end(ctx); return(ret); }
int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { BIGNUM *f, *result; BN_CTX *ctx = NULL; unsigned blinding_index = 0; BN_BLINDING *blinding = NULL; int ret = 0; ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); f = BN_CTX_get(ctx); result = BN_CTX_get(ctx); if (f == NULL || result == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (BN_bin2bn(in, len, f) == NULL) { goto err; } if (BN_ucmp(f, rsa->n) >= 0) { /* Usually the padding functions would catch this. */ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_blinding_get(rsa, &blinding_index, ctx); if (blinding == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } if (!BN_BLINDING_convert_ex(f, NULL, blinding, ctx)) { goto err; } } if ((rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->mod_exp(result, f, rsa, ctx)) { goto err; } } else { BIGNUM local_d; BIGNUM *d = NULL; BN_init(&local_d); d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) { goto err; } } if (!rsa->meth->bn_mod_exp(result, f, d, rsa->n, ctx, rsa->mont_n)) { goto err; } } if (blinding) { if (!BN_BLINDING_invert_ex(result, NULL, blinding, ctx)) { goto err; } } if (!BN_bn2bin_padded(out, len, result)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } ret = 1; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (blinding != NULL) { rsa_blinding_release(rsa, blinding, blinding_index); } return ret; }
static int 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; size_t i, num_additional_primes = 0; if (rsa->additional_primes != NULL) { num_additional_primes = sk_RSA_additional_prime_num(rsa->additional_primes); } 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) */ 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); if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { if (BN_MONT_CTX_set_locked(&rsa->_method_mod_p, &rsa->lock, p, ctx) == NULL) { goto err; } if (BN_MONT_CTX_set_locked(&rsa->_method_mod_q, &rsa->lock, q, ctx) == NULL) { goto err; } } } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { if (BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n, ctx) == NULL) { goto err; } } /* compute I mod q */ c = &local_c; BN_with_flags(c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, c, rsa->q, ctx)) { goto err; } /* compute r1^dmq1 mod q */ dmq1 = &local_dmq1; BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) { goto err; } /* compute I mod p */ c = &local_c; BN_with_flags(c, I, BN_FLG_CONSTTIME); if (!BN_mod(r1, c, rsa->p, ctx)) { goto err; } /* compute r1^dmp1 mod p */ dmp1 = &local_dmp1; BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); 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; } } if (!BN_mul(r1, r0, rsa->iqmp, ctx)) { goto err; } /* Turn BN_FLG_CONSTTIME flag on before division operation */ pr1 = &local_r1; BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); if (!BN_mod(r0, pr1, rsa->p, ctx)) { goto err; } /* If p < q it is occasionally possible for the correction of * adding 'p' if r0 is negative above to leave the result still * negative. This can break the private key operations: the following * second correction should *always* correct this rare occurrence. * This will *never* happen with OpenSSL generated keys because * they ensure p > q [steve] */ if (BN_is_negative(r0)) { if (!BN_add(r0, r0, rsa->p)) { goto err; } } if (!BN_mul(r1, r0, rsa->q, ctx)) { goto err; } if (!BN_add(r0, r1, m1)) { goto err; } for (i = 0; i < num_additional_primes; i++) { /* multi-prime RSA. */ BIGNUM local_exp, local_prime; BIGNUM *exp = &local_exp, *prime = &local_prime; RSA_additional_prime *ap = sk_RSA_additional_prime_value(rsa->additional_primes, i); BN_with_flags(exp, ap->exp, BN_FLG_CONSTTIME); BN_with_flags(prime, ap->prime, BN_FLG_CONSTTIME); /* c will already point to a BIGNUM with the correct flags. */ if (!BN_mod(r1, c, prime, ctx)) { goto err; } if ((rsa->flags & RSA_FLAG_CACHE_PRIVATE) && !BN_MONT_CTX_set_locked(&ap->method_mod, &rsa->lock, prime, ctx)) { goto err; } if (!rsa->meth->bn_mod_exp(m1, r1, exp, prime, ctx, ap->method_mod)) { goto err; } BN_set_flags(m1, BN_FLG_CONSTTIME); if (!BN_sub(m1, m1, r0) || !BN_mul(m1, m1, ap->coeff, ctx) || !BN_mod(m1, m1, prime, ctx) || (BN_is_negative(m1) && !BN_add(m1, m1, prime)) || !BN_mul(m1, m1, ap->r, ctx) || !BN_add(r0, r0, m1)) { goto err; } } if (rsa->e && rsa->n) { if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) { goto err; } /* If 'I' was greater than (or equal to) rsa->n, the operation * will be equivalent to using 'I mod n'. However, the result of * the verify will *always* be less than 'n' so we don't check * for absolute equality, just congruency. */ if (!BN_sub(vrfy, vrfy, I)) { goto err; } if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) { goto err; } if (BN_is_negative(vrfy)) { if (!BN_add(vrfy, vrfy, rsa->n)) { goto err; } } if (!BN_is_zero(vrfy)) { /* 'I' and 'vrfy' aren't congruent mod n. Don't leak * miscalculated CRT output, just do a raw (slower) * mod_exp and return that instead. */ BIGNUM local_d; BIGNUM *d = NULL; d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->_method_mod_n)) { goto err; } } } ret = 1; err: BN_CTX_end(ctx); return ret; }
static int RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret; int j, num = 0, r = -1; unsigned char *p; unsigned char *buf = NULL; BN_CTX *ctx = NULL; int local_blinding = 0; /* * Used only if the blinding structure is shared. A non-NULL unblind * instructs rsa_blinding_convert() and rsa_blinding_invert() to store * the unblinding factor outside the blinding structure. */ BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); return -1; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); return -1; } /* for large moduli, enforce exponent limit */ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); return -1; } } if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (!f || !ret || !buf) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } /* * This check was for equality but PGP does evil things and chops off the * top '0' bytes */ if (flen > num) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } /* make data into a big number */ if (BN_bin2bn(from, (int)flen, f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) goto err; } /* do the decrypt */ if ((rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM local_d; BIGNUM *d = NULL; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; 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; if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, rsa->_method_mod_n)) goto err; } if (blinding) if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; p = buf; j = BN_bn2bin(ret, p); /* j is only used with no-padding mode */ switch (padding) { case RSA_PKCS1_PADDING: r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); break; # ifndef OPENSSL_NO_SHA case RSA_PKCS1_OAEP_PADDING: r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); break; # endif case RSA_SSLV23_PADDING: r = RSA_padding_check_SSLv23(to, num, buf, j, num); break; case RSA_NO_PADDING: r = RSA_padding_check_none(to, num, buf, j, num); break; default: RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (buf != NULL) { OPENSSL_cleanse(buf, num); OPENSSL_free(buf); } return (r); }