1# !/usr/bin/env python3 2 3import json 4 5from pathlib import Path 6 7# Can only process base mode 0 8# https://www.rfc-editor.org/rfc/rfc9180.html#name-hybrid-public-key-encryptio 9MODE_BASE = 0x00 10 11# Can only process KEM DHKEM(X25519, HKDF-SHA256) = 0x0020 12# https://www.rfc-editor.org/rfc/rfc9180.html#name-key-encapsulation-mechanism 13KEM_DHKEM_X25519_SHA256 = 0x0020 14 15# Can only process KDF HKDF-SHA256 16# https://www.rfc-editor.org/rfc/rfc9180.html#name-key-derivation-functions-kd 17KDF_HKDF_SHA256 = 0x0001 18 19# Can process all AEADs except EXPORT-only as this will be generating 20# a file to test encryption/decryption only, not secret exports 21# https://www.rfc-editor.org/rfc/rfc9180.html#name-authenticated-encryption-wi 22AEAD_EXPORT_ONLY = 0xffff 23 24 25def parse_and_format(file_in_path: str, file_out_path: str) -> None: 26 """ 27 Parse and formats test-vectors.txt into Conscrypt's format. 28 A copy of the JSON file mentioned in RFC 9180 must be placed right next to 29 this script. A file will be created named "hpke-encryption.csv" 30 31 Parameters: 32 file_in_path: Absolute path to test-vectors.txt. 33 file_out_path: Absolute path to output file. 34 """ 35 36 with open(file_in_path) as input: 37 payload = json.load(input) 38 39 records = ["# Several lines conform cryptographic operations ordered in sequence.", 40 "# If records belong to a sequence, the following values won't change: ", 41 "# kem_id, kdf_id, aead_id, info, skRm, skEm, pkRm, and pkEm.", 42 "# The first record in the sequence contains all the data, while the ", 43 "# next records in the sequence has the data omitted to make the file readable.", 44 "# Please use the data from the first record of the sequence when performing ", 45 "# the cryptographic operations. ", 46 "# ", 47 "# Data is in the format:", 48 "# kem_id,kdf_id,aead_id,info,skRm,skEm,pkRm,pkEm,aad,ct,pt"] 49 50 for key in payload: 51 # Skip these to test only capabilities exposed by BoringSSL 52 if (key["mode"] != MODE_BASE or 53 key["kem_id"] != KEM_DHKEM_X25519_SHA256 or 54 key["kdf_id"] != KDF_HKDF_SHA256 or 55 key["aead_id"] == AEAD_EXPORT_ONLY): 56 continue 57 58 firstEncryptionKeyIteration = True 59 for encryptionKey in key["encryptions"]: 60 if (firstEncryptionKeyIteration): 61 firstEncryptionKeyIteration = False 62 records.append("{},{},{},{},{},{},{},{},{},{},{}" 63 .format(str(key["kem_id"]), 64 str(key["kdf_id"]), 65 str(key["aead_id"]), 66 str(key["info"]), 67 str(key["skRm"]), 68 str(key["skEm"]), 69 str(key["pkRm"]), 70 str(key["pkEm"]), 71 str(encryptionKey["aad"]), 72 str(encryptionKey["ct"]), 73 str(encryptionKey["pt"]))) 74 else: 75 records.append(",,,,,,,,{},{},{}" 76 .format(str(encryptionKey["aad"]), 77 str(encryptionKey["ct"]), 78 str(encryptionKey["pt"]))) 79 80 with open(file_out_path, "w") as output: 81 output.write("\n".join(records)) 82 83 84def main(): 85 path = Path(__file__).parent.absolute() 86 parse_and_format(path / "test-vectors.txt", path / "hpke-encryption.csv") 87 88 89if __name__ == "__main__": 90 main() 91