diff options
Diffstat (limited to 'frozen_deps/Cryptodome/Protocol/KDF.py')
-rw-r--r-- | frozen_deps/Cryptodome/Protocol/KDF.py | 80 |
1 files changed, 74 insertions, 6 deletions
diff --git a/frozen_deps/Cryptodome/Protocol/KDF.py b/frozen_deps/Cryptodome/Protocol/KDF.py index 4baa276..b6d747e 100644 --- a/frozen_deps/Cryptodome/Protocol/KDF.py +++ b/frozen_deps/Cryptodome/Protocol/KDF.py @@ -27,7 +27,7 @@ import struct from functools import reduce from Cryptodome.Util.py3compat import (tobytes, bord, _copy_bytes, iter_range, - tostr, bchr, bstr) + tostr, bchr, bstr) from Cryptodome.Hash import SHA1, SHA256, HMAC, CMAC, BLAKE2s from Cryptodome.Util.strxor import strxor @@ -103,10 +103,16 @@ def PBKDF2(password, salt, dkLen=16, count=1000, prf=None, hmac_hash_module=None Args: password (string or byte string): The secret password to generate the key from. + + Strings will be encoded as ISO 8859-1 (also known as Latin-1), + which does not allow any characters with codepoints > 255. salt (string or byte string): A (byte) string to use for better protection from dictionary attacks. This value does not need to be kept secret, but it should be randomly chosen for each derivation. It is recommended to use at least 16 bytes. + + Strings will be encoded as ISO 8859-1 (also known as Latin-1), + which does not allow any characters with codepoints > 255. dkLen (integer): The cumulative length of the keys to produce. @@ -201,10 +207,10 @@ class _S2V(object): self._key = _copy_bytes(None, None, key) self._ciphermod = ciphermod self._last_string = self._cache = b'\x00' * ciphermod.block_size - + # Max number of update() call we can process self._n_updates = ciphermod.block_size * 8 - 1 - + if cipher_params is None: self._cipher_params = {} else: @@ -281,13 +287,13 @@ def HKDF(master, key_len, salt, hashmod, num_keys=1, context=None): The unguessable value used by the KDF to generate the other keys. It must be a high-entropy secret, though not necessarily uniform. It must not be a password. + key_len (integer): + The length in bytes of every derived key. salt (byte string): A non-secret, reusable value that strengthens the randomness extraction step. Ideally, it is as long as the digest size of the chosen hash. If empty, a string of zeroes in used. - key_len (integer): - The length in bytes of every derived key. hashmod (module): A cryptographic hash algorithm from :mod:`Cryptodome.Hash`. :mod:`Cryptodome.Hash.SHA512` is a good choice. @@ -346,7 +352,7 @@ def scrypt(password, salt, key_len, N, r, p, num_keys=1): but it should be randomly chosen for each derivation. It is recommended to be at least 16 bytes long. key_len (integer): - The length in bytes of every derived key. + The length in bytes of each derived key. N (integer): CPU/Memory cost parameter. It must be a power of 2 and less than :math:`2^{32}`. @@ -572,3 +578,65 @@ def bcrypt_check(password, bcrypt_hash): mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=bcrypt_hash2).digest() if mac1 != mac2: raise ValueError("Incorrect bcrypt hash") + + +def SP800_108_Counter(master, key_len, prf, num_keys=None, label=b'', context=b''): + """Derive one or more keys from a master secret using + a pseudorandom function in Counter Mode, as specified in + `NIST SP 800-108r1 <https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-108r1.pdf>`_. + + Args: + master (byte string): + The secret value used by the KDF to derive the other keys. + It must not be a password. + The length on the secret must be consistent with the input expected by + the :data:`prf` function. + key_len (integer): + The length in bytes of each derived key. + prf (function): + A pseudorandom function that takes two byte strings as parameters: + the secret and an input. It returns another byte string. + num_keys (integer): + The number of keys to derive. Every key is :data:`key_len` bytes long. + By default, only 1 key is derived. + label (byte string): + Optional description of the purpose of the derived keys. + It must not contain zero bytes. + context (byte string): + Optional information pertaining to + the protocol that uses the keys, such as the identity of the + participants, nonces, session IDs, etc. + It must not contain zero bytes. + + Return: + - a byte string (if ``num_keys`` is not specified), or + - a tuple of byte strings (if ``num_key`` is specified). + """ + + if num_keys is None: + num_keys = 1 + + if label.find(b'\x00') != -1: + raise ValueError("Null byte found in label") + + if context.find(b'\x00') != -1: + raise ValueError("Null byte found in context") + + key_len_enc = long_to_bytes(key_len * num_keys * 8, 4) + output_len = key_len * num_keys + + i = 1 + dk = b"" + while len(dk) < output_len: + info = long_to_bytes(i, 4) + label + b'\x00' + context + key_len_enc + dk += prf(master, info) + i += 1 + if i > 0xFFFFFFFF: + raise ValueError("Overflow in SP800 108 counter") + + if num_keys == 1: + return dk[:key_len] + else: + kol = [dk[idx:idx + key_len] + for idx in iter_range(0, output_len, key_len)] + return kol |