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 pytest 8 9from cryptography.exceptions import AlreadyFinalized, InvalidKey, _Reasons 10from cryptography.hazmat.backends.interfaces import HMACBackend 11from cryptography.hazmat.primitives import hashes 12from cryptography.hazmat.primitives.kdf.kbkdf import ( 13 CounterLocation, 14 KBKDFHMAC, 15 Mode, 16) 17 18from ...doubles import DummyHashAlgorithm 19from ...utils import raises_unsupported_algorithm 20 21 22@pytest.mark.requires_backend_interface(interface=HMACBackend) 23class TestKBKDFHMAC(object): 24 def test_invalid_key(self, backend): 25 kdf = KBKDFHMAC( 26 hashes.SHA256(), 27 Mode.CounterMode, 28 32, 29 4, 30 4, 31 CounterLocation.BeforeFixed, 32 b"label", 33 b"context", 34 None, 35 backend=backend, 36 ) 37 38 key = kdf.derive(b"material") 39 40 kdf = KBKDFHMAC( 41 hashes.SHA256(), 42 Mode.CounterMode, 43 32, 44 4, 45 4, 46 CounterLocation.BeforeFixed, 47 b"label", 48 b"context", 49 None, 50 backend=backend, 51 ) 52 53 with pytest.raises(InvalidKey): 54 kdf.verify(b"material2", key) 55 56 def test_already_finalized(self, backend): 57 kdf = KBKDFHMAC( 58 hashes.SHA256(), 59 Mode.CounterMode, 60 32, 61 4, 62 4, 63 CounterLocation.BeforeFixed, 64 b"label", 65 b"context", 66 None, 67 backend=backend, 68 ) 69 70 kdf.derive(b"material") 71 72 with pytest.raises(AlreadyFinalized): 73 kdf.derive(b"material2") 74 75 kdf = KBKDFHMAC( 76 hashes.SHA256(), 77 Mode.CounterMode, 78 32, 79 4, 80 4, 81 CounterLocation.BeforeFixed, 82 b"label", 83 b"context", 84 None, 85 backend=backend, 86 ) 87 88 key = kdf.derive(b"material") 89 90 with pytest.raises(AlreadyFinalized): 91 kdf.verify(b"material", key) 92 93 kdf = KBKDFHMAC( 94 hashes.SHA256(), 95 Mode.CounterMode, 96 32, 97 4, 98 4, 99 CounterLocation.BeforeFixed, 100 b"label", 101 b"context", 102 None, 103 backend=backend, 104 ) 105 kdf.verify(b"material", key) 106 107 with pytest.raises(AlreadyFinalized): 108 kdf.verify(b"material", key) 109 110 def test_key_length(self, backend): 111 kdf = KBKDFHMAC( 112 hashes.SHA1(), 113 Mode.CounterMode, 114 85899345920, 115 4, 116 4, 117 CounterLocation.BeforeFixed, 118 b"label", 119 b"context", 120 None, 121 backend=backend, 122 ) 123 124 with pytest.raises(ValueError): 125 kdf.derive(b"material") 126 127 def test_rlen(self, backend): 128 with pytest.raises(ValueError): 129 KBKDFHMAC( 130 hashes.SHA256(), 131 Mode.CounterMode, 132 32, 133 5, 134 4, 135 CounterLocation.BeforeFixed, 136 b"label", 137 b"context", 138 None, 139 backend=backend, 140 ) 141 142 def test_r_type(self, backend): 143 with pytest.raises(TypeError): 144 KBKDFHMAC( 145 hashes.SHA1(), 146 Mode.CounterMode, 147 32, 148 b"r", 149 4, 150 CounterLocation.BeforeFixed, 151 b"label", 152 b"context", 153 None, 154 backend=backend, 155 ) 156 157 def test_l_type(self, backend): 158 with pytest.raises(TypeError): 159 KBKDFHMAC( 160 hashes.SHA1(), 161 Mode.CounterMode, 162 32, 163 4, 164 b"l", 165 CounterLocation.BeforeFixed, 166 b"label", 167 b"context", 168 None, 169 backend=backend, 170 ) 171 172 def test_l(self, backend): 173 with pytest.raises(ValueError): 174 KBKDFHMAC( 175 hashes.SHA1(), 176 Mode.CounterMode, 177 32, 178 4, 179 None, 180 CounterLocation.BeforeFixed, 181 b"label", 182 b"context", 183 None, 184 backend=backend, 185 ) 186 187 def test_unsupported_mode(self, backend): 188 with pytest.raises(TypeError): 189 KBKDFHMAC( 190 hashes.SHA256(), 191 None, 192 32, 193 4, 194 4, 195 CounterLocation.BeforeFixed, 196 b"label", 197 b"context", 198 None, 199 backend=backend, 200 ) 201 202 def test_unsupported_location(self, backend): 203 with pytest.raises(TypeError): 204 KBKDFHMAC( 205 hashes.SHA256(), 206 Mode.CounterMode, 207 32, 208 4, 209 4, 210 None, 211 b"label", 212 b"context", 213 None, 214 backend=backend, 215 ) 216 217 def test_unsupported_parameters(self, backend): 218 with pytest.raises(ValueError): 219 KBKDFHMAC( 220 hashes.SHA256(), 221 Mode.CounterMode, 222 32, 223 4, 224 4, 225 CounterLocation.BeforeFixed, 226 b"label", 227 b"context", 228 b"fixed", 229 backend=backend, 230 ) 231 232 def test_unsupported_hash(self, backend): 233 with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH): 234 KBKDFHMAC( 235 object(), 236 Mode.CounterMode, 237 32, 238 4, 239 4, 240 CounterLocation.BeforeFixed, 241 b"label", 242 b"context", 243 None, 244 backend=backend, 245 ) 246 247 def test_unsupported_algorithm(self, backend): 248 with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH): 249 KBKDFHMAC( 250 DummyHashAlgorithm(), 251 Mode.CounterMode, 252 32, 253 4, 254 4, 255 CounterLocation.BeforeFixed, 256 b"label", 257 b"context", 258 None, 259 backend=backend, 260 ) 261 262 def test_invalid_backend(self, backend): 263 with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE): 264 KBKDFHMAC( 265 hashes.SHA256(), 266 Mode.CounterMode, 267 32, 268 4, 269 4, 270 CounterLocation.BeforeFixed, 271 b"label", 272 b"context", 273 None, 274 backend=object(), 275 ) 276 277 def test_unicode_error_label(self, backend): 278 with pytest.raises(TypeError): 279 KBKDFHMAC( 280 hashes.SHA256(), 281 Mode.CounterMode, 282 32, 283 4, 284 4, 285 CounterLocation.BeforeFixed, 286 u"label", 287 b"context", 288 backend=backend, 289 ) 290 291 def test_unicode_error_context(self, backend): 292 with pytest.raises(TypeError): 293 KBKDFHMAC( 294 hashes.SHA256(), 295 Mode.CounterMode, 296 32, 297 4, 298 4, 299 CounterLocation.BeforeFixed, 300 b"label", 301 u"context", 302 None, 303 backend=backend, 304 ) 305 306 def test_unicode_error_key_material(self, backend): 307 with pytest.raises(TypeError): 308 kdf = KBKDFHMAC( 309 hashes.SHA256(), 310 Mode.CounterMode, 311 32, 312 4, 313 4, 314 CounterLocation.BeforeFixed, 315 b"label", 316 b"context", 317 None, 318 backend=backend, 319 ) 320 kdf.derive(u"material") 321 322 def test_buffer_protocol(self, backend): 323 kdf = KBKDFHMAC( 324 hashes.SHA256(), 325 Mode.CounterMode, 326 10, 327 4, 328 4, 329 CounterLocation.BeforeFixed, 330 b"label", 331 b"context", 332 None, 333 backend=backend, 334 ) 335 336 key = kdf.derive(bytearray(b"material")) 337 assert key == b"\xb7\x01\x05\x98\xf5\x1a\x12L\xc7." 338