summaryrefslogtreecommitdiffstats
path: root/crypto/openssl/crypto/rsa/rsa_eay.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssl/crypto/rsa/rsa_eay.c')
-rw-r--r--crypto/openssl/crypto/rsa/rsa_eay.c101
1 files changed, 84 insertions, 17 deletions
diff --git a/crypto/openssl/crypto/rsa/rsa_eay.c b/crypto/openssl/crypto/rsa/rsa_eay.c
index ce70190f..9db3738 100644
--- a/crypto/openssl/crypto/rsa/rsa_eay.c
+++ b/crypto/openssl/crypto/rsa/rsa_eay.c
@@ -56,7 +56,7 @@
* [including the GNU Public Licence.]
*/
/* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -169,6 +169,28 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
unsigned char *buf=NULL;
BN_CTX *ctx=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);
@@ -239,40 +261,63 @@ err:
return(r);
}
-static BN_BLINDING *rsa_get_blinding(RSA *rsa, BIGNUM **r, int *local, BN_CTX *ctx)
+static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
{
BN_BLINDING *ret;
+ int got_write_lock = 0;
+
+ CRYPTO_r_lock(CRYPTO_LOCK_RSA);
if (rsa->blinding == NULL)
{
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ got_write_lock = 1;
+
if (rsa->blinding == NULL)
- {
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- if (rsa->blinding == NULL)
- rsa->blinding = RSA_setup_blinding(rsa, ctx);
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- }
+ rsa->blinding = RSA_setup_blinding(rsa, ctx);
}
ret = rsa->blinding;
if (ret == NULL)
- return NULL;
+ goto err;
- if (BN_BLINDING_get_thread_id(ret) != CRYPTO_thread_id())
+ if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id())
{
- *local = 0;
+ /* rsa->blinding is ours! */
+
+ *local = 1;
+ }
+ else
+ {
+ /* resort to rsa->mt_blinding instead */
+
+ *local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert()
+ * that the BN_BLINDING is shared, meaning that accesses
+ * require locks, and that the blinding factor must be
+ * stored outside the BN_BLINDING
+ */
+
if (rsa->mt_blinding == NULL)
{
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ if (!got_write_lock)
+ {
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ got_write_lock = 1;
+ }
+
if (rsa->mt_blinding == NULL)
rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
}
ret = rsa->mt_blinding;
}
- else
- *local = 1;
+ err:
+ if (got_write_lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
+ else
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
return ret;
}
@@ -359,7 +404,7 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
{
- blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
+ blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
if (blinding == NULL)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
@@ -480,7 +525,7 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
{
- blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
+ blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
if (blinding == NULL)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
@@ -575,6 +620,28 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
+ return -1;
+ }
+
+ if (BN_ucmp(rsa->n, rsa->e) <= 0)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, 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_DECRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+ }
+
if((ctx = BN_CTX_new()) == NULL) goto err;
BN_CTX_start(ctx);
f = BN_CTX_get(ctx);
OpenPOWER on IntegriCloud