Skip to content

Commit 8aad46c

Browse files
committed
Fix test_pkey_rsa.rb in FIPS.
* Fix test_new. * Fix test_s_generate. * Fix test_new_break. * Fix test_sign_verify. Note that I created the signature text (`signature_encoded.txt`), that is used as a text to create the `signature0` in the `test_sign_verify` by the following steps with the `openssl` CLI on FIPS module. ``` $ OPENSSL_DIR="${HOME}/.local/openssl-3.4.0-dev-fips-debug-3c6e114959" $ export OPENSSL_CONF="${OPENSSL_DIR}/ssl/openssl_fips.cnf" $ echo -n "Sign me!" > data.txt $ "${OPENSSL_DIR}/bin/openssl" dgst -sha256 -sign test/openssl/fixtures/pkey/rsa2048.pem data.txt > signature.txt $ cat signature.txt | base64 > signature_encoded.txt ``` * Fix test_sign_verify_options. * Fix test_sign_verify_pss.
1 parent 13b03ba commit 8aad46c

File tree

2 files changed

+70
-34
lines changed

2 files changed

+70
-34
lines changed

Rakefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Rake::TestTask.new(:test_fips_internal) do |t|
3232
'test/openssl/test_pkey_dh.rb',
3333
'test/openssl/test_pkey_dsa.rb',
3434
'test/openssl/test_pkey_ec.rb',
35+
'test/openssl/test_pkey_rsa.rb',
3536
]
3637
t.warning = true
3738
end

test/openssl/test_pkey_rsa.rb

Lines changed: 69 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@ def test_no_private_exp
1414
end if !openssl?(3, 0, 0) # Impossible state in OpenSSL 3.0
1515

1616
def test_private
17+
# In FIPS, the `OpenSSL::PKey::RSA.new(2048, 65537)` with 2048 bits is at
18+
# least required. However, generating a 2048-bit RSA key takes
19+
# non-negligible amount of time. We want to avoid such slow tests as much
20+
# as possible.
21+
#
22+
# SP800 requires ossl_ifc_ffc_compute_security_bits that the return value
23+
# (strength in bits) is more than equal RSA_FIPS1864_MIN_KEYGEN_STRENGTH
24+
# (112) in FIPS.
25+
# https://github.com/openssl/openssl/blob/3c6e11495975a4eda4cc5886080afed6203711ac/crypto/rsa/rsa_sp800_56b_gen.c#L176-L182
26+
# The ossl_ifc_ffc_compute_security_bits returns 112 with the argument nbits
27+
# 2048.
28+
# https://github.com/openssl/openssl/blob/3c6e11495975a4eda4cc5886080afed6203711ac/crypto/rsa/rsa_lib.c#L334-L335
29+
omit_on_fips
30+
1731
# Generated by key size and public exponent
1832
key = OpenSSL::PKey::RSA.new(512, 3)
1933
assert(key.private?)
@@ -46,63 +60,76 @@ def test_private
4660
end
4761

4862
def test_new
49-
key = OpenSSL::PKey::RSA.new(512)
50-
assert_equal 512, key.n.num_bits
63+
key = OpenSSL::PKey::RSA.new(2048)
64+
assert_equal 2048, key.n.num_bits
5165
assert_equal 65537, key.e
5266
assert_not_nil key.d
5367

54-
# Specify public exponent
55-
key2 = OpenSSL::PKey::RSA.new(512, 3)
56-
assert_equal 512, key2.n.num_bits
57-
assert_equal 3, key2.e
68+
key2 = OpenSSL::PKey::RSA.new(2048, 65537)
69+
assert_equal 2048, key2.n.num_bits
70+
assert_equal 65537, key2.e
5871
assert_not_nil key2.d
5972
end
6073

74+
def test_new_exponent
75+
# At least 2024-bits RSA key are required in FIPS.
76+
omit_on_fips
77+
78+
# Specify public exponent
79+
key = OpenSSL::PKey::RSA.new(512, 3)
80+
assert_equal 512, key.n.num_bits
81+
assert_equal 3, key.e
82+
end
83+
6184
def test_s_generate
62-
key1 = OpenSSL::PKey::RSA.generate(512)
63-
assert_equal 512, key1.n.num_bits
85+
key1 = OpenSSL::PKey::RSA.generate(2048)
86+
assert_equal 2048, key1.n.num_bits
6487
assert_equal 65537, key1.e
6588

6689
# Specify public exponent
67-
key2 = OpenSSL::PKey::RSA.generate(512, 3)
68-
assert_equal 512, key2.n.num_bits
69-
assert_equal 3, key2.e
90+
key2 = OpenSSL::PKey::RSA.generate(2048, 65537)
91+
assert_equal 2048, key2.n.num_bits
92+
assert_equal 65537, key2.e
7093
assert_not_nil key2.d
7194
end
7295

7396
def test_new_break
74-
assert_nil(OpenSSL::PKey::RSA.new(1024) { break })
97+
assert_nil(OpenSSL::PKey::RSA.new(2048) { break })
7598
assert_raise(RuntimeError) do
76-
OpenSSL::PKey::RSA.new(1024) { raise }
99+
OpenSSL::PKey::RSA.new(2048) { raise }
77100
end
78101
end
79102

