From nobody Fri Oct 2 11:41:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BAAFF265CA8; Sun, 2 Aug 2026 22:24:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785709499; cv=none; b=F3fUtPKMSJJU4X2ljogtSu1K3RyPXzpyQo/AIaJaqr6eHxVvhlbuJsFpUlmdtWEDy5/L4zZUUcuw6vP23DAdX9DTo3y+ZBv1aIbIJ6RALhrNxlFprpyOFWocCcyxRUeLQXZYdJur0bJTSWf7oRxJ09yNhXrZx4FgkRStZfq2iUk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785709499; c=relaxed/simple; bh=IK8KY9dg6DlobN5DM9Amg7uy3nUvmZSS0aD7FWd0a8A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=A7HOYn5l9xNZQ3EdDQ6KurO7ancfKWP5SXWTlxzSjD5ZA1P50QRs8ECx/f2aGnvY+2IY1esdoayjGrxMM30SC+g7gWeyFBzVp/g5nbWL7HA8NgQ36H1LCZZ4XoghAUl4A6nNaWVkP2L+pyll/n0Uq6+iNfERiTVOo/cgODQDthU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k7vg7lmB; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="k7vg7lmB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 691A01F00A3E; Sun, 2 Aug 2026 22:24:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1785709497; bh=mWHXek4T8sV8rsC6PTjZeiu/zvOnoWIldk2ujRgFahY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=k7vg7lmB3U6hwI1zjR5QeMtqKe6x5ltZaIfn0bS3mZv7/+xd7TXBBrqdLBbRRY4rz R0SKyUSez+5nDCgdJFQ90oBoSSL4GIEXyS5woqT7BhV/gCk5fAztkJt56mzE84wLaz rfIC5LzJCmO5JmF9N45LXtkkRjzjYiiMWOz7GQ+oPVe7lAFI+j2ABYDWPoO/Zkpo4U 5DW2VAVRTrqGRxx3rRdWcfGdMzAuB7IWn+91pZa0CHUUtbBqAGscfM10l1DjJMUG/r 1z2nHaNh3snqLpeJLvXWEnL9oJ/uaiorLb9p28w/V8Y7JJ+npgrSDLrnSZ9fV+AM2E ZZLRiz/QZpi6A== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , Herbert Xu , Eric Biggers Subject: [PATCH 1/3] lib/crypto: fips: Split fips.h into fips-aes.h and fips-sha.h Date: Sun, 2 Aug 2026 15:24:06 -0700 Message-ID: <20260802222408.91757-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260802222408.91757-1-ebiggers@kernel.org> References: <20260802222408.91757-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for adding FIPS self-tests for AES encryption modes, split fips.h into separate files for the AES and SHA test vectors. They are still generated by the same script, but this keeps things a bit more organized. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- lib/crypto/aes.c | 2 +- lib/crypto/fips-aes.h | 20 +++++++ lib/crypto/{fips.h =3D> fips-sha.h} | 6 +- lib/crypto/sha1.c | 2 +- lib/crypto/sha256.c | 2 +- lib/crypto/sha3.c | 2 +- lib/crypto/sha512.c | 2 +- scripts/crypto/gen-fips-testvecs.py | 93 +++++++++++++++++++---------- 8 files changed, 88 insertions(+), 41 deletions(-) create mode 100644 lib/crypto/fips-aes.h rename lib/crypto/{fips.h =3D> fips-sha.h} (90%) diff --git a/lib/crypto/aes.c b/lib/crypto/aes.c index 4222a4cec2f2..617c913d512e 100644 --- a/lib/crypto/aes.c +++ b/lib/crypto/aes.c @@ -19,7 +19,7 @@ #include #include #include -#include "fips.h" +#include "fips-aes.h" =20 static const u8 ____cacheline_aligned aes_sbox[] =3D { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, diff --git a/lib/crypto/fips-aes.h b/lib/crypto/fips-aes.h new file mode 100644 index 000000000000..b257cb216871 --- /dev/null +++ b/lib/crypto/fips-aes.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* This file was generated by: gen-fips-testvecs.py */ +/* clang-format off */ + +#include + +static const u8 fips_test_data[] __initconst __maybe_unused =3D { + 0x66, 0x69, 0x70, 0x73, 0x20, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, +}; + +static const u8 fips_test_key[] __initconst __maybe_unused =3D { + 0x66, 0x69, 0x70, 0x73, 0x20, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, +}; + +static const u8 fips_test_aes_cmac_value[] __initconst __maybe_unused =3D { + 0xc5, 0x88, 0x28, 0x55, 0xd7, 0x2c, 0x00, 0xb6, + 0x6a, 0xa7, 0xfc, 0x82, 0x90, 0x81, 0xcf, 0x18, +}; diff --git a/lib/crypto/fips.h b/lib/crypto/fips-sha.h similarity index 90% rename from lib/crypto/fips.h rename to lib/crypto/fips-sha.h index 9fc49747db64..68af7e14e09c 100644 --- a/lib/crypto/fips.h +++ b/lib/crypto/fips-sha.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file was generated by: gen-fips-testvecs.py */ +/* clang-format off */ =20 #include =20 @@ -43,8 +44,3 @@ static const u8 fips_test_sha3_256_value[] __initconst __= maybe_unused =3D { 0xba, 0x9b, 0xb6, 0xaa, 0x32, 0xa7, 0x97, 0x00, 0x98, 0xdb, 0xff, 0xe7, 0xc6, 0xde, 0xb5, 0x82, }; - -static const u8 fips_test_aes_cmac_value[] __initconst __maybe_unused =3D { - 0xc5, 0x88, 0x28, 0x55, 0xd7, 0x2c, 0x00, 0xb6, - 0x6a, 0xa7, 0xfc, 0x82, 0x90, 0x81, 0xcf, 0x18, -}; diff --git a/lib/crypto/sha1.c b/lib/crypto/sha1.c index daf18c862fdf..b687b89d97cb 100644 --- a/lib/crypto/sha1.c +++ b/lib/crypto/sha1.c @@ -12,7 +12,7 @@ #include #include #include -#include "fips.h" +#include "fips-sha.h" =20 static const struct sha1_block_state sha1_iv =3D { .h =3D { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 }, diff --git a/lib/crypto/sha256.c b/lib/crypto/sha256.c index 5d6b77e7e141..e8c346f563c5 100644 --- a/lib/crypto/sha256.c +++ b/lib/crypto/sha256.c @@ -17,7 +17,7 @@ #include #include #include -#include "fips.h" +#include "fips-sha.h" =20 static const struct sha256_block_state sha224_iv =3D { .h =3D { diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index 32b7074de792..286a2373c156 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -17,7 +17,7 @@ #include #include #include -#include "fips.h" +#include "fips-sha.h" =20 /* * On some 32-bit architectures, such as h8300, GCC ends up using over 1 K= B of diff --git a/lib/crypto/sha512.c b/lib/crypto/sha512.c index 605eab51aabd..0dd6fb4ca15b 100644 --- a/lib/crypto/sha512.c +++ b/lib/crypto/sha512.c @@ -17,7 +17,7 @@ #include #include #include -#include "fips.h" +#include "fips-sha.h" =20 static const struct sha512_block_state sha384_iv =3D { .h =3D { diff --git a/scripts/crypto/gen-fips-testvecs.py b/scripts/crypto/gen-fips-= testvecs.py index 9f18bcb97412..aa6c0a81fbf8 100755 --- a/scripts/crypto/gen-fips-testvecs.py +++ b/scripts/crypto/gen-fips-testvecs.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-or-later # -# Script that generates lib/crypto/fips.h +# Script that generates lib/crypto/fips-aes.h and lib/crypto/fips-sha.h # # Requires that python-cryptography be installed. # @@ -12,35 +12,66 @@ import cryptography.hazmat.primitives.cmac import hashlib import hmac =20 -fips_test_data =3D b"fips test data\0\0" -fips_test_key =3D b"fips test key\0\0\0" =20 -def print_static_u8_array_definition(name, value): - print('') - print(f'static const u8 {name}[] __initconst __maybe_unused =3D {{') +def print_static_u8_array_definition(file, name, value): + print("", file=3Dfile) + print(f"static const u8 {name}[] __initconst __maybe_unused =3D {{", f= ile=3Dfile) for i in range(0, len(value), 8): - line =3D '\t' + ''.join(f'0x{b:02x}, ' for b in value[i:i+8]) - print(f'{line.rstrip()}') - print('};') - -print('/* SPDX-License-Identifier: GPL-2.0-or-later */') -print(f'/* This file was generated by: gen-fips-testvecs.py */') -print() -print('#include ') - -print_static_u8_array_definition("fips_test_data", fips_test_data) -print_static_u8_array_definition("fips_test_key", fips_test_key) - -for alg in 'sha1', 'sha256', 'sha512': - ctx =3D hmac.new(fips_test_key, digestmod=3Dalg) - ctx.update(fips_test_data) - print_static_u8_array_definition(f'fips_test_hmac_{alg}_value', ctx.di= gest()) - -print_static_u8_array_definition(f'fips_test_sha3_256_value', - hashlib.sha3_256(fips_test_data).digest()) - -aes =3D cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_test_ke= y) -aes_cmac =3D cryptography.hazmat.primitives.cmac.CMAC(aes) -aes_cmac.update(fips_test_data) -print_static_u8_array_definition('fips_test_aes_cmac_value', - aes_cmac.finalize()) + line =3D "\t" + "".join(f"0x{b:02x}, " for b in value[i : i + 8]) + print(f"{line.rstrip()}", file=3Dfile) + print("};", file=3Dfile) + + +def print_header(file): + print("/* SPDX-License-Identifier: GPL-2.0-or-later */", file=3Dfile) + print("/* This file was generated by: gen-fips-testvecs.py */", file= =3Dfile) + print("/* clang-format off */", file=3Dfile) + print("", file=3Dfile) + print("#include ", file=3Dfile) + + +def gen_aes_test_data(file): + fips_test_data =3D b"fips test data\0\0" + fips_test_key =3D b"fips test key\0\0\0" + + print_header(file) + print_static_u8_array_definition(file, "fips_test_data", fips_test_dat= a) + print_static_u8_array_definition(file, "fips_test_key", fips_test_key) + + aes =3D cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_tes= t_key) + aes_cmac =3D cryptography.hazmat.primitives.cmac.CMAC(aes) + aes_cmac.update(fips_test_data) + print_static_u8_array_definition( + file, "fips_test_aes_cmac_value", aes_cmac.finalize() + ) + + +def gen_sha_test_data(file): + fips_test_data =3D b"fips test data\0\0" + fips_test_key =3D b"fips test key\0\0\0" + + print_header(file) + print_static_u8_array_definition(file, "fips_test_data", fips_test_dat= a) + print_static_u8_array_definition(file, "fips_test_key", fips_test_key) + + for alg in "sha1", "sha256", "sha512": + ctx =3D hmac.new(fips_test_key, digestmod=3Dalg) + ctx.update(fips_test_data) + print_static_u8_array_definition( + file, f"fips_test_hmac_{alg}_value", ctx.digest() + ) + + print_static_u8_array_definition( + file, "fips_test_sha3_256_value", hashlib.sha3_256(fips_test_data)= .digest() + ) + + +filename =3D "lib/crypto/fips-aes.h" +with open(filename, "w") as file: + print(f"Generating {filename}") + gen_aes_test_data(file) + +filename =3D "lib/crypto/fips-sha.h" +with open(filename, "w") as file: + print(f"Generating {filename}") + gen_sha_test_data(file) --=20 2.55.0 From nobody Fri Oct 2 11:41:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3FD1B29C35A; Sun, 2 Aug 2026 22:24:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785709499; cv=none; b=Wz5zUOJuhyRV9kEXud4YZDAkwrJh7PXrc8fix7iZjpAG/fYOVc9/iZNfT9xljvlV1KOWRd5v/+uj3RdeF6WLkBZpH5XP1wvu89+6QbvnRC6oui5vEkmWT/ekF7N67gfFQI3R49EoEK7Pk2b7PpoixQS+TX2en/sMbTTsLo1Hmsw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785709499; c=relaxed/simple; bh=hUvSITSaDRxL50PMtyAzPgYnL7smIFvJucc6fI4h6m0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KC6dHTsGZwnvg15nnIKN8BOJkD09u4cYeXP1AO0207BxETDPwPtnhHgHDxmh7BFAVVbtPuSdO2NybURANiWACG3rdC97f9uMsK1ikT1EzDxGPebM1JSIG3oY3qr8ueIJq92+SPpm90hyrTv3Vngv7EKTy7sbhWyJNq9tCZcMKR0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=diau56UP; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="diau56UP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B87EF1F00A3F; Sun, 2 Aug 2026 22:24:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1785709497; bh=jNx6qI6JUX7COnXFEZ/z2+Yl6IaA80PSmQcMGwUIt+o=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=diau56UPOTjJn0dmPDm76bF9Q6SAPd7/Q1DUzd574Fw80fnls+kLCWq+tp0IkfZB2 9TqpUs9iqy9iyAtitQaqfWdFCOVI5c8flrOOCiMaJEa2l2y781DAAoANH3qG+Zv9Ga i9+L3cZb7KZtgRDgKuLz8W5v3y4g52QLiH84oWeNL8S5/k36oiQoz4g8b7tLW84Jly k0K3e8Smnpo3dkYm5CgKuCEe6pPZ8eZbdgpmJXNb3CzX7Ti7UfM61CgyRVf0vHkE4e lZ+CnsvjqMwJSiCbjsTFJWw5mDaQiNyKcffKB9nOn/u6XX9ky1VjZ7vTrWVMyLG55F O0j7I9RMjptCQ== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , Herbert Xu , Eric Biggers Subject: [PATCH 2/3] lib/crypto: aes: Add FIPS self-tests for unauthenticated modes Date: Sun, 2 Aug 2026 15:24:07 -0700 Message-ID: <20260802222408.91757-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260802222408.91757-1-ebiggers@kernel.org> References: <20260802222408.91757-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Upcoming changes will wire up architecture-optimized implementations of ECB, CBC, CBC-CTS, CTR, and XTS. FIPS labs can consider such designs to meet the threshold for separate self-tests to be needed. The inverse direction of the block cipher also needs to be exercised, which the existing CMAC self-test doesn't do. Therefore, add FIPS self-tests for encryption and decryption in these modes as well as the "bare" AES. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- lib/crypto/aes.c | 176 +++++++++++++++++++++++++++- lib/crypto/fips-aes.h | 39 ++++++ scripts/crypto/gen-fips-testvecs.py | 48 ++++++++ 3 files changed, 258 insertions(+), 5 deletions(-) diff --git a/lib/crypto/aes.c b/lib/crypto/aes.c index 617c913d512e..e9119f82b0cc 100644 --- a/lib/crypto/aes.c +++ b/lib/crypto/aes.c @@ -522,6 +522,26 @@ void aes_decrypt(const struct aes_key *key, u8 out[AES= _BLOCK_SIZE], } EXPORT_SYMBOL(aes_decrypt); =20 +/* FIPS cryptographic algorithm self-test for "bare" AES */ +static void __init aes_fips_test(void) +{ + struct aes_key key; + u8 data[AES_BLOCK_SIZE]; + + if (aes_preparekey(&key, fips_test_key, sizeof(fips_test_key)) !=3D 0) + panic("aes: FIPS self-test failed (preparekey)\n"); + + aes_encrypt(&key, data, fips_test_data); + if (memcmp(fips_test_aes_ecb_ctext, data, sizeof(data)) !=3D 0) + panic("aes: FIPS self-test failed (wrong ciphertext)\n"); + + aes_decrypt(&key, data, data); + if (memcmp(fips_test_data, data, sizeof(data)) !=3D 0) + panic("aes: FIPS self-test failed (wrong plaintext)\n"); + + memzero_explicit(&key, sizeof(key)); +} + #if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_CBC_MACS) =20 #ifndef aes_cbcmac_blocks_arch @@ -797,7 +817,31 @@ void aes_ecb_decrypt(u8 *dst, const u8 *src, size_t le= n, aes_decrypt(key, &dst[i], &src[i]); } EXPORT_SYMBOL_GPL(aes_ecb_decrypt); -#endif /* CONFIG_CRYPTO_LIB_AES_ECB */ + +/* FIPS cryptographic algorithm self-test for AES-ECB */ +static void __init aes_ecb_fips_test(void) +{ + struct aes_key key; + u8 data[sizeof(fips_test_data)]; + + if (aes_preparekey(&key, fips_test_key, sizeof(fips_test_key)) !=3D 0) + panic("aes: ECB FIPS self-test failed (preparekey)\n"); + + aes_ecb_encrypt(data, fips_test_data, sizeof(data), &key); + if (memcmp(fips_test_aes_ecb_ctext, data, sizeof(data)) !=3D 0) + panic("aes: ECB FIPS self-test failed (wrong ciphertext)\n"); + + aes_ecb_decrypt(data, data, sizeof(data), &key); + if (memcmp(fips_test_data, data, sizeof(data)) !=3D 0) + panic("aes: ECB FIPS self-test failed (wrong plaintext)\n"); + + memzero_explicit(&key, sizeof(key)); +} +#else /* CONFIG_CRYPTO_LIB_AES_ECB */ +static inline void aes_ecb_fips_test(void) +{ +} +#endif /* !CONFIG_CRYPTO_LIB_AES_ECB */ =20 #if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_CBC) /* @@ -983,7 +1027,66 @@ void aes_cbc_cts_decrypt(u8 *dst, const u8 *src, size= _t len, crypto_xor(pad, iv, AES_BLOCK_SIZE); /* P[n - 1] */ } EXPORT_SYMBOL_GPL(aes_cbc_cts_decrypt); -#endif /* CONFIG_CRYPTO_LIB_AES_CBC */ + +/* FIPS cryptographic algorithm self-test for AES-CBC */ +static void __init aes_cbc_fips_test(void) +{ + struct aes_key key; + u8 iv[AES_BLOCK_SIZE]; + u8 data[sizeof(fips_test_data)]; + + if (aes_preparekey(&key, fips_test_key, sizeof(fips_test_key)) !=3D 0) + panic("aes: CBC FIPS self-test failed (preparekey)\n"); + + memcpy(iv, fips_test_iv, sizeof(iv)); + aes_cbc_encrypt(data, fips_test_data, sizeof(data), iv, &key); + if (memcmp(fips_test_aes_cbc_ctext, data, sizeof(data)) !=3D 0) + panic("aes: CBC FIPS self-test failed (wrong ciphertext)\n"); + + memcpy(iv, fips_test_iv, sizeof(iv)); + aes_cbc_decrypt(data, data, sizeof(data), iv, &key); + if (memcmp(fips_test_data, data, sizeof(data)) !=3D 0) + panic("aes: CBC FIPS self-test failed (wrong plaintext)\n"); + + memzero_explicit(&key, sizeof(key)); +} + +/* FIPS cryptographic algorithm self-test for AES-CBC-CTS */ +static void __init aes_cbc_cts_fips_test(void) +{ + struct aes_key key; + u8 iv[AES_BLOCK_SIZE]; + const size_t data_len =3D 2 * AES_BLOCK_SIZE; + u8 ptext[2 * AES_BLOCK_SIZE]; + u8 data[2 * AES_BLOCK_SIZE]; + + /* ptext =3D fips_test_data || fips_test_data */ + memcpy(ptext, fips_test_data, AES_BLOCK_SIZE); + memcpy(&ptext[AES_BLOCK_SIZE], ptext, AES_BLOCK_SIZE); + + if (aes_preparekey(&key, fips_test_key, sizeof(fips_test_key)) !=3D 0) + panic("aes: CBC-CTS FIPS self-test failed (preparekey)\n"); + + memcpy(iv, fips_test_iv, sizeof(iv)); + aes_cbc_cts_encrypt(data, ptext, data_len, iv, &key); + if (memcmp(fips_test_aes_cbc_cts_ctext, data, data_len) !=3D 0) + panic("aes: CBC-CTS FIPS self-test failed (wrong ciphertext)\n"); + + memcpy(iv, fips_test_iv, sizeof(iv)); + aes_cbc_cts_decrypt(data, data, data_len, iv, &key); + if (memcmp(ptext, data, data_len) !=3D 0) + panic("aes: CBC-CTS FIPS self-test failed (wrong plaintext)\n"); + + memzero_explicit(&key, sizeof(key)); +} +#else /* CONFIG_CRYPTO_LIB_AES_CBC */ +static inline void aes_cbc_fips_test(void) +{ +} +static inline void aes_cbc_cts_fips_test(void) +{ +} +#endif /* !CONFIG_CRYPTO_LIB_AES_CBC */ =20 #if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_CTR) /* @@ -1078,7 +1181,34 @@ void aes_xctr(u8 *dst, const u8 *src, size_t len, u6= 4 *ctr, memzero_explicit(aes_input, sizeof(aes_input)); } EXPORT_SYMBOL_GPL(aes_xctr); -#endif /* CONFIG_CRYPTO_LIB_AES_CTR */ + +/* FIPS cryptographic algorithm self-test for AES-CTR */ +static void __init aes_ctr_fips_test(void) +{ + struct aes_enckey key; + u8 ctr[AES_BLOCK_SIZE]; + u8 data[sizeof(fips_test_data)]; + + if (aes_prepareenckey(&key, fips_test_key, sizeof(fips_test_key)) !=3D 0) + panic("aes: CTR FIPS self-test failed (preparekey)\n"); + + memcpy(ctr, fips_test_iv, sizeof(ctr)); + aes_ctr(data, fips_test_data, sizeof(data), ctr, &key); + if (memcmp(fips_test_aes_ctr_ctext, data, sizeof(data)) !=3D 0) + panic("aes: CTR FIPS self-test failed (wrong ciphertext)\n"); + + memcpy(ctr, fips_test_iv, sizeof(ctr)); + aes_ctr(data, data, sizeof(data), ctr, &key); + if (memcmp(fips_test_data, data, sizeof(data)) !=3D 0) + panic("aes: CTR FIPS self-test failed (wrong plaintext)\n"); + + memzero_explicit(&key, sizeof(key)); +} +#else /* CONFIG_CRYPTO_LIB_AES_CTR */ +static inline void aes_ctr_fips_test(void) +{ +} +#endif /* !CONFIG_CRYPTO_LIB_AES_CTR */ =20 #if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_XTS) int aes_xts_preparekey(struct aes_xts_key *key, const u8 *in_key, @@ -1307,7 +1437,36 @@ void aes_xts_decrypt(u8 *dst, const u8 *src, size_t = len, aes_xts_decrypt_nocts(dst, src, len, tweak, key, cont); } EXPORT_SYMBOL_GPL(aes_xts_decrypt); -#endif /* CONFIG_CRYPTO_LIB_AES_XTS */ + +/* FIPS cryptographic algorithm self-test for AES-XTS */ +static void __init aes_xts_fips_test(void) +{ + struct aes_xts_key *key __free(kfree_sensitive) =3D kmalloc_obj(*key); + u8 tweak[AES_BLOCK_SIZE]; + u8 data[sizeof(fips_test_data)]; + + if (key =3D=3D NULL) + panic("aes: XTS FIPS self-test failed (kmalloc)\n"); + + if (aes_xts_preparekey(key, fips_test_xts_key, + sizeof(fips_test_xts_key), 0) !=3D 0) + panic("aes: XTS FIPS self-test failed (preparekey)\n"); + + memcpy(tweak, fips_test_iv, sizeof(tweak)); + aes_xts_encrypt(data, fips_test_data, sizeof(data), tweak, key, false); + if (memcmp(fips_test_aes_xts_ctext, data, sizeof(data)) !=3D 0) + panic("aes: XTS FIPS self-test failed (wrong ciphertext)\n"); + + memcpy(tweak, fips_test_iv, sizeof(tweak)); + aes_xts_decrypt(data, data, sizeof(data), tweak, key, false); + if (memcmp(fips_test_data, data, sizeof(data)) !=3D 0) + panic("aes: XTS FIPS self-test failed (wrong plaintext)\n"); +} +#else /* CONFIG_CRYPTO_LIB_AES_XTS */ +static inline void aes_xts_fips_test(void) +{ +} +#endif /* !CONFIG_CRYPTO_LIB_AES_XTS */ =20 #if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_GCM) /* @@ -1905,8 +2064,15 @@ static int __init aes_mod_init(void) #ifdef aes_mod_init_arch aes_mod_init_arch(); #endif - if (fips_enabled) + if (fips_enabled) { + aes_fips_test(); aes_cmac_fips_test(); + aes_ecb_fips_test(); + aes_cbc_fips_test(); + aes_cbc_cts_fips_test(); + aes_ctr_fips_test(); + aes_xts_fips_test(); + } return 0; } subsys_initcall(aes_mod_init); diff --git a/lib/crypto/fips-aes.h b/lib/crypto/fips-aes.h index b257cb216871..cfacf5d98e07 100644 --- a/lib/crypto/fips-aes.h +++ b/lib/crypto/fips-aes.h @@ -9,12 +9,51 @@ static const u8 fips_test_data[] __initconst __maybe_unus= ed =3D { 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, }; =20 +static const u8 fips_test_iv[] __initconst __maybe_unused =3D { + 0x66, 0x69, 0x70, 0x73, 0x20, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x69, 0x76, 0x00, 0x00, 0x00, 0x00, +}; + static const u8 fips_test_key[] __initconst __maybe_unused =3D { 0x66, 0x69, 0x70, 0x73, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, }; =20 +static const u8 fips_test_xts_key[] __initconst __maybe_unused =3D { + 0x6b, 0x65, 0x79, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6b, 0x65, 0x79, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + static const u8 fips_test_aes_cmac_value[] __initconst __maybe_unused =3D { 0xc5, 0x88, 0x28, 0x55, 0xd7, 0x2c, 0x00, 0xb6, 0x6a, 0xa7, 0xfc, 0x82, 0x90, 0x81, 0xcf, 0x18, }; + +static const u8 fips_test_aes_ecb_ctext[] __initconst __maybe_unused =3D { + 0x47, 0x76, 0x48, 0xaf, 0x1b, 0xd8, 0x4c, 0xe6, + 0xb5, 0xa7, 0x20, 0x8d, 0x64, 0x88, 0xbc, 0x3f, +}; + +static const u8 fips_test_aes_cbc_ctext[] __initconst __maybe_unused =3D { + 0xc8, 0x7d, 0x7c, 0x25, 0xba, 0x15, 0xf7, 0xe1, + 0x08, 0xa0, 0xd0, 0x7a, 0x20, 0x37, 0xaf, 0x5e, +}; + +static const u8 fips_test_aes_cbc_cts_ctext[] __initconst __maybe_unused = =3D { + 0x36, 0x8e, 0x37, 0xb4, 0x78, 0xe2, 0x88, 0x59, + 0xd5, 0xe8, 0x17, 0x65, 0x5c, 0xa1, 0x25, 0xe6, + 0xc8, 0x7d, 0x7c, 0x25, 0xba, 0x15, 0xf7, 0xe1, + 0x08, 0xa0, 0xd0, 0x7a, 0x20, 0x37, 0xaf, 0x5e, +}; + +static const u8 fips_test_aes_ctr_ctext[] __initconst __maybe_unused =3D { + 0x95, 0xf4, 0xf4, 0x7a, 0xc8, 0xa2, 0x53, 0x73, + 0x53, 0x8f, 0x95, 0xfc, 0x18, 0xfe, 0x58, 0x2f, +}; + +static const u8 fips_test_aes_xts_ctext[] __initconst __maybe_unused =3D { + 0xd4, 0x51, 0x7f, 0x01, 0x14, 0x91, 0x16, 0x29, + 0x26, 0xbe, 0xec, 0x9b, 0x90, 0xed, 0x59, 0x30, +}; diff --git a/scripts/crypto/gen-fips-testvecs.py b/scripts/crypto/gen-fips-= testvecs.py index aa6c0a81fbf8..a79eaf081c26 100755 --- a/scripts/crypto/gen-fips-testvecs.py +++ b/scripts/crypto/gen-fips-testvecs.py @@ -32,19 +32,67 @@ def print_header(file): =20 def gen_aes_test_data(file): fips_test_data =3D b"fips test data\0\0" + fips_test_iv =3D b"fips test iv\0\0\0\0" fips_test_key =3D b"fips test key\0\0\0" + fips_test_xts_key =3D b"key1" + (b"\0" * 12) + b"key2" + (b"\0" * 12) =20 print_header(file) print_static_u8_array_definition(file, "fips_test_data", fips_test_dat= a) + print_static_u8_array_definition(file, "fips_test_iv", fips_test_iv) print_static_u8_array_definition(file, "fips_test_key", fips_test_key) + print_static_u8_array_definition(file, "fips_test_xts_key", fips_test_= xts_key) =20 aes =3D cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_tes= t_key) + + # AES-CMAC aes_cmac =3D cryptography.hazmat.primitives.cmac.CMAC(aes) aes_cmac.update(fips_test_data) print_static_u8_array_definition( file, "fips_test_aes_cmac_value", aes_cmac.finalize() ) =20 + # AES-ECB + cipher =3D cryptography.hazmat.primitives.ciphers.Cipher( + aes, cryptography.hazmat.primitives.ciphers.modes.ECB() + ) + encryptor =3D cipher.encryptor() + ctext =3D encryptor.update(fips_test_data) + encryptor.finalize() + print_static_u8_array_definition(file, "fips_test_aes_ecb_ctext", ctex= t) + + # AES-CBC + cipher =3D cryptography.hazmat.primitives.ciphers.Cipher( + aes, cryptography.hazmat.primitives.ciphers.modes.CBC(fips_test_iv) + ) + encryptor =3D cipher.encryptor() + ctext =3D encryptor.update(fips_test_data) + encryptor.finalize() + print_static_u8_array_definition(file, "fips_test_aes_cbc_ctext", ctex= t) + + # AES-CBC-CTS + cipher =3D cryptography.hazmat.primitives.ciphers.Cipher( + aes, cryptography.hazmat.primitives.ciphers.modes.CBC(fips_test_iv) + ) + encryptor =3D cipher.encryptor() + ctext =3D encryptor.update(fips_test_data * 2) + encryptor.finalize() + ctext =3D ctext[16:32] + ctext[0:16] + print_static_u8_array_definition(file, "fips_test_aes_cbc_cts_ctext", = ctext) + + # AES-CTR + cipher =3D cryptography.hazmat.primitives.ciphers.Cipher( + aes, cryptography.hazmat.primitives.ciphers.modes.CTR(fips_test_iv) + ) + encryptor =3D cipher.encryptor() + ctext =3D encryptor.update(fips_test_data) + encryptor.finalize() + print_static_u8_array_definition(file, "fips_test_aes_ctr_ctext", ctex= t) + + # AES-XTS + cipher =3D cryptography.hazmat.primitives.ciphers.Cipher( + cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_test_xt= s_key), + cryptography.hazmat.primitives.ciphers.modes.XTS(fips_test_iv), + ) + encryptor =3D cipher.encryptor() + ctext =3D encryptor.update(fips_test_data) + encryptor.finalize() + print_static_u8_array_definition(file, "fips_test_aes_xts_ctext", ctex= t) + =20 def gen_sha_test_data(file): fips_test_data =3D b"fips test data\0\0" --=20 2.55.0 From nobody Fri Oct 2 11:41:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97267339383; Sun, 2 Aug 2026 22:24:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785709499; cv=none; b=L2K0fOOcgpdTgn1XvZFU0KDUsioDF8BLSwWUCghU3tCFxwbzitTVRz3qdq8iaow/1iqZ+HX+ZBYoAV/WE9Ff3ETtOp5x88SlzgbkT+s1bxCZSne9bpptif+y4h5Fk6zG0rmP6T3FdtFbJ1XfjC/e+tUgP/9LM0bJPceeqSYXDE4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785709499; c=relaxed/simple; bh=xqZgx/O9WpRyP4ZKdQj/XpGbKIOdjEFmq89FbW+0V7U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rbRjG7AF2gya/4QRjXHrRuLKj1+rMfhSE60ZURzMkXo2poodoXv9Ueb0P/xiNB30vCMOPCsXd4R63MVYcitCaxWEnn9Ub+PS1ToglwyHNzNvruLv66BOF/wRDScd9ZWgTlCn8BZstKgt8642IxmP8ZN8Iut2nDxE1SEb6M8dUk4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=B5Qje7uG; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="B5Qje7uG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1475F1F00AC4; Sun, 2 Aug 2026 22:24:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1785709498; bh=f43uyzOhFRcbS8DIL5LfQmcZIB/iVAmcYeNPPdOhx0U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=B5Qje7uG1dfav7mqeHrgsNtYSIY6Od04dVgQ9QlK1yDFzsa686+RDmohg9PJsZKRj lnF0OynHCDZ8gNKDrqZW+G9BmcLtLjNvDx2Wjm4ONRFBhSblWzJ88lVS8OM14XE6XK cf5IV61PTSDeenyz7gYsraaqQR9JZYV8a99Ri7xpRI/IeuoHG43ObNkdfHgUgDwUTR Vr3b0d3met4vVu6OQUnLrpS4AL5txxcPnR/49yVVdyXKuIexj4tg0RdVZ8DhJW1oEl iMLNl6tY/gfMuXFzCE0BtsBiPK5J90hlnbgwRojXDG1NHlI44wh9J2PWA5R3XHrTsv iKyUwvDyX4iwA== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , Herbert Xu , Eric Biggers Subject: [PATCH 3/3] lib/crypto: aes: Add FIPS self-tests for GCM and CCM Date: Sun, 2 Aug 2026 15:24:08 -0700 Message-ID: <20260802222408.91757-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260802222408.91757-1-ebiggers@kernel.org> References: <20260802222408.91757-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Upcoming changes will wire up architecture-optimized implementations of GCM and CCM. FIPS labs can consider such designs to meet the threshold for separate self-tests to be needed. Therefore, add FIPS self-tests for encryption and decryption in these modes. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- lib/crypto/aes.c | 81 +++++++++++++++++++++++++---- lib/crypto/fips-aes.h | 19 +++++++ scripts/crypto/gen-fips-testvecs.py | 23 ++++++++ 3 files changed, 113 insertions(+), 10 deletions(-) diff --git a/lib/crypto/aes.c b/lib/crypto/aes.c index e9119f82b0cc..41aaa82cb1a1 100644 --- a/lib/crypto/aes.c +++ b/lib/crypto/aes.c @@ -737,14 +737,7 @@ void aes_cbcmac_final(struct aes_cbcmac_ctx *ctx, u8 o= ut[AES_BLOCK_SIZE]) } EXPORT_SYMBOL_NS_GPL(aes_cbcmac_final, "CRYPTO_INTERNAL"); =20 -/* - * FIPS cryptographic algorithm self-test for AES-CMAC. As per the FIPS 1= 40-3 - * Implementation Guidance, a cryptographic algorithm self-test for at lea= st one - * of AES-GCM, AES-CCM, AES-CMAC, or AES-GMAC is required if any of those = modes - * is implemented. This fulfills that requirement via AES-CMAC. - * - * This is just for FIPS. The full tests are in the KUnit test suite. - */ +/* FIPS cryptographic algorithm self-test for AES-CMAC */ static void __init aes_cmac_fips_test(void) { struct aes_cmac_key key; @@ -1745,7 +1738,37 @@ int aes_gcm_decrypt(u8 *dst, const u8 *src, size_t d= ata_len, const u8 *authtag, } EXPORT_SYMBOL_GPL(aes_gcm_decrypt); =20 -#endif /* CONFIG_CRYPTO_LIB_AES_GCM */ +/* FIPS cryptographic algorithm self-test for AES-GCM */ +static void __init aes_gcm_fips_test(void) +{ + const size_t data_len =3D sizeof(fips_test_data); + u8 buf[sizeof(fips_test_data) + AES_BLOCK_SIZE]; + struct aes_gcm_key key; + int err; + + if (aes_gcm_preparekey(&key, fips_test_key, sizeof(fips_test_key), + AES_BLOCK_SIZE) !=3D 0) + panic("aes: GCM FIPS self-test failed (preparekey)\n"); + + aes_gcm_encrypt(buf, fips_test_data, data_len, &buf[data_len], + fips_test_ad, sizeof(fips_test_ad), fips_test_iv, &key); + if (memcmp(fips_test_aes_gcm_ctext_and_tag, buf, sizeof(buf)) !=3D 0) + panic("aes: GCM FIPS self-test failed (wrong ciphertext and/or tag)\n"); + + err =3D aes_gcm_decrypt(buf, buf, data_len, &buf[data_len], fips_test_ad, + sizeof(fips_test_ad), fips_test_iv, &key); + if (err !=3D 0) + panic("aes: GCM FIPS self-test failed (decryption failed)\n"); + if (memcmp(fips_test_data, buf, data_len) !=3D 0) + panic("aes: GCM FIPS self-test failed (wrong plaintext)\n"); + + memzero_explicit(&key, sizeof(key)); +} +#else /* CONFIG_CRYPTO_LIB_AES_GCM */ +static inline void aes_gcm_fips_test(void) +{ +} +#endif /* !CONFIG_CRYPTO_LIB_AES_GCM */ =20 #if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_CCM) int aes_ccm_preparekey(struct aes_ccm_key *key, const u8 *in_key, @@ -2057,7 +2080,43 @@ int aes_ccm_decrypt(u8 *dst, const u8 *src, size_t d= ata_len, const u8 *authtag, return err; } EXPORT_SYMBOL_GPL(aes_ccm_decrypt); -#endif /* CONFIG_CRYPTO_LIB_AES_CCM */ + +/* FIPS cryptographic algorithm self-test for AES-CCM */ +static void __init aes_ccm_fips_test(void) +{ + const size_t data_len =3D sizeof(fips_test_data); + const size_t nonce_len =3D 13; + u8 buf[sizeof(fips_test_data) + AES_BLOCK_SIZE]; + struct aes_ccm_key key; + int err; + + if (aes_ccm_preparekey(&key, fips_test_key, sizeof(fips_test_key), + AES_BLOCK_SIZE) !=3D 0) + panic("aes: CCM FIPS self-test failed (preparekey)\n"); + + err =3D aes_ccm_encrypt(buf, fips_test_data, data_len, &buf[data_len], + fips_test_ad, sizeof(fips_test_ad), fips_test_iv, + nonce_len, &key); + if (err !=3D 0) + panic("aes: CCM FIPS self-test failed (encryption failed)\n"); + if (memcmp(fips_test_aes_ccm_ctext_and_tag, buf, sizeof(buf)) !=3D 0) + panic("aes: CCM FIPS self-test failed (wrong ciphertext and/or tag)\n"); + + err =3D aes_ccm_decrypt(buf, buf, data_len, &buf[data_len], fips_test_ad, + sizeof(fips_test_ad), fips_test_iv, nonce_len, + &key); + if (err !=3D 0) + panic("aes: CCM FIPS self-test failed (decryption failed)\n"); + if (memcmp(fips_test_data, buf, data_len) !=3D 0) + panic("aes: CCM FIPS self-test failed (wrong plaintext)\n"); + + memzero_explicit(&key, sizeof(key)); +} +#else /* CONFIG_CRYPTO_LIB_AES_CCM */ +static inline void aes_ccm_fips_test(void) +{ +} +#endif /* !CONFIG_CRYPTO_LIB_AES_CCM */ =20 static int __init aes_mod_init(void) { @@ -2072,6 +2131,8 @@ static int __init aes_mod_init(void) aes_cbc_cts_fips_test(); aes_ctr_fips_test(); aes_xts_fips_test(); + aes_gcm_fips_test(); + aes_ccm_fips_test(); } return 0; } diff --git a/lib/crypto/fips-aes.h b/lib/crypto/fips-aes.h index cfacf5d98e07..2a1746606533 100644 --- a/lib/crypto/fips-aes.h +++ b/lib/crypto/fips-aes.h @@ -9,6 +9,11 @@ static const u8 fips_test_data[] __initconst __maybe_unuse= d =3D { 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, }; =20 +static const u8 fips_test_ad[] __initconst __maybe_unused =3D { + 0x66, 0x69, 0x70, 0x73, 0x20, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, +}; + static const u8 fips_test_iv[] __initconst __maybe_unused =3D { 0x66, 0x69, 0x70, 0x73, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x69, 0x76, 0x00, 0x00, 0x00, 0x00, @@ -57,3 +62,17 @@ static const u8 fips_test_aes_xts_ctext[] __initconst __= maybe_unused =3D { 0xd4, 0x51, 0x7f, 0x01, 0x14, 0x91, 0x16, 0x29, 0x26, 0xbe, 0xec, 0x9b, 0x90, 0xed, 0x59, 0x30, }; + +static const u8 fips_test_aes_gcm_ctext_and_tag[] __initconst __maybe_unus= ed =3D { + 0x12, 0x0c, 0x5d, 0x03, 0x32, 0x93, 0x13, 0x44, + 0x06, 0x35, 0x26, 0x9d, 0xe0, 0xea, 0xbc, 0xe2, + 0x30, 0xa9, 0xa4, 0x15, 0xc5, 0x3d, 0xb3, 0xf9, + 0x30, 0x82, 0xdf, 0x9c, 0xd8, 0xc4, 0x3f, 0x2f, +}; + +static const u8 fips_test_aes_ccm_ctext_and_tag[] __initconst __maybe_unus= ed =3D { + 0x11, 0x8e, 0x01, 0xcb, 0xb5, 0x22, 0x6d, 0xb4, + 0x66, 0x98, 0x97, 0x1d, 0x35, 0x53, 0x78, 0xdd, + 0xd1, 0xc5, 0xff, 0xb6, 0x90, 0xcf, 0xb1, 0xf2, + 0x87, 0x99, 0xd6, 0x1e, 0xd5, 0xd1, 0xed, 0x63, +}; diff --git a/scripts/crypto/gen-fips-testvecs.py b/scripts/crypto/gen-fips-= testvecs.py index a79eaf081c26..b8c8a78cb8a8 100755 --- a/scripts/crypto/gen-fips-testvecs.py +++ b/scripts/crypto/gen-fips-testvecs.py @@ -8,6 +8,7 @@ # Copyright 2025 Google LLC =20 import cryptography.hazmat.primitives.ciphers +import cryptography.hazmat.primitives.ciphers.aead import cryptography.hazmat.primitives.cmac import hashlib import hmac @@ -32,12 +33,14 @@ def print_header(file): =20 def gen_aes_test_data(file): fips_test_data =3D b"fips test data\0\0" + fips_test_ad =3D b"fips test ad\0\0\0\0" fips_test_iv =3D b"fips test iv\0\0\0\0" fips_test_key =3D b"fips test key\0\0\0" fips_test_xts_key =3D b"key1" + (b"\0" * 12) + b"key2" + (b"\0" * 12) =20 print_header(file) print_static_u8_array_definition(file, "fips_test_data", fips_test_dat= a) + print_static_u8_array_definition(file, "fips_test_ad", fips_test_ad) print_static_u8_array_definition(file, "fips_test_iv", fips_test_iv) print_static_u8_array_definition(file, "fips_test_key", fips_test_key) print_static_u8_array_definition(file, "fips_test_xts_key", fips_test_= xts_key) @@ -93,6 +96,26 @@ def gen_aes_test_data(file): ctext =3D encryptor.update(fips_test_data) + encryptor.finalize() print_static_u8_array_definition(file, "fips_test_aes_xts_ctext", ctex= t) =20 + # AES-GCM + cipher =3D cryptography.hazmat.primitives.ciphers.aead.AESGCM(fips_tes= t_key) + ct_and_tag =3D cipher.encrypt( + nonce=3Dfips_test_iv[:12], data=3Dfips_test_data, associated_data= =3Dfips_test_ad + ) + print_static_u8_array_definition( + file, "fips_test_aes_gcm_ctext_and_tag", ct_and_tag + ) + + # AES-CCM + cipher =3D cryptography.hazmat.primitives.ciphers.aead.AESCCM( + fips_test_key, tag_length=3D16 + ) + ct_and_tag =3D cipher.encrypt( + nonce=3Dfips_test_iv[:13], data=3Dfips_test_data, associated_data= =3Dfips_test_ad + ) + print_static_u8_array_definition( + file, "fips_test_aes_ccm_ctext_and_tag", ct_and_tag + ) + =20 def gen_sha_test_data(file): fips_test_data =3D b"fips test data\0\0" --=20 2.55.0