1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
# 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.
import binascii
from cryptography.hazmat.primitives.ciphers.aead import AESGCMSIV
def convert_key_to_192_bits(key: str) -> str:
"""
This takes existing 128 and 256-bit keys from test vectors from OpenSSL
and makes them 192-bit by either appending 0 or truncating the key.
"""
new_key = binascii.unhexlify(key)
if len(new_key) == 16:
new_key += b"\x00" * 8
elif len(new_key) == 32:
new_key = new_key[0:24]
else:
raise RuntimeError(
"Unexpected key length. OpenSSL AES-GCM-SIV test vectors only "
"contain 128-bit and 256-bit keys"
)
return binascii.hexlify(new_key).decode("ascii")
def encrypt(key: str, iv: str, plaintext: str, aad: str) -> (str, str):
aesgcmsiv = AESGCMSIV(binascii.unhexlify(key))
encrypted_output = aesgcmsiv.encrypt(
binascii.unhexlify(iv),
binascii.unhexlify(plaintext),
binascii.unhexlify(aad) if aad else None,
)
ciphertext, tag = encrypted_output[:-16], encrypted_output[-16:]
return (
binascii.hexlify(ciphertext).decode("ascii"),
binascii.hexlify(tag).decode("ascii"),
)
def build_vectors(filename):
count = 0
output = []
key = None
iv = None
aad = None
plaintext = None
with open(filename) as vector_file:
for line in vector_file:
line = line.strip()
if line.startswith("Key"):
if count != 0:
ciphertext, tag = encrypt(key, iv, plaintext, aad)
output.append(f"Tag = {tag}\nCiphertext = {ciphertext}\n")
output.append(f"\nCOUNT = {count}")
count += 1
aad = None
_, key = line.split(" = ")
key = convert_key_to_192_bits(key)
output.append(f"Key = {key}")
elif line.startswith("IV"):
_, iv = line.split(" = ")
output.append(f"IV = {iv}")
elif line.startswith("AAD"):
_, aad = line.split(" = ")
output.append(f"AAD = {aad}")
elif line.startswith("Plaintext"):
_, plaintext = line.split(" = ")
output.append(f"Plaintext = {plaintext}")
ciphertext, tag = encrypt(key, iv, plaintext, aad)
output.append(f"Tag = {tag}\nCiphertext = {ciphertext}\n")
return "\n".join(output)
def write_file(data, filename):
with open(filename, "w") as f:
f.write(data)
path = "vectors/cryptography_vectors/ciphers/AES/GCM-SIV/openssl.txt"
write_file(build_vectors(path), "aes-192-gcm-siv.txt")
|