You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
267 lines
7.5 KiB
267 lines
7.5 KiB
# 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 binascii
|
|
import os
|
|
|
|
import pytest
|
|
|
|
from cryptography.exceptions import (
|
|
AlreadyFinalized, InvalidKey, _Reasons
|
|
)
|
|
from cryptography.hazmat.backends.interfaces import HMACBackend
|
|
from cryptography.hazmat.primitives import hashes
|
|
from cryptography.hazmat.primitives.kdf.hkdf import HKDF, HKDFExpand
|
|
|
|
from ...utils import (
|
|
load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm
|
|
)
|
|
|
|
|
|
@pytest.mark.requires_backend_interface(interface=HMACBackend)
|
|
class TestHKDF(object):
|
|
def test_length_limit(self, backend):
|
|
big_length = 255 * hashes.SHA256().digest_size + 1
|
|
|
|
with pytest.raises(ValueError):
|
|
HKDF(
|
|
hashes.SHA256(),
|
|
big_length,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
def test_already_finalized(self, backend):
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
hkdf.derive(b"\x01" * 16)
|
|
|
|
with pytest.raises(AlreadyFinalized):
|
|
hkdf.derive(b"\x02" * 16)
|
|
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
hkdf.verify(b"\x01" * 16, b"gJ\xfb{\xb1Oi\xc5sMC\xb7\xe4@\xf7u")
|
|
|
|
with pytest.raises(AlreadyFinalized):
|
|
hkdf.verify(b"\x02" * 16, b"gJ\xfb{\xb1Oi\xc5sMC\xb7\xe4@\xf7u")
|
|
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
def test_verify(self, backend):
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
hkdf.verify(b"\x01" * 16, b"gJ\xfb{\xb1Oi\xc5sMC\xb7\xe4@\xf7u")
|
|
|
|
def test_verify_invalid(self, backend):
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
with pytest.raises(InvalidKey):
|
|
hkdf.verify(b"\x02" * 16, b"gJ\xfb{\xb1Oi\xc5sMC\xb7\xe4@\xf7u")
|
|
|
|
def test_unicode_typeerror(self, backend):
|
|
with pytest.raises(TypeError):
|
|
HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=u"foo",
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
with pytest.raises(TypeError):
|
|
HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=None,
|
|
info=u"foo",
|
|
backend=backend
|
|
)
|
|
|
|
with pytest.raises(TypeError):
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
hkdf.derive(u"foo")
|
|
|
|
with pytest.raises(TypeError):
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
hkdf.verify(u"foo", b"bar")
|
|
|
|
with pytest.raises(TypeError):
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
16,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
hkdf.verify(b"foo", u"bar")
|
|
|
|
def test_derive_short_output(self, backend):
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
4,
|
|
salt=None,
|
|
info=None,
|
|
backend=backend
|
|
)
|
|
|
|
assert hkdf.derive(b"\x01" * 16) == b"gJ\xfb{"
|
|
|
|
def test_derive_long_output(self, backend):
|
|
vector = load_vectors_from_file(
|
|
os.path.join("KDF", "hkdf-generated.txt"), load_nist_vectors
|
|
)[0]
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
int(vector["l"]),
|
|
salt=vector["salt"],
|
|
info=vector["info"],
|
|
backend=backend
|
|
)
|
|
ikm = binascii.unhexlify(vector["ikm"])
|
|
|
|
assert hkdf.derive(ikm) == binascii.unhexlify(vector["okm"])
|
|
|
|
def test_buffer_protocol(self, backend):
|
|
vector = load_vectors_from_file(
|
|
os.path.join("KDF", "hkdf-generated.txt"), load_nist_vectors
|
|
)[0]
|
|
hkdf = HKDF(
|
|
hashes.SHA256(),
|
|
int(vector["l"]),
|
|
salt=vector["salt"],
|
|
info=vector["info"],
|
|
backend=backend
|
|
)
|
|
ikm = bytearray(binascii.unhexlify(vector["ikm"]))
|
|
|
|
assert hkdf.derive(ikm) == binascii.unhexlify(vector["okm"])
|
|
|
|
|
|
@pytest.mark.requires_backend_interface(interface=HMACBackend)
|
|
class TestHKDFExpand(object):
|
|
def test_derive(self, backend):
|
|
prk = binascii.unhexlify(
|
|
b"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5"
|
|
)
|
|
|
|
okm = (b"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c"
|
|
b"5bf34007208d5b887185865")
|
|
|
|
info = binascii.unhexlify(b"f0f1f2f3f4f5f6f7f8f9")
|
|
hkdf = HKDFExpand(hashes.SHA256(), 42, info, backend)
|
|
|
|
assert binascii.hexlify(hkdf.derive(prk)) == okm
|
|
|
|
def test_buffer_protocol(self, backend):
|
|
prk = bytearray(binascii.unhexlify(
|
|
b"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5"
|
|
))
|
|
|
|
okm = (b"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c"
|
|
b"5bf34007208d5b887185865")
|
|
|
|
info = binascii.unhexlify(b"f0f1f2f3f4f5f6f7f8f9")
|
|
hkdf = HKDFExpand(hashes.SHA256(), 42, info, backend)
|
|
|
|
assert binascii.hexlify(hkdf.derive(prk)) == okm
|
|
|
|
def test_verify(self, backend):
|
|
prk = binascii.unhexlify(
|
|
b"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5"
|
|
)
|
|
|
|
okm = (b"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c"
|
|
b"5bf34007208d5b887185865")
|
|
|
|
info = binascii.unhexlify(b"f0f1f2f3f4f5f6f7f8f9")
|
|
hkdf = HKDFExpand(hashes.SHA256(), 42, info, backend)
|
|
|
|
assert hkdf.verify(prk, binascii.unhexlify(okm)) is None
|
|
|
|
def test_invalid_verify(self, backend):
|
|
prk = binascii.unhexlify(
|
|
b"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5"
|
|
)
|
|
|
|
info = binascii.unhexlify(b"f0f1f2f3f4f5f6f7f8f9")
|
|
hkdf = HKDFExpand(hashes.SHA256(), 42, info, backend)
|
|
|
|
with pytest.raises(InvalidKey):
|
|
hkdf.verify(prk, b"wrong key")
|
|
|
|
def test_already_finalized(self, backend):
|
|
info = binascii.unhexlify(b"f0f1f2f3f4f5f6f7f8f9")
|
|
hkdf = HKDFExpand(hashes.SHA256(), 42, info, backend)
|
|
|
|
hkdf.derive(b"first")
|
|
|
|
with pytest.raises(AlreadyFinalized):
|
|
hkdf.derive(b"second")
|
|
|
|
def test_unicode_error(self, backend):
|
|
info = binascii.unhexlify(b"f0f1f2f3f4f5f6f7f8f9")
|
|
hkdf = HKDFExpand(hashes.SHA256(), 42, info, backend)
|
|
|
|
with pytest.raises(TypeError):
|
|
hkdf.derive(u"first")
|
|
|
|
|
|
def test_invalid_backend():
|
|
pretend_backend = object()
|
|
|
|
with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):
|
|
HKDF(hashes.SHA256(), 16, None, None, pretend_backend)
|
|
|
|
with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):
|
|
HKDFExpand(hashes.SHA256(), 16, None, pretend_backend)
|