diff options
author | Pauli <paul.dale@oracle.com> | 2018-10-05 02:19:30 +0300 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2018-10-23 01:01:48 +0300 |
commit | 97b0b713fbeb74d7531fe88a2362250c6324655f (patch) | |
tree | d46adba14dcdc37a77216340110dd560afe0fd38 /test | |
parent | 5b4cb385c18a5bb4e118e300f1c746bf7c2a5628 (diff) |
RSA security bits calculation
NIST has updated their guidelines in appendix D of SP 800-56B rev2 (draft)
providing a formula for the number of security bits it terms of the length
of the RSA key.
This is an implementation of this formula using fixed point arithmetic.
For integers 1 .. 100,000 it rounds down to the next smaller 8 bit strength
270 times. It never errs to the high side. None of the rounded values occur
near any of the commonly selected lengths.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7352)
Diffstat (limited to 'test')
-rw-r--r-- | test/rsa_test.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/test/rsa_test.c b/test/rsa_test.c index 2ad4de4734..25709e418c 100644 --- a/test/rsa_test.c +++ b/test/rsa_test.c @@ -329,10 +329,70 @@ err: return ret; } +static const struct { + int bits; + unsigned int r; +} rsa_security_bits_cases[] = { + /* NIST SP 800-56B rev 2 (draft) Appendix D Table 5 */ + { 2048, 112 }, + { 3072, 128 }, + { 4096, 152 }, + { 6144, 176 }, + { 8192, 200 }, + /* Older values */ + { 256, 40 }, + { 512, 56 }, + { 1024, 80 }, + /* Slightly different value to the 256 that NIST lists in their tables */ + { 15360, 264 }, + /* Some other values */ + { 8888, 208 }, + { 2468, 120 }, + { 13456, 248 } +}; + +static int test_rsa_security_bit(int n) +{ + static const unsigned char vals[8] = { + 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 + }; + RSA *key = RSA_new(); + const int bits = rsa_security_bits_cases[n].bits; + const int result = rsa_security_bits_cases[n].r; + const int bytes = (bits + 7) / 8; + int r = 0; + unsigned char num[2000]; + + if (!TEST_ptr(key) || !TEST_int_le(bytes, (int)sizeof(num))) + goto err; + + /* + * It is necessary to set the RSA key in order to ask for the strength. + * A BN of an appropriate size is created, in general it won't have the + * properties necessary for RSA to function. This is okay here since + * the RSA key is never used. + */ + memset(num, vals[bits % 8], bytes); + + /* + * The 'e' parameter is set to the same value as 'n'. This saves having + * an extra BN to hold a sensible value for 'e'. This is safe since the + * RSA key is not used. The 'd' parameter can be NULL safely. + */ + if (TEST_true(RSA_set0_key(key, BN_bin2bn(num, bytes, NULL), + BN_bin2bn(num, bytes, NULL), NULL)) + && TEST_uint_eq(RSA_security_bits(key), result)) + r = 1; +err: + RSA_free(key); + return r; +} + int setup_tests(void) { ADD_ALL_TESTS(test_rsa_pkcs1, 3); ADD_ALL_TESTS(test_rsa_oaep, 3); + ADD_ALL_TESTS(test_rsa_security_bit, OSSL_NELEM(rsa_security_bits_cases)); return 1; } #endif |