goto err;
}
- if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+ if (FIPS_module_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+ && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
return -1;
return ret;
}
-static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f,
- BIGNUM *r, BN_CTX *ctx)
-{
- if (local)
+static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+ BN_CTX *ctx)
+ {
+ if (unblind == NULL)
+ /* Local blinding: store the unblinding factor
+ * in BN_BLINDING. */
return BN_BLINDING_convert_ex(f, NULL, b, ctx);
else
{
- int ret;
- CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING);
- ret = BN_BLINDING_convert_ex(f, r, b, ctx);
- CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING);
- return ret;
- }
-}
-
-static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f,
- BIGNUM *r, BN_CTX *ctx)
-{
- if (local)
- return BN_BLINDING_invert_ex(f, NULL, b, ctx);
- else
- {
+ /* Shared blinding: store the unblinding factor
+ * outside BN_BLINDING. */
int ret;
CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
- ret = BN_BLINDING_invert_ex(f, r, b, ctx);
+ ret = BN_BLINDING_convert_ex(f, unblind, b, ctx);
CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
return ret;
}
-}
+ }
+
+static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+ BN_CTX *ctx)
+ {
+ /* For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex
+ * will use the unblinding factor stored in BN_BLINDING.
+ * If BN_BLINDING is shared between threads, unblind must be non-null:
+ * BN_BLINDING_invert_ex will then use the local unblinding factor,
+ * and will only read the modulus from BN_BLINDING.
+ * In both cases it's safe to access the blinding without a lock.
+ */
+ return BN_BLINDING_invert_ex(f, unblind, b, ctx);
+ }
/* 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;
+ 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;
#ifdef OPENSSL_FIPS
if(FIPS_selftest_failed())
{
- FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
+ FIPSerr(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
goto err;
}
- if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+ if (FIPS_module_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+ && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
{
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
return -1;
}
#endif
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 (blinding != NULL)
- if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ {
+ if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
+ {
+ RSAerr(RSA_F_RSA_EAY_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->p != NULL) &&
}
if (blinding)
- if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+ if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
goto err;
if (padding == RSA_X931_PADDING)
static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- BIGNUM *f, *ret, *br;
+ 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;
#ifdef OPENSSL_FIPS
if(FIPS_selftest_failed())
{
- FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
+ FIPSerr(FIPS_F_RSA_EAY_PRIVATE_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
goto err;
}
- if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+ if (FIPS_module_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+ && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
{
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
return -1;
}
#endif
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 (blinding != NULL)
- if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ {
+ 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) ||
}
if (blinding)
- if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+ if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
goto err;
p=buf;
r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
break;
#ifndef OPENSSL_NO_SHA
- case RSA_PKCS1_OAEP_PADDING:
+ case RSA_PKCS1_OAEP_PADDING:
r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
- break;
+ break;
#endif
case RSA_SSLV23_PADDING:
r=RSA_padding_check_SSLv23(to,num,buf,j,num);
#ifdef OPENSSL_FIPS
if(FIPS_selftest_failed())
{
- FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
+ FIPSerr(FIPS_F_RSA_EAY_PUBLIC_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
goto err;
}
- if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+ if (FIPS_module_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+ && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
{
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
return -1;
}
#endif
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
+ * 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]
- */
+ * 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;
static int RSA_eay_init(RSA *rsa)
{
#ifdef OPENSSL_FIPS
- FIPS_selftest_check();
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_RSA_EAY_INIT,FIPS_R_FIPS_SELFTEST_FAILED);
+ return 0;
+ }
#endif
rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
return(1);