From: Eric Biggers <ebiggers@kernel.org>
To: linux-crypto@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel <ardb@kernel.org>,
"Jason A . Donenfeld" <Jason@zx2c4.com>,
Herbert Xu <herbert@gondor.apana.org.au>,
Thomas Huth <thuth@redhat.com>,
Eric Biggers <ebiggers@kernel.org>
Subject: [PATCH 4/5] lib/crypto: tests: Add KUnit test suite for AES-CCM
Date: Wed, 29 Jul 2026 18:32:59 -0700 [thread overview]
Message-ID: <20260730013301.160203-5-ebiggers@kernel.org> (raw)
In-Reply-To: <20260730013301.160203-1-ebiggers@kernel.org>
Add a KUnit test suite for the AES-CCM library API.
It consists of:
- All the shared test cases from aead-test-template.h. These include
extensive consistency tests, a "Monte-Carlo test", and a benchmark.
- Tests against hardcoded AES-CCM test vectors from external sources.
- Tests for CCM-specific message length validation.
To generate the expected aes_ccm_monte_carlo_checksum[] value, add a
script gen-aead-testvecs.py which computes it using python-cryptography.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
lib/crypto/.kunitconfig | 1 +
lib/crypto/tests/Kconfig | 9 +
lib/crypto/tests/Makefile | 1 +
lib/crypto/tests/aes_ccm_kunit.c | 352 ++++++++++++++++++++++++++++
scripts/crypto/gen-aead-testvecs.py | 60 +++++
5 files changed, 423 insertions(+)
create mode 100644 lib/crypto/tests/aes_ccm_kunit.c
create mode 100755 scripts/crypto/gen-aead-testvecs.py
diff --git a/lib/crypto/.kunitconfig b/lib/crypto/.kunitconfig
index 3efc854a2c08..f0237e602f28 100644
--- a/lib/crypto/.kunitconfig
+++ b/lib/crypto/.kunitconfig
@@ -3,6 +3,7 @@ CONFIG_KUNIT=y
CONFIG_CRYPTO_LIB_ENABLE_ALL_FOR_KUNIT=y
CONFIG_CRYPTO_LIB_AES_CBC_MACS_KUNIT_TEST=y
+CONFIG_CRYPTO_LIB_AES_CCM_KUNIT_TEST=y
CONFIG_CRYPTO_LIB_BLAKE2B_KUNIT_TEST=y
CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST=y
CONFIG_CRYPTO_LIB_CHACHA20POLY1305_KUNIT_TEST=y
diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig
index bc084dde424f..320236e996b1 100644
--- a/lib/crypto/tests/Kconfig
+++ b/lib/crypto/tests/Kconfig
@@ -9,6 +9,15 @@ config CRYPTO_LIB_AES_CBC_MACS_KUNIT_TEST
KUnit tests for the AES-CMAC, AES-XCBC-MAC, and AES-CBC-MAC message
authentication codes.
+config CRYPTO_LIB_AES_CCM_KUNIT_TEST
+ tristate "KUnit tests for AES-CCM" if !KUNIT_ALL_TESTS
+ depends on KUNIT && CRYPTO_LIB_AES_CCM
+ default KUNIT_ALL_TESTS
+ select CRYPTO_LIB_BENCHMARK_VISIBLE
+ # This test uses BLAKE2s, but that's always built-in.
+ help
+ KUnit tests for the AES-CCM authenticated encryption algorithm.
+
config CRYPTO_LIB_BLAKE2B_KUNIT_TEST
tristate "KUnit tests for BLAKE2b" if !KUNIT_ALL_TESTS
depends on KUNIT && CRYPTO_LIB_BLAKE2B
diff --git a/lib/crypto/tests/Makefile b/lib/crypto/tests/Makefile
index a739413500b6..085852ba008b 100644
--- a/lib/crypto/tests/Makefile
+++ b/lib/crypto/tests/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
obj-$(CONFIG_CRYPTO_LIB_AES_CBC_MACS_KUNIT_TEST) += aes_cbc_macs_kunit.o
+obj-$(CONFIG_CRYPTO_LIB_AES_CCM_KUNIT_TEST) += aes_ccm_kunit.o
obj-$(CONFIG_CRYPTO_LIB_BLAKE2B_KUNIT_TEST) += blake2b_kunit.o
obj-$(CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST) += blake2s_kunit.o
obj-$(CONFIG_CRYPTO_LIB_CHACHA20POLY1305_KUNIT_TEST) += chacha20poly1305_kunit.o
diff --git a/lib/crypto/tests/aes_ccm_kunit.c b/lib/crypto/tests/aes_ccm_kunit.c
new file mode 100644
index 000000000000..b39df319450d
--- /dev/null
+++ b/lib/crypto/tests/aes_ccm_kunit.c
@@ -0,0 +1,352 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * KUnit test suite for AES-CCM
+ *
+ * Copyright 2026 Google LLC
+ */
+#include <crypto/aes-ccm.h>
+#include <crypto/blake2s.h>
+#include "test-utils.h"
+
+/* AES-CCM test vectors from external sources */
+static const struct aes_ccm_testvec {
+ const char *name;
+ const char *key;
+ size_t key_len;
+ const char *nonce;
+ size_t nonce_len;
+ const char *ad;
+ size_t ad_len;
+ const char *ptext;
+ const char *ctext;
+ size_t data_len;
+ const char *tag;
+ size_t tag_len;
+} aes_ccm_testvecs[] = {
+ {
+ .name = "RFC 3610 Packet Vector #1",
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .key_len = 16,
+ .nonce = "\x00\x00\x00\x03\x02\x01\x00\xa0"
+ "\xa1\xa2\xa3\xa4\xa5",
+ .nonce_len = 13,
+ .ad = "\x00\x01\x02\x03\x04\x05\x06\x07",
+ .ad_len = 8,
+ .ptext = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e",
+ .ctext = "\x58\x8c\x97\x9a\x61\xc6\x63\xd2"
+ "\xf0\x66\xd0\xc2\xc0\xf9\x89\x80"
+ "\x6d\x5f\x6b\x61\xda\xc3\x84",
+ .data_len = 23,
+ .tag = "\x17\xe8\xd1\x2c\xfd\xf9\x26\xe0",
+ .tag_len = 8,
+ },
+ {
+ .name = "RFC 3610 Packet Vector #5",
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .key_len = 16,
+ .nonce = "\x00\x00\x00\x07\x06\x05\x04\xa0"
+ "\xa1\xa2\xa3\xa4\xa5",
+ .nonce_len = 13,
+ .ad = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b",
+ .ad_len = 12,
+ .ptext = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+ "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+ "\x1c\x1d\x1e\x1f",
+ .ctext = "\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb"
+ "\x9d\x4e\x13\x12\x53\x65\x8a\xd8"
+ "\x6e\xbd\xca\x3e",
+ .data_len = 20,
+ .tag = "\x51\xe8\x3f\x07\x7d\x9c\x2d\x93",
+ .tag_len = 8,
+ },
+ {
+ .name = "RFC 3610 Packet Vector #9",
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .key_len = 16,
+ .nonce = "\x00\x00\x00\x0b\x0a\x09\x08\xa0"
+ "\xa1\xa2\xa3\xa4\xa5",
+ .nonce_len = 13,
+ .ad = "\x00\x01\x02\x03\x04\x05\x06\x07",
+ .ad_len = 8,
+ .ptext = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20",
+ .ctext = "\x82\x53\x1a\x60\xcc\x24\x94\x5a"
+ "\x4b\x82\x79\x18\x1a\xb5\xc8\x4d"
+ "\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1"
+ "\x97",
+ .data_len = 25,
+ .tag = "\xea\x9c\x07\xe5\x6b\x5e\xb1\x7e"
+ "\x5f\x4e",
+ .tag_len = 10,
+ },
+ {
+ .name = "NIST SP 800-38C Example 1",
+ .key = "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
+ .key_len = 16,
+ .nonce = "\x10\x11\x12\x13\x14\x15\x16",
+ .nonce_len = 7,
+ .ad = "\x00\x01\x02\x03\x04\x05\x06\x07",
+ .ad_len = 8,
+ .ptext = "\x20\x21\x22\x23",
+ .ctext = "\x71\x62\x01\x5b",
+ .data_len = 4,
+ .tag = "\x4d\xac\x25\x5d",
+ .tag_len = 4,
+ },
+ {
+ .name = "NIST SP 800-38C Example 2",
+ .key = "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
+ .key_len = 16,
+ .nonce = "\x10\x11\x12\x13\x14\x15\x16\x17",
+ .nonce_len = 8,
+ .ad = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .ad_len = 16,
+ .ptext = "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f",
+ .ctext = "\xd2\xa1\xf0\xe0\x51\xea\x5f\x62"
+ "\x08\x1a\x77\x92\x07\x3d\x59\x3d",
+ .data_len = 16,
+ .tag = "\x1f\xc6\x4f\xbf\xac\xcd",
+ .tag_len = 6,
+ },
+ {
+ .name = "NIST SP 800-38C Example 3",
+ .key = "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
+ .key_len = 16,
+ .nonce = "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b",
+ .nonce_len = 12,
+ .ad = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13",
+ .ad_len = 20,
+ .ptext = "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37",
+ .ctext = "\xe3\xb2\x01\xa9\xf5\xb7\x1a\x7a"
+ "\x9b\x1c\xea\xec\xcd\x97\xe7\x0b"
+ "\x61\x76\xaa\xd9\xa4\x42\x8a\xa5",
+ .data_len = 24,
+ .tag = "\x48\x43\x92\xfb\xc1\xb0\x99\x51",
+ .tag_len = 8,
+ },
+};
+
+static void test_aes_ccm_one_test_vector(struct kunit *test,
+ const struct aes_ccm_testvec *tv)
+{
+ u8 *ctext = alloc_buf(test, tv->data_len);
+ u8 *decrypted = alloc_buf(test, tv->data_len);
+ u8 *tag = alloc_buf(test, tv->tag_len);
+ struct aes_ccm_key key;
+ int err;
+
+ err = aes_ccm_preparekey(&key, tv->key, tv->key_len, tv->tag_len);
+ KUNIT_ASSERT_EQ_MSG(test, 0, err, "Failed to prepare key for %s",
+ tv->name);
+
+ err = aes_ccm_encrypt(ctext, tv->ptext, tv->data_len, tag, tv->ad,
+ tv->ad_len, tv->nonce, tv->nonce_len, &key);
+ KUNIT_ASSERT_EQ_MSG(test, 0, err, "Encryption failed for %s", tv->name);
+ KUNIT_ASSERT_MEMEQ_MSG(test, tv->ctext, ctext, tv->data_len,
+ "Wrong ciphertext for %s", tv->name);
+ KUNIT_ASSERT_MEMEQ_MSG(test, tag, tv->tag, tv->tag_len,
+ "Wrong tag for %s", tv->name);
+
+ err = aes_ccm_decrypt(decrypted, ctext, tv->data_len, tag, tv->ad,
+ tv->ad_len, tv->nonce, tv->nonce_len, &key);
+ KUNIT_ASSERT_EQ_MSG(test, 0, err, "Decryption failed for %s", tv->name);
+ KUNIT_ASSERT_MEMEQ_MSG(test, tv->ptext, decrypted, tv->data_len,
+ "Wrong plaintext for %s", tv->name);
+}
+
+static void test_aes_ccm_test_vectors(struct kunit *test)
+{
+ for (size_t i = 0; i < ARRAY_SIZE(aes_ccm_testvecs); i++)
+ test_aes_ccm_one_test_vector(test, &aes_ccm_testvecs[i]);
+}
+
+/*
+ * Test NIST SP 800-38C Example 4, which uses a deterministically-generated
+ * 65536-byte associated data string.
+ */
+static void test_aes_ccm_nist_sp800_38c_example4(struct kunit *test)
+{
+ struct aes_ccm_testvec tv = {
+ .name = "NIST SP 800-38C Example 4",
+ .key_len = 16,
+ .nonce_len = 13,
+ .ad_len = 65536,
+ .ctext = "\x69\x91\x5d\xad\x1e\x84\xc6\x37"
+ "\x6a\x68\xc2\x96\x7e\x4d\xab\x61"
+ "\x5a\xe0\xfd\x1f\xae\xc4\x4c\xc4"
+ "\x84\x82\x85\x29\x46\x3c\xcf\x72",
+ .data_len = 32,
+ .tag = "\xb4\xac\x6b\xec\x93\xe8\x59\x8e"
+ "\x7f\x0d\xad\xbc\xea\x5b",
+ .tag_len = 14,
+ };
+ u8 *key, *nonce, *ad, *ptext;
+
+ key = alloc_buf(test, tv.key_len);
+ for (size_t i = 0; i < tv.key_len; i++)
+ key[i] = 0x40 + i;
+
+ nonce = alloc_guarded_buf(test, tv.nonce_len);
+ for (size_t i = 0; i < tv.nonce_len; i++)
+ nonce[i] = 0x10 + i;
+
+ ad = alloc_guarded_buf(test, tv.ad_len);
+ for (size_t i = 0; i < tv.ad_len; i++)
+ ad[i] = (u8)i;
+
+ ptext = alloc_guarded_buf(test, tv.data_len);
+ for (size_t i = 0; i < tv.data_len; i++)
+ ptext[i] = 0x20 + i;
+
+ tv.key = key;
+ tv.nonce = nonce;
+ tv.ad = ad;
+ tv.ptext = ptext;
+
+ test_aes_ccm_one_test_vector(test, &tv);
+}
+
+static const size_t aes_ccm_valid_key_lens[] = { 16, 24, 32 };
+#define AEAD_MAX_KEY_LEN 32
+#define AEAD_VALID_KEY_LENS aes_ccm_valid_key_lens
+
+static const size_t aes_ccm_valid_nonce_lens[] = { 7, 8, 9, 10, 11, 12, 13 };
+#define AEAD_MAX_NONCE_LEN 13
+#define AEAD_VALID_NONCE_LENS aes_ccm_valid_nonce_lens
+
+static const size_t aes_ccm_valid_tag_lens[] = { 4, 6, 8, 10, 12, 14, 16 };
+#define AEAD_MAX_TAG_LEN 16
+#define AEAD_VALID_TAG_LENS aes_ccm_valid_tag_lens
+
+#define AEAD_KEY aes_ccm_key
+#define AEAD_CTX aes_ccm_ctx
+#define AEAD_PREPAREKEY aes_ccm_preparekey
+#define AEAD_ENCRYPT aes_ccm_encrypt
+#define AEAD_DECRYPT aes_ccm_decrypt
+
+#define AEAD_INIT aes_ccm_init
+#define AEAD_AUTH_UPDATE aes_ccm_auth_update
+#define AEAD_ENCRYPT_UPDATE aes_ccm_encrypt_update
+#define AEAD_DECRYPT_UPDATE aes_ccm_decrypt_update
+#define AEAD_ENCRYPT_FINAL aes_ccm_encrypt_final
+#define AEAD_DECRYPT_FINAL aes_ccm_decrypt_final
+
+/* This value was generated by gen-aead-testvecs.py. */
+static const u8 aes_ccm_monte_carlo_checksum[BLAKE2S_HASH_SIZE] = {
+ 0x70, 0x1c, 0xde, 0xa4, 0xe2, 0x03, 0x50, 0xb2, 0xf5, 0x9e, 0x61,
+ 0x66, 0xe4, 0xe5, 0x13, 0x1a, 0x00, 0x95, 0x34, 0x03, 0xb7, 0x61,
+ 0x2c, 0xdb, 0xc3, 0x15, 0x36, 0x84, 0x93, 0x7f, 0xb4, 0x5b,
+};
+#define AEAD_MONTE_CARLO_CHECKSUM aes_ccm_monte_carlo_checksum
+
+#include "aead-test-template.h"
+
+/*
+ * Test for each AES-CCM nonce length, the message length is validated against
+ * the correct corresponding maximum message length.
+ */
+static void test_aes_ccm_data_len_too_large(struct kunit *test)
+{
+ static const struct {
+ size_t nonce_len;
+ u64 max_data_len;
+ } lens[] = {
+ /* clang-format off */
+ { 7, 0xffffffffffffffff }, /* U64_MAX */
+ { 8, 0xffffffffffffff },
+ { 9, 0xffffffffffff },
+ { 10, 0xffffffffff },
+ { 11, 0xffffffff },
+ { 12, 0xffffff },
+ { 13, 0xffff },
+ /* clang-format on */
+ };
+ u8 nonce[13] = {};
+ u8 raw_key[AES_KEYSIZE_256] = {};
+ int err;
+ struct aes_ccm_key *key = alloc_buf(test, sizeof(*key));
+ struct aes_ccm_ctx ctx;
+
+ err = aes_ccm_preparekey(key, raw_key, sizeof(raw_key), 16);
+ KUNIT_ASSERT_EQ(test, 0, err);
+
+ for (size_t i = 0; i < ARRAY_SIZE(lens); i++) {
+ size_t nonce_len = lens[i].nonce_len;
+ u64 max_data_len = lens[i].max_data_len;
+
+ /* data_len <= max_data_len should be accepted. */
+ err = aes_ccm_init(&ctx, 0, 0, nonce, nonce_len, key);
+ KUNIT_ASSERT_EQ_MSG(
+ test, 0, err,
+ "data_len=0 wasn't accepted with nonce_len=%zu",
+ nonce_len);
+ err = aes_ccm_init(&ctx, max_data_len, 0, nonce, nonce_len,
+ key);
+ KUNIT_ASSERT_EQ_MSG(
+ test, 0, err,
+ "data_len=%llu wasn't accepted with nonce_len=%zu",
+ max_data_len, nonce_len);
+
+ /* data_len > max_data_len should be rejected. */
+ if (max_data_len == U64_MAX)
+ continue;
+ err = aes_ccm_init(&ctx, max_data_len + 1, 0, nonce, nonce_len,
+ key);
+ KUNIT_ASSERT_EQ_MSG(
+ test, -EOVERFLOW, err,
+ "data_len=%llu wasn't rejected with -EOVERFLOW with nonce_len=%zu (aes_ccm_init)",
+ max_data_len + 1, nonce_len);
+ err = aes_ccm_encrypt(NULL, NULL, max_data_len + 1, NULL, NULL,
+ 0, nonce, nonce_len, key);
+ KUNIT_ASSERT_EQ_MSG(
+ test, -EOVERFLOW, err,
+ "data_len=%llu wasn't rejected with -EOVERFLOW with nonce_len=%zu (aes_ccm_encrypt)",
+ max_data_len + 1, nonce_len);
+ err = aes_ccm_decrypt(NULL, NULL, max_data_len + 1, NULL, NULL,
+ 0, nonce, nonce_len, key);
+ KUNIT_ASSERT_EQ_MSG(
+ test, -EOVERFLOW, err,
+ "data_len=%llu wasn't rejected with -EOVERFLOW with nonce_len=%zu (aes_ccm_decrypt)",
+ max_data_len + 1, nonce_len);
+ err = aes_ccm_init(&ctx, U64_MAX, 0, nonce, nonce_len, key);
+ KUNIT_ASSERT_EQ_MSG(
+ test, -EOVERFLOW, err,
+ "data_len=U64_MAX wasn't rejected with -EOVERFLOW with nonce_len=%zu (aes_ccm_init)",
+ nonce_len);
+ }
+}
+
+static struct kunit_case aes_ccm_test_cases[] = {
+ KUNIT_CASE(test_aes_ccm_test_vectors),
+ KUNIT_CASE(test_aes_ccm_nist_sp800_38c_example4),
+ KUNIT_CASE(test_aes_ccm_data_len_too_large),
+ AEAD_KUNIT_CASES,
+ {},
+};
+
+static struct kunit_suite aes_ccm_test_suite = {
+ .name = "aes_ccm",
+ .test_cases = aes_ccm_test_cases,
+};
+kunit_test_suite(aes_ccm_test_suite);
+
+MODULE_DESCRIPTION("KUnit tests and benchmark for AES-CCM");
+MODULE_LICENSE("GPL");
diff --git a/scripts/crypto/gen-aead-testvecs.py b/scripts/crypto/gen-aead-testvecs.py
new file mode 100755
index 000000000000..048043735819
--- /dev/null
+++ b/scripts/crypto/gen-aead-testvecs.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Script that generates known-good data used in the AEAD tests.
+#
+# Requires that python-cryptography be installed.
+#
+# Copyright 2026 Google LLC
+
+import hashlib
+import sys
+import cryptography.hazmat.primitives.ciphers.aead
+
+
+# Deterministically generate 'length' random bytes.
+def rand_bytes(length):
+ seed = length
+ out = []
+ for _ in range(length):
+ seed = (seed * 25214903917 + 11) % 2**48
+ out.append((seed >> 16) % 256)
+ return bytes(out)
+
+
+# Deterministically generate many different AEAD inputs using exactly the same
+# method that the test uses; encrypt them using an independent implementation of
+# the algorithm; compute the checksum of all the resulting (ciphertext, authtag)
+# pairs concatenated to each other; and print the checksum as a C struct.
+def gen_monte_carlo_checksum(alg):
+ blake2s = hashlib.blake2s()
+ for data_len in range(1025):
+ ad_len = data_len % 293
+ pt = rand_bytes(data_len)
+ ad = rand_bytes(ad_len)
+ if alg == "aes-ccm":
+ key_len = [16, 24, 32][data_len % 3]
+ key = rand_bytes(key_len)
+ nonce = rand_bytes([7, 8, 9, 10, 11, 12, 13][data_len % 7])
+ tag_len = [4, 6, 8, 10, 12, 14, 16][data_len % 7]
+ ccm = cryptography.hazmat.primitives.ciphers.aead.AESCCM(
+ key, tag_length=tag_len
+ )
+ ct_and_tag = ccm.encrypt(nonce, pt, ad)
+
+ blake2s.update(ct_and_tag)
+
+ name = f"{alg.replace('-', '_')}_monte_carlo_checksum"
+ value = blake2s.digest()
+ print(f"static const u8 {name}[BLAKE2S_HASH_SIZE] = {{")
+ for i in range(0, len(value), 11):
+ line = "\t" + "".join(f"0x{b:02x}, " for b in value[i : i + 11])
+ print(f"{line.rstrip()}")
+ print("};")
+
+
+if len(sys.argv) != 2 or sys.argv[1] not in ("aes-ccm"):
+ sys.stderr.write("Usage: gen-aead-testvecs.py [aes-ccm]\n")
+ sys.exit(1)
+
+gen_monte_carlo_checksum(sys.argv[1])
--
2.55.0
next prev parent reply other threads:[~2026-07-30 1:35 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-30 1:32 [PATCH 0/5] lib/crypto: KUnit tests for AES-CCM and AES-GCM Eric Biggers
2026-07-30 1:32 ` [PATCH 1/5] lib/crypto: tests: Create test-utils.h Eric Biggers
2026-07-30 1:32 ` [PATCH 2/5] lib/crypto: tests: Use per-test-case buffers in hash tests Eric Biggers
2026-07-30 1:32 ` [PATCH 3/5] lib/crypto: tests: Add aead-test-template.h Eric Biggers
2026-07-30 1:32 ` Eric Biggers [this message]
2026-07-30 1:33 ` [PATCH 5/5] lib/crypto: tests: Add KUnit test suite for AES-GCM Eric Biggers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260730013301.160203-5-ebiggers@kernel.org \
--to=ebiggers@kernel.org \
--cc=Jason@zx2c4.com \
--cc=ardb@kernel.org \
--cc=herbert@gondor.apana.org.au \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.