1#!/usr/bin/env python3 2# SPDX-License-Identifier: GPL-2.0-or-later 3# 4# Script that generates lib/crypto/fips-aes.h and lib/crypto/fips-sha.h 5# 6# Requires that python-cryptography be installed. 7# 8# Copyright 2025 Google LLC 9 10import cryptography.hazmat.primitives.ciphers 11import cryptography.hazmat.primitives.ciphers.aead 12import cryptography.hazmat.primitives.cmac 13import hashlib 14import hmac 15 16 17def print_static_u8_array_definition(file, name, value): 18 print("", file=file) 19 print(f"static const u8 {name}[] __initconst __maybe_unused = {{", file=file) 20 for i in range(0, len(value), 8): 21 line = "\t" + "".join(f"0x{b:02x}, " for b in value[i : i + 8]) 22 print(f"{line.rstrip()}", file=file) 23 print("};", file=file) 24 25 26def print_header(file): 27 print("/* SPDX-License-Identifier: GPL-2.0-or-later */", file=file) 28 print("/* This file was generated by: gen-fips-testvecs.py */", file=file) 29 print("/* clang-format off */", file=file) 30 print("", file=file) 31 print("#include <linux/fips.h>", file=file) 32 33 34def gen_aes_test_data(file): 35 fips_test_data = b"fips test data\0\0" 36 fips_test_ad = b"fips test ad\0\0\0\0" 37 fips_test_iv = b"fips test iv\0\0\0\0" 38 fips_test_key = b"fips test key\0\0\0" 39 fips_test_xts_key = b"key1" + (b"\0" * 12) + b"key2" + (b"\0" * 12) 40 41 print_header(file) 42 print_static_u8_array_definition(file, "fips_test_data", fips_test_data) 43 print_static_u8_array_definition(file, "fips_test_ad", fips_test_ad) 44 print_static_u8_array_definition(file, "fips_test_iv", fips_test_iv) 45 print_static_u8_array_definition(file, "fips_test_key", fips_test_key) 46 print_static_u8_array_definition(file, "fips_test_xts_key", fips_test_xts_key) 47 48 aes = cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_test_key) 49 50 # AES-CMAC 51 aes_cmac = cryptography.hazmat.primitives.cmac.CMAC(aes) 52 aes_cmac.update(fips_test_data) 53 print_static_u8_array_definition( 54 file, "fips_test_aes_cmac_value", aes_cmac.finalize() 55 ) 56 57 # AES-ECB 58 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 59 aes, cryptography.hazmat.primitives.ciphers.modes.ECB() 60 ) 61 encryptor = cipher.encryptor() 62 ctext = encryptor.update(fips_test_data) + encryptor.finalize() 63 print_static_u8_array_definition(file, "fips_test_aes_ecb_ctext", ctext) 64 65 # AES-CBC 66 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 67 aes, cryptography.hazmat.primitives.ciphers.modes.CBC(fips_test_iv) 68 ) 69 encryptor = cipher.encryptor() 70 ctext = encryptor.update(fips_test_data) + encryptor.finalize() 71 print_static_u8_array_definition(file, "fips_test_aes_cbc_ctext", ctext) 72 73 # AES-CBC-CTS 74 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 75 aes, cryptography.hazmat.primitives.ciphers.modes.CBC(fips_test_iv) 76 ) 77 encryptor = cipher.encryptor() 78 ctext = encryptor.update(fips_test_data * 2) + encryptor.finalize() 79 ctext = ctext[16:32] + ctext[0:16] 80 print_static_u8_array_definition(file, "fips_test_aes_cbc_cts_ctext", ctext) 81 82 # AES-CTR 83 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 84 aes, cryptography.hazmat.primitives.ciphers.modes.CTR(fips_test_iv) 85 ) 86 encryptor = cipher.encryptor() 87 ctext = encryptor.update(fips_test_data) + encryptor.finalize() 88 print_static_u8_array_definition(file, "fips_test_aes_ctr_ctext", ctext) 89 90 # AES-XTS 91 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 92 cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_test_xts_key), 93 cryptography.hazmat.primitives.ciphers.modes.XTS(fips_test_iv), 94 ) 95 encryptor = cipher.encryptor() 96 ctext = encryptor.update(fips_test_data) + encryptor.finalize() 97 print_static_u8_array_definition(file, "fips_test_aes_xts_ctext", ctext) 98 99 # AES-GCM 100 cipher = cryptography.hazmat.primitives.ciphers.aead.AESGCM(fips_test_key) 101 ct_and_tag = cipher.encrypt( 102 nonce=fips_test_iv[:12], data=fips_test_data, associated_data=fips_test_ad 103 ) 104 print_static_u8_array_definition( 105 file, "fips_test_aes_gcm_ctext_and_tag", ct_and_tag 106 ) 107 108 # AES-CCM 109 cipher = cryptography.hazmat.primitives.ciphers.aead.AESCCM( 110 fips_test_key, tag_length=16 111 ) 112 ct_and_tag = cipher.encrypt( 113 nonce=fips_test_iv[:13], data=fips_test_data, associated_data=fips_test_ad 114 ) 115 print_static_u8_array_definition( 116 file, "fips_test_aes_ccm_ctext_and_tag", ct_and_tag 117 ) 118 119 120def gen_sha_test_data(file): 121 fips_test_data = b"fips test data\0\0" 122 fips_test_key = b"fips test key\0\0\0" 123 124 print_header(file) 125 print_static_u8_array_definition(file, "fips_test_data", fips_test_data) 126 print_static_u8_array_definition(file, "fips_test_key", fips_test_key) 127 128 for alg in "sha1", "sha256", "sha512": 129 ctx = hmac.new(fips_test_key, digestmod=alg) 130 ctx.update(fips_test_data) 131 print_static_u8_array_definition( 132 file, f"fips_test_hmac_{alg}_value", ctx.digest() 133 ) 134 135 print_static_u8_array_definition( 136 file, "fips_test_sha3_256_value", hashlib.sha3_256(fips_test_data).digest() 137 ) 138 139 140filename = "lib/crypto/fips-aes.h" 141with open(filename, "w") as file: 142 print(f"Generating {filename}") 143 gen_aes_test_data(file) 144 145filename = "lib/crypto/fips-sha.h" 146with open(filename, "w") as file: 147 print(f"Generating {filename}") 148 gen_sha_test_data(file) 149