aboutsummaryrefslogtreecommitdiffstats
path: root/tests/wycheproof/test_aes.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/wycheproof/test_aes.py')
-rw-r--r--tests/wycheproof/test_aes.py144
1 files changed, 144 insertions, 0 deletions
diff --git a/tests/wycheproof/test_aes.py b/tests/wycheproof/test_aes.py
new file mode 100644
index 00000000..55e45454
--- /dev/null
+++ b/tests/wycheproof/test_aes.py
@@ -0,0 +1,144 @@
+# 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 pytest
+
+from cryptography.exceptions import InvalidTag
+from cryptography.hazmat.backends.interfaces import CipherBackend
+from cryptography.hazmat.primitives import padding
+from cryptography.hazmat.primitives.ciphers import (
+ Cipher, algorithms, modes
+)
+from cryptography.hazmat.primitives.ciphers.aead import AESCCM, AESGCM
+
+from ..hazmat.primitives.test_aead import _aead_supported
+
+
+@pytest.mark.requires_backend_interface(interface=CipherBackend)
+@pytest.mark.wycheproof_tests("aes_cbc_pkcs5_test.json")
+def test_aes_cbc_pkcs5(backend, wycheproof):
+ key = binascii.unhexlify(wycheproof.testcase["key"])
+ iv = binascii.unhexlify(wycheproof.testcase["iv"])
+ msg = binascii.unhexlify(wycheproof.testcase["msg"])
+ ct = binascii.unhexlify(wycheproof.testcase["ct"])
+
+ padder = padding.PKCS7(128).padder()
+
+ cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend)
+ enc = cipher.encryptor()
+ computed_ct = enc.update(
+ padder.update(msg) + padder.finalize()) + enc.finalize()
+ dec = cipher.decryptor()
+ padded_msg = dec.update(ct) + dec.finalize()
+ unpadder = padding.PKCS7(128).unpadder()
+ if wycheproof.valid or wycheproof.acceptable:
+ assert computed_ct == ct
+ computed_msg = unpadder.update(padded_msg) + unpadder.finalize()
+ assert computed_msg == msg
+ else:
+ assert computed_ct != ct
+ with pytest.raises(ValueError):
+ unpadder.update(padded_msg) + unpadder.finalize()
+
+
+@pytest.mark.requires_backend_interface(interface=CipherBackend)
+@pytest.mark.wycheproof_tests("aes_gcm_test.json")
+def test_aes_gcm(backend, wycheproof):
+ key = binascii.unhexlify(wycheproof.testcase["key"])
+ iv = binascii.unhexlify(wycheproof.testcase["iv"])
+ aad = binascii.unhexlify(wycheproof.testcase["aad"])
+ msg = binascii.unhexlify(wycheproof.testcase["msg"])
+ ct = binascii.unhexlify(wycheproof.testcase["ct"])
+ tag = binascii.unhexlify(wycheproof.testcase["tag"])
+ if wycheproof.valid or wycheproof.acceptable:
+ enc = Cipher(algorithms.AES(key), modes.GCM(iv), backend).encryptor()
+ enc.authenticate_additional_data(aad)
+ computed_ct = enc.update(msg) + enc.finalize()
+ computed_tag = enc.tag
+ assert computed_ct == ct
+ assert computed_tag == tag
+ dec = Cipher(
+ algorithms.AES(key),
+ modes.GCM(iv, tag, min_tag_length=len(tag)),
+ backend
+ ).decryptor()
+ dec.authenticate_additional_data(aad)
+ computed_msg = dec.update(ct) + dec.finalize()
+ assert computed_msg == msg
+ elif len(iv) == 0:
+ with pytest.raises(ValueError):
+ Cipher(algorithms.AES(key), modes.GCM(iv), backend)
+ else:
+ dec = Cipher(
+ algorithms.AES(key),
+ modes.GCM(iv, tag, min_tag_length=len(tag)),
+ backend
+ ).decryptor()
+ dec.authenticate_additional_data(aad)
+ dec.update(ct)
+ with pytest.raises(InvalidTag):
+ dec.finalize()
+
+
+@pytest.mark.requires_backend_interface(interface=CipherBackend)
+@pytest.mark.wycheproof_tests("aes_gcm_test.json")
+def test_aes_gcm_aead_api(backend, wycheproof):
+ key = binascii.unhexlify(wycheproof.testcase["key"])
+ iv = binascii.unhexlify(wycheproof.testcase["iv"])
+ aad = binascii.unhexlify(wycheproof.testcase["aad"])
+ msg = binascii.unhexlify(wycheproof.testcase["msg"])
+ ct = binascii.unhexlify(wycheproof.testcase["ct"])
+ tag = binascii.unhexlify(wycheproof.testcase["tag"])
+ aesgcm = AESGCM(key)
+ if wycheproof.valid or wycheproof.acceptable:
+ computed_ct = aesgcm.encrypt(iv, msg, aad)
+ assert computed_ct == ct + tag
+ computed_msg = aesgcm.decrypt(iv, ct + tag, aad)
+ assert computed_msg == msg
+ elif len(iv) == 0:
+ with pytest.raises(ValueError):
+ aesgcm.encrypt(iv, msg, aad)
+ else:
+ with pytest.raises(InvalidTag):
+ aesgcm.decrypt(iv, ct + tag, aad)
+
+
+@pytest.mark.skipif(
+ not _aead_supported(AESCCM),
+ reason="Requires OpenSSL with AES-CCM support",
+)
+@pytest.mark.requires_backend_interface(interface=CipherBackend)
+@pytest.mark.wycheproof_tests("aes_ccm_test.json")
+def test_aes_ccm_aead_api(backend, wycheproof):
+ key = binascii.unhexlify(wycheproof.testcase["key"])
+ iv = binascii.unhexlify(wycheproof.testcase["iv"])
+ aad = binascii.unhexlify(wycheproof.testcase["aad"])
+ msg = binascii.unhexlify(wycheproof.testcase["msg"])
+ ct = binascii.unhexlify(wycheproof.testcase["ct"])
+ tag = binascii.unhexlify(wycheproof.testcase["tag"])
+
+ if (
+ wycheproof.invalid and
+ wycheproof.testcase["comment"] == "Invalid tag size"
+ ):
+ with pytest.raises(ValueError):
+ AESCCM(key, tag_length=wycheproof.testgroup["tagSize"] // 8)
+ return
+
+ aesccm = AESCCM(key, tag_length=wycheproof.testgroup["tagSize"] // 8)
+ if wycheproof.valid or wycheproof.acceptable:
+ computed_ct = aesccm.encrypt(iv, msg, aad)
+ assert computed_ct == ct + tag
+ computed_msg = aesccm.decrypt(iv, ct + tag, aad)
+ assert computed_msg == msg
+ elif not 7 <= len(iv) <= 13:
+ with pytest.raises(ValueError):
+ aesccm.decrypt(iv, ct + tag, aad)
+ else:
+ with pytest.raises(InvalidTag):
+ aesccm.decrypt(iv, ct + tag, aad)