Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py: 79%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

28 statements  

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 annotations 

6 

7import typing 

8 

9from cryptography import utils 

10from cryptography.exceptions import ( 

11 AlreadyFinalized, 

12 InvalidKey, 

13 UnsupportedAlgorithm, 

14 _Reasons, 

15) 

16from cryptography.hazmat.bindings._rust import openssl as rust_openssl 

17from cryptography.hazmat.primitives import constant_time, hashes 

18from cryptography.hazmat.primitives.kdf import KeyDerivationFunction 

19 

20 

21class PBKDF2HMAC(KeyDerivationFunction): 

22 def __init__( 

23 self, 

24 algorithm: hashes.HashAlgorithm, 

25 length: int, 

26 salt: bytes, 

27 iterations: int, 

28 backend: typing.Any = None, 

29 ): 

30 from cryptography.hazmat.backends.openssl.backend import ( 

31 backend as ossl, 

32 ) 

33 

34 if not ossl.pbkdf2_hmac_supported(algorithm): 

35 raise UnsupportedAlgorithm( 

36 f"{algorithm.name} is not supported for PBKDF2.", 

37 _Reasons.UNSUPPORTED_HASH, 

38 ) 

39 self._used = False 

40 self._algorithm = algorithm 

41 self._length = length 

42 utils._check_bytes("salt", salt) 

43 self._salt = salt 

44 self._iterations = iterations 

45 

46 def derive(self, key_material: utils.Buffer) -> bytes: 

47 if self._used: 

48 raise AlreadyFinalized("PBKDF2 instances can only be used once.") 

49 self._used = True 

50 

51 return rust_openssl.kdf.derive_pbkdf2_hmac( 

52 key_material, 

53 self._algorithm, 

54 self._salt, 

55 self._iterations, 

56 self._length, 

57 ) 

58 

59 def verify(self, key_material: bytes, expected_key: bytes) -> None: 

60 derived_key = self.derive(key_material) 

61 if not constant_time.bytes_eq(derived_key, expected_key): 

62 raise InvalidKey("Keys do not match.")