xref: /linux/scripts/crypto/gen-fips-testvecs.py (revision e967fa98f7618e98b50b3d49a1768deba8981a98)
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