blob: 926bb44e999f5f6242a9eb40a66b82f83b690054 [file] [log] [blame]
Alex Gaynor2e85a922018-07-16 11:18:33 -04001# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
7import binascii
8
9import pytest
10
11from cryptography.exceptions import InvalidSignature
12from cryptography.hazmat.backends.interfaces import RSABackend
13from cryptography.hazmat.primitives import hashes, serialization
14from cryptography.hazmat.primitives.asymmetric import padding
15
16
17_DIGESTS = {
18 "SHA-1": hashes.SHA1(),
19 "SHA-224": hashes.SHA224(),
20 "SHA-256": hashes.SHA256(),
21 "SHA-384": hashes.SHA384(),
22 "SHA-512": hashes.SHA512(),
Lucia Lic6ba99d2021-11-08 22:06:11 +080023 # Not supported by OpenSSL for RSA signing
24 "SHA-512/224": None,
25 "SHA-512/256": None,
26 "SHA3-224": hashes.SHA3_224(),
27 "SHA3-256": hashes.SHA3_256(),
28 "SHA3-384": hashes.SHA3_384(),
29 "SHA3-512": hashes.SHA3_512(),
Alex Gaynor2e85a922018-07-16 11:18:33 -040030}
31
32
33def should_verify(backend, wycheproof):
34 if wycheproof.valid:
35 return True
36
37 if wycheproof.acceptable:
Lucia Lic6ba99d2021-11-08 22:06:11 +080038 return not wycheproof.has_flag("MissingNull")
Alex Gaynor2e85a922018-07-16 11:18:33 -040039
40 return False
41
42
43@pytest.mark.requires_backend_interface(interface=RSABackend)
Alex Gaynor2e85a922018-07-16 11:18:33 -040044@pytest.mark.wycheproof_tests(
45 "rsa_signature_test.json",
46 "rsa_signature_2048_sha224_test.json",
47 "rsa_signature_2048_sha256_test.json",
Lucia Lic6ba99d2021-11-08 22:06:11 +080048 "rsa_signature_2048_sha384_test.json",
Alex Gaynor2e85a922018-07-16 11:18:33 -040049 "rsa_signature_2048_sha512_test.json",
Lucia Lic6ba99d2021-11-08 22:06:11 +080050 "rsa_signature_2048_sha512_224_test.json",
51 "rsa_signature_2048_sha512_256_test.json",
52 "rsa_signature_2048_sha3_224_test.json",
53 "rsa_signature_2048_sha3_256_test.json",
54 "rsa_signature_2048_sha3_384_test.json",
55 "rsa_signature_2048_sha3_512_test.json",
Alex Gaynor2e85a922018-07-16 11:18:33 -040056 "rsa_signature_3072_sha256_test.json",
57 "rsa_signature_3072_sha384_test.json",
58 "rsa_signature_3072_sha512_test.json",
Lucia Lic6ba99d2021-11-08 22:06:11 +080059 "rsa_signature_3072_sha512_256_test.json",
60 "rsa_signature_3072_sha3_256_test.json",
61 "rsa_signature_3072_sha3_384_test.json",
62 "rsa_signature_3072_sha3_512_test.json",
Alex Gaynor2e85a922018-07-16 11:18:33 -040063 "rsa_signature_4096_sha384_test.json",
64 "rsa_signature_4096_sha512_test.json",
Lucia Lic6ba99d2021-11-08 22:06:11 +080065 "rsa_signature_4096_sha512_256_test.json",
Alex Gaynor2e85a922018-07-16 11:18:33 -040066)
Alex Gaynorebfa6692018-08-02 18:49:25 -040067def test_rsa_pkcs1v15_signature(backend, wycheproof):
Alex Gaynor2e85a922018-07-16 11:18:33 -040068 key = serialization.load_der_public_key(
69 binascii.unhexlify(wycheproof.testgroup["keyDer"]), backend
70 )
71 digest = _DIGESTS[wycheproof.testgroup["sha"]]
72
Lucia Lic6ba99d2021-11-08 22:06:11 +080073 if digest is None or not backend.hash_supported(digest):
74 pytest.skip(
75 "Hash {} not supported".format(wycheproof.testgroup["sha"])
76 )
77
Alex Gaynor2e85a922018-07-16 11:18:33 -040078 if should_verify(backend, wycheproof):
79 key.verify(
80 binascii.unhexlify(wycheproof.testcase["sig"]),
81 binascii.unhexlify(wycheproof.testcase["msg"]),
82 padding.PKCS1v15(),
83 digest,
84 )
85 else:
86 with pytest.raises(InvalidSignature):
87 key.verify(
88 binascii.unhexlify(wycheproof.testcase["sig"]),
89 binascii.unhexlify(wycheproof.testcase["msg"]),
90 padding.PKCS1v15(),
91 digest,
92 )
Alex Gaynorebfa6692018-08-02 18:49:25 -040093
94
Lucia Lic6ba99d2021-11-08 22:06:11 +080095@pytest.mark.wycheproof_tests("rsa_sig_gen_misc_test.json")
96def test_rsa_pkcs1v15_signature_generation(backend, wycheproof):
97 key = serialization.load_pem_private_key(
98 wycheproof.testgroup["privateKeyPem"].encode(),
99 password=None,
100 backend=backend,
101 )
102 digest = _DIGESTS[wycheproof.testgroup["sha"]]
103
104 sig = key.sign(
105 binascii.unhexlify(wycheproof.testcase["msg"]),
106 padding.PKCS1v15(),
107 digest,
108 )
109 assert sig == binascii.unhexlify(wycheproof.testcase["sig"])
110
111
Alex Gaynorebfa6692018-08-02 18:49:25 -0400112@pytest.mark.requires_backend_interface(interface=RSABackend)
113@pytest.mark.wycheproof_tests(
114 "rsa_pss_2048_sha1_mgf1_20_test.json",
115 "rsa_pss_2048_sha256_mgf1_0_test.json",
116 "rsa_pss_2048_sha256_mgf1_32_test.json",
Lucia Lic6ba99d2021-11-08 22:06:11 +0800117 "rsa_pss_2048_sha512_256_mgf1_28_test.json",
118 "rsa_pss_2048_sha512_256_mgf1_32_test.json",
Alex Gaynorebfa6692018-08-02 18:49:25 -0400119 "rsa_pss_3072_sha256_mgf1_32_test.json",
120 "rsa_pss_4096_sha256_mgf1_32_test.json",
121 "rsa_pss_4096_sha512_mgf1_32_test.json",
122 "rsa_pss_misc_test.json",
123)
124def test_rsa_pss_signature(backend, wycheproof):
125 key = serialization.load_der_public_key(
126 binascii.unhexlify(wycheproof.testgroup["keyDer"]), backend
127 )
128 digest = _DIGESTS[wycheproof.testgroup["sha"]]
129 mgf_digest = _DIGESTS[wycheproof.testgroup["mgfSha"]]
130
Lucia Lic6ba99d2021-11-08 22:06:11 +0800131 if digest is None or mgf_digest is None:
132 pytest.skip(
133 "PSS with digest={} and MGF digest={} not supported".format(
134 wycheproof.testgroup["sha"],
135 wycheproof.testgroup["mgfSha"],
136 )
137 )
138
Alex Gaynorebfa6692018-08-02 18:49:25 -0400139 if wycheproof.valid or wycheproof.acceptable:
140 key.verify(
141 binascii.unhexlify(wycheproof.testcase["sig"]),
142 binascii.unhexlify(wycheproof.testcase["msg"]),
143 padding.PSS(
144 mgf=padding.MGF1(mgf_digest),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800145 salt_length=wycheproof.testgroup["sLen"],
Alex Gaynorebfa6692018-08-02 18:49:25 -0400146 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800147 digest,
Alex Gaynorebfa6692018-08-02 18:49:25 -0400148 )
149 else:
150 with pytest.raises(InvalidSignature):
151 key.verify(
152 binascii.unhexlify(wycheproof.testcase["sig"]),
153 binascii.unhexlify(wycheproof.testcase["msg"]),
154 padding.PSS(
155 mgf=padding.MGF1(mgf_digest),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800156 salt_length=wycheproof.testgroup["sLen"],
Alex Gaynorebfa6692018-08-02 18:49:25 -0400157 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800158 digest,
159 )
160
161
162@pytest.mark.requires_backend_interface(interface=RSABackend)
163@pytest.mark.wycheproof_tests(
164 "rsa_oaep_2048_sha1_mgf1sha1_test.json",
165 "rsa_oaep_2048_sha224_mgf1sha1_test.json",
166 "rsa_oaep_2048_sha224_mgf1sha224_test.json",
167 "rsa_oaep_2048_sha256_mgf1sha1_test.json",
168 "rsa_oaep_2048_sha256_mgf1sha256_test.json",
169 "rsa_oaep_2048_sha384_mgf1sha1_test.json",
170 "rsa_oaep_2048_sha384_mgf1sha384_test.json",
171 "rsa_oaep_2048_sha512_mgf1sha1_test.json",
172 "rsa_oaep_2048_sha512_mgf1sha512_test.json",
173 "rsa_oaep_3072_sha256_mgf1sha1_test.json",
174 "rsa_oaep_3072_sha256_mgf1sha256_test.json",
175 "rsa_oaep_3072_sha512_mgf1sha1_test.json",
176 "rsa_oaep_3072_sha512_mgf1sha512_test.json",
177 "rsa_oaep_4096_sha256_mgf1sha1_test.json",
178 "rsa_oaep_4096_sha256_mgf1sha256_test.json",
179 "rsa_oaep_4096_sha512_mgf1sha1_test.json",
180 "rsa_oaep_4096_sha512_mgf1sha512_test.json",
181 "rsa_oaep_misc_test.json",
182)
183def test_rsa_oaep_encryption(backend, wycheproof):
184 key = serialization.load_pem_private_key(
185 wycheproof.testgroup["privateKeyPem"].encode("ascii"),
186 password=None,
187 backend=backend,
188 )
189 digest = _DIGESTS[wycheproof.testgroup["sha"]]
190 mgf_digest = _DIGESTS[wycheproof.testgroup["mgfSha"]]
191
192 padding_algo = padding.OAEP(
193 mgf=padding.MGF1(algorithm=mgf_digest),
194 algorithm=digest,
195 label=binascii.unhexlify(wycheproof.testcase["label"]),
196 )
197
198 if not backend.rsa_padding_supported(padding_algo):
199 pytest.skip(
200 "OAEP with digest={} and MGF digest={} not supported".format(
201 wycheproof.testgroup["sha"],
202 wycheproof.testgroup["mgfSha"],
203 )
204 )
205
206 if wycheproof.valid or wycheproof.acceptable:
207 pt = key.decrypt(
208 binascii.unhexlify(wycheproof.testcase["ct"]), padding_algo
209 )
210 assert pt == binascii.unhexlify(wycheproof.testcase["msg"])
211 else:
212 with pytest.raises(ValueError):
213 key.decrypt(
214 binascii.unhexlify(wycheproof.testcase["ct"]), padding_algo
215 )
216
217
218@pytest.mark.wycheproof_tests(
219 "rsa_pkcs1_2048_test.json",
220 "rsa_pkcs1_3072_test.json",
221 "rsa_pkcs1_4096_test.json",
222)
223def test_rsa_pkcs1_encryption(backend, wycheproof):
224 key = serialization.load_pem_private_key(
225 wycheproof.testgroup["privateKeyPem"].encode("ascii"),
226 password=None,
227 backend=backend,
228 )
229
230 if wycheproof.valid:
231 pt = key.decrypt(
232 binascii.unhexlify(wycheproof.testcase["ct"]), padding.PKCS1v15()
233 )
234 assert pt == binascii.unhexlify(wycheproof.testcase["msg"])
235 else:
236 with pytest.raises(ValueError):
237 key.decrypt(
238 binascii.unhexlify(wycheproof.testcase["ct"]),
239 padding.PKCS1v15(),
Alex Gaynorebfa6692018-08-02 18:49:25 -0400240 )