2
0
mirror of https://github.com/openkmip/pykmip synced 2025-12-15 15:53:36 +00:00

Add key derivation support to the server cryptography engine

This change adds key derivation functionality to the cryptographic
engine, adding support for multiple key derivation methods,
including encrypting, hashing, HMACing, and specific algorithms
like PBKDF2 and NIST 800-108. Numerous unit tests are included
from established cryptographic testing sources to verify the
added functionality.
This commit is contained in:
Peter Hamilton
2017-07-05 12:58:16 -04:00
parent 4c244a1f6f
commit 86e49b4c35
2 changed files with 982 additions and 0 deletions

View File

@@ -507,6 +507,169 @@ class TestCryptographyEngine(testtools.TestCase):
*args
)
def test_derive_key_missing_hash_algorithm(self):
"""
Test that the right error is raised when the hash algorithm is not
provided for key derivation.
"""
engine = crypto.CryptographyEngine()
args = (
enums.DerivationMethod.HASH,
16
)
self.assertRaisesRegexp(
exceptions.InvalidField,
"Hash algorithm is required.",
engine.derive_key,
*args
)
def test_derive_key_invalid_hash_algorithm(self):
"""
Test that the right error is raised when an invalid hash algorithm is
provided for key derivation.
"""
engine = crypto.CryptographyEngine()
args = (
enums.DerivationMethod.HASH,
16
)
kwargs = {
'hash_algorithm': 'invalid'
}
self.assertRaisesRegexp(
exceptions.InvalidField,
"Hash algorithm 'invalid' is not a supported hashing algorithm.",
engine.derive_key,
*args,
**kwargs
)
def test_derive_key_both_derivation_data_and_key_material(self):
"""
Test that the right error is raised when both derivation data and key
material are provided for hash-based key derivation.
"""
engine = crypto.CryptographyEngine()
args = (
enums.DerivationMethod.HASH,
16
)
kwargs = {
'hash_algorithm': enums.HashingAlgorithm.SHA_256,
'derivation_data': b'\x01\x02\x03\x04',
'key_material': b'\x0A\x0B\x0C\x0D'
}
self.assertRaisesRegexp(
exceptions.InvalidField,
"For hash-based key derivation, specify only derivation data or "
"key material, not both.",
engine.derive_key,
*args,
**kwargs
)
def test_derive_key_missing_derivation_data_and_key_material(self):
"""
Test that the right error is raised when neither derivation data nor
key material are provided for hash-based key derivation.
"""
engine = crypto.CryptographyEngine()
args = (
enums.DerivationMethod.HASH,
16
)
kwargs = {
'hash_algorithm': enums.HashingAlgorithm.SHA_256
}
self.assertRaisesRegexp(
exceptions.InvalidField,
"For hash-based key derivation, derivation data or key material "
"must be specified.",
engine.derive_key,
*args,
**kwargs
)
def test_derive_key_missing_salt(self):
"""
Test that the right error is raised when the salt is not provided for
PBKDF2-based key derivation.
"""
engine = crypto.CryptographyEngine()
args = (
enums.DerivationMethod.PBKDF2,
16
)
kwargs = {
'hash_algorithm': enums.HashingAlgorithm.SHA_256
}
self.assertRaisesRegexp(
exceptions.InvalidField,
"For PBKDF2 key derivation, salt must be specified.",
engine.derive_key,
*args,
**kwargs
)
def test_derive_key_missing_iteration_count(self):
"""
Test that the right error is raised when the iteration count is not
provided for PBKDF2-based key derivation.
"""
engine = crypto.CryptographyEngine()
args = (
enums.DerivationMethod.PBKDF2,
16
)
kwargs = {
'hash_algorithm': enums.HashingAlgorithm.SHA_256,
'salt': b'\x11\x22\x33\x44'
}
self.assertRaisesRegexp(
exceptions.InvalidField,
"For PBKDF2 key derivation, iteration count must be specified.",
engine.derive_key,
*args,
**kwargs
)
def test_derive_key_invalid_derivation_method(self):
"""
Test that the right error is raised when an invalid derivation method
is specified for key derivation.
"""
engine = crypto.CryptographyEngine()
args = (
'invalid',
16
)
kwargs = {
'hash_algorithm': enums.HashingAlgorithm.SHA_256
}
self.assertRaisesRegexp(
exceptions.InvalidField,
"Derivation method 'invalid' is not a supported key derivation "
"method.",
engine.derive_key,
*args,
**kwargs
)
# TODO(peter-hamilton): Replace this with actual fixture files from NIST CAPV.
# Most of these test vectors were obtained from the pyca/cryptography test
@@ -788,3 +951,633 @@ def test_handle_symmetric_padding_undo(symmetric_padding_parameters):
)
assert result == symmetric_padding_parameters.get('plain_text')
# PBKDF2 test vectors were obtained from IETF RFC 6070:
#
# https://www.ietf.org/rfc/rfc6070.txt
#
# HMAC test vectors were obtained from IETF RFC 2202 and RFC 4231:
#
# https://tools.ietf.org/html/rfc2202
# https://tools.ietf.org/html/rfc4231
#
# HASH test vectors for SHA1/SHA224/SHA256/SHA384/SHA512
# were obtained from the NIST CAVP test suite. Test vectors for MD5 were
# obtained from NIST NSRL:
#
# http://csrc.nist.gov/groups/STM/cavp/documents/shs/shabytetestvectors.zip
# https://www.nsrl.nist.gov/testdata/
#
# NIST 800-108 Counter Mode test vectors were obtained from the NIST CAVP
# test suite:
#
# http://csrc.nist.gov/groups/STM/cavp/documents/KBKDF800-108/kbkdfvs.pdf
# http://csrc.nist.gov/groups/STM/cavp/documents/KBKDF800-108/CounterMode.zip
@pytest.fixture(
scope='function',
params=[
{'derivation_method': enums.DerivationMethod.PBKDF2,
'derivation_length': 20,
'key_material': b'password',
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'salt': b'salt',
'iteration_count': 1,
'derived_data': (
b'\x0c\x60\xc8\x0f\x96\x1f\x0e\x71'
b'\xf3\xa9\xb5\x24\xaf\x60\x12\x06'
b'\x2f\xe0\x37\xa6'
)},
{'derivation_method': enums.DerivationMethod.PBKDF2,
'derivation_length': 20,
'key_material': b'password',
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'salt': b'salt',
'iteration_count': 4096,
'derived_data': (
b'\x4b\x00\x79\x01\xb7\x65\x48\x9a'
b'\xbe\xad\x49\xd9\x26\xf7\x21\xd0'
b'\x65\xa4\x29\xc1'
)},
{'derivation_method': enums.DerivationMethod.PBKDF2,
'derivation_length': 25,
'key_material': b'passwordPASSWORDpassword',
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'salt': b'saltSALTsaltSALTsaltSALTsaltSALTsalt',
'iteration_count': 4096,
'derived_data': (
b'\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b'
b'\x80\xc8\xd8\x36\x62\xc0\xe4\x4a'
b'\x8b\x29\x1a\x96\x4c\xf2\xf0\x70'
b'\x38'
)},
{'derivation_method': enums.DerivationMethod.PBKDF2,
'derivation_length': 16,
'key_material': b'pass\x00word',
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'salt': b'sa\x00lt',
'iteration_count': 4096,
'derived_data': (
b'\x56\xfa\x6a\xa7\x55\x48\x09\x9d'
b'\xcc\x37\xd7\xf0\x34\x25\xe0\xc3'
)},
{'derivation_method': enums.DerivationMethod.HMAC,
'derivation_length': 42,
'derivation_data': (
b'\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7'
b'\xf8\xf9'
),
'key_material': (
b'\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
b'\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
b'\x0b\x0b\x0b\x0b\x0b\x0b'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_256,
'salt': (
b'\x00\x01\x02\x03\x04\x05\x06\x07'
b'\x08\x09\x0a\x0b\x0c'
),
'derived_data': (
b'\x3c\xb2\x5f\x25\xfa\xac\xd5\x7a'
b'\x90\x43\x4f\x64\xd0\x36\x2f\x2a'
b'\x2d\x2d\x0a\x90\xcf\x1a\x5a\x4c'
b'\x5d\xb0\x2d\x56\xec\xc4\xc5\xbf'
b'\x34\x00\x72\x08\xd5\xb8\x87\x18'
b'\x58\x65'
)},
{'derivation_method': enums.DerivationMethod.HMAC,
'derivation_length': 82,
'derivation_data': (
b'\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7'
b'\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf'
b'\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7'
b'\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf'
b'\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7'
b'\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf'
b'\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7'
b'\xe8\xe9\xea\xeb\xec\xed\xee\xef'
b'\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7'
b'\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
),
'key_material': (
b'\x00\x01\x02\x03\x04\x05\x06\x07'
b'\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'
b'\x10\x11\x12\x13\x14\x15\x16\x17'
b'\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'
b'\x20\x21\x22\x23\x24\x25\x26\x27'
b'\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f'
b'\x30\x31\x32\x33\x34\x35\x36\x37'
b'\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f'
b'\x40\x41\x42\x43\x44\x45\x46\x47'
b'\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_256,
'salt': (
b'\x60\x61\x62\x63\x64\x65\x66\x67'
b'\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f'
b'\x70\x71\x72\x73\x74\x75\x76\x77'
b'\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f'
b'\x80\x81\x82\x83\x84\x85\x86\x87'
b'\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f'
b'\x90\x91\x92\x93\x94\x95\x96\x97'
b'\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f'
b'\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7'
b'\xa8\xa9\xaa\xab\xac\xad\xae\xaf'
),
'derived_data': (
b'\xb1\x1e\x39\x8d\xc8\x03\x27\xa1'
b'\xc8\xe7\xf7\x8c\x59\x6a\x49\x34'
b'\x4f\x01\x2e\xda\x2d\x4e\xfa\xd8'
b'\xa0\x50\xcc\x4c\x19\xaf\xa9\x7c'
b'\x59\x04\x5a\x99\xca\xc7\x82\x72'
b'\x71\xcb\x41\xc6\x5e\x59\x0e\x09'
b'\xda\x32\x75\x60\x0c\x2f\x09\xb8'
b'\x36\x77\x93\xa9\xac\xa3\xdb\x71'
b'\xcc\x30\xc5\x81\x79\xec\x3e\x87'
b'\xc1\x4c\x01\xd5\xc1\xf3\x43\x4f'
b'\x1d\x87'
)},
{'derivation_method': enums.DerivationMethod.HMAC,
'derivation_length': 42,
'derivation_data': b'',
'key_material': (
b'\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
b'\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
b'\x0b\x0b\x0b\x0b\x0b\x0b'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_256,
'salt': b'',
'derived_data': (
b'\x8d\xa4\xe7\x75\xa5\x63\xc1\x8f'
b'\x71\x5f\x80\x2a\x06\x3c\x5a\x31'
b'\xb8\xa1\x1f\x5c\x5e\xe1\x87\x9e'
b'\xc3\x45\x4e\x5f\x3c\x73\x8d\x2d'
b'\x9d\x20\x13\x95\xfa\xa4\xb6\x1a'
b'\x96\xc8'
)},
{'derivation_method': enums.DerivationMethod.HMAC,
'derivation_length': 42,
'derivation_data': (
b'\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7'
b'\xf8\xf9'
),
'key_material': (
b'\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
b'\x0b\x0b\x0b'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'salt': (
b'\x00\x01\x02\x03\x04\x05\x06\x07'
b'\x08\x09\x0a\x0b\x0c'
),
'derived_data': (
b'\x08\x5a\x01\xea\x1b\x10\xf3\x69'
b'\x33\x06\x8b\x56\xef\xa5\xad\x81'
b'\xa4\xf1\x4b\x82\x2f\x5b\x09\x15'
b'\x68\xa9\xcd\xd4\xf1\x55\xfd\xa2'
b'\xc2\x2e\x42\x24\x78\xd3\x05\xf3'
b'\xf8\x96'
)},
{'derivation_method': enums.DerivationMethod.HMAC,
'derivation_length': 82,
'derivation_data': (
b'\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7'
b'\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf'
b'\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7'
b'\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf'
b'\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7'
b'\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf'
b'\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7'
b'\xe8\xe9\xea\xeb\xec\xed\xee\xef'
b'\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7'
b'\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
),
'key_material': (
b'\x00\x01\x02\x03\x04\x05\x06\x07'
b'\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'
b'\x10\x11\x12\x13\x14\x15\x16\x17'
b'\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'
b'\x20\x21\x22\x23\x24\x25\x26\x27'
b'\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f'
b'\x30\x31\x32\x33\x34\x35\x36\x37'
b'\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f'
b'\x40\x41\x42\x43\x44\x45\x46\x47'
b'\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'salt': (
b'\x60\x61\x62\x63\x64\x65\x66\x67'
b'\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f'
b'\x70\x71\x72\x73\x74\x75\x76\x77'
b'\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f'
b'\x80\x81\x82\x83\x84\x85\x86\x87'
b'\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f'
b'\x90\x91\x92\x93\x94\x95\x96\x97'
b'\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f'
b'\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7'
b'\xa8\xa9\xaa\xab\xac\xad\xae\xaf'
),
'derived_data': (
b'\x0b\xd7\x70\xa7\x4d\x11\x60\xf7'
b'\xc9\xf1\x2c\xd5\x91\x2a\x06\xeb'
b'\xff\x6a\xdc\xae\x89\x9d\x92\x19'
b'\x1f\xe4\x30\x56\x73\xba\x2f\xfe'
b'\x8f\xa3\xf1\xa4\xe5\xad\x79\xf3'
b'\xf3\x34\xb3\xb2\x02\xb2\x17\x3c'
b'\x48\x6e\xa3\x7c\xe3\xd3\x97\xed'
b'\x03\x4c\x7f\x9d\xfe\xb1\x5c\x5e'
b'\x92\x73\x36\xd0\x44\x1f\x4c\x43'
b'\x00\xe2\xcf\xf0\xd0\x90\x0b\x52'
b'\xd3\xb4'
)},
{'derivation_method': enums.DerivationMethod.HMAC,
'derivation_length': 42,
'derivation_data': b'',
'key_material': (
b'\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
b'\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
b'\x0b\x0b\x0b\x0b\x0b\x0b'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'salt': b'',
'derived_data': (
b'\x0a\xc1\xaf\x70\x02\xb3\xd7\x61'
b'\xd1\xe5\x52\x98\xda\x9d\x05\x06'
b'\xb9\xae\x52\x05\x72\x20\xa3\x06'
b'\xe0\x7b\x6b\x87\xe8\xdf\x21\xd0'
b'\xea\x00\x03\x3d\xe0\x39\x84\xd3'
b'\x49\x18'
)},
{'derivation_method': enums.DerivationMethod.HMAC,
'derivation_length': 42,
'derivation_data': b'',
'key_material': (
b'\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
b'\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
b'\x0c\x0c\x0c\x0c\x0c\x0c'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'salt': b'',
'derived_data': (
b'\x2c\x91\x11\x72\x04\xd7\x45\xf3'
b'\x50\x0d\x63\x6a\x62\xf6\x4f\x0a'
b'\xb3\xba\xe5\x48\xaa\x53\xd4\x23'
b'\xb0\xd1\xf2\x7e\xbb\xa6\xf5\xe5'
b'\x67\x3a\x08\x1d\x70\xcc\xe7\xac'
b'\xfc\x48'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 16,
'derivation_data': (
b'abc'
),
'hash_algorithm': enums.HashingAlgorithm.MD5,
'derived_data': (
b'\x90\x01\x50\x98\x3C\xD2\x4F\xB0'
b'\xD6\x96\x3F\x7D\x28\xE1\x7F\x72'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 16,
'derivation_data': (
b'abcdbcdecdefdefgefghfghighijhijk'
b'ijkljklmklmnlmnomnopnopq'
),
'hash_algorithm': enums.HashingAlgorithm.MD5,
'derived_data': (
b'\x82\x15\xEF\x07\x96\xA2\x0B\xCA'
b'\xAA\xE1\x16\xD3\x87\x6C\x66\x4A'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 20,
'derivation_data': b'',
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'derived_data': (
b'\xda\x39\xa3\xee\x5e\x6b\x4b\x0d'
b'\x32\x55\xbf\xef\x95\x60\x18\x90'
b'\xaf\xd8\x07\x09'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 20,
'derivation_data': (
b'\x03\x21\x79\x4b\x73\x94\x18\xc2'
b'\x4e\x7c\x2e\x56\x52\x74\x79\x1c'
b'\x4b\xe7\x49\x75\x2a\xd2\x34\xed'
b'\x56\xcb\x0a\x63\x47\x43\x0c\x6b'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'derived_data': (
b'\xb8\x99\x62\xc9\x4d\x60\xf6\xa3'
b'\x32\xfd\x60\xf6\xf0\x7d\x4f\x03'
b'\x2a\x58\x6b\x76'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 28,
'derivation_data': b'',
'hash_algorithm': enums.HashingAlgorithm.SHA_224,
'derived_data': (
b'\xd1\x4a\x02\x8c\x2a\x3a\x2b\xc9'
b'\x47\x61\x02\xbb\x28\x82\x34\xc4'
b'\x15\xa2\xb0\x1f\x82\x8e\xa6\x2a'
b'\xc5\xb3\xe4\x2f'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 28,
'derivation_data': (
b'\xa3\x31\x0b\xa0\x64\xbe\x2e\x14'
b'\xad\x32\x27\x6e\x18\xcd\x03\x10'
b'\xc9\x33\xa6\xe6\x50\xc3\xc7\x54'
b'\xd0\x24\x3c\x6c\x61\x20\x78\x65'
b'\xb4\xb6\x52\x48\xf6\x6a\x08\xed'
b'\xf6\xe0\x83\x26\x89\xa9\xdc\x3a'
b'\x2e\x5d\x20\x95\xee\xea\x50\xbd'
b'\x86\x2b\xac\x88\xc8\xbd\x31\x8d'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_224,
'derived_data': (
b'\xb2\xa5\x58\x6d\x9c\xbf\x0b\xaa'
b'\x99\x91\x57\xb4\xaf\x06\xd8\x8a'
b'\xe0\x8d\x7c\x9f\xaa\xb4\xbc\x1a'
b'\x96\x82\x9d\x65'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 32,
'derivation_data': b'',
'hash_algorithm': enums.HashingAlgorithm.SHA_256,
'derived_data': (
b'\xe3\xb0\xc4\x42\x98\xfc\x1c\x14'
b'\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24'
b'\x27\xae\x41\xe4\x64\x9b\x93\x4c'
b'\xa4\x95\x99\x1b\x78\x52\xb8\x55'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 32,
'derivation_data': (
b'\xf4\x99\xcc\x3f\x6e\x3c\xf7\xc3'
b'\x12\xff\xdf\xba\x61\xb1\x26\x0c'
b'\x37\x12\x9c\x1a\xfb\x39\x10\x47'
b'\x19\x33\x67\xb7\xb2\xed\xeb\x57'
b'\x92\x53\xe5\x1d\x62\xba\x6d\x91'
b'\x1e\x7b\x81\x8c\xca\xe1\x55\x3f'
b'\x61\x46\xea\x78\x0f\x78\xe2\x21'
b'\x9f\x62\x93\x09'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_256,
'derived_data': (
b'\x0b\x66\xc8\xb4\xfe\xfe\xbc\x8d'
b'\xc7\xda\x0b\xbe\xdc\x11\x14\xf2'
b'\x28\xaa\x63\xc3\x7d\x5c\x30\xe9'
b'\x1a\xb5\x00\xf3\xea\xdf\xce\xc5'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 48,
'derivation_data': b'',
'hash_algorithm': enums.HashingAlgorithm.SHA_384,
'derived_data': (
b'\x38\xb0\x60\xa7\x51\xac\x96\x38'
b'\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a'
b'\x21\xfd\xb7\x11\x14\xbe\x07\x43'
b'\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda'
b'\x27\x4e\xde\xbf\xe7\x6f\x65\xfb'
b'\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 48,
'derivation_data': (
b'\x3b\xf5\x2c\xc5\xee\x86\xb9\xa0'
b'\x19\x0f\x39\x0a\x5c\x03\x66\xa5'
b'\x60\xb5\x57\x00\x0d\xbe\x51\x15'
b'\xfd\x9e\xe1\x16\x30\xa6\x27\x69'
b'\x01\x15\x75\xf1\x58\x81\x19\x8f'
b'\x22\x78\x76\xe8\xfe\x68\x5a\x69'
b'\x39\xbc\x8b\x89\xfd\x48\xa3\x4e'
b'\xc5\xe7\x1e\x13\x14\x62\xb2\x88'
b'\x67\x94\xdf\xfa\x68\xcc\xc6\xd5'
b'\x64\x73\x3e\x67\xff\xef\x25\xe6'
b'\x27\xc6\xf4\xb5\x46\x07\x96\xe3'
b'\xbc\xe6\x7b\xf5\x8c\xa6\xe8\xe5'
b'\x55\xbc\x91\x6a\x85\x31\x69\x7a'
b'\xc9\x48\xb9\x0d\xc8\x61\x6f\x25'
b'\x10\x1d\xb9\x0b\x50\xc3\xd3\xdb'
b'\xc9\xe2\x1e\x42\xff\x38\x71\x87'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_384,
'derived_data': (
b'\x12\xb6\xcb\x35\xed\xa9\x2e\xe3'
b'\x73\x56\xdd\xee\x77\x78\x1a\x17'
b'\xb3\xd9\x0e\x56\x38\x24\xa9\x84'
b'\xfa\xff\xc6\xfd\xd1\x69\x3b\xd7'
b'\x62\x60\x39\x63\x55\x63\xcf\xc3'
b'\xb9\xa2\xb0\x0f\x9c\x65\xee\xfd'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 64,
'key_material': b'',
'hash_algorithm': enums.HashingAlgorithm.SHA_512,
'derived_data': (
b'\xcf\x83\xe1\x35\x7e\xef\xb8\xbd'
b'\xf1\x54\x28\x50\xd6\x6d\x80\x07'
b'\xd6\x20\xe4\x05\x0b\x57\x15\xdc'
b'\x83\xf4\xa9\x21\xd3\x6c\xe9\xce'
b'\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0'
b'\xff\x83\x18\xd2\x87\x7e\xec\x2f'
b'\x63\xb9\x31\xbd\x47\x41\x7a\x81'
b'\xa5\x38\x32\x7a\xf9\x27\xda\x3e'
)},
{'derivation_method': enums.DerivationMethod.HASH,
'derivation_length': 64,
'derivation_data': (
b'\xa7\x66\xb2\xa7\xef\x91\x67\x21'
b'\xf4\x67\x7b\x67\xdb\xc6\x5e\xf9'
b'\xb4\xd1\xbd\xa1\xad\x4e\x53\xfc'
b'\x85\x4b\x02\x36\x44\x08\x22\x15'
b'\x2a\x11\x19\x39\xe5\xab\x2b\xa2'
b'\x07\x71\x94\x72\xb6\x3f\xd4\xf4'
b'\xa5\x4f\x4b\xde\x44\xa2\x05\xd3'
b'\x34\xa2\xd7\x2c\xfe\x05\xab\xf8'
b'\x04\xf4\x18\x41\xb8\x6d\x36\x92'
b'\x0b\xe6\xb0\xb5\x29\x33\x1a\xc1'
b'\x63\xa9\x85\x55\x6c\x84\x51\x1e'
b'\xc9\x86\x43\x9f\x83\xe1\xd7\x31'
b'\x1f\x57\xd8\x48\xcf\xa0\x2d\xf9'
b'\xea\x0c\xf6\xb9\x9a'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_512,
'derived_data': (
b'\xdd\xd6\x0f\x93\xa3\xba\xbc\x78'
b'\x29\x9c\xf7\x63\xe7\x91\x9d\x45'
b'\xac\x6f\x47\x97\x00\xe1\xad\xb0'
b'\x5a\xb1\x37\xac\xdf\x89\xc1\x52'
b'\x1e\xcb\x9d\xfe\xac\xd0\x91\xe5'
b'\x8c\xa5\x7a\x1d\xb9\x64\xa9\xc3'
b'\xcd\x1f\xa3\x91\x92\xcc\x1e\x9f'
b'\x73\x4c\xaa\x1c\x5f\xa6\x29\x75'
)},
{'derivation_method': enums.DerivationMethod.NIST800_108_C,
'derivation_length': 16,
'derivation_data': (
b'\x8e\x34\x7e\xf5\x5d\x5f\x5e\x99'
b'\xea\xb6\xde\x70\x6b\x51\xde\x7c'
b'\xe0\x04\xf3\x88\x28\x89\xe2\x59'
b'\xff\x4e\x5c\xff\x10\x21\x67\xa5'
b'\xa4\xbd\x71\x15\x78\xd4\xce\x17'
b'\xdd\x9a\xbe\x56\xe5\x1c\x1f\x2d'
b'\xf9\x50\xe2\xfc\x81\x2e\xc1\xb2'
b'\x17\xca\x08\xd6'
),
'key_material': (
b'\xf7\x59\x17\x33\xc8\x56\x59\x35'
b'\x65\x13\x09\x75\x35\x19\x54\xd0'
b'\x15\x5a\xbf\x3c'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_1,
'derived_data': (
b'\x34\xfe\x44\xb0\xd8\xc4\x1b\x93'
b'\xf5\xfa\x64\xfb\x96\xf0\x0e\x5b'
)},
{'derivation_method': enums.DerivationMethod.NIST800_108_C,
'derivation_length': 16,
'derivation_data': (
b'\x4e\x5a\xc7\x53\x98\x03\xda\x89'
b'\x58\x1e\xe0\x88\xc7\xd1\x02\x35'
b'\xa1\x05\x36\x36\x00\x54\xb7\x2b'
b'\x8e\x9f\x18\xf7\x7c\x25\xaf\x01'
b'\x01\x9b\x29\x06\x56\xb6\x04\x28'
b'\x02\x4c\xe0\x1f\xcc\xf4\x90\x22'
b'\xd8\x31\x94\x14\x07\xe6\xbd\x27'
b'\xff\x9e\x2d\x28'
),
'key_material': (
b'\xf5\xcb\x7c\xc6\x20\x7f\x59\x20'
b'\xdd\x60\x15\x5d\xdb\x68\xc3\xfb'
b'\xbd\xf5\x10\x43\x65\x30\x5d\x2c'
b'\x1a\xbc\xd3\x11'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_224,
'derived_data': (
b'\x0a\xdb\xaa\xb4\x3e\xdd\x53\x2b'
b'\x56\x0a\x32\x2c\x84\xac\x54\x0e'
)},
{'derivation_method': enums.DerivationMethod.NIST800_108_C,
'derivation_length': 16,
'derivation_data': (
b'\x01\x32\x2b\x96\xb3\x0a\xcd\x19'
b'\x79\x79\x44\x4e\x46\x8e\x1c\x5c'
b'\x68\x59\xbf\x1b\x1c\xf9\x51\xb7'
b'\xe7\x25\x30\x3e\x23\x7e\x46\xb8'
b'\x64\xa1\x45\xfa\xb2\x5e\x51\x7b'
b'\x08\xf8\x68\x3d\x03\x15\xbb\x29'
b'\x11\xd8\x0a\x0e\x8a\xba\x17\xf3'
b'\xb4\x13\xfa\xac'
),
'key_material': (
b'\xdd\x1d\x91\xb7\xd9\x0b\x2b\xd3'
b'\x13\x85\x33\xce\x92\xb2\x72\xfb'
b'\xf8\xa3\x69\x31\x6a\xef\xe2\x42'
b'\xe6\x59\xcc\x0a\xe2\x38\xaf\xe0'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_256,
'derived_data': (
b'\x10\x62\x13\x42\xbf\xb0\xfd\x40'
b'\x04\x6c\x0e\x29\xf2\xcf\xdb\xf0'
)},
{'derivation_method': enums.DerivationMethod.NIST800_108_C,
'derivation_length': 16,
'derivation_data': (
b'\x63\x8e\x95\x06\xa2\xc7\xbe\x69'
b'\xea\x34\x6b\x84\x62\x9a\x01\x0c'
b'\x0e\x22\x5b\x75\x48\xf5\x08\x16'
b'\x2c\x89\xf2\x9c\x1d\xdb\xfd\x70'
b'\x47\x2c\x2b\x58\xe7\xdc\x8a\xa6'
b'\xa5\xb0\x66\x02\xf1\xc8\xed\x49'
b'\x48\xcd\xa7\x9c\x62\x70\x82\x18'
b'\xe2\x6a\xc0\xe2'
),
'key_material': (
b'\x21\x6e\xd0\x44\x76\x9c\x4c\x39'
b'\x08\x18\x8e\xce\x61\x60\x1a\xf8'
b'\x81\x9c\x30\xf5\x01\xd1\x29\x95'
b'\xdf\x60\x8e\x06\xf5\xe0\xe6\x07'
b'\xab\x54\xf5\x42\xee\x2d\xa4\x19'
b'\x06\xdf\xdb\x49\x71\xf2\x0f\x9d'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_384,
'derived_data': (
b'\xd4\xb1\x44\xbb\x40\xc7\xca\xbe'
b'\xd1\x39\x63\xd7\xd4\x31\x8e\x72'
)},
{'derivation_method': enums.DerivationMethod.NIST800_108_C,
'derivation_length': 16,
'derivation_data': (
b'\xb5\x0b\x0c\x96\x3c\x6b\x30\x34'
b'\xb8\xcf\x19\xcd\x3f\x5c\x4e\xbe'
b'\x4f\x49\x85\xaf\x0c\x03\xe5\x75'
b'\xdb\x62\xe6\xfd\xf1\xec\xfe\x4f'
b'\x28\xb9\x5d\x7c\xe1\x6d\xf8\x58'
b'\x43\x24\x6e\x15\x57\xce\x95\xbb'
b'\x26\xcc\x9a\x21\x97\x4b\xbd\x2e'
b'\xb6\x9e\x83\x55'
),
'key_material': (
b'\xdd\x5d\xbd\x45\x59\x3e\xe2\xac'
b'\x13\x97\x48\xe7\x64\x5b\x45\x0f'
b'\x22\x3d\x2f\xf2\x97\xb7\x3f\xd7'
b'\x1c\xbc\xeb\xe7\x1d\x41\x65\x3c'
b'\x95\x0b\x88\x50\x0d\xe5\x32\x2d'
b'\x99\xef\x18\xdf\xdd\x30\x42\x82'
b'\x94\xc4\xb3\x09\x4f\x4c\x95\x43'
b'\x34\xe5\x93\xbd\x98\x2e\xc6\x14'
),
'hash_algorithm': enums.HashingAlgorithm.SHA_512,
'derived_data': (
b'\xe5\x99\x3b\xf9\xbd\x2a\xa1\xc4'
b'\x57\x46\x04\x2e\x12\x59\x81\x55'
)},
{'derivation_method': enums.DerivationMethod.ENCRYPT,
'derivation_data': (
b'\x37\x36\x35\x34\x33\x32\x31\x20'
b'\x4E\x6F\x77\x20\x69\x73\x20\x74'
b'\x68\x65\x20\x74\x69\x6D\x65\x20'
b'\x66\x6F\x72\x20\x00'
),
'key_material': (
b'\x01\x23\x45\x67\x89\xAB\xCD\xEF'
b'\xF0\xE1\xD2\xC3\xB4\xA5\x96\x87'
),
'encryption_algorithm': enums.CryptographicAlgorithm.BLOWFISH,
'cipher_mode': enums.BlockCipherMode.CBC,
'padding_method': enums.PaddingMethod.PKCS5,
'iv_nonce': b'\xFE\xDC\xBA\x98\x76\x54\x32\x10',
'derived_data': (
b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6'
b'\x05\xB1\x56\xE2\x74\x03\x97\x93'
b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9'
b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B'
)}
]
)
def derivation_parameters(request):
return request.param
def test_derive_key(derivation_parameters):
"""
Test that various derivation methods and settings can be used to correctly
derive key data.
"""
engine = crypto.CryptographyEngine()
result = engine.derive_key(
derivation_parameters.get('derivation_method'),
derivation_parameters.get('derivation_length'),
derivation_data=derivation_parameters.get('derivation_data'),
key_material=derivation_parameters.get('key_material'),
hash_algorithm=derivation_parameters.get('hash_algorithm'),
salt=derivation_parameters.get('salt'),
iteration_count=derivation_parameters.get('iteration_count'),
encryption_algorithm=derivation_parameters.get('encryption_algorithm'),
padding_method=derivation_parameters.get('padding_method'),
cipher_mode=derivation_parameters.get('cipher_mode'),
iv_nonce=derivation_parameters.get('iv_nonce')
)
assert derivation_parameters.get('derived_data') == result