blob: 3f1eff66e00f33f7ac2fb0c11756fa75ea4ada71 [file] [log] [blame]
Alex Gaynor5951f462014-11-16 09:08:42 -08001# 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.
Alex Gaynorc37feed2014-03-08 08:32:56 -08004
5from __future__ import absolute_import, division, print_function
6
Alex Gaynorbd458ae2013-10-16 11:59:30 -07007import binascii
David Reid5443e9d2014-01-22 17:18:49 -08008import itertools
Paul Kehrerafc1ccd2014-03-19 11:49:32 -04009import os
David Reid5443e9d2014-01-22 17:18:49 -080010
Alex Gaynorbd458ae2013-10-16 11:59:30 -070011import pytest
12
Paul Kehrerafc1ccd2014-03-19 11:49:32 -040013from cryptography.exceptions import (
Lucia Lic6ba99d2021-11-08 22:06:11 +080014 AlreadyFinalized,
15 AlreadyUpdated,
16 InvalidSignature,
17 InvalidTag,
18 NotYetFinalized,
Paul Kehrerafc1ccd2014-03-19 11:49:32 -040019)
Lucia Lic6ba99d2021-11-08 22:06:11 +080020from cryptography.hazmat.primitives import hashes, hmac, serialization
Paul Kehrerc85f1792014-03-19 09:45:42 -040021from cryptography.hazmat.primitives.asymmetric import rsa
Paul Kehrer21dde562013-11-06 12:22:09 +080022from cryptography.hazmat.primitives.ciphers import Cipher
Lucia Lic6ba99d2021-11-08 22:06:11 +080023from cryptography.hazmat.primitives.ciphers.modes import GCM
Ayrxac1a0792014-05-07 17:02:21 +080024from cryptography.hazmat.primitives.kdf.hkdf import HKDF, HKDFExpand
Jared6d7fe002016-05-29 17:32:37 -070025from cryptography.hazmat.primitives.kdf.kbkdf import (
Lucia Lic6ba99d2021-11-08 22:06:11 +080026 CounterLocation,
27 KBKDFHMAC,
28 Mode,
Jared6d7fe002016-05-29 17:32:37 -070029)
Paul Kehrerafc1ccd2014-03-19 11:49:32 -040030from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
Alex Gaynorbd458ae2013-10-16 11:59:30 -070031
Paul Kehrerf7f6a9f2013-11-11 20:43:52 -060032from ...utils import load_vectors_from_file
33
Alex Gaynorbd458ae2013-10-16 11:59:30 -070034
Alex Gaynore5c5eec2013-12-13 08:10:20 -080035def _load_all_params(path, file_names, param_loader):
36 all_params = []
37 for file_name in file_names:
38 all_params.extend(
39 load_vectors_from_file(os.path.join(path, file_name), param_loader)
40 )
41 return all_params
42
Alex Gaynor4eec0bb2013-12-13 09:12:19 -080043
Lucia Lic6ba99d2021-11-08 22:06:11 +080044def generate_encrypt_test(
45 param_loader, path, file_names, cipher_factory, mode_factory
46):
Alex Gaynore5c5eec2013-12-13 08:10:20 -080047 all_params = _load_all_params(path, file_names, param_loader)
48
49 @pytest.mark.parametrize("params", all_params)
50 def test_encryption(self, backend, params):
Paul Kehrer783479c2013-12-26 21:08:45 -060051 encrypt_test(backend, cipher_factory, mode_factory, params)
Alex Gaynore5c5eec2013-12-13 08:10:20 -080052
Alex Gaynorbd458ae2013-10-16 11:59:30 -070053 return test_encryption
54
55
Paul Kehrer783479c2013-12-26 21:08:45 -060056def encrypt_test(backend, cipher_factory, mode_factory, params):
Paul Kehrer51032352017-05-20 10:09:02 -070057 assert backend.cipher_supported(
Paul Kehrerdbb64bd2016-07-11 02:13:40 +000058 cipher_factory(**params), mode_factory(**params)
Paul Kehrer51032352017-05-20 10:09:02 -070059 )
Paul Kehrerdbb64bd2016-07-11 02:13:40 +000060
Paul Kehrera620b7d2013-12-20 22:59:02 -060061 plaintext = params["plaintext"]
62 ciphertext = params["ciphertext"]
Alex Gaynor21919e22013-12-13 08:56:32 -080063 cipher = Cipher(
Lucia Lic6ba99d2021-11-08 22:06:11 +080064 cipher_factory(**params), mode_factory(**params), backend=backend
Alex Gaynor21919e22013-12-13 08:56:32 -080065 )
66 encryptor = cipher.encryptor()
67 actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext))
68 actual_ciphertext += encryptor.finalize()
69 assert actual_ciphertext == binascii.unhexlify(ciphertext)
70 decryptor = cipher.decryptor()
71 actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext))
72 actual_plaintext += decryptor.finalize()
73 assert actual_plaintext == binascii.unhexlify(plaintext)
74
75
Lucia Lic6ba99d2021-11-08 22:06:11 +080076def generate_aead_test(
77 param_loader, path, file_names, cipher_factory, mode_factory
78):
Alex Gaynore5c5eec2013-12-13 08:10:20 -080079 all_params = _load_all_params(path, file_names, param_loader)
80
81 @pytest.mark.parametrize("params", all_params)
82 def test_aead(self, backend, params):
Paul Kehrer783479c2013-12-26 21:08:45 -060083 aead_test(backend, cipher_factory, mode_factory, params)
Alex Gaynore5c5eec2013-12-13 08:10:20 -080084
Paul Kehrer22e80cb2013-11-20 21:27:00 -060085 return test_aead
86
87
Paul Kehrer783479c2013-12-26 21:08:45 -060088def aead_test(backend, cipher_factory, mode_factory, params):
Lucia Lic6ba99d2021-11-08 22:06:11 +080089 if mode_factory is GCM and len(params["iv"]) < 16:
90 # 16 because this is hex encoded data
91 pytest.skip("Less than 64-bit IVs are no longer supported")
92
93 if (
94 mode_factory is GCM
95 and backend._fips_enabled
96 and len(params["iv"]) != 24
97 ):
98 # Red Hat disables non-96-bit IV support as part of its FIPS
99 # patches. The check is for a byte length of 24 because the value is
100 # hex encoded.
101 pytest.skip("Non-96-bit IVs unsupported in FIPS mode.")
102
Alex Gaynor21919e22013-12-13 08:56:32 -0800103 if params.get("pt") is not None:
Paul Kehrera620b7d2013-12-20 22:59:02 -0600104 plaintext = params["pt"]
105 ciphertext = params["ct"]
106 aad = params["aad"]
Alex Gaynor21919e22013-12-13 08:56:32 -0800107 if params.get("fail") is True:
108 cipher = Cipher(
109 cipher_factory(binascii.unhexlify(params["key"])),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800110 mode_factory(
111 binascii.unhexlify(params["iv"]),
112 binascii.unhexlify(params["tag"]),
113 len(binascii.unhexlify(params["tag"])),
114 ),
115 backend,
Alex Gaynor21919e22013-12-13 08:56:32 -0800116 )
117 decryptor = cipher.decryptor()
118 decryptor.authenticate_additional_data(binascii.unhexlify(aad))
119 actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext))
120 with pytest.raises(InvalidTag):
121 decryptor.finalize()
122 else:
123 cipher = Cipher(
124 cipher_factory(binascii.unhexlify(params["key"])),
125 mode_factory(binascii.unhexlify(params["iv"]), None),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800126 backend,
Alex Gaynor21919e22013-12-13 08:56:32 -0800127 )
128 encryptor = cipher.encryptor()
129 encryptor.authenticate_additional_data(binascii.unhexlify(aad))
130 actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext))
131 actual_ciphertext += encryptor.finalize()
Alex Gaynor8f1b8e82014-06-29 20:43:29 -0700132 tag_len = len(binascii.unhexlify(params["tag"]))
133 assert binascii.hexlify(encryptor.tag[:tag_len]) == params["tag"]
Alex Gaynor21919e22013-12-13 08:56:32 -0800134 cipher = Cipher(
135 cipher_factory(binascii.unhexlify(params["key"])),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800136 mode_factory(
137 binascii.unhexlify(params["iv"]),
138 binascii.unhexlify(params["tag"]),
139 min_tag_length=tag_len,
140 ),
141 backend,
Alex Gaynor21919e22013-12-13 08:56:32 -0800142 )
143 decryptor = cipher.decryptor()
144 decryptor.authenticate_additional_data(binascii.unhexlify(aad))
145 actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext))
146 actual_plaintext += decryptor.finalize()
147 assert actual_plaintext == binascii.unhexlify(plaintext)
148
149
Lucia Lic6ba99d2021-11-08 22:06:11 +0800150def generate_stream_encryption_test(
151 param_loader, path, file_names, cipher_factory
152):
Alex Gaynore5c5eec2013-12-13 08:10:20 -0800153 all_params = _load_all_params(path, file_names, param_loader)
154
155 @pytest.mark.parametrize("params", all_params)
156 def test_stream_encryption(self, backend, params):
Paul Kehrer783479c2013-12-26 21:08:45 -0600157 stream_encryption_test(backend, cipher_factory, params)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800158
Paul Kehrer4da28c32013-11-07 07:50:17 +0800159 return test_stream_encryption
160
161
Paul Kehrer783479c2013-12-26 21:08:45 -0600162def stream_encryption_test(backend, cipher_factory, params):
Paul Kehrera620b7d2013-12-20 22:59:02 -0600163 plaintext = params["plaintext"]
164 ciphertext = params["ciphertext"]
165 offset = params["offset"]
Alex Gaynor21919e22013-12-13 08:56:32 -0800166 cipher = Cipher(cipher_factory(**params), None, backend=backend)
167 encryptor = cipher.encryptor()
168 # throw away offset bytes
169 encryptor.update(b"\x00" * int(offset))
170 actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext))
171 actual_ciphertext += encryptor.finalize()
172 assert actual_ciphertext == binascii.unhexlify(ciphertext)
173 decryptor = cipher.decryptor()
174 decryptor.update(b"\x00" * int(offset))
175 actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext))
176 actual_plaintext += decryptor.finalize()
177 assert actual_plaintext == binascii.unhexlify(plaintext)
178
179
Paul Kehrer783479c2013-12-26 21:08:45 -0600180def generate_hash_test(param_loader, path, file_names, hash_cls):
Alex Gaynore5c5eec2013-12-13 08:10:20 -0800181 all_params = _load_all_params(path, file_names, param_loader)
Paul Kehrer4da28c32013-11-07 07:50:17 +0800182
Alex Gaynore5c5eec2013-12-13 08:10:20 -0800183 @pytest.mark.parametrize("params", all_params)
184 def test_hash(self, backend, params):
Paul Kehrer783479c2013-12-26 21:08:45 -0600185 hash_test(backend, hash_cls, params)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800186
Paul Kehrerbde6fb52013-10-18 18:08:49 -0500187 return test_hash
188
189
Paul Kehrer783479c2013-12-26 21:08:45 -0600190def hash_test(backend, algorithm, params):
Alex Gaynor36e651c2014-01-27 10:08:35 -0800191 msg, md = params
Alex Gaynor21919e22013-12-13 08:56:32 -0800192 m = hashes.Hash(algorithm, backend=backend)
193 m.update(binascii.unhexlify(msg))
194 expected_md = md.replace(" ", "").lower().encode("ascii")
195 assert m.finalize() == binascii.unhexlify(expected_md)
196
197
Paul Kehrer162a17e2018-07-23 19:55:06 +0800198def generate_base_hash_test(algorithm, digest_size):
Paul Kehrerb078d8e2013-12-27 16:33:14 -0600199 def test_base_hash(self, backend):
Paul Kehrer162a17e2018-07-23 19:55:06 +0800200 base_hash_test(backend, algorithm, digest_size)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800201
Paul Kehrerb078d8e2013-12-27 16:33:14 -0600202 return test_base_hash
203
204
Paul Kehrer162a17e2018-07-23 19:55:06 +0800205def base_hash_test(backend, algorithm, digest_size):
Alex Gaynor21919e22013-12-13 08:56:32 -0800206 m = hashes.Hash(algorithm, backend=backend)
207 assert m.algorithm.digest_size == digest_size
Alex Gaynor21919e22013-12-13 08:56:32 -0800208 m_copy = m.copy()
209 assert m != m_copy
210 assert m._ctx != m_copy._ctx
211
212 m.update(b"abc")
213 copy = m.copy()
214 copy.update(b"123")
215 m.update(b"123")
216 assert copy.finalize() == m.finalize()
217
218
Paul Kehrerb078d8e2013-12-27 16:33:14 -0600219def generate_base_hmac_test(hash_cls):
220 def test_base_hmac(self, backend):
221 base_hmac_test(backend, hash_cls)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800222
Paul Kehrerb078d8e2013-12-27 16:33:14 -0600223 return test_base_hmac
224
225
226def base_hmac_test(backend, algorithm):
227 key = b"ab"
228 h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend)
229 h_copy = h.copy()
230 assert h != h_copy
231 assert h._ctx != h_copy._ctx
232
233
Paul Kehrer783479c2013-12-26 21:08:45 -0600234def generate_hmac_test(param_loader, path, file_names, algorithm):
Alex Gaynore5c5eec2013-12-13 08:10:20 -0800235 all_params = _load_all_params(path, file_names, param_loader)
Paul Kehrer0317b042013-10-28 17:34:27 -0500236
Alex Gaynore5c5eec2013-12-13 08:10:20 -0800237 @pytest.mark.parametrize("params", all_params)
238 def test_hmac(self, backend, params):
Paul Kehrer783479c2013-12-26 21:08:45 -0600239 hmac_test(backend, algorithm, params)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800240
Paul Kehrer0317b042013-10-28 17:34:27 -0500241 return test_hmac
242
243
Paul Kehrer783479c2013-12-26 21:08:45 -0600244def hmac_test(backend, algorithm, params):
Alex Gaynor36e651c2014-01-27 10:08:35 -0800245 msg, md, key = params
Alex Gaynor21919e22013-12-13 08:56:32 -0800246 h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend)
247 h.update(binascii.unhexlify(msg))
248 assert h.finalize() == binascii.unhexlify(md.encode("ascii"))
Paul Kehrer0317b042013-10-28 17:34:27 -0500249
Alex Gaynor21919e22013-12-13 08:56:32 -0800250
Paul Kehrer1050ddf2014-01-27 21:04:03 -0600251def generate_pbkdf2_test(param_loader, path, file_names, algorithm):
252 all_params = _load_all_params(path, file_names, param_loader)
253
254 @pytest.mark.parametrize("params", all_params)
255 def test_pbkdf2(self, backend, params):
256 pbkdf2_test(backend, algorithm, params)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800257
Paul Kehrer1050ddf2014-01-27 21:04:03 -0600258 return test_pbkdf2
259
260
261def pbkdf2_test(backend, algorithm, params):
262 # Password and salt can contain \0, which should be loaded as a null char.
263 # The NIST loader loads them as literal strings so we replace with the
264 # proper value.
Paul Kehrer1277bc72014-01-28 17:09:59 -0600265 kdf = PBKDF2HMAC(
Paul Kehrer1050ddf2014-01-27 21:04:03 -0600266 algorithm,
267 int(params["length"]),
268 params["salt"],
269 int(params["iterations"]),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800270 backend,
Paul Kehrer1050ddf2014-01-27 21:04:03 -0600271 )
272 derived_key = kdf.derive(params["password"])
273 assert binascii.hexlify(derived_key) == params["derived_key"]
274
275
Paul Kehrer783479c2013-12-26 21:08:45 -0600276def generate_aead_exception_test(cipher_factory, mode_factory):
Alex Gaynor21919e22013-12-13 08:56:32 -0800277 def test_aead_exception(self, backend):
Paul Kehrer783479c2013-12-26 21:08:45 -0600278 aead_exception_test(backend, cipher_factory, mode_factory)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800279
Paul Kehrerce9c6112013-11-22 14:10:59 -0600280 return test_aead_exception
Paul Kehrer22e80cb2013-11-20 21:27:00 -0600281
282
Paul Kehrer783479c2013-12-26 21:08:45 -0600283def aead_exception_test(backend, cipher_factory, mode_factory):
Alex Gaynor21919e22013-12-13 08:56:32 -0800284 cipher = Cipher(
285 cipher_factory(binascii.unhexlify(b"0" * 32)),
286 mode_factory(binascii.unhexlify(b"0" * 24)),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800287 backend,
Alex Gaynor21919e22013-12-13 08:56:32 -0800288 )
289 encryptor = cipher.encryptor()
290 encryptor.update(b"a" * 16)
291 with pytest.raises(NotYetFinalized):
292 encryptor.tag
293 with pytest.raises(AlreadyUpdated):
294 encryptor.authenticate_additional_data(b"b" * 16)
295 encryptor.finalize()
296 with pytest.raises(AlreadyFinalized):
297 encryptor.authenticate_additional_data(b"b" * 16)
298 with pytest.raises(AlreadyFinalized):
299 encryptor.update(b"b" * 16)
300 with pytest.raises(AlreadyFinalized):
301 encryptor.finalize()
302 cipher = Cipher(
303 cipher_factory(binascii.unhexlify(b"0" * 32)),
304 mode_factory(binascii.unhexlify(b"0" * 24), b"0" * 16),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800305 backend,
Alex Gaynor21919e22013-12-13 08:56:32 -0800306 )
307 decryptor = cipher.decryptor()
308 decryptor.update(b"a" * 16)
309 with pytest.raises(AttributeError):
310 decryptor.tag
Paul Kehrerb91221d2013-12-04 17:56:40 -0600311
Alex Gaynor21919e22013-12-13 08:56:32 -0800312
Paul Kehrer783479c2013-12-26 21:08:45 -0600313def generate_aead_tag_exception_test(cipher_factory, mode_factory):
Alex Gaynor21919e22013-12-13 08:56:32 -0800314 def test_aead_tag_exception(self, backend):
Paul Kehrer783479c2013-12-26 21:08:45 -0600315 aead_tag_exception_test(backend, cipher_factory, mode_factory)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800316
Paul Kehrerb91221d2013-12-04 17:56:40 -0600317 return test_aead_tag_exception
Alex Gaynor21919e22013-12-13 08:56:32 -0800318
319
Paul Kehrer783479c2013-12-26 21:08:45 -0600320def aead_tag_exception_test(backend, cipher_factory, mode_factory):
Alex Gaynor21919e22013-12-13 08:56:32 -0800321 cipher = Cipher(
322 cipher_factory(binascii.unhexlify(b"0" * 32)),
323 mode_factory(binascii.unhexlify(b"0" * 24)),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800324 backend,
Alex Gaynor21919e22013-12-13 08:56:32 -0800325 )
Alex Gaynor516b1ad2014-01-01 12:28:37 -0800326
Paul Kehrerf7b4ede2013-12-21 17:25:19 -0600327 with pytest.raises(ValueError):
Alex Gaynor516b1ad2014-01-01 12:28:37 -0800328 mode_factory(binascii.unhexlify(b"0" * 24), b"000")
329
Alex Gaynora9477592014-06-30 10:03:22 -0700330 with pytest.raises(ValueError):
331 mode_factory(binascii.unhexlify(b"0" * 24), b"000000", 2)
332
Paul Kehrerf7b4ede2013-12-21 17:25:19 -0600333 cipher = Cipher(
334 cipher_factory(binascii.unhexlify(b"0" * 32)),
Alex Gaynor21919e22013-12-13 08:56:32 -0800335 mode_factory(binascii.unhexlify(b"0" * 24), b"0" * 16),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800336 backend,
Alex Gaynor21919e22013-12-13 08:56:32 -0800337 )
338 with pytest.raises(ValueError):
339 cipher.encryptor()
David Reid66c9cd92014-01-20 16:05:53 -0800340
341
David Reid5443e9d2014-01-22 17:18:49 -0800342def hkdf_derive_test(backend, algorithm, params):
David Reid0d492db2014-01-27 17:05:49 -0800343 hkdf = HKDF(
David Reid66c9cd92014-01-20 16:05:53 -0800344 algorithm,
David Reid0d492db2014-01-27 17:05:49 -0800345 int(params["l"]),
346 salt=binascii.unhexlify(params["salt"]) or None,
347 info=binascii.unhexlify(params["info"]) or None,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800348 backend=backend,
David Reid66c9cd92014-01-20 16:05:53 -0800349 )
350
David Reid0d492db2014-01-27 17:05:49 -0800351 okm = hkdf.derive(binascii.unhexlify(params["ikm"]))
352
David Reid14367302014-01-27 16:33:31 -0800353 assert okm == binascii.unhexlify(params["okm"])
David Reid66c9cd92014-01-20 16:05:53 -0800354
355
David Reid5443e9d2014-01-22 17:18:49 -0800356def hkdf_extract_test(backend, algorithm, params):
David Reid0d492db2014-01-27 17:05:49 -0800357 hkdf = HKDF(
David Reid5443e9d2014-01-22 17:18:49 -0800358 algorithm,
David Reid0d492db2014-01-27 17:05:49 -0800359 int(params["l"]),
360 salt=binascii.unhexlify(params["salt"]) or None,
361 info=binascii.unhexlify(params["info"]) or None,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800362 backend=backend,
David Reid5443e9d2014-01-22 17:18:49 -0800363 )
364
David Reid15fd6432014-01-30 15:28:09 -0800365 prk = hkdf._extract(binascii.unhexlify(params["ikm"]))
David Reid0d492db2014-01-27 17:05:49 -0800366
David Reid14367302014-01-27 16:33:31 -0800367 assert prk == binascii.unhexlify(params["prk"])
David Reid5443e9d2014-01-22 17:18:49 -0800368
369
370def hkdf_expand_test(backend, algorithm, params):
Ayrxac1a0792014-05-07 17:02:21 +0800371 hkdf = HKDFExpand(
David Reid5443e9d2014-01-22 17:18:49 -0800372 algorithm,
David Reid14367302014-01-27 16:33:31 -0800373 int(params["l"]),
David Reid0d492db2014-01-27 17:05:49 -0800374 info=binascii.unhexlify(params["info"]) or None,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800375 backend=backend,
David Reid5443e9d2014-01-22 17:18:49 -0800376 )
377
Ayrx2d6cd442014-05-09 14:48:06 +0800378 okm = hkdf.derive(binascii.unhexlify(params["prk"]))
David Reid0d492db2014-01-27 17:05:49 -0800379
David Reid14367302014-01-27 16:33:31 -0800380 assert okm == binascii.unhexlify(params["okm"])
David Reid5443e9d2014-01-22 17:18:49 -0800381
382
David Reid66c9cd92014-01-20 16:05:53 -0800383def generate_hkdf_test(param_loader, path, file_names, algorithm):
384 all_params = _load_all_params(path, file_names, param_loader)
385
David Reid5443e9d2014-01-22 17:18:49 -0800386 all_tests = [hkdf_extract_test, hkdf_expand_test, hkdf_derive_test]
387
388 @pytest.mark.parametrize(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800389 ("params", "hkdf_test"), itertools.product(all_params, all_tests)
David Reid5443e9d2014-01-22 17:18:49 -0800390 )
391 def test_hkdf(self, backend, params, hkdf_test):
David Reid66c9cd92014-01-20 16:05:53 -0800392 hkdf_test(backend, algorithm, params)
393
394 return test_hkdf
Paul Kehrerb5936a72014-03-13 21:03:00 -0400395
396
Jared6d7fe002016-05-29 17:32:37 -0700397def generate_kbkdf_counter_mode_test(param_loader, path, file_names):
398 all_params = _load_all_params(path, file_names, param_loader)
399
400 @pytest.mark.parametrize("params", all_params)
401 def test_kbkdf(self, backend, params):
402 kbkdf_counter_mode_test(backend, params)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800403
Jared6d7fe002016-05-29 17:32:37 -0700404 return test_kbkdf
405
406
407def kbkdf_counter_mode_test(backend, params):
408 supported_algorithms = {
Lucia Lic6ba99d2021-11-08 22:06:11 +0800409 "hmac_sha1": hashes.SHA1,
410 "hmac_sha224": hashes.SHA224,
411 "hmac_sha256": hashes.SHA256,
412 "hmac_sha384": hashes.SHA384,
413 "hmac_sha512": hashes.SHA512,
Jared6d7fe002016-05-29 17:32:37 -0700414 }
415
Paul Kehrercb0fa2e2016-05-29 22:37:33 -0500416 supported_counter_locations = {
Jared6d7fe002016-05-29 17:32:37 -0700417 "before_fixed": CounterLocation.BeforeFixed,
418 "after_fixed": CounterLocation.AfterFixed,
419 }
420
Lucia Lic6ba99d2021-11-08 22:06:11 +0800421 algorithm = supported_algorithms.get(params.get("prf"))
Jared6d7fe002016-05-29 17:32:37 -0700422 if algorithm is None or not backend.hmac_supported(algorithm()):
Lucia Lic6ba99d2021-11-08 22:06:11 +0800423 pytest.skip(
424 "KBKDF does not support algorithm: {}".format(params.get("prf"))
425 )
Jared6d7fe002016-05-29 17:32:37 -0700426
Paul Kehrercb0fa2e2016-05-29 22:37:33 -0500427 ctr_loc = supported_counter_locations.get(params.get("ctrlocation"))
Jared6d7fe002016-05-29 17:32:37 -0700428 if ctr_loc is None or not isinstance(ctr_loc, CounterLocation):
Lucia Lic6ba99d2021-11-08 22:06:11 +0800429 pytest.skip(
430 "Does not support counter location: {}".format(
431 params.get("ctrlocation")
432 )
433 )
Jared6d7fe002016-05-29 17:32:37 -0700434
435 ctrkdf = KBKDFHMAC(
436 algorithm(),
437 Mode.CounterMode,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800438 params["l"] // 8,
439 params["rlen"] // 8,
Jared6d7fe002016-05-29 17:32:37 -0700440 None,
441 ctr_loc,
442 None,
443 None,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800444 binascii.unhexlify(params["fixedinputdata"]),
445 backend=backend,
446 )
Jared6d7fe002016-05-29 17:32:37 -0700447
Lucia Lic6ba99d2021-11-08 22:06:11 +0800448 ko = ctrkdf.derive(binascii.unhexlify(params["ki"]))
Jared6d7fe002016-05-29 17:32:37 -0700449 assert binascii.hexlify(ko) == params["ko"]
450
451
Lucia Lic6ba99d2021-11-08 22:06:11 +0800452def generate_rsa_verification_test(
453 param_loader, path, file_names, hash_alg, pad_factory
454):
Paul Kehrerb5936a72014-03-13 21:03:00 -0400455 all_params = _load_all_params(path, file_names, param_loader)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800456 all_params = [
457 i for i in all_params if i["algorithm"] == hash_alg.name.upper()
458 ]
Paul Kehrerb5936a72014-03-13 21:03:00 -0400459
460 @pytest.mark.parametrize("params", all_params)
Paul Kehrerf29c3c52014-03-19 09:35:40 -0400461 def test_rsa_verification(self, backend, params):
Paul Kehrerc85f1792014-03-19 09:45:42 -0400462 rsa_verification_test(backend, params, hash_alg, pad_factory)
Paul Kehrerb5936a72014-03-13 21:03:00 -0400463
Paul Kehrerf29c3c52014-03-19 09:35:40 -0400464 return test_rsa_verification
Paul Kehrerb5936a72014-03-13 21:03:00 -0400465
466
Paul Kehrerc85f1792014-03-19 09:45:42 -0400467def rsa_verification_test(backend, params, hash_alg, pad_factory):
Paul Kehrer6af3c6e2014-06-06 21:05:23 -0500468 public_numbers = rsa.RSAPublicNumbers(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800469 e=params["public_exponent"], n=params["modulus"]
Paul Kehrer762014e2014-03-16 17:47:22 -0400470 )
Paul Kehrer144a4152014-06-20 11:52:37 -0600471 public_key = public_numbers.public_key(backend)
Paul Kehrerc85f1792014-03-19 09:45:42 -0400472 pad = pad_factory(params, hash_alg)
Alex Gaynor0242c082017-12-09 20:58:52 -0500473 signature = binascii.unhexlify(params["s"])
474 msg = binascii.unhexlify(params["msg"])
Paul Kehrer49c8e212014-03-18 07:54:34 -0400475 if params["fail"]:
476 with pytest.raises(InvalidSignature):
Lucia Lic6ba99d2021-11-08 22:06:11 +0800477 public_key.verify(signature, msg, pad, hash_alg)
Paul Kehrer49c8e212014-03-18 07:54:34 -0400478 else:
Lucia Lic6ba99d2021-11-08 22:06:11 +0800479 public_key.verify(signature, msg, pad, hash_alg)
Alex Stapleton458c09b2014-04-23 20:58:37 +0100480
481
Paul Kehrer6af3c6e2014-06-06 21:05:23 -0500482def _check_rsa_private_numbers(skey):
Alex Stapleton458c09b2014-04-23 20:58:37 +0100483 assert skey
Paul Kehrer6af3c6e2014-06-06 21:05:23 -0500484 pkey = skey.public_numbers
485 assert pkey
486 assert pkey.e
487 assert pkey.n
488 assert skey.d
489 assert skey.p * skey.q == pkey.n
Alex Stapleton458c09b2014-04-23 20:58:37 +0100490 assert skey.dmp1 == rsa.rsa_crt_dmp1(skey.d, skey.p)
491 assert skey.dmq1 == rsa.rsa_crt_dmq1(skey.d, skey.q)
492 assert skey.iqmp == rsa.rsa_crt_iqmp(skey.p, skey.q)
Paul Kehrer85c11062014-12-22 07:56:05 -0600493
494
495def _check_dsa_private_numbers(skey):
496 assert skey
497 pkey = skey.public_numbers
498 params = pkey.parameter_numbers
499 assert pow(params.g, skey.x, params.p) == pkey.y
Lucia Lic6ba99d2021-11-08 22:06:11 +0800500
501
502def skip_fips_traditional_openssl(backend, fmt):
503 if (
504 fmt is serialization.PrivateFormat.TraditionalOpenSSL
505 and backend._fips_enabled
506 ):
507 pytest.skip(
508 "Traditional OpenSSL key format is not supported in FIPS mode."
509 )