157 lines
6.0 KiB
Python
157 lines
6.0 KiB
Python
# 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 len(iv) < 8 or len(iv) > 128:
|
|
pytest.skip(
|
|
"Less than 64-bit IVs (and greater than 1024-bit) are no longer "
|
|
"supported"
|
|
)
|
|
if backend._fips_enabled and len(iv) != 12:
|
|
# Red Hat disables non-96-bit IV support as part of its FIPS
|
|
# patches.
|
|
pytest.skip("Non-96-bit IVs unsupported in FIPS mode.")
|
|
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
|
|
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"])
|
|
if len(iv) < 8 or len(iv) > 128:
|
|
pytest.skip(
|
|
"Less than 64-bit IVs (and greater than 1024-bit) are no longer "
|
|
"supported"
|
|
)
|
|
|
|
if backend._fips_enabled and len(iv) != 12:
|
|
# Red Hat disables non-96-bit IV support as part of its FIPS
|
|
# patches.
|
|
pytest.skip("Non-96-bit IVs unsupported in FIPS mode.")
|
|
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
|
|
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)
|