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
« 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.
6import sys
7import typing
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
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
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 )
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.")
46 if r < 1:
47 raise ValueError("r must be greater than or equal to 1.")
49 if p < 1:
50 raise ValueError("p must be greater than or equal to 1.")
52 self._used = False
53 self._salt = salt
54 self._n = n
55 self._r = r
56 self._p = p
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
63 utils._check_byteslike("key_material", key_material)
64 from cryptography.hazmat.backends.openssl.backend import backend
66 return backend.derive_scrypt(
67 key_material, self._salt, self._length, self._n, self._r, self._p
68 )
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.")