1# 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 ( 12 AlreadyFinalized, InvalidKey, _Reasons 13) 14from cryptography.hazmat.backends.interfaces import HMACBackend 15from cryptography.hazmat.backends.interfaces import HashBackend 16from cryptography.hazmat.primitives import hashes 17from cryptography.hazmat.primitives.kdf.concatkdf import ConcatKDFHMAC 18from cryptography.hazmat.primitives.kdf.concatkdf import ConcatKDFHash 19 20from ...utils import raises_unsupported_algorithm 21 22 23@pytest.mark.requires_backend_interface(interface=HashBackend) 24class TestConcatKDFHash(object): 25 def test_length_limit(self, backend): 26 big_length = hashes.SHA256().digest_size * (2 ** 32 - 1) + 1 27 28 with pytest.raises(ValueError): 29 ConcatKDFHash(hashes.SHA256(), big_length, None, backend) 30 31 def test_already_finalized(self, backend): 32 ckdf = ConcatKDFHash(hashes.SHA256(), 16, None, backend) 33 34 ckdf.derive(b"\x01" * 16) 35 36 with pytest.raises(AlreadyFinalized): 37 ckdf.derive(b"\x02" * 16) 38 39 def test_derive(self, backend): 40 prk = binascii.unhexlify( 41 b"52169af5c485dcc2321eb8d26d5efa21fb9b93c98e38412ee2484cf14f0d0d23" 42 ) 43 44 okm = binascii.unhexlify(b"1c3bc9e7c4547c5191c0d478cccaed55") 45 46 oinfo = binascii.unhexlify( 47 b"a1b2c3d4e53728157e634612c12d6d5223e204aeea4341565369647bd184bcd2" 48 b"46f72971f292badaa2fe4124612cba" 49 ) 50 51 ckdf = ConcatKDFHash(hashes.SHA256(), 16, oinfo, backend) 52 53 assert ckdf.derive(prk) == okm 54 55 def test_buffer_protocol(self, backend): 56 prk = binascii.unhexlify( 57 b"52169af5c485dcc2321eb8d26d5efa21fb9b93c98e38412ee2484cf14f0d0d23" 58 ) 59 60 okm = binascii.unhexlify(b"1c3bc9e7c4547c5191c0d478cccaed55") 61 62 oinfo = binascii.unhexlify( 63 b"a1b2c3d4e53728157e634612c12d6d5223e204aeea4341565369647bd184bcd2" 64 b"46f72971f292badaa2fe4124612cba" 65 ) 66 67 ckdf = ConcatKDFHash(hashes.SHA256(), 16, oinfo, backend) 68 69 assert ckdf.derive(bytearray(prk)) == okm 70 71 def test_verify(self, backend): 72 prk = binascii.unhexlify( 73 b"52169af5c485dcc2321eb8d26d5efa21fb9b93c98e38412ee2484cf14f0d0d23" 74 ) 75 76 okm = binascii.unhexlify(b"1c3bc9e7c4547c5191c0d478cccaed55") 77 78 oinfo = binascii.unhexlify( 79 b"a1b2c3d4e53728157e634612c12d6d5223e204aeea4341565369647bd184bcd2" 80 b"46f72971f292badaa2fe4124612cba" 81 ) 82 83 ckdf = ConcatKDFHash(hashes.SHA256(), 16, oinfo, backend) 84 85 assert ckdf.verify(prk, okm) is None 86 87 def test_invalid_verify(self, backend): 88 prk = binascii.unhexlify( 89 b"52169af5c485dcc2321eb8d26d5efa21fb9b93c98e38412ee2484cf14f0d0d23" 90 ) 91 92 oinfo = binascii.unhexlify( 93 b"a1b2c3d4e53728157e634612c12d6d5223e204aeea4341565369647bd184bcd2" 94 b"46f72971f292badaa2fe4124612cba" 95 ) 96 97 ckdf = ConcatKDFHash(hashes.SHA256(), 16, oinfo, backend) 98 99 with pytest.raises(InvalidKey): 100 ckdf.verify(prk, b"wrong key") 101 102 def test_unicode_typeerror(self, backend): 103 with pytest.raises(TypeError): 104 ConcatKDFHash( 105 hashes.SHA256(), 106 16, 107 otherinfo=u"foo", 108 backend=backend 109 ) 110 111 with pytest.raises(TypeError): 112 ckdf = ConcatKDFHash( 113 hashes.SHA256(), 114 16, 115 otherinfo=None, 116 backend=backend 117 ) 118 119 ckdf.derive(u"foo") 120 121 with pytest.raises(TypeError): 122 ckdf = ConcatKDFHash( 123 hashes.SHA256(), 124 16, 125 otherinfo=None, 126 backend=backend 127 ) 128 129 ckdf.verify(u"foo", b"bar") 130 131 with pytest.raises(TypeError): 132 ckdf = ConcatKDFHash( 133 hashes.SHA256(), 134 16, 135 otherinfo=None, 136 backend=backend 137 ) 138 139 ckdf.verify(b"foo", u"bar") 140 141 142@pytest.mark.requires_backend_interface(interface=HMACBackend) 143class TestConcatKDFHMAC(object): 144 def test_length_limit(self, backend): 145 big_length = hashes.SHA256().digest_size * (2 ** 32 - 1) + 1 146 147 with pytest.raises(ValueError): 148 ConcatKDFHMAC(hashes.SHA256(), big_length, None, None, backend) 149 150 def test_already_finalized(self, backend): 151 ckdf = ConcatKDFHMAC(hashes.SHA256(), 16, None, None, backend) 152 153 ckdf.derive(b"\x01" * 16) 154 155 with pytest.raises(AlreadyFinalized): 156 ckdf.derive(b"\x02" * 16) 157 158 def test_derive(self, backend): 159 prk = binascii.unhexlify( 160 b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4" 161 b"b831cde499dff1ce45f6179f741c728aa733583b02409208" 162 b"8f0af7fce1d045edbc5790931e8d5ca79c73" 163 ) 164 165 okm = binascii.unhexlify(b"64ce901db10d558661f10b6836a122a7" 166 b"605323ce2f39bf27eaaac8b34cf89f2f") 167 168 oinfo = binascii.unhexlify( 169 b"a1b2c3d4e55e600be5f367e0e8a465f4bf2704db00c9325c" 170 b"9fbd216d12b49160b2ae5157650f43415653696421e68e" 171 ) 172 173 ckdf = ConcatKDFHMAC(hashes.SHA512(), 32, None, oinfo, backend) 174 175 assert ckdf.derive(prk) == okm 176 177 def test_buffer_protocol(self, backend): 178 prk = binascii.unhexlify( 179 b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4" 180 b"b831cde499dff1ce45f6179f741c728aa733583b02409208" 181 b"8f0af7fce1d045edbc5790931e8d5ca79c73" 182 ) 183 184 okm = binascii.unhexlify(b"64ce901db10d558661f10b6836a122a7" 185 b"605323ce2f39bf27eaaac8b34cf89f2f") 186 187 oinfo = binascii.unhexlify( 188 b"a1b2c3d4e55e600be5f367e0e8a465f4bf2704db00c9325c" 189 b"9fbd216d12b49160b2ae5157650f43415653696421e68e" 190 ) 191 192 ckdf = ConcatKDFHMAC(hashes.SHA512(), 32, None, oinfo, backend) 193 194 assert ckdf.derive(bytearray(prk)) == okm 195 196 def test_derive_explicit_salt(self, backend): 197 prk = binascii.unhexlify( 198 b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4" 199 b"b831cde499dff1ce45f6179f741c728aa733583b02409208" 200 b"8f0af7fce1d045edbc5790931e8d5ca79c73" 201 ) 202 203 okm = binascii.unhexlify(b"64ce901db10d558661f10b6836a122a7" 204 b"605323ce2f39bf27eaaac8b34cf89f2f") 205 206 oinfo = binascii.unhexlify( 207 b"a1b2c3d4e55e600be5f367e0e8a465f4bf2704db00c9325c" 208 b"9fbd216d12b49160b2ae5157650f43415653696421e68e" 209 ) 210 211 ckdf = ConcatKDFHMAC( 212 hashes.SHA512(), 32, b"\x00" * 128, oinfo, backend 213 ) 214 215 assert ckdf.derive(prk) == okm 216 217 def test_verify(self, backend): 218 prk = binascii.unhexlify( 219 b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4" 220 b"b831cde499dff1ce45f6179f741c728aa733583b02409208" 221 b"8f0af7fce1d045edbc5790931e8d5ca79c73" 222 ) 223 224 okm = binascii.unhexlify(b"64ce901db10d558661f10b6836a122a7" 225 b"605323ce2f39bf27eaaac8b34cf89f2f") 226 227 oinfo = binascii.unhexlify( 228 b"a1b2c3d4e55e600be5f367e0e8a465f4bf2704db00c9325c" 229 b"9fbd216d12b49160b2ae5157650f43415653696421e68e" 230 ) 231 232 ckdf = ConcatKDFHMAC(hashes.SHA512(), 32, None, oinfo, backend) 233 234 assert ckdf.verify(prk, okm) is None 235 236 def test_invalid_verify(self, backend): 237 prk = binascii.unhexlify( 238 b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4" 239 b"b831cde499dff1ce45f6179f741c728aa733583b02409208" 240 b"8f0af7fce1d045edbc5790931e8d5ca79c73" 241 ) 242 243 oinfo = binascii.unhexlify( 244 b"a1b2c3d4e55e600be5f367e0e8a465f4bf2704db00c9325c" 245 b"9fbd216d12b49160b2ae5157650f43415653696421e68e" 246 ) 247 248 ckdf = ConcatKDFHMAC(hashes.SHA512(), 32, None, oinfo, backend) 249 250 with pytest.raises(InvalidKey): 251 ckdf.verify(prk, b"wrong key") 252 253 def test_unicode_typeerror(self, backend): 254 with pytest.raises(TypeError): 255 ConcatKDFHMAC( 256 hashes.SHA256(), 257 16, salt=u"foo", 258 otherinfo=None, 259 backend=backend 260 ) 261 262 with pytest.raises(TypeError): 263 ConcatKDFHMAC( 264 hashes.SHA256(), 265 16, salt=None, 266 otherinfo=u"foo", 267 backend=backend 268 ) 269 270 with pytest.raises(TypeError): 271 ckdf = ConcatKDFHMAC( 272 hashes.SHA256(), 273 16, salt=None, 274 otherinfo=None, 275 backend=backend 276 ) 277 278 ckdf.derive(u"foo") 279 280 with pytest.raises(TypeError): 281 ckdf = ConcatKDFHMAC( 282 hashes.SHA256(), 283 16, salt=None, 284 otherinfo=None, 285 backend=backend 286 ) 287 288 ckdf.verify(u"foo", b"bar") 289 290 with pytest.raises(TypeError): 291 ckdf = ConcatKDFHMAC( 292 hashes.SHA256(), 293 16, salt=None, 294 otherinfo=None, 295 backend=backend 296 ) 297 298 ckdf.verify(b"foo", u"bar") 299 300 301def test_invalid_backend(): 302 pretend_backend = object() 303 304 with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE): 305 ConcatKDFHash(hashes.SHA256(), 16, None, pretend_backend) 306 with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE): 307 ConcatKDFHMAC(hashes.SHA256(), 16, None, None, pretend_backend) 308