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.cmac 12import hashlib 13import hmac 14 15 16def print_static_u8_array_definition(file, name, value): 17 print("", file=file) 18 print(f"static const u8 {name}[] __initconst __maybe_unused = {{", file=file) 19 for i in range(0, len(value), 8): 20 line = "\t" + "".join(f"0x{b:02x}, " for b in value[i : i + 8]) 21 print(f"{line.rstrip()}", file=file) 22 print("};", file=file) 23 24 25def print_header(file): 26 print("/* SPDX-License-Identifier: GPL-2.0-or-later */", file=file) 27 print("/* This file was generated by: gen-fips-testvecs.py */", file=file) 28 print("/* clang-format off */", file=file) 29 print("", file=file) 30 print("#include <linux/fips.h>", file=file) 31 32 33def gen_aes_test_data(file): 34 fips_test_data = b"fips test data\0\0" 35 fips_test_iv = b"fips test iv\0\0\0\0" 36 fips_test_key = b"fips test key\0\0\0" 37 fips_test_xts_key = b"key1" + (b"\0" * 12) + b"key2" + (b"\0" * 12) 38 39 print_header(file) 40 print_static_u8_array_definition(file, "fips_test_data", fips_test_data) 41 print_static_u8_array_definition(file, "fips_test_iv", fips_test_iv) 42 print_static_u8_array_definition(file, "fips_test_key", fips_test_key) 43 print_static_u8_array_definition(file, "fips_test_xts_key", fips_test_xts_key) 44 45 aes = cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_test_key) 46 47 # AES-CMAC 48 aes_cmac = cryptography.hazmat.primitives.cmac.CMAC(aes) 49 aes_cmac.update(fips_test_data) 50 print_static_u8_array_definition( 51 file, "fips_test_aes_cmac_value", aes_cmac.finalize() 52 ) 53 54 # AES-ECB 55 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 56 aes, cryptography.hazmat.primitives.ciphers.modes.ECB() 57 ) 58 encryptor = cipher.encryptor() 59 ctext = encryptor.update(fips_test_data) + encryptor.finalize() 60 print_static_u8_array_definition(file, "fips_test_aes_ecb_ctext", ctext) 61 62 # AES-CBC 63 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 64 aes, cryptography.hazmat.primitives.ciphers.modes.CBC(fips_test_iv) 65 ) 66 encryptor = cipher.encryptor() 67 ctext = encryptor.update(fips_test_data) + encryptor.finalize() 68 print_static_u8_array_definition(file, "fips_test_aes_cbc_ctext", ctext) 69 70 # AES-CBC-CTS 71 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 72 aes, cryptography.hazmat.primitives.ciphers.modes.CBC(fips_test_iv) 73 ) 74 encryptor = cipher.encryptor() 75 ctext = encryptor.update(fips_test_data * 2) + encryptor.finalize() 76 ctext = ctext[16:32] + ctext[0:16] 77 print_static_u8_array_definition(file, "fips_test_aes_cbc_cts_ctext", ctext) 78 79 # AES-CTR 80 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 81 aes, cryptography.hazmat.primitives.ciphers.modes.CTR(fips_test_iv) 82 ) 83 encryptor = cipher.encryptor() 84 ctext = encryptor.update(fips_test_data) + encryptor.finalize() 85 print_static_u8_array_definition(file, "fips_test_aes_ctr_ctext", ctext) 86 87 # AES-XTS 88 cipher = cryptography.hazmat.primitives.ciphers.Cipher( 89 cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_test_xts_key), 90 cryptography.hazmat.primitives.ciphers.modes.XTS(fips_test_iv), 91 ) 92 encryptor = cipher.encryptor() 93 ctext = encryptor.update(fips_test_data) + encryptor.finalize() 94 print_static_u8_array_definition(file, "fips_test_aes_xts_ctext", ctext) 95 96 97def gen_sha_test_data(file): 98 fips_test_data = b"fips test data\0\0" 99 fips_test_key = b"fips test key\0\0\0" 100 101 print_header(file) 102 print_static_u8_array_definition(file, "fips_test_data", fips_test_data) 103 print_static_u8_array_definition(file, "fips_test_key", fips_test_key) 104 105 for alg in "sha1", "sha256", "sha512": 106 ctx = hmac.new(fips_test_key, digestmod=alg) 107 ctx.update(fips_test_data) 108 print_static_u8_array_definition( 109 file, f"fips_test_hmac_{alg}_value", ctx.digest() 110 ) 111 112 print_static_u8_array_definition( 113 file, "fips_test_sha3_256_value", hashlib.sha3_256(fips_test_data).digest() 114 ) 115 116 117filename = "lib/crypto/fips-aes.h" 118with open(filename, "w") as file: 119 print(f"Generating {filename}") 120 gen_aes_test_data(file) 121 122filename = "lib/crypto/fips-sha.h" 123with open(filename, "w") as file: 124 print(f"Generating {filename}") 125 gen_sha_test_data(file) 126