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

36 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2022-12-25 06:11 +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 

5 

6import sys 

7import typing 

8 

9from cryptography import utils 

10from cryptography.exceptions import ( 

11 AlreadyFinalized, 

12 InvalidKey, 

13 UnsupportedAlgorithm, 

14) 

15from cryptography.hazmat.primitives import constant_time 

16from cryptography.hazmat.primitives.kdf import KeyDerivationFunction 

17 

18 

19# This is used by the scrypt tests to skip tests that require more memory 

20# than the MEM_LIMIT 

21_MEM_LIMIT = sys.maxsize // 2 

22 

23 

24class Scrypt(KeyDerivationFunction): 

25 def __init__( 

26 self, 

27 salt: bytes, 

28 length: int, 

29 n: int, 

30 r: int, 

31 p: int, 

32 backend: typing.Any = None, 

33 ): 

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

35 backend as ossl, 

36 ) 

37 

38 if not ossl.scrypt_supported(): 

39 raise UnsupportedAlgorithm( 

40 "This version of OpenSSL does not support scrypt" 

41 ) 

42 self._length = length 

43 utils._check_bytes("salt", salt) 

44 if n < 2 or (n & (n - 1)) != 0: 

45 raise ValueError("n must be greater than 1 and be a power of 2.") 

46 

47 if r < 1: 

48 raise ValueError("r must be greater than or equal to 1.") 

49 

50 if p < 1: 

51 raise ValueError("p must be greater than or equal to 1.") 

52 

53 self._used = False 

54 self._salt = salt 

55 self._n = n 

56 self._r = r 

57 self._p = p 

58 

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

60 if self._used: 

61 raise AlreadyFinalized("Scrypt instances can only be used once.") 

62 self._used = True 

63 

64 utils._check_byteslike("key_material", key_material) 

65 from cryptography.hazmat.backends.openssl.backend import backend 

66 

67 return backend.derive_scrypt( 

68 key_material, self._salt, self._length, self._n, self._r, self._p 

69 ) 

70 

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

72 derived_key = self.derive(key_material) 

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

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