summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorPauli <pauli@openssl.org>2021-05-23 15:28:30 +1000
committerPauli <pauli@openssl.org>2021-05-26 20:39:38 +1000
commit1cf520e9d045c1d97c740367b1b94db88e90d9db (patch)
tree51d3f167b4d79f2c7b7788c789586b3652035a3a /crypto
parent1ee04b791b396385cce2a0c46c112158b2005293 (diff)
rsa: special case the strengths of RSA with 7680 and 15360 bits
Also cap the strengths for values under these two because the formula overestimates around them. The formula NIST gives doesn't match the table also presented in IG 7.5 Partial fix for #15421 Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Kurt Roeckx <kurt@roeckx.be> (Merged from https://github.com/openssl/openssl/pull/15428)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/rsa/rsa_lib.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index c70b622bae..bbcfbdde3d 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -312,21 +312,30 @@ uint16_t ossl_ifc_ffc_compute_security_bits(int n)
{
uint64_t x;
uint32_t lx;
- uint16_t y;
+ uint16_t y, cap;
- /* Look for common values as listed in SP 800-56B rev 2 Appendix D */
+ /*
+ * Look for common values as listed in standards.
+ * These values are not exactly equal to the results from the forumlæ in
+ * the standards but are defined to be canonical.
+ */
switch (n) {
- case 2048:
+ case 2048: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */
return 112;
- case 3072:
+ case 3072: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */
return 128;
- case 4096:
+ case 4096: /* SP 800-56B rev 2 Appendix D */
return 152;
- case 6144:
+ case 6144: /* SP 800-56B rev 2 Appendix D */
return 176;
- case 8192:
+ case 7680: /* FIPS 140-2 IG 7.5 */
+ return 192;
+ case 8192: /* SP 800-56B rev 2 Appendix D */
return 200;
+ case 15360: /* FIPS 140-2 IG 7.5 */
+ return 256;
}
+
/*
* The first incorrect result (i.e. not accurate or off by one low) occurs
* for n = 699668. The true value here is 1200. Instead of using this n
@@ -338,11 +347,26 @@ uint16_t ossl_ifc_ffc_compute_security_bits(int n)
if (n < 8)
return 0;
+ /*
+ * To ensure that the output is non-decreasing with respect to n,
+ * a cap needs to be applied to the two values where the function over
+ * estimates the strength (according to the above fast path).
+ */
+ if (n <= 7680)
+ cap = 192;
+ else if (n <= 15360)
+ cap = 256;
+ else
+ cap = 1200;
+
x = n * (uint64_t)log_2;
lx = ilog_e(x);
y = (uint16_t)((mul2(c1_923, icbrt64(mul2(mul2(x, lx), lx))) - c4_690)
/ log_2);
- return (y + 4) & ~7;
+ y = (y + 4) & ~7;
+ if (y > cap)
+ y = cap;
+ return y;
}