rsa/rsa_lib.c: make RSA_security_bits multi-prime aware.
authorAndy Polyakov <appro@openssl.org>
Fri, 24 Nov 2017 20:31:11 +0000 (21:31 +0100)
committerAndy Polyakov <appro@openssl.org>
Tue, 28 Nov 2017 19:04:57 +0000 (20:04 +0100)
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)

crypto/rsa/rsa_lib.c
crypto/rsa/rsa_locl.h
crypto/rsa/rsa_mp.c

index 198dbd3fc7ce6c8d76dba0b452083f36955b2e6f..133ba2185c5b8713d4dcce7e1288029bedfc3c67 100644 (file)
@@ -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)
index 6a53d89edef1dabb1d16d924b0475c17d4fcdec3..a301dc6749646c268d34b598a522d9ec4360c556 100644 (file)
@@ -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);
index d9705648400c92b356d97ecd83c1ffe407d3ddac..8ff4b636256d9e01f4ce7d56b5a78c6c09fe2446 100644 (file)
@@ -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;
+}