From a397d75a1e091299d012035655bdc30376378b4c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 2 Oct 2017 10:03:20 +0800 Subject: Add support for AES XTS (#3900) * Add support for AES XTS We drop the non-byte aligned test vectors because according to NIST http://csrc.nist.gov/groups/STM/cavp/documents/aes/XTSVS.pdf "An implementation may support a data unit length that is not a multiple of 8 bits." OpenSSL does not support this, so we can't use those test vectors. * fix docs and pep8 * docs fix * the spellchecker is so frustrating * add note about AES 192 for XTS (it's not supported) * docs work * enforce key length on ECB mode in AES as well (thanks XTS) * a few more words about why we exclude some test vectors for XTS --- tests/hazmat/primitives/test_aes.py | 36 ++++++++++++++++++++++++++++++++- tests/hazmat/primitives/test_ciphers.py | 24 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index a6b1e5f2..a2a29881 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -12,10 +12,44 @@ import pytest from cryptography.hazmat.backends.interfaces import CipherBackend from cryptography.hazmat.primitives.ciphers import algorithms, base, modes -from .utils import generate_aead_test, generate_encrypt_test +from .utils import _load_all_params, generate_aead_test, generate_encrypt_test from ...utils import load_nist_vectors +@pytest.mark.supported( + only_if=lambda backend: backend.cipher_supported( + algorithms.AES(b"\x00" * 32), modes.XTS(b"\x00" * 16) + ), + skip_message="Does not support AES XTS", +) +@pytest.mark.requires_backend_interface(interface=CipherBackend) +class TestAESModeXTS(object): + @pytest.mark.parametrize( + "vector", + # This list comprehension excludes any vector that does not have a + # data unit length that is divisible by 8. The NIST vectors include + # tests for implementations that support encryption of data that is + # not divisible modulo 8, but OpenSSL is not such an implementation. + [x for x in _load_all_params( + os.path.join("ciphers", "AES", "XTS", "tweak-128hexstr"), + ["XTSGenAES128.rsp", "XTSGenAES256.rsp"], + load_nist_vectors + ) if int(x["dataunitlen"]) / 8.0 == int(x["dataunitlen"]) // 8] + ) + def test_xts_vectors(self, vector, backend): + key = binascii.unhexlify(vector["key"]) + tweak = binascii.unhexlify(vector["i"]) + pt = binascii.unhexlify(vector["pt"]) + ct = binascii.unhexlify(vector["ct"]) + cipher = base.Cipher(algorithms.AES(key), modes.XTS(tweak), backend) + enc = cipher.encryptor() + computed_ct = enc.update(pt) + enc.finalize() + assert computed_ct == ct + dec = cipher.decryptor() + computed_pt = dec.update(ct) + dec.finalize() + assert computed_pt == pt + + @pytest.mark.supported( only_if=lambda backend: backend.cipher_supported( algorithms.AES(b"\x00" * 16), modes.CBC(b"\x00" * 16) diff --git a/tests/hazmat/primitives/test_ciphers.py b/tests/hazmat/primitives/test_ciphers.py index f1718c07..2f58c9fc 100644 --- a/tests/hazmat/primitives/test_ciphers.py +++ b/tests/hazmat/primitives/test_ciphers.py @@ -37,6 +37,30 @@ class TestAES(object): AES(binascii.unhexlify(b"0" * 12)) +class TestAESXTS(object): + @pytest.mark.requires_backend_interface(interface=CipherBackend) + @pytest.mark.parametrize( + "mode", + (modes.CBC, modes.CTR, modes.CFB, modes.CFB8, modes.OFB) + ) + def test_invalid_key_size_with_mode(self, mode, backend): + with pytest.raises(ValueError): + ciphers.Cipher(AES(b"0" * 64), mode(b"0" * 16), backend) + + def test_xts_tweak_not_bytes(self): + with pytest.raises(TypeError): + modes.XTS(32) + + def test_xts_tweak_too_small(self): + with pytest.raises(ValueError): + modes.XTS(b"0") + + @pytest.mark.requires_backend_interface(interface=CipherBackend) + def test_xts_wrong_key_size(self, backend): + with pytest.raises(ValueError): + ciphers.Cipher(AES(b"0" * 16), modes.XTS(b"0" * 16), backend) + + class TestCamellia(object): @pytest.mark.parametrize(("key", "keysize"), [ (b"0" * 32, 128), -- cgit v1.2.3