summaryrefslogtreecommitdiffstats
path: root/crypto/rsa
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2017-11-24 21:31:11 +0100
committerAndy Polyakov <appro@openssl.org>2017-11-28 20:04:57 +0100
commit0122add6549c7d5671f77a81c5a32571a5d46f3f (patch)
treede731841d36e5abc6e2c73e52e88cf75fd7c1367 /crypto/rsa
parent83ccead4d0fb496c8f00ee53c28e957b8cab4181 (diff)
rsa/rsa_lib.c: make RSA_security_bits multi-prime aware.
Multi-prime RSA security is not determined by modulus length alone, but depends even on number of primes. Too many primes render security inadequate, but there is no common amount of primes or common factors' length that provide equivalent secuity promise as two-prime for given modulus length. Maximum amount of permitted primes is determined according to following table. <1024 | >=1024 | >=4096 | >=8192 ------+--------+--------+------- 2 | 3 | 4 | 5 Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/4791)
Diffstat (limited to 'crypto/rsa')
-rw-r--r--crypto/rsa/rsa_lib.c11
-rw-r--r--crypto/rsa/rsa_locl.h1
-rw-r--r--crypto/rsa/rsa_mp.c14
3 files changed, 25 insertions, 1 deletions
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index 198dbd3fc7..133ba2185c 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -165,7 +165,16 @@ void *RSA_get_ex_data(const RSA *r, int idx)
int RSA_security_bits(const RSA *rsa)
{
- return BN_security_bits(BN_num_bits(rsa->n), -1);
+ int bits = BN_num_bits(rsa->n);
+
+ if (rsa->version == RSA_ASN1_VERSION_MULTI) {
+ /* This ought to mean that we have private key at hand. */
+ int ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos);
+
+ if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits))
+ return 0;
+ }
+ return BN_security_bits(bits, -1);
}
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
diff --git a/crypto/rsa/rsa_locl.h b/crypto/rsa/rsa_locl.h
index 6a53d89ede..a301dc6749 100644
--- a/crypto/rsa/rsa_locl.h
+++ b/crypto/rsa/rsa_locl.h
@@ -129,3 +129,4 @@ void rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo);
void rsa_multip_info_free(RSA_PRIME_INFO *pinfo);
RSA_PRIME_INFO *rsa_multip_info_new(void);
int rsa_multip_calc_product(RSA *rsa);
+int rsa_multip_cap(int bits);
diff --git a/crypto/rsa/rsa_mp.c b/crypto/rsa/rsa_mp.c
index d970564840..8ff4b63625 100644
--- a/crypto/rsa/rsa_mp.c
+++ b/crypto/rsa/rsa_mp.c
@@ -93,3 +93,17 @@ int rsa_multip_calc_product(RSA *rsa)
BN_CTX_free(ctx);
return rv;
}
+
+int rsa_multip_cap(int bits)
+{
+ int cap = 5;
+
+ if (bits < 1024)
+ cap = 2;
+ else if (bits < 4096)
+ cap = 3;
+ else if (bits < 8192)
+ cap = 4;
+
+ return cap;
+}