80103
def test_sign_verify
81-
rsa1024 = Fixtures.pkey("rsa1024")
104+
# Use 2024-bits RSA key, as OpenSSL 1.1.0 introduced that 512 or 1024-bits
105+
# RSA key is insecure.
106+
rsa = Fixtures.pkey("rsa2048")
82107
data = "Sign me!"
83-
signature = rsa1024.sign("SHA256", data)
84-
assert_equal true, rsa1024.verify("SHA256", signature, data)
108+
signature = rsa.sign("SHA256", data)
109+
assert_equal true, rsa.verify("SHA256", signature, data)
85110

86111
signature0 = (<<~'end;').unpack1("m")
87-
oLCgbprPvfhM4pjFQiDTFeWI9Sk+Og7Nh9TmIZ/xSxf2CGXQrptlwo7NQ28+
88-
WA6YQo8jPH4hSuyWIM4Gz4qRYiYRkl5TDMUYob94zm8Si1HxEiS9354tzvqS
89-
zS8MLW2BtNPuTubMxTItHGTnOzo9sUg0LAHVFt8kHG2NfKAw/gQ=
112+
ooy49i8aeFtkDYUU0RPDsEugGiNw4lZxpbQPnIwtdftEkka945IqKZ/MY3YSw7wKsvBZeaTy8GqL
113+
lSWLThsRFDV+UUS9zUBbQ9ygNIT8OjdV+tNL63ZpKGprczSnw4F05MQIpajNRud/8jiI9rf+Wysi
114+
WwXecjMl2FlXlLJHY4PFQZU5TiametB4VCQRMcjLo1uf26u/yRpiGaYyqn5vxs0SqNtUDM1UL6x4
115+
NHCAdqLjuFRQPjYp1vGLD3eSl4061pS8x1NVap3YGbYfGUyzZO4VfwFwf1jPdhp/OX/uZw4dGB2H
116+
gSK+q1JiDFwEE6yym5tdKovL1g1NhFYHF6gkZg==
90117
end;
91-
assert_equal true, rsa1024.verify("SHA256", signature0, data)
118+
assert_equal true, rsa.verify("SHA256", signature0, data)
92119
signature1 = signature0.succ
93-
assert_equal false, rsa1024.verify("SHA256", signature1, data)
120+
assert_equal false, rsa.verify("SHA256", signature1, data)
94121
end
95122

96123
def test_sign_verify_options
97-
key = Fixtures.pkey("rsa1024")
124+
key = Fixtures.pkey("rsa2048")
98125
data = "Sign me!"
99126
pssopts = {
100127
"rsa_padding_mode" => "pss",
101128
"rsa_pss_saltlen" => 20,
102129
"rsa_mgf1_md" => "SHA1"
103130
}
104131
sig_pss = key.sign("SHA256", data, pssopts)
105-
assert_equal 128, sig_pss.bytesize
132+
assert_equal 256, sig_pss.bytesize
106133
assert_equal true, key.verify("SHA256", sig_pss, data, pssopts)
107134
assert_equal true, key.verify_pss("SHA256", sig_pss, data,
108135
salt_length: 20, mgf1_hash: "SHA1")
@@ -175,12 +202,12 @@ def test_verify_empty_rsa
175202
end
176203

177204
def test_sign_verify_pss
178-
key = Fixtures.pkey("rsa1024")
205+
key = Fixtures.pkey("rsa2048")
179206
data = "Sign me!"
180207
invalid_data = "Sign me?"
181208

182209
signature = key.sign_pss("SHA256", data, salt_length: 20, mgf1_hash: "SHA1")
183-
assert_equal 128, signature.bytesize
210+
assert_equal 256, signature.bytesize
184211
assert_equal true,
185212
key.verify_pss("SHA256", signature, data, salt_length: 20, mgf1_hash: "SHA1")
186213
assert_equal true,
@@ -196,15 +223,23 @@ def test_sign_verify_pss
196223
assert_equal false,
197224
key.verify_pss("SHA256", signature, data, salt_length: 20, mgf1_hash: "SHA1")
198225

199-
signature = key.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA1")
200-
assert_equal true,
201-
key.verify_pss("SHA256", signature, data, salt_length: 94, mgf1_hash: "SHA1")
202-
assert_equal true,
203-
key.verify_pss("SHA256", signature, data, salt_length: :auto, mgf1_hash: "SHA1")
204-
205-
assert_raise(OpenSSL::PKey::RSAError) {
206-
key.sign_pss("SHA256", data, salt_length: 95, mgf1_hash: "SHA1")
207-
}
226+
# The sign_pss with `salt_length: :max` raises the "invalid salt length"
227+
# error on the following part in FIPS. We need to skip the tests in FIPS.
228+
# https://github.com/openssl/openssl/blob/d550d2aae531c6fa2e10b1a30d2acdf373663889/providers/implementations/signature/rsa_sig.c#L580-L597
229+
unless OpenSSL.fips_mode
230+
signature = key.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA1")
231+
# Should verify on the following salt_length (sLen).
232+
# sLen <= emLen (octat) - 2 - hLen (octet) = 2048 / 8 - 2 - 256 / 8 = 222
233+
# https://datatracker.ietf.org/doc/html/rfc8017#section-9.1.1
234+
assert_equal true,
235+
key.verify_pss("SHA256", signature, data, salt_length: 222, mgf1_hash: "SHA1")
236+
assert_equal true,
237+
key.verify_pss("SHA256", signature, data, salt_length: :auto, mgf1_hash: "SHA1")
238+
239+
assert_raise(OpenSSL::PKey::RSAError) {
240+
key.sign_pss("SHA256", data, salt_length: 223, mgf1_hash: "SHA1")
241+
}
242+
end
208243
end
209244

210245
def test_encrypt_decrypt

0 commit comments

Comments
 (0)