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.2.2, created at 2023-03-26 06:36 +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# This is used by the scrypt tests to skip tests that require more memory 

19# than the MEM_LIMIT 

20_MEM_LIMIT = sys.maxsize // 2 

21 

22 

23class Scrypt(KeyDerivationFunction): 

24 def __init__( 

25 self, 

26 salt: bytes, 

27 length: int, 

28 n: int, 

29 r: int, 

30 p: int, 

31 backend: typing.Any = None, 

32 ): 

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

34 backend as ossl, 

35 ) 

36 

37 if not ossl.scrypt_supported(): 

38 raise UnsupportedAlgorithm( 

39 "This version of OpenSSL does not support scrypt" 

40 ) 

41 self._length = length 

42 utils._check_bytes("salt", salt) 

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

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

45 

46 if r < 1: 

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

48 

49 if p < 1: 

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

51 

52 self._used = False 

53 self._salt = salt 

54 self._n = n 

55 self._r = r 

56 self._p = p 

57 

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

59 if self._used: 

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

61 self._used = True 

62 

63 utils._check_byteslike("key_material", key_material) 

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

65 

66 return backend.derive_scrypt( 

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

68 ) 

69 

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

71 derived_key = self.derive(key_material) 

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

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