def test_key_length(self, backend): kdf = KBKDFHMAC(hashes.SHA1(), Mode.CounterMode, 85899345920, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=backend) with pytest.raises(ValueError): kdf.derive(b'material')
def test_already_finalized(self, backend): kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=backend) kdf.derive(b'material') with pytest.raises(AlreadyFinalized): kdf.derive(b'material2') kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=backend) key = kdf.derive(b'material') with pytest.raises(AlreadyFinalized): kdf.verify(b'material', key) kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=backend) kdf.verify(b'material', key) with pytest.raises(AlreadyFinalized): kdf.verify(b"material", key)
def test_already_finalized(self, backend): kdf = KBKDFHMAC( hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b"label", b"context", None, backend=backend, ) kdf.derive(b"material") with pytest.raises(AlreadyFinalized): kdf.derive(b"material2") kdf = KBKDFHMAC( hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b"label", b"context", None, backend=backend, ) key = kdf.derive(b"material") with pytest.raises(AlreadyFinalized): kdf.verify(b"material", key) kdf = KBKDFHMAC( hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b"label", b"context", None, backend=backend, ) kdf.verify(b"material", key) with pytest.raises(AlreadyFinalized): kdf.verify(b"material", key)
def test_unicode_error_key_material(self): with pytest.raises(TypeError): kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=default_backend()) kdf.derive(u'material')
def test_key_length(self): kdf = KBKDFHMAC(hashes.SHA1(), Mode.CounterMode, 85899345920, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=default_backend()) with pytest.raises(ValueError): kdf.derive(b'material')
def test_unicode_error_key_material(self, backend): with pytest.raises(TypeError): kdf = KBKDFHMAC( hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b"label", b"context", None, backend=backend, ) kdf.derive("material") # type: ignore[arg-type]
def test_invalid_key(self): kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=default_backend()) key = kdf.derive(b"material") kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=default_backend()) with pytest.raises(InvalidKey): kdf.verify(b"material2", key)
def test_key_length(self, backend): kdf = KBKDFHMAC( hashes.SHA1(), Mode.CounterMode, 85899345920, 4, 4, CounterLocation.BeforeFixed, b"label", b"context", None, backend=backend, ) with pytest.raises(ValueError): kdf.derive(b"material")
def test_buffer_protocol(self, backend): kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 10, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=backend) key = kdf.derive(bytearray(b"material")) assert key == b'\xb7\x01\x05\x98\xf5\x1a\x12L\xc7.'
def test_invalid_key(self, backend): kdf = KBKDFHMAC( hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b"label", b"context", None, backend=backend, ) key = kdf.derive(b"material") kdf = KBKDFHMAC( hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b"label", b"context", None, backend=backend, ) with pytest.raises(InvalidKey): kdf.verify(b"material2", key)
def calculate_derived_key(self, sessionkey, context=None): """ Calculate the derived key given a session key and optional context using KBKDFHMAC """ label = b"AzureAD-SecureConversation" if not context: context = os.urandom(32) else: context = binascii.unhexlify(context) backend = default_backend() kdf = KBKDFHMAC(algorithm=hashes.SHA256(), mode=Mode.CounterMode, length=32, rlen=4, llen=4, location=CounterLocation.BeforeFixed, label=label, context=context, fixed=None, backend=backend) if len(sessionkey) == 44: keybytes = base64.b64decode(sessionkey) else: keybytes = binascii.unhexlify(sessionkey) derived_key = kdf.derive(keybytes) # This is not ideal but further code expects it as hex string return binascii.hexlify(context).decode('utf-8'), binascii.hexlify( derived_key).decode('utf-8')
def _kbkdf_hmac_counter_mode_test(backend, prf, ctr_loc, params): supported_hash_algorithms: typing.Dict[ str, typing.Type[hashes.HashAlgorithm]] = { "hmac_sha1": hashes.SHA1, "hmac_sha224": hashes.SHA224, "hmac_sha256": hashes.SHA256, "hmac_sha384": hashes.SHA384, "hmac_sha512": hashes.SHA512, } algorithm = supported_hash_algorithms.get(prf) assert algorithm is not None assert backend.hmac_supported(algorithm()) ctrkdf = KBKDFHMAC( algorithm(), Mode.CounterMode, params["l"] // 8, params["rlen"] // 8, None, ctr_loc, None, None, binascii.unhexlify(params["fixedinputdata"]), backend=backend, ) ko = ctrkdf.derive(binascii.unhexlify(params["ki"])) assert binascii.hexlify(ko) == params["ko"]
def test_already_finalized(self): kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=default_backend()) kdf.derive(b'material') with pytest.raises(AlreadyFinalized): kdf.derive(b'material2') kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=default_backend()) key = kdf.derive(b'material') with pytest.raises(AlreadyFinalized): kdf.verify(b'material', key) kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=default_backend()) kdf.verify(b'material', key) with pytest.raises(AlreadyFinalized): kdf.verify(b"material", key)
def test_invalid_key(self, backend): kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=backend) key = kdf.derive(b"material") kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=backend) with pytest.raises(InvalidKey): kdf.verify(b"material2", key)
def __genKey(self): label = "!There is the sun label" context = "!There is the sun context" kdf = KBKDFHMAC(algorithm=hashes.SHA256(),\ mode=Mode.CounterMode,length=32,\ rlen=4,\ llen=4,\ location=CounterLocation.BeforeFixed,\ label=label,\ context=context,\ fixed=None,\ backend=default_backend()) return base64.urlsafe_b64encode( kdf.derive(self.__getSerialNum(config.SER_N_FILE_LOC)))
def test_buffer_protocol(self, backend): kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 10, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=backend) key = kdf.derive(bytearray(b"material")) assert key == b'\xb7\x01\x05\x98\xf5\x1a\x12L\xc7.'
def _derive_urlsafe_key(*, label, context): backend = default_backend() kdf = KBKDFHMAC(algorithm=hashes.SHA256(), mode=Mode.CounterMode, length=32, rlen=4, llen=4, location=CounterLocation.BeforeFixed, label=label, context=context, fixed=None, backend=backend) key = kdf.derive(settings.SECRET_KEY.encode()) return urlsafe_b64encode(key)
def kdfa(halg, key, label, contextU, contextV, bits): klen = int(bits / 8) context = contextU + contextV kdf = KBKDFHMAC( algorithm=halg(), mode=Mode.CounterMode, length=klen, rlen=4, llen=4, location=CounterLocation.BeforeFixed, label=label, context=context, fixed=None, backend=default_backend(), ) return kdf.derive(key)
def kbkdf_counter_mode_test(backend, params): supported_algorithms = { "hmac_sha1": hashes.SHA1, "hmac_sha224": hashes.SHA224, "hmac_sha256": hashes.SHA256, "hmac_sha384": hashes.SHA384, "hmac_sha512": hashes.SHA512, } supported_counter_locations = { "before_fixed": CounterLocation.BeforeFixed, "after_fixed": CounterLocation.AfterFixed, } algorithm = supported_algorithms.get(params.get("prf")) if algorithm is None or not backend.hmac_supported(algorithm()): pytest.skip( "KBKDF does not support algorithm: {}".format(params.get("prf")) ) ctr_loc = supported_counter_locations.get(params.get("ctrlocation")) if ctr_loc is None or not isinstance(ctr_loc, CounterLocation): pytest.skip( "Does not support counter location: {}".format( params.get("ctrlocation") ) ) ctrkdf = KBKDFHMAC( algorithm(), Mode.CounterMode, params["l"] // 8, params["rlen"] // 8, None, ctr_loc, None, None, binascii.unhexlify(params["fixedinputdata"]), backend=backend, ) ko = ctrkdf.derive(binascii.unhexlify(params["ki"])) assert binascii.hexlify(ko) == params["ko"]
def kdfa(hashAlg, key, label, contextU, contextV, bits): halg = _get_digest(hashAlg) if halg is None: raise ValueError(f"unsupported digest algorithm: {hashAlg}") if bits % 8: raise ValueError(f"bad key length {bits}, not a multiple of 8") klen = int(bits / 8) context = contextU + contextV kdf = KBKDFHMAC( algorithm=halg(), mode=Mode.CounterMode, length=klen, rlen=4, llen=4, location=CounterLocation.BeforeFixed, label=label, context=context, fixed=None, backend=default_backend(), ) return kdf.derive(key)
def kbkdf_counter_mode_test(backend, params): supported_algorithms = { 'hmac_sha1': hashes.SHA1, 'hmac_sha224': hashes.SHA224, 'hmac_sha256': hashes.SHA256, 'hmac_sha384': hashes.SHA384, 'hmac_sha512': hashes.SHA512, } supported_counter_locations = { "before_fixed": CounterLocation.BeforeFixed, "after_fixed": CounterLocation.AfterFixed, } algorithm = supported_algorithms.get(params.get('prf')) if algorithm is None or not backend.hmac_supported(algorithm()): pytest.skip("KBKDF does not support algorithm: {}".format( params.get('prf') )) ctr_loc = supported_counter_locations.get(params.get("ctrlocation")) if ctr_loc is None or not isinstance(ctr_loc, CounterLocation): pytest.skip("Does not support counter location: {}".format( params.get('ctrlocation') )) ctrkdf = KBKDFHMAC( algorithm(), Mode.CounterMode, params['l'] // 8, params['rlen'] // 8, None, ctr_loc, None, None, binascii.unhexlify(params['fixedinputdata']), backend=backend) ko = ctrkdf.derive(binascii.unhexlify(params['ki'])) assert binascii.hexlify(ko) == params["ko"]
def _derive_keys(self, password=None): label = encode(self.encryption_oid) + encode(self.mac_oid) context = self.nonce.asOctets() backend = default_backend() kdf = KBKDFHMAC(algorithm=hashes.SHA256(), mode=Mode.CounterMode, length=48, rlen=4, llen=4, location=CounterLocation.BeforeFixed, label=label, context=context, fixed=None, backend=backend) key = kdf.derive(password) if self.DEBUG: sys.stderr.write("Derived key: {0}\n".format(key)) self.encryption_key = key[0:16] self.mac_key = key[16:]
def _smb3kdf(self, ki, label, context): """ See SMB 3.x key derivation function https://blogs.msdn.microsoft.com/openspecification/2017/05/26/smb-2-and-smb-3-security-in-windows-10-the-anatomy-of-signing-and-cryptographic-keys/ :param ki: The session key is the KDK used as an input to the KDF :param label: The purpose of this derived key as bytes string :param context: The context information of this derived key as bytes string :return: Key derived by the KDF as specified by [SP800-108] 5.1 """ kdf = KBKDFHMAC(algorithm=hashes.SHA256(), mode=Mode.CounterMode, length=16, rlen=4, llen=4, location=CounterLocation.BeforeFixed, label=label, context=context, fixed=None, backend=default_backend()) return kdf.derive(ki)
context = b'KBKDF HMAC Context' kdf = KBKDFHMAC( algorithm=hash_algo, # An instance of HashAlgorithm mode=Mode. CounterMode, # The desired mode of the PRF.A value from the Mode enum length=32, # The desired length of the derived key in bytes rlen= 4, # An integer that indicates the length of the counter in bytes llen= 4, # An integer that indicates the length of the length in bytes location=CounterLocation. BeforeFixed, # The desired location of the counter label= label, # Application specific label information. Byte string or None context= context, # Application specific context information. Byte string or None fixed= None, # Instead of specifying label and context, supply your own fixed data backend=backend) # A cryptography backend HashBackend instance # Derive a new key from the shared secret derived_key = kdf.derive(alice_shared) # Make sure shared keys agree if alice_shared == bob_shared: print(Fore.GREEN + '\nDerived AES key ({} bits): {}'.format( len(derived_key) * 8, derived_key.hex().upper())) else: print(Fore.RED + "\nERROR: Shared secrets don't match!")
def test_unicode_error_key_material(self, backend): with pytest.raises(TypeError): kdf = KBKDFHMAC(hashes.SHA256(), Mode.CounterMode, 32, 4, 4, CounterLocation.BeforeFixed, b'label', b'context', None, backend=backend) kdf.derive(u'material')
# The KBKDF (Key Based Key Derivation Function) used here is defined by the NIST SP 800-108 document, to be used # to derive additional keys from a key that has been established through an automated key-establishment scheme label = b'KBKDF HMAC Label' context = b'KBKDF HMAC Context' kdf = KBKDFHMAC( algorithm=hash_algo, # An instance of HashAlgorithm mode=Mode. CounterMode, # The desired mode of the PRF.A value from the Mode enum length=32, # The desired length of the derived key in bytes rlen= 4, # An integer that indicates the length of the counter in bytes llen= 4, # An integer that indicates the length of the length in bytes location=CounterLocation. BeforeFixed, # The desired location of the counter label= label, # Application specific label information. Byte string or None context= context, # Application specific context information. Byte string or None fixed= None, # Instead of specifying label and context, supply your own fixed data backend=backend) # A cryptography backend HashBackend instance # Derive a new key from the shared secret derived_key = kdf.derive(password) # Make sure shared keys agree print(Fore.GREEN + '\nDerived AES key ({} bits): {}'.format( len(derived_key) * 8, derived_key.hex().upper()))