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

27 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 07:26 +0000

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 "{} is not supported for PBKDF2 by this backend.".format( 

37 algorithm.name 

38 ), 

39 _Reasons.UNSUPPORTED_HASH, 

40 ) 

41 self._used = False 

42 self._algorithm = algorithm 

43 self._length = length 

44 utils._check_bytes("salt", salt) 

45 self._salt = salt 

46 self._iterations = iterations 

47 

48 def derive(self, key_material: bytes) -> bytes: 

49 if self._used: 

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

51 self._used = True 

52 

53 return rust_openssl.kdf.derive_pbkdf2_hmac( 

54 key_material, 

55 self._algorithm, 

56 self._salt, 

57 self._iterations, 

58 self._length, 

59 ) 

60 

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

62 derived_key = self.derive(key_material) 

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

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