Ausgabe der neuen DB Einträge
This commit is contained in:
parent
bad48e1627
commit
cfbbb9ee3d
2399 changed files with 843193 additions and 43 deletions
|
|
@ -0,0 +1,26 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class KeyDerivationFunction(object):
|
||||
@abc.abstractmethod
|
||||
def derive(self, key_material):
|
||||
"""
|
||||
Deterministically generates and returns a new key based on the existing
|
||||
key material.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def verify(self, key_material, expected_key):
|
||||
"""
|
||||
Checks whether the key generated by the key material matches the
|
||||
expected derived key. Raises an exception if they do not match.
|
||||
"""
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import struct
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
AlreadyFinalized,
|
||||
InvalidKey,
|
||||
UnsupportedAlgorithm,
|
||||
_Reasons,
|
||||
)
|
||||
from cryptography.hazmat.backends import _get_backend
|
||||
from cryptography.hazmat.backends.interfaces import HMACBackend
|
||||
from cryptography.hazmat.backends.interfaces import HashBackend
|
||||
from cryptography.hazmat.primitives import constant_time, hashes, hmac
|
||||
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
|
||||
|
||||
|
||||
def _int_to_u32be(n):
|
||||
return struct.pack(">I", n)
|
||||
|
||||
|
||||
def _common_args_checks(algorithm, length, otherinfo):
|
||||
max_length = algorithm.digest_size * (2 ** 32 - 1)
|
||||
if length > max_length:
|
||||
raise ValueError(
|
||||
"Can not derive keys larger than {} bits.".format(max_length)
|
||||
)
|
||||
if otherinfo is not None:
|
||||
utils._check_bytes("otherinfo", otherinfo)
|
||||
|
||||
|
||||
def _concatkdf_derive(key_material, length, auxfn, otherinfo):
|
||||
utils._check_byteslike("key_material", key_material)
|
||||
output = [b""]
|
||||
outlen = 0
|
||||
counter = 1
|
||||
|
||||
while length > outlen:
|
||||
h = auxfn()
|
||||
h.update(_int_to_u32be(counter))
|
||||
h.update(key_material)
|
||||
h.update(otherinfo)
|
||||
output.append(h.finalize())
|
||||
outlen += len(output[-1])
|
||||
counter += 1
|
||||
|
||||
return b"".join(output)[:length]
|
||||
|
||||
|
||||
@utils.register_interface(KeyDerivationFunction)
|
||||
class ConcatKDFHash(object):
|
||||
def __init__(self, algorithm, length, otherinfo, backend=None):
|
||||
backend = _get_backend(backend)
|
||||
|
||||
_common_args_checks(algorithm, length, otherinfo)
|
||||
self._algorithm = algorithm
|
||||
self._length = length
|
||||
self._otherinfo = otherinfo
|
||||
if self._otherinfo is None:
|
||||
self._otherinfo = b""
|
||||
|
||||
if not isinstance(backend, HashBackend):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Backend object does not implement HashBackend.",
|
||||
_Reasons.BACKEND_MISSING_INTERFACE,
|
||||
)
|
||||
self._backend = backend
|
||||
self._used = False
|
||||
|
||||
def _hash(self):
|
||||
return hashes.Hash(self._algorithm, self._backend)
|
||||
|
||||
def derive(self, key_material):
|
||||
if self._used:
|
||||
raise AlreadyFinalized
|
||||
self._used = True
|
||||
return _concatkdf_derive(
|
||||
key_material, self._length, self._hash, self._otherinfo
|
||||
)
|
||||
|
||||
def verify(self, key_material, expected_key):
|
||||
if not constant_time.bytes_eq(self.derive(key_material), expected_key):
|
||||
raise InvalidKey
|
||||
|
||||
|
||||
@utils.register_interface(KeyDerivationFunction)
|
||||
class ConcatKDFHMAC(object):
|
||||
def __init__(self, algorithm, length, salt, otherinfo, backend=None):
|
||||
backend = _get_backend(backend)
|
||||
|
||||
_common_args_checks(algorithm, length, otherinfo)
|
||||
self._algorithm = algorithm
|
||||
self._length = length
|
||||
self._otherinfo = otherinfo
|
||||
if self._otherinfo is None:
|
||||
self._otherinfo = b""
|
||||
|
||||
if salt is None:
|
||||
salt = b"\x00" * algorithm.block_size
|
||||
else:
|
||||
utils._check_bytes("salt", salt)
|
||||
|
||||
self._salt = salt
|
||||
|
||||
if not isinstance(backend, HMACBackend):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Backend object does not implement HMACBackend.",
|
||||
_Reasons.BACKEND_MISSING_INTERFACE,
|
||||
)
|
||||
self._backend = backend
|
||||
self._used = False
|
||||
|
||||
def _hmac(self):
|
||||
return hmac.HMAC(self._salt, self._algorithm, self._backend)
|
||||
|
||||
def derive(self, key_material):
|
||||
if self._used:
|
||||
raise AlreadyFinalized
|
||||
self._used = True
|
||||
return _concatkdf_derive(
|
||||
key_material, self._length, self._hmac, self._otherinfo
|
||||
)
|
||||
|
||||
def verify(self, key_material, expected_key):
|
||||
if not constant_time.bytes_eq(self.derive(key_material), expected_key):
|
||||
raise InvalidKey
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import six
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
AlreadyFinalized,
|
||||
InvalidKey,
|
||||
UnsupportedAlgorithm,
|
||||
_Reasons,
|
||||
)
|
||||
from cryptography.hazmat.backends import _get_backend
|
||||
from cryptography.hazmat.backends.interfaces import HMACBackend
|
||||
from cryptography.hazmat.primitives import constant_time, hmac
|
||||
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
|
||||
|
||||
|
||||
@utils.register_interface(KeyDerivationFunction)
|
||||
class HKDF(object):
|
||||
def __init__(self, algorithm, length, salt, info, backend=None):
|
||||
backend = _get_backend(backend)
|
||||
if not isinstance(backend, HMACBackend):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Backend object does not implement HMACBackend.",
|
||||
_Reasons.BACKEND_MISSING_INTERFACE,
|
||||
)
|
||||
|
||||
self._algorithm = algorithm
|
||||
|
||||
if salt is None:
|
||||
salt = b"\x00" * self._algorithm.digest_size
|
||||
else:
|
||||
utils._check_bytes("salt", salt)
|
||||
|
||||
self._salt = salt
|
||||
|
||||
self._backend = backend
|
||||
|
||||
self._hkdf_expand = HKDFExpand(self._algorithm, length, info, backend)
|
||||
|
||||
def _extract(self, key_material):
|
||||
h = hmac.HMAC(self._salt, self._algorithm, backend=self._backend)
|
||||
h.update(key_material)
|
||||
return h.finalize()
|
||||
|
||||
def derive(self, key_material):
|
||||
utils._check_byteslike("key_material", key_material)
|
||||
return self._hkdf_expand.derive(self._extract(key_material))
|
||||
|
||||
def verify(self, key_material, expected_key):
|
||||
if not constant_time.bytes_eq(self.derive(key_material), expected_key):
|
||||
raise InvalidKey
|
||||
|
||||
|
||||
@utils.register_interface(KeyDerivationFunction)
|
||||
class HKDFExpand(object):
|
||||
def __init__(self, algorithm, length, info, backend=None):
|
||||
backend = _get_backend(backend)
|
||||
if not isinstance(backend, HMACBackend):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Backend object does not implement HMACBackend.",
|
||||
_Reasons.BACKEND_MISSING_INTERFACE,
|
||||
)
|
||||
|
||||
self._algorithm = algorithm
|
||||
|
||||
self._backend = backend
|
||||
|
||||
max_length = 255 * algorithm.digest_size
|
||||
|
||||
if length > max_length:
|
||||
raise ValueError(
|
||||
"Can not derive keys larger than {} octets.".format(max_length)
|
||||
)
|
||||
|
||||
self._length = length
|
||||
|
||||
if info is None:
|
||||
info = b""
|
||||
else:
|
||||
utils._check_bytes("info", info)
|
||||
|
||||
self._info = info
|
||||
|
||||
self._used = False
|
||||
|
||||
def _expand(self, key_material):
|
||||
output = [b""]
|
||||
counter = 1
|
||||
|
||||
while self._algorithm.digest_size * (len(output) - 1) < self._length:
|
||||
h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)
|
||||
h.update(output[-1])
|
||||
h.update(self._info)
|
||||
h.update(six.int2byte(counter))
|
||||
output.append(h.finalize())
|
||||
counter += 1
|
||||
|
||||
return b"".join(output)[: self._length]
|
||||
|
||||
def derive(self, key_material):
|
||||
utils._check_byteslike("key_material", key_material)
|
||||
if self._used:
|
||||
raise AlreadyFinalized
|
||||
|
||||
self._used = True
|
||||
return self._expand(key_material)
|
||||
|
||||
def verify(self, key_material, expected_key):
|
||||
if not constant_time.bytes_eq(self.derive(key_material), expected_key):
|
||||
raise InvalidKey
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from six.moves import range
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
AlreadyFinalized,
|
||||
InvalidKey,
|
||||
UnsupportedAlgorithm,
|
||||
_Reasons,
|
||||
)
|
||||
from cryptography.hazmat.backends import _get_backend
|
||||
from cryptography.hazmat.backends.interfaces import HMACBackend
|
||||
from cryptography.hazmat.primitives import constant_time, hashes, hmac
|
||||
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
|
||||
|
||||
|
||||
class Mode(Enum):
|
||||
CounterMode = "ctr"
|
||||
|
||||
|
||||
class CounterLocation(Enum):
|
||||
BeforeFixed = "before_fixed"
|
||||
AfterFixed = "after_fixed"
|
||||
|
||||
|
||||
@utils.register_interface(KeyDerivationFunction)
|
||||
class KBKDFHMAC(object):
|
||||
def __init__(
|
||||
self,
|
||||
algorithm,
|
||||
mode,
|
||||
length,
|
||||
rlen,
|
||||
llen,
|
||||
location,
|
||||
label,
|
||||
context,
|
||||
fixed,
|
||||
backend=None,
|
||||
):
|
||||
backend = _get_backend(backend)
|
||||
if not isinstance(backend, HMACBackend):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Backend object does not implement HMACBackend.",
|
||||
_Reasons.BACKEND_MISSING_INTERFACE,
|
||||
)
|
||||
|
||||
if not isinstance(algorithm, hashes.HashAlgorithm):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Algorithm supplied is not a supported hash algorithm.",
|
||||
_Reasons.UNSUPPORTED_HASH,
|
||||
)
|
||||
|
||||
if not backend.hmac_supported(algorithm):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Algorithm supplied is not a supported hmac algorithm.",
|
||||
_Reasons.UNSUPPORTED_HASH,
|
||||
)
|
||||
|
||||
if not isinstance(mode, Mode):
|
||||
raise TypeError("mode must be of type Mode")
|
||||
|
||||
if not isinstance(location, CounterLocation):
|
||||
raise TypeError("location must be of type CounterLocation")
|
||||
|
||||
if (label or context) and fixed:
|
||||
raise ValueError(
|
||||
"When supplying fixed data, " "label and context are ignored."
|
||||
)
|
||||
|
||||
if rlen is None or not self._valid_byte_length(rlen):
|
||||
raise ValueError("rlen must be between 1 and 4")
|
||||
|
||||
if llen is None and fixed is None:
|
||||
raise ValueError("Please specify an llen")
|
||||
|
||||
if llen is not None and not isinstance(llen, int):
|
||||
raise TypeError("llen must be an integer")
|
||||
|
||||
if label is None:
|
||||
label = b""
|
||||
|
||||
if context is None:
|
||||
context = b""
|
||||
|
||||
utils._check_bytes("label", label)
|
||||
utils._check_bytes("context", context)
|
||||
self._algorithm = algorithm
|
||||
self._mode = mode
|
||||
self._length = length
|
||||
self._rlen = rlen
|
||||
self._llen = llen
|
||||
self._location = location
|
||||
self._label = label
|
||||
self._context = context
|
||||
self._backend = backend
|
||||
self._used = False
|
||||
self._fixed_data = fixed
|
||||
|
||||
def _valid_byte_length(self, value):
|
||||
if not isinstance(value, int):
|
||||
raise TypeError("value must be of type int")
|
||||
|
||||
value_bin = utils.int_to_bytes(1, value)
|
||||
if not 1 <= len(value_bin) <= 4:
|
||||
return False
|
||||
return True
|
||||
|
||||
def derive(self, key_material):
|
||||
if self._used:
|
||||
raise AlreadyFinalized
|
||||
|
||||
utils._check_byteslike("key_material", key_material)
|
||||
self._used = True
|
||||
|
||||
# inverse floor division (equivalent to ceiling)
|
||||
rounds = -(-self._length // self._algorithm.digest_size)
|
||||
|
||||
output = [b""]
|
||||
|
||||
# For counter mode, the number of iterations shall not be
|
||||
# larger than 2^r-1, where r <= 32 is the binary length of the counter
|
||||
# This ensures that the counter values used as an input to the
|
||||
# PRF will not repeat during a particular call to the KDF function.
|
||||
r_bin = utils.int_to_bytes(1, self._rlen)
|
||||
if rounds > pow(2, len(r_bin) * 8) - 1:
|
||||
raise ValueError("There are too many iterations.")
|
||||
|
||||
for i in range(1, rounds + 1):
|
||||
h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)
|
||||
|
||||
counter = utils.int_to_bytes(i, self._rlen)
|
||||
if self._location == CounterLocation.BeforeFixed:
|
||||
h.update(counter)
|
||||
|
||||
h.update(self._generate_fixed_input())
|
||||
|
||||
if self._location == CounterLocation.AfterFixed:
|
||||
h.update(counter)
|
||||
|
||||
output.append(h.finalize())
|
||||
|
||||
return b"".join(output)[: self._length]
|
||||
|
||||
def _generate_fixed_input(self):
|
||||
if self._fixed_data and isinstance(self._fixed_data, bytes):
|
||||
return self._fixed_data
|
||||
|
||||
l_val = utils.int_to_bytes(self._length * 8, self._llen)
|
||||
|
||||
return b"".join([self._label, b"\x00", self._context, l_val])
|
||||
|
||||
def verify(self, key_material, expected_key):
|
||||
if not constant_time.bytes_eq(self.derive(key_material), expected_key):
|
||||
raise InvalidKey
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
AlreadyFinalized,
|
||||
InvalidKey,
|
||||
UnsupportedAlgorithm,
|
||||
_Reasons,
|
||||
)
|
||||
from cryptography.hazmat.backends import _get_backend
|
||||
from cryptography.hazmat.backends.interfaces import PBKDF2HMACBackend
|
||||
from cryptography.hazmat.primitives import constant_time
|
||||
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
|
||||
|
||||
|
||||
@utils.register_interface(KeyDerivationFunction)
|
||||
class PBKDF2HMAC(object):
|
||||
def __init__(self, algorithm, length, salt, iterations, backend=None):
|
||||
backend = _get_backend(backend)
|
||||
if not isinstance(backend, PBKDF2HMACBackend):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Backend object does not implement PBKDF2HMACBackend.",
|
||||
_Reasons.BACKEND_MISSING_INTERFACE,
|
||||
)
|
||||
|
||||
if not backend.pbkdf2_hmac_supported(algorithm):
|
||||
raise UnsupportedAlgorithm(
|
||||
"{} is not supported for PBKDF2 by this backend.".format(
|
||||
algorithm.name
|
||||
),
|
||||
_Reasons.UNSUPPORTED_HASH,
|
||||
)
|
||||
self._used = False
|
||||
self._algorithm = algorithm
|
||||
self._length = length
|
||||
utils._check_bytes("salt", salt)
|
||||
self._salt = salt
|
||||
self._iterations = iterations
|
||||
self._backend = backend
|
||||
|
||||
def derive(self, key_material):
|
||||
if self._used:
|
||||
raise AlreadyFinalized("PBKDF2 instances can only be used once.")
|
||||
self._used = True
|
||||
|
||||
utils._check_byteslike("key_material", key_material)
|
||||
return self._backend.derive_pbkdf2_hmac(
|
||||
self._algorithm,
|
||||
self._length,
|
||||
self._salt,
|
||||
self._iterations,
|
||||
key_material,
|
||||
)
|
||||
|
||||
def verify(self, key_material, expected_key):
|
||||
derived_key = self.derive(key_material)
|
||||
if not constant_time.bytes_eq(derived_key, expected_key):
|
||||
raise InvalidKey("Keys do not match.")
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import sys
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
AlreadyFinalized,
|
||||
InvalidKey,
|
||||
UnsupportedAlgorithm,
|
||||
_Reasons,
|
||||
)
|
||||
from cryptography.hazmat.backends import _get_backend
|
||||
from cryptography.hazmat.backends.interfaces import ScryptBackend
|
||||
from cryptography.hazmat.primitives import constant_time
|
||||
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
|
||||
|
||||
|
||||
# This is used by the scrypt tests to skip tests that require more memory
|
||||
# than the MEM_LIMIT
|
||||
_MEM_LIMIT = sys.maxsize // 2
|
||||
|
||||
|
||||
@utils.register_interface(KeyDerivationFunction)
|
||||
class Scrypt(object):
|
||||
def __init__(self, salt, length, n, r, p, backend=None):
|
||||
backend = _get_backend(backend)
|
||||
if not isinstance(backend, ScryptBackend):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Backend object does not implement ScryptBackend.",
|
||||
_Reasons.BACKEND_MISSING_INTERFACE,
|
||||
)
|
||||
|
||||
self._length = length
|
||||
utils._check_bytes("salt", salt)
|
||||
if n < 2 or (n & (n - 1)) != 0:
|
||||
raise ValueError("n must be greater than 1 and be a power of 2.")
|
||||
|
||||
if r < 1:
|
||||
raise ValueError("r must be greater than or equal to 1.")
|
||||
|
||||
if p < 1:
|
||||
raise ValueError("p must be greater than or equal to 1.")
|
||||
|
||||
self._used = False
|
||||
self._salt = salt
|
||||
self._n = n
|
||||
self._r = r
|
||||
self._p = p
|
||||
self._backend = backend
|
||||
|
||||
def derive(self, key_material):
|
||||
if self._used:
|
||||
raise AlreadyFinalized("Scrypt instances can only be used once.")
|
||||
self._used = True
|
||||
|
||||
utils._check_byteslike("key_material", key_material)
|
||||
return self._backend.derive_scrypt(
|
||||
key_material, self._salt, self._length, self._n, self._r, self._p
|
||||
)
|
||||
|
||||
def verify(self, key_material, expected_key):
|
||||
derived_key = self.derive(key_material)
|
||||
if not constant_time.bytes_eq(derived_key, expected_key):
|
||||
raise InvalidKey("Keys do not match.")
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import struct
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
AlreadyFinalized,
|
||||
InvalidKey,
|
||||
UnsupportedAlgorithm,
|
||||
_Reasons,
|
||||
)
|
||||
from cryptography.hazmat.backends import _get_backend
|
||||
from cryptography.hazmat.backends.interfaces import HashBackend
|
||||
from cryptography.hazmat.primitives import constant_time, hashes
|
||||
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
|
||||
|
||||
|
||||
def _int_to_u32be(n):
|
||||
return struct.pack(">I", n)
|
||||
|
||||
|
||||
@utils.register_interface(KeyDerivationFunction)
|
||||
class X963KDF(object):
|
||||
def __init__(self, algorithm, length, sharedinfo, backend=None):
|
||||
backend = _get_backend(backend)
|
||||
|
||||
max_len = algorithm.digest_size * (2 ** 32 - 1)
|
||||
if length > max_len:
|
||||
raise ValueError(
|
||||
"Can not derive keys larger than {} bits.".format(max_len)
|
||||
)
|
||||
if sharedinfo is not None:
|
||||
utils._check_bytes("sharedinfo", sharedinfo)
|
||||
|
||||
self._algorithm = algorithm
|
||||
self._length = length
|
||||
self._sharedinfo = sharedinfo
|
||||
|
||||
if not isinstance(backend, HashBackend):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Backend object does not implement HashBackend.",
|
||||
_Reasons.BACKEND_MISSING_INTERFACE,
|
||||
)
|
||||
self._backend = backend
|
||||
self._used = False
|
||||
|
||||
def derive(self, key_material):
|
||||
if self._used:
|
||||
raise AlreadyFinalized
|
||||
self._used = True
|
||||
utils._check_byteslike("key_material", key_material)
|
||||
output = [b""]
|
||||
outlen = 0
|
||||
counter = 1
|
||||
|
||||
while self._length > outlen:
|
||||
h = hashes.Hash(self._algorithm, self._backend)
|
||||
h.update(key_material)
|
||||
h.update(_int_to_u32be(counter))
|
||||
if self._sharedinfo is not None:
|
||||
h.update(self._sharedinfo)
|
||||
output.append(h.finalize())
|
||||
outlen += len(output[-1])
|
||||
counter += 1
|
||||
|
||||
return b"".join(output)[: self._length]
|
||||
|
||||
def verify(self, key_material, expected_key):
|
||||
if not constant_time.bytes_eq(self.derive(key_material), expected_key):
|
||||
raise InvalidKey
|
||||
Loading…
Add table
Add a link
Reference in a new issue