mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 02:53:16 -04:00
Merge tag 'libcrypto-tests-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux
Pull crypto library test updates from Eric Biggers: - Add comprehensive KUnit test suites for the new AES-GCM and AES-CCM library APIs - Add FIPS self-tests for all the AES encryption modes. This is needed for parity with the traditional crypto API - Fix a couple more issues in the IRQ test helper * tag 'libcrypto-tests-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux: lib/crypto: aes-cmac: Use __cleanup() instead of memzero_explicit() kunit: irq: Unregister on-stack timer and work from debugobjects kunit: irq: Continue increasing hrtimer interval for longer lib/crypto: tests: Add KUnit test suite for AES-GCM lib/crypto: tests: Add KUnit test suite for AES-CCM lib/crypto: tests: Add aead-test-template.h lib/crypto: tests: Use per-test-case buffers in hash tests lib/crypto: tests: Create test-utils.h lib/crypto: aes: Add FIPS self-tests for GCM and CCM lib/crypto: aes: Add FIPS self-tests for unauthenticated modes lib/crypto: fips: Split fips.h into fips-aes.h and fips-sha.h
This commit is contained in:
@@ -38,11 +38,13 @@ static enum hrtimer_restart kunit_irq_test_timer_func(struct hrtimer *timer)
|
||||
softirq_calls = atomic_read(&state->softirq_func_calls);
|
||||
|
||||
/*
|
||||
* If the timer is firing too often for the softirq or task to ever have
|
||||
* a chance to run, increase the timer interval. This is needed on very
|
||||
* slow systems.
|
||||
* If the hrtimer is running much faster than the bh_work or the task,
|
||||
* then it is firing too fast and might be starving those contexts as
|
||||
* well as the actual system timer tick. Increase the interval.
|
||||
*/
|
||||
if (hardirq_calls >= 20 && (softirq_calls == 0 || task_calls == 0))
|
||||
if (hardirq_calls >= 20 &&
|
||||
(hardirq_calls / 2 > softirq_calls ||
|
||||
hardirq_calls / 2 > task_calls))
|
||||
state->interval = ktime_add_ns(state->interval, 250);
|
||||
|
||||
if (!state->func(state->test_specific_state))
|
||||
@@ -135,6 +137,8 @@ static inline void kunit_run_irq_test(struct kunit *test, bool (*func)(void *),
|
||||
/* Cancel the timer and work. */
|
||||
hrtimer_cancel(&state.timer);
|
||||
flush_work(&state.bh_work);
|
||||
destroy_hrtimer_on_stack(&state.timer);
|
||||
destroy_work_on_stack(&state.bh_work);
|
||||
|
||||
/* Sanity check: the timer and BH functions should have been run. */
|
||||
KUNIT_EXPECT_GT_MSG(test, atomic_read(&state.hardirq_func_calls), 0,
|
||||
|
||||
@@ -3,6 +3,8 @@ 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_AES_GCM_KUNIT_TEST=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2B_KUNIT_TEST=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST=y
|
||||
CONFIG_CRYPTO_LIB_CHACHA20POLY1305_KUNIT_TEST=y
|
||||
|
||||
262
lib/crypto/aes.c
262
lib/crypto/aes.c
@@ -19,7 +19,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/unaligned.h>
|
||||
#include "fips.h"
|
||||
#include "fips-aes.h"
|
||||
|
||||
static const u8 ____cacheline_aligned aes_sbox[] = {
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
|
||||
@@ -522,6 +522,26 @@ void aes_decrypt(const struct aes_key *key, u8 out[AES_BLOCK_SIZE],
|
||||
}
|
||||
EXPORT_SYMBOL(aes_decrypt);
|
||||
|
||||
/* 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)) != 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)) != 0)
|
||||
panic("aes: FIPS self-test failed (wrong ciphertext)\n");
|
||||
|
||||
aes_decrypt(&key, data, data);
|
||||
if (memcmp(fips_test_data, data, sizeof(data)) != 0)
|
||||
panic("aes: FIPS self-test failed (wrong plaintext)\n");
|
||||
|
||||
memzero_explicit(&key, sizeof(key));
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_CBC_MACS)
|
||||
|
||||
#ifndef aes_cbcmac_blocks_arch
|
||||
@@ -717,17 +737,10 @@ void aes_cbcmac_final(struct aes_cbcmac_ctx *ctx, u8 out[AES_BLOCK_SIZE])
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(aes_cbcmac_final, "CRYPTO_INTERNAL");
|
||||
|
||||
/*
|
||||
* FIPS cryptographic algorithm self-test for AES-CMAC. As per the FIPS 140-3
|
||||
* Implementation Guidance, a cryptographic algorithm self-test for at least 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;
|
||||
struct aes_cmac_key key __cleanup(aes_cmac_zeroize_key);
|
||||
u8 mac[AES_BLOCK_SIZE];
|
||||
|
||||
if (aes_cmac_preparekey(&key, fips_test_key, sizeof(fips_test_key)) !=
|
||||
@@ -736,7 +749,6 @@ static void __init aes_cmac_fips_test(void)
|
||||
aes_cmac(&key, fips_test_data, sizeof(fips_test_data), mac);
|
||||
if (memcmp(fips_test_aes_cmac_value, mac, sizeof(mac)) != 0)
|
||||
panic("aes: CMAC FIPS self-test failed (wrong MAC)\n");
|
||||
memzero_explicit(&key, sizeof(key));
|
||||
}
|
||||
#else /* CONFIG_CRYPTO_LIB_AES_CBC_MACS */
|
||||
static inline void aes_cmac_fips_test(void)
|
||||
@@ -797,7 +809,31 @@ void aes_ecb_decrypt(u8 *dst, const u8 *src, size_t len,
|
||||
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)) != 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)) != 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)) != 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 */
|
||||
|
||||
#if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_CBC)
|
||||
/*
|
||||
@@ -983,7 +1019,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)) != 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)) != 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)) != 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 = 2 * AES_BLOCK_SIZE;
|
||||
u8 ptext[2 * AES_BLOCK_SIZE];
|
||||
u8 data[2 * AES_BLOCK_SIZE];
|
||||
|
||||
/* ptext = 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)) != 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) != 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) != 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 */
|
||||
|
||||
#if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_CTR)
|
||||
/*
|
||||
@@ -1078,7 +1173,34 @@ void aes_xctr(u8 *dst, const u8 *src, size_t len, u64 *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)) != 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)) != 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)) != 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 */
|
||||
|
||||
#if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_XTS)
|
||||
int aes_xts_preparekey(struct aes_xts_key *key, const u8 *in_key,
|
||||
@@ -1307,7 +1429,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) = kmalloc_obj(*key);
|
||||
u8 tweak[AES_BLOCK_SIZE];
|
||||
u8 data[sizeof(fips_test_data)];
|
||||
|
||||
if (key == 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) != 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)) != 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)) != 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 */
|
||||
|
||||
#if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_GCM)
|
||||
/*
|
||||
@@ -1586,7 +1737,37 @@ int aes_gcm_decrypt(u8 *dst, const u8 *src, size_t data_len, const u8 *authtag,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aes_gcm_decrypt);
|
||||
|
||||
#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 = 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) != 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)) != 0)
|
||||
panic("aes: GCM FIPS self-test failed (wrong ciphertext and/or tag)\n");
|
||||
|
||||
err = aes_gcm_decrypt(buf, buf, data_len, &buf[data_len], fips_test_ad,
|
||||
sizeof(fips_test_ad), fips_test_iv, &key);
|
||||
if (err != 0)
|
||||
panic("aes: GCM FIPS self-test failed (decryption failed)\n");
|
||||
if (memcmp(fips_test_data, buf, data_len) != 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 */
|
||||
|
||||
#if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_CCM)
|
||||
int aes_ccm_preparekey(struct aes_ccm_key *key, const u8 *in_key,
|
||||
@@ -1898,15 +2079,60 @@ int aes_ccm_decrypt(u8 *dst, const u8 *src, size_t data_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 = sizeof(fips_test_data);
|
||||
const size_t nonce_len = 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) != 0)
|
||||
panic("aes: CCM FIPS self-test failed (preparekey)\n");
|
||||
|
||||
err = 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 != 0)
|
||||
panic("aes: CCM FIPS self-test failed (encryption failed)\n");
|
||||
if (memcmp(fips_test_aes_ccm_ctext_and_tag, buf, sizeof(buf)) != 0)
|
||||
panic("aes: CCM FIPS self-test failed (wrong ciphertext and/or tag)\n");
|
||||
|
||||
err = 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 != 0)
|
||||
panic("aes: CCM FIPS self-test failed (decryption failed)\n");
|
||||
if (memcmp(fips_test_data, buf, data_len) != 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 */
|
||||
|
||||
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();
|
||||
aes_gcm_fips_test();
|
||||
aes_ccm_fips_test();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(aes_mod_init);
|
||||
|
||||
78
lib/crypto/fips-aes.h
Normal file
78
lib/crypto/fips-aes.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* This file was generated by: gen-fips-testvecs.py */
|
||||
/* clang-format off */
|
||||
|
||||
#include <linux/fips.h>
|
||||
|
||||
static const u8 fips_test_data[] __initconst __maybe_unused = {
|
||||
0x66, 0x69, 0x70, 0x73, 0x20, 0x74, 0x65, 0x73,
|
||||
0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const u8 fips_test_ad[] __initconst __maybe_unused = {
|
||||
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 = {
|
||||
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 = {
|
||||
0x66, 0x69, 0x70, 0x73, 0x20, 0x74, 0x65, 0x73,
|
||||
0x74, 0x20, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const u8 fips_test_xts_key[] __initconst __maybe_unused = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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 = {
|
||||
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_unused = {
|
||||
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_unused = {
|
||||
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,
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* This file was generated by: gen-fips-testvecs.py */
|
||||
/* clang-format off */
|
||||
|
||||
#include <linux/fips.h>
|
||||
|
||||
@@ -43,8 +44,3 @@ static const u8 fips_test_sha3_256_value[] __initconst __maybe_unused = {
|
||||
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 = {
|
||||
0xc5, 0x88, 0x28, 0x55, 0xd7, 0x2c, 0x00, 0xb6,
|
||||
0x6a, 0xa7, 0xfc, 0x82, 0x90, 0x81, 0xcf, 0x18,
|
||||
};
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/unaligned.h>
|
||||
#include <linux/wordpart.h>
|
||||
#include "fips.h"
|
||||
#include "fips-sha.h"
|
||||
|
||||
static const struct sha1_block_state sha1_iv = {
|
||||
.h = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/unaligned.h>
|
||||
#include <linux/wordpart.h>
|
||||
#include "fips.h"
|
||||
#include "fips-sha.h"
|
||||
|
||||
static const struct sha256_block_state sha224_iv = {
|
||||
.h = {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/unaligned.h>
|
||||
#include "fips.h"
|
||||
#include "fips-sha.h"
|
||||
|
||||
/*
|
||||
* On some 32-bit architectures, such as h8300, GCC ends up using over 1 KB of
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/unaligned.h>
|
||||
#include <linux/wordpart.h>
|
||||
#include "fips.h"
|
||||
#include "fips-sha.h"
|
||||
|
||||
static const struct sha512_block_state sha384_iv = {
|
||||
.h = {
|
||||
|
||||
@@ -9,6 +9,24 @@ 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_AES_GCM_KUNIT_TEST
|
||||
tristate "KUnit tests for AES-GCM" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT && CRYPTO_LIB_AES_GCM
|
||||
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-GCM authenticated encryption algorithm.
|
||||
|
||||
config CRYPTO_LIB_BLAKE2B_KUNIT_TEST
|
||||
tristate "KUnit tests for BLAKE2b" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT && CRYPTO_LIB_BLAKE2B
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# 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_AES_GCM_KUNIT_TEST) += aes_gcm_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
|
||||
|
||||
1039
lib/crypto/tests/aead-test-template.h
Normal file
1039
lib/crypto/tests/aead-test-template.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -34,18 +34,9 @@ static void aes_cmac_withtestkey(const u8 *data, size_t data_len,
|
||||
static int aes_cbc_macs_suite_init(struct kunit_suite *suite)
|
||||
{
|
||||
u8 raw_key[AES_KEYSIZE_256];
|
||||
int err;
|
||||
|
||||
rand_bytes_seeded_from_len(raw_key, sizeof(raw_key));
|
||||
err = aes_cmac_preparekey(&test_key, raw_key, sizeof(raw_key));
|
||||
if (err)
|
||||
return err;
|
||||
return hash_suite_init(suite);
|
||||
}
|
||||
|
||||
static void aes_cbc_macs_suite_exit(struct kunit_suite *suite)
|
||||
{
|
||||
hash_suite_exit(suite);
|
||||
return aes_cmac_preparekey(&test_key, raw_key, sizeof(raw_key));
|
||||
}
|
||||
|
||||
/* Verify compatibility of the AES-CMAC implementation with RFC 4493. */
|
||||
@@ -218,7 +209,6 @@ static struct kunit_suite aes_cbc_macs_test_suite = {
|
||||
.name = "aes_cbc_macs",
|
||||
.test_cases = aes_cbc_macs_test_cases,
|
||||
.suite_init = aes_cbc_macs_suite_init,
|
||||
.suite_exit = aes_cbc_macs_suite_exit,
|
||||
};
|
||||
kunit_test_suite(aes_cbc_macs_test_suite);
|
||||
|
||||
|
||||
356
lib/crypto/tests/aes_ccm_kunit.c
Normal file
356
lib/crypto/tests/aes_ccm_kunit.c
Normal file
@@ -0,0 +1,356 @@
|
||||
// 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 that 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);
|
||||
if (max_data_len + 1 <= SIZE_MAX) {
|
||||
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");
|
||||
472
lib/crypto/tests/aes_gcm_kunit.c
Normal file
472
lib/crypto/tests/aes_gcm_kunit.c
Normal file
@@ -0,0 +1,472 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* KUnit test suite for AES-GCM
|
||||
*
|
||||
* Copyright 2026 Google LLC
|
||||
*/
|
||||
#include <crypto/aes-gcm.h>
|
||||
#include <crypto/blake2s.h>
|
||||
#include "test-utils.h"
|
||||
|
||||
/* The kernel's AES-GCM implementation supports only 12-byte nonces. */
|
||||
#define AES_GCM_NONCE_LEN 12
|
||||
|
||||
/*
|
||||
* AES-GCM test vectors from the original paper "The Galois/Counter Mode of
|
||||
* Operation (GCM)" by McGrew & Viega. Vectors with nonce lengths other than 12
|
||||
* bytes are excluded.
|
||||
*/
|
||||
static const struct aes_gcm_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_gcm_testvecs[] = {
|
||||
/* AES-128 Test Vectors */
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 1",
|
||||
.key = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.key_len = 16,
|
||||
.nonce = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00",
|
||||
.nonce_len = 12,
|
||||
.ptext = "",
|
||||
.ctext = "",
|
||||
.data_len = 0,
|
||||
.ad = "",
|
||||
.ad_len = 0,
|
||||
.tag = "\x58\xe2\xfc\xce\xfa\x7e\x30\x61"
|
||||
"\x36\x7f\x1d\x57\xa4\xe7\x45\x5a",
|
||||
.tag_len = 16,
|
||||
},
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 2",
|
||||
.key = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.key_len = 16,
|
||||
.nonce = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00",
|
||||
.nonce_len = 12,
|
||||
.ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.ctext = "\x03\x88\xda\xce\x60\xb6\xa3\x92"
|
||||
"\xf3\x28\xc2\xb9\x71\xb2\xfe\x78",
|
||||
.data_len = 16,
|
||||
.ad = "",
|
||||
.ad_len = 0,
|
||||
.tag = "\xab\x6e\x47\xd4\x2c\xec\x13\xbd"
|
||||
"\xf5\x3a\x67\xb2\x12\x57\xbd\xdf",
|
||||
.tag_len = 16,
|
||||
},
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 3",
|
||||
.key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
|
||||
"\x6d\x6a\x8f\x94\x67\x30\x83\x08",
|
||||
.key_len = 16,
|
||||
.nonce = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
|
||||
"\xde\xca\xf8\x88",
|
||||
.nonce_len = 12,
|
||||
.ptext = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
|
||||
"\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
|
||||
"\x86\xa7\xa9\x53\x15\x34\xf7\xda"
|
||||
"\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
|
||||
"\x1c\x3c\x0c\x95\x95\x68\x09\x53"
|
||||
"\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
|
||||
"\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
|
||||
"\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
|
||||
.ctext = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
|
||||
"\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
|
||||
"\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
|
||||
"\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
|
||||
"\x21\xd5\x14\xb2\x54\x66\x93\x1c"
|
||||
"\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
|
||||
"\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
|
||||
"\x3d\x58\xe0\x91\x47\x3f\x59\x85",
|
||||
.data_len = 64,
|
||||
.ad = "",
|
||||
.ad_len = 0,
|
||||
.tag = "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6"
|
||||
"\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4",
|
||||
.tag_len = 16,
|
||||
},
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 4",
|
||||
.key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
|
||||
"\x6d\x6a\x8f\x94\x67\x30\x83\x08",
|
||||
.key_len = 16,
|
||||
.nonce = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
|
||||
"\xde\xca\xf8\x88",
|
||||
.nonce_len = 12,
|
||||
.ptext = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
|
||||
"\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
|
||||
"\x86\xa7\xa9\x53\x15\x34\xf7\xda"
|
||||
"\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
|
||||
"\x1c\x3c\x0c\x95\x95\x68\x09\x53"
|
||||
"\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
|
||||
"\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
|
||||
"\xba\x63\x7b\x39",
|
||||
.ctext = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
|
||||
"\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
|
||||
"\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
|
||||
"\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
|
||||
"\x21\xd5\x14\xb2\x54\x66\x93\x1c"
|
||||
"\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
|
||||
"\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
|
||||
"\x3d\x58\xe0\x91",
|
||||
.data_len = 60,
|
||||
.ad = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
|
||||
"\xfe\xed\xfa\xce\xde\xad\xbe\xef"
|
||||
"\xab\xad\xda\xd2",
|
||||
.ad_len = 20,
|
||||
.tag = "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb"
|
||||
"\x94\xfa\xe9\x5a\xe7\x12\x1a\x47",
|
||||
.tag_len = 16,
|
||||
},
|
||||
|
||||
/* AES-192 Test Vectors */
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 7",
|
||||
.key = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.key_len = 24,
|
||||
.nonce = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00",
|
||||
.nonce_len = 12,
|
||||
.ptext = "",
|
||||
.ctext = "",
|
||||
.data_len = 0,
|
||||
.ad = "",
|
||||
.ad_len = 0,
|
||||
.tag = "\xcd\x33\xb2\x8a\xc7\x73\xf7\x4b"
|
||||
"\xa0\x0e\xd1\xf3\x12\x57\x24\x35",
|
||||
.tag_len = 16,
|
||||
},
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 8",
|
||||
.key = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.key_len = 24,
|
||||
.nonce = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00",
|
||||
.nonce_len = 12,
|
||||
.ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.ctext = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41"
|
||||
"\x1c\x26\x7e\x43\x84\xb0\xf6\x00",
|
||||
.data_len = 16,
|
||||
.ad = "",
|
||||
.ad_len = 0,
|
||||
.tag = "\x2f\xf5\x8d\x80\x03\x39\x27\xab"
|
||||
"\x8e\xf4\xd4\x58\x75\x14\xf0\xfb",
|
||||
.tag_len = 16,
|
||||
},
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 9",
|
||||
.key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
|
||||
"\x6d\x6a\x8f\x94\x67\x30\x83\x08"
|
||||
"\xfe\xff\xe9\x92\x86\x65\x73\x1c",
|
||||
.key_len = 24,
|
||||
.nonce = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
|
||||
"\xde\xca\xf8\x88",
|
||||
.nonce_len = 12,
|
||||
.ptext = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
|
||||
"\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
|
||||
"\x86\xa7\xa9\x53\x15\x34\xf7\xda"
|
||||
"\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
|
||||
"\x1c\x3c\x0c\x95\x95\x68\x09\x53"
|
||||
"\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
|
||||
"\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
|
||||
"\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
|
||||
.ctext = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
|
||||
"\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
|
||||
"\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
|
||||
"\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
|
||||
"\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
|
||||
"\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
|
||||
"\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
|
||||
"\xcc\xda\x27\x10\xac\xad\xe2\x56",
|
||||
.data_len = 64,
|
||||
.ad = "",
|
||||
.ad_len = 0,
|
||||
.tag = "\x99\x24\xa7\xc8\x58\x73\x36\xbf"
|
||||
"\xb1\x18\x02\x4d\xb8\x67\x4a\x14",
|
||||
.tag_len = 16,
|
||||
},
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 10",
|
||||
.key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
|
||||
"\x6d\x6a\x8f\x94\x67\x30\x83\x08"
|
||||
"\xfe\xff\xe9\x92\x86\x65\x73\x1c",
|
||||
.key_len = 24,
|
||||
.nonce = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
|
||||
"\xde\xca\xf8\x88",
|
||||
.nonce_len = 12,
|
||||
.ptext = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
|
||||
"\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
|
||||
"\x86\xa7\xa9\x53\x15\x34\xf7\xda"
|
||||
"\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
|
||||
"\x1c\x3c\x0c\x95\x95\x68\x09\x53"
|
||||
"\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
|
||||
"\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
|
||||
"\xba\x63\x7b\x39",
|
||||
.ctext = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
|
||||
"\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
|
||||
"\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
|
||||
"\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
|
||||
"\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
|
||||
"\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
|
||||
"\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
|
||||
"\xcc\xda\x27\x10",
|
||||
.data_len = 60,
|
||||
.ad = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
|
||||
"\xfe\xed\xfa\xce\xde\xad\xbe\xef"
|
||||
"\xab\xad\xda\xd2",
|
||||
.ad_len = 20,
|
||||
.tag = "\x25\x19\x49\x8e\x80\xf1\x47\x8f"
|
||||
"\x37\xba\x55\xbd\x6d\x27\x61\x8c",
|
||||
.tag_len = 16,
|
||||
},
|
||||
|
||||
/* AES-256 Test Vectors */
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 13",
|
||||
.key = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.key_len = 32,
|
||||
.nonce = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00",
|
||||
.nonce_len = 12,
|
||||
.ptext = "",
|
||||
.ctext = "",
|
||||
.data_len = 0,
|
||||
.ad = "",
|
||||
.ad_len = 0,
|
||||
.tag = "\x53\x0f\x8a\xfb\xc7\x45\x36\xb9"
|
||||
"\xa9\x63\xb4\xf1\xc4\xcb\x73\x8b",
|
||||
.tag_len = 16,
|
||||
},
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 14",
|
||||
.key = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.key_len = 32,
|
||||
.nonce = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00",
|
||||
.nonce_len = 12,
|
||||
.ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.ctext = "\xce\xa7\x40\x3d\x4d\x60\x6b\x6e"
|
||||
"\x07\x4e\xc5\xd3\xba\xf3\x9d\x18",
|
||||
.data_len = 16,
|
||||
.ad = "",
|
||||
.ad_len = 0,
|
||||
.tag = "\xd0\xd1\xc8\xa7\x99\x99\x6b\xf0"
|
||||
"\x26\x5b\x98\xb5\xd4\x8a\xb9\x19",
|
||||
.tag_len = 16,
|
||||
},
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 15",
|
||||
.key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
|
||||
"\x6d\x6a\x8f\x94\x67\x30\x83\x08"
|
||||
"\xfe\xff\xe9\x92\x86\x65\x73\x1c"
|
||||
"\x6d\x6a\x8f\x94\x67\x30\x83\x08",
|
||||
.key_len = 32,
|
||||
.nonce = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
|
||||
"\xde\xca\xf8\x88",
|
||||
.nonce_len = 12,
|
||||
.ptext = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
|
||||
"\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
|
||||
"\x86\xa7\xa9\x53\x15\x34\xf7\xda"
|
||||
"\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
|
||||
"\x1c\x3c\x0c\x95\x95\x68\x09\x53"
|
||||
"\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
|
||||
"\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
|
||||
"\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
|
||||
.ctext = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
|
||||
"\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
|
||||
"\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
|
||||
"\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
|
||||
"\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
|
||||
"\xa7\xb0\x8b\x10\x56\x82\x88\x38"
|
||||
"\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
|
||||
"\xbc\xc9\xf6\x62\x89\x80\x15\xad",
|
||||
.data_len = 64,
|
||||
.ad = "",
|
||||
.ad_len = 0,
|
||||
.tag = "\xb0\x94\xda\xc5\xd9\x34\x71\xbd"
|
||||
"\xec\x1a\x50\x22\x70\xe3\xcc\x6c",
|
||||
.tag_len = 16,
|
||||
},
|
||||
{
|
||||
.name = "McGrew & Viega Test Case 16",
|
||||
.key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
|
||||
"\x6d\x6a\x8f\x94\x67\x30\x83\x08"
|
||||
"\xfe\xff\xe9\x92\x86\x65\x73\x1c"
|
||||
"\x6d\x6a\x8f\x94\x67\x30\x83\x08",
|
||||
.key_len = 32,
|
||||
.nonce = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
|
||||
"\xde\xca\xf8\x88",
|
||||
.nonce_len = 12,
|
||||
.ptext = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
|
||||
"\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
|
||||
"\x86\xa7\xa9\x53\x15\x34\xf7\xda"
|
||||
"\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
|
||||
"\x1c\x3c\x0c\x95\x95\x68\x09\x53"
|
||||
"\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
|
||||
"\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
|
||||
"\xba\x63\x7b\x39",
|
||||
.ctext = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
|
||||
"\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
|
||||
"\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
|
||||
"\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
|
||||
"\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
|
||||
"\xa7\xb0\x8b\x10\x56\x82\x88\x38"
|
||||
"\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
|
||||
"\xbc\xc9\xf6\x62",
|
||||
.data_len = 60,
|
||||
.ad = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
|
||||
"\xfe\xed\xfa\xce\xde\xad\xbe\xef"
|
||||
"\xab\xad\xda\xd2",
|
||||
.ad_len = 20,
|
||||
.tag = "\x76\xfc\x6e\xce\x0f\x4e\x17\x68"
|
||||
"\xcd\xdf\x88\x53\xbb\x2d\x55\x1b",
|
||||
.tag_len = 16,
|
||||
},
|
||||
};
|
||||
|
||||
static void test_aes_gcm_one_test_vector(struct kunit *test,
|
||||
const struct aes_gcm_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_gcm_key key;
|
||||
int err;
|
||||
|
||||
KUNIT_ASSERT_EQ(test, AES_GCM_NONCE_LEN, tv->nonce_len);
|
||||
|
||||
err = aes_gcm_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);
|
||||
|
||||
aes_gcm_encrypt(ctext, tv->ptext, tv->data_len, tag, tv->ad, tv->ad_len,
|
||||
tv->nonce, &key);
|
||||
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_gcm_decrypt(decrypted, ctext, tv->data_len, tag, tv->ad,
|
||||
tv->ad_len, tv->nonce, &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_gcm_test_vectors(struct kunit *test)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(aes_gcm_testvecs); i++)
|
||||
test_aes_gcm_one_test_vector(test, &aes_gcm_testvecs[i]);
|
||||
}
|
||||
|
||||
static int aes_gcm_init_test(struct aes_gcm_ctx *ctx, u64 data_len, u64 ad_len,
|
||||
const u8 *nonce, size_t nonce_len,
|
||||
const struct aes_gcm_key *key)
|
||||
{
|
||||
if (nonce_len != AES_GCM_NONCE_LEN)
|
||||
return -EINVAL;
|
||||
/*
|
||||
* Ignore data_len and ad_len. Incremental AES-GCM doesn't need them at
|
||||
* initialization time.
|
||||
*/
|
||||
aes_gcm_init(ctx, nonce, key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aes_gcm_encrypt_test(u8 *dst, const u8 *src, size_t data_len,
|
||||
u8 *authtag, const u8 *ad, size_t ad_len,
|
||||
const u8 *nonce, size_t nonce_len,
|
||||
const struct aes_gcm_key *key)
|
||||
{
|
||||
if (nonce_len != AES_GCM_NONCE_LEN)
|
||||
return -EINVAL;
|
||||
/* aes_gcm_encrypt() returns void. */
|
||||
aes_gcm_encrypt(dst, src, data_len, authtag, ad, ad_len, nonce, key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aes_gcm_decrypt_test(u8 *dst, const u8 *src, size_t data_len,
|
||||
const u8 *authtag, const u8 *ad, size_t ad_len,
|
||||
const u8 *nonce, size_t nonce_len,
|
||||
const struct aes_gcm_key *key)
|
||||
{
|
||||
if (nonce_len != AES_GCM_NONCE_LEN)
|
||||
return -EINVAL;
|
||||
return aes_gcm_decrypt(dst, src, data_len, authtag, ad, ad_len, nonce,
|
||||
key);
|
||||
}
|
||||
|
||||
static const size_t aes_gcm_valid_key_lens[] = { 16, 24, 32 };
|
||||
#define AEAD_MAX_KEY_LEN 32
|
||||
#define AEAD_VALID_KEY_LENS aes_gcm_valid_key_lens
|
||||
|
||||
static const size_t aes_gcm_valid_nonce_lens[] = { AES_GCM_NONCE_LEN };
|
||||
#define AEAD_MAX_NONCE_LEN AES_GCM_NONCE_LEN
|
||||
#define AEAD_VALID_NONCE_LENS aes_gcm_valid_nonce_lens
|
||||
|
||||
static const size_t aes_gcm_valid_tag_lens[] = { 4, 8, 12, 13, 14, 15, 16 };
|
||||
#define AEAD_MAX_TAG_LEN 16
|
||||
#define AEAD_VALID_TAG_LENS aes_gcm_valid_tag_lens
|
||||
|
||||
#define AEAD_KEY aes_gcm_key
|
||||
#define AEAD_CTX aes_gcm_ctx
|
||||
#define AEAD_PREPAREKEY aes_gcm_preparekey
|
||||
#define AEAD_ENCRYPT aes_gcm_encrypt_test
|
||||
#define AEAD_DECRYPT aes_gcm_decrypt_test
|
||||
|
||||
#define AEAD_INIT aes_gcm_init_test
|
||||
#define AEAD_AUTH_UPDATE aes_gcm_auth_update
|
||||
#define AEAD_ENCRYPT_UPDATE aes_gcm_encrypt_update
|
||||
#define AEAD_DECRYPT_UPDATE aes_gcm_decrypt_update
|
||||
#define AEAD_ENCRYPT_FINAL aes_gcm_encrypt_final
|
||||
#define AEAD_DECRYPT_FINAL aes_gcm_decrypt_final
|
||||
|
||||
/* This value was generated by gen-aead-testvecs.py. */
|
||||
static const u8 aes_gcm_monte_carlo_checksum[BLAKE2S_HASH_SIZE] = {
|
||||
0x6d, 0xd0, 0x6e, 0x6b, 0xde, 0x3e, 0x92, 0x9f, 0xae, 0x1f, 0xf1,
|
||||
0x84, 0x99, 0x5a, 0x9e, 0x7b, 0xfe, 0x20, 0x9e, 0x22, 0x7c, 0x5f,
|
||||
0x15, 0xb3, 0x59, 0x89, 0xd0, 0xb7, 0x74, 0x5d, 0xd2, 0xa5,
|
||||
};
|
||||
#define AEAD_MONTE_CARLO_CHECKSUM aes_gcm_monte_carlo_checksum
|
||||
|
||||
#include "aead-test-template.h"
|
||||
|
||||
static struct kunit_case aes_gcm_test_cases[] = {
|
||||
KUNIT_CASE(test_aes_gcm_test_vectors),
|
||||
AEAD_KUNIT_CASES,
|
||||
{},
|
||||
};
|
||||
|
||||
static struct kunit_suite aes_gcm_test_suite = {
|
||||
.name = "aes_gcm",
|
||||
.test_cases = aes_gcm_test_cases,
|
||||
};
|
||||
kunit_test_suite(aes_gcm_test_suite);
|
||||
|
||||
MODULE_DESCRIPTION("KUnit tests and benchmark for AES-GCM");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -41,9 +41,9 @@ static void blake2b_init_default(struct blake2b_ctx *ctx)
|
||||
static void test_blake2b_all_key_and_hash_lens(struct kunit *test)
|
||||
{
|
||||
const size_t data_len = 100;
|
||||
u8 *data = &test_buf[0];
|
||||
u8 *key = data + data_len;
|
||||
u8 *hash = key + BLAKE2B_KEY_SIZE;
|
||||
u8 *data = alloc_buf(test, data_len);
|
||||
u8 *key = alloc_buf(test, BLAKE2B_KEY_SIZE);
|
||||
u8 *hash = alloc_buf(test, BLAKE2B_HASH_SIZE);
|
||||
struct blake2b_ctx main_ctx;
|
||||
u8 main_hash[BLAKE2B_HASH_SIZE];
|
||||
|
||||
@@ -68,11 +68,13 @@ static void test_blake2b_all_key_and_hash_lens(struct kunit *test)
|
||||
static void test_blake2b_with_guarded_key_buf(struct kunit *test)
|
||||
{
|
||||
const size_t data_len = 100;
|
||||
u8 *data = alloc_buf(test, data_len);
|
||||
u8 *guarded_key_buf = alloc_guarded_buf(test, BLAKE2B_KEY_SIZE);
|
||||
|
||||
rand_bytes(test_buf, data_len);
|
||||
rand_bytes(data, data_len);
|
||||
for (int key_len = 0; key_len <= BLAKE2B_KEY_SIZE; key_len++) {
|
||||
u8 key[BLAKE2B_KEY_SIZE];
|
||||
u8 *guarded_key = &test_buf[TEST_BUF_LEN - key_len];
|
||||
u8 *guarded_key = &guarded_key_buf[BLAKE2B_KEY_SIZE - key_len];
|
||||
u8 hash1[BLAKE2B_HASH_SIZE];
|
||||
u8 hash2[BLAKE2B_HASH_SIZE];
|
||||
struct blake2b_ctx ctx;
|
||||
@@ -80,14 +82,13 @@ static void test_blake2b_with_guarded_key_buf(struct kunit *test)
|
||||
rand_bytes(key, key_len);
|
||||
memcpy(guarded_key, key, key_len);
|
||||
|
||||
blake2b(key, key_len, test_buf, data_len,
|
||||
hash1, BLAKE2B_HASH_SIZE);
|
||||
blake2b(guarded_key, key_len, test_buf, data_len,
|
||||
hash2, BLAKE2B_HASH_SIZE);
|
||||
blake2b(key, key_len, data, data_len, hash1, BLAKE2B_HASH_SIZE);
|
||||
blake2b(guarded_key, key_len, data, data_len, hash2,
|
||||
BLAKE2B_HASH_SIZE);
|
||||
KUNIT_ASSERT_MEMEQ(test, hash1, hash2, BLAKE2B_HASH_SIZE);
|
||||
|
||||
blake2b_init_key(&ctx, BLAKE2B_HASH_SIZE, guarded_key, key_len);
|
||||
blake2b_update(&ctx, test_buf, data_len);
|
||||
blake2b_update(&ctx, data, data_len);
|
||||
blake2b_final(&ctx, hash2);
|
||||
KUNIT_ASSERT_MEMEQ(test, hash1, hash2, BLAKE2B_HASH_SIZE);
|
||||
}
|
||||
@@ -100,14 +101,16 @@ static void test_blake2b_with_guarded_key_buf(struct kunit *test)
|
||||
static void test_blake2b_with_guarded_out_buf(struct kunit *test)
|
||||
{
|
||||
const size_t data_len = 100;
|
||||
u8 *data = alloc_buf(test, data_len);
|
||||
u8 *out_buf = alloc_guarded_buf(test, BLAKE2B_HASH_SIZE);
|
||||
|
||||
rand_bytes(test_buf, data_len);
|
||||
rand_bytes(data, data_len);
|
||||
for (int out_len = 1; out_len <= BLAKE2B_HASH_SIZE; out_len++) {
|
||||
u8 hash[BLAKE2B_HASH_SIZE];
|
||||
u8 *guarded_hash = &test_buf[TEST_BUF_LEN - out_len];
|
||||
u8 *guarded_hash = &out_buf[BLAKE2B_HASH_SIZE - out_len];
|
||||
|
||||
blake2b(NULL, 0, test_buf, data_len, hash, out_len);
|
||||
blake2b(NULL, 0, test_buf, data_len, guarded_hash, out_len);
|
||||
blake2b(NULL, 0, data, data_len, hash, out_len);
|
||||
blake2b(NULL, 0, data, data_len, guarded_hash, out_len);
|
||||
KUNIT_ASSERT_MEMEQ(test, hash, guarded_hash, out_len);
|
||||
}
|
||||
}
|
||||
@@ -124,8 +127,6 @@ static struct kunit_case blake2b_test_cases[] = {
|
||||
static struct kunit_suite blake2b_test_suite = {
|
||||
.name = "blake2b",
|
||||
.test_cases = blake2b_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(blake2b_test_suite);
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@ static void blake2s_init_default(struct blake2s_ctx *ctx)
|
||||
static void test_blake2s_all_key_and_hash_lens(struct kunit *test)
|
||||
{
|
||||
const size_t data_len = 100;
|
||||
u8 *data = &test_buf[0];
|
||||
u8 *key = data + data_len;
|
||||
u8 *hash = key + BLAKE2S_KEY_SIZE;
|
||||
u8 *data = alloc_buf(test, data_len);
|
||||
u8 *key = alloc_buf(test, BLAKE2S_KEY_SIZE);
|
||||
u8 *hash = alloc_buf(test, BLAKE2S_HASH_SIZE);
|
||||
struct blake2s_ctx main_ctx;
|
||||
u8 main_hash[BLAKE2S_HASH_SIZE];
|
||||
|
||||
@@ -68,11 +68,13 @@ static void test_blake2s_all_key_and_hash_lens(struct kunit *test)
|
||||
static void test_blake2s_with_guarded_key_buf(struct kunit *test)
|
||||
{
|
||||
const size_t data_len = 100;
|
||||
u8 *data = alloc_buf(test, data_len);
|
||||
u8 *guarded_key_buf = alloc_guarded_buf(test, BLAKE2S_KEY_SIZE);
|
||||
|
||||
rand_bytes(test_buf, data_len);
|
||||
rand_bytes(data, data_len);
|
||||
for (int key_len = 0; key_len <= BLAKE2S_KEY_SIZE; key_len++) {
|
||||
u8 key[BLAKE2S_KEY_SIZE];
|
||||
u8 *guarded_key = &test_buf[TEST_BUF_LEN - key_len];
|
||||
u8 *guarded_key = &guarded_key_buf[BLAKE2S_KEY_SIZE - key_len];
|
||||
u8 hash1[BLAKE2S_HASH_SIZE];
|
||||
u8 hash2[BLAKE2S_HASH_SIZE];
|
||||
struct blake2s_ctx ctx;
|
||||
@@ -80,14 +82,13 @@ static void test_blake2s_with_guarded_key_buf(struct kunit *test)
|
||||
rand_bytes(key, key_len);
|
||||
memcpy(guarded_key, key, key_len);
|
||||
|
||||
blake2s(key, key_len, test_buf, data_len,
|
||||
hash1, BLAKE2S_HASH_SIZE);
|
||||
blake2s(guarded_key, key_len, test_buf, data_len,
|
||||
hash2, BLAKE2S_HASH_SIZE);
|
||||
blake2s(key, key_len, data, data_len, hash1, BLAKE2S_HASH_SIZE);
|
||||
blake2s(guarded_key, key_len, data, data_len, hash2,
|
||||
BLAKE2S_HASH_SIZE);
|
||||
KUNIT_ASSERT_MEMEQ(test, hash1, hash2, BLAKE2S_HASH_SIZE);
|
||||
|
||||
blake2s_init_key(&ctx, BLAKE2S_HASH_SIZE, guarded_key, key_len);
|
||||
blake2s_update(&ctx, test_buf, data_len);
|
||||
blake2s_update(&ctx, data, data_len);
|
||||
blake2s_final(&ctx, hash2);
|
||||
KUNIT_ASSERT_MEMEQ(test, hash1, hash2, BLAKE2S_HASH_SIZE);
|
||||
}
|
||||
@@ -100,14 +101,16 @@ static void test_blake2s_with_guarded_key_buf(struct kunit *test)
|
||||
static void test_blake2s_with_guarded_out_buf(struct kunit *test)
|
||||
{
|
||||
const size_t data_len = 100;
|
||||
u8 *data = alloc_buf(test, data_len);
|
||||
u8 *out_buf = alloc_guarded_buf(test, BLAKE2S_HASH_SIZE);
|
||||
|
||||
rand_bytes(test_buf, data_len);
|
||||
rand_bytes(data, data_len);
|
||||
for (int out_len = 1; out_len <= BLAKE2S_HASH_SIZE; out_len++) {
|
||||
u8 hash[BLAKE2S_HASH_SIZE];
|
||||
u8 *guarded_hash = &test_buf[TEST_BUF_LEN - out_len];
|
||||
u8 *guarded_hash = &out_buf[BLAKE2S_HASH_SIZE - out_len];
|
||||
|
||||
blake2s(NULL, 0, test_buf, data_len, hash, out_len);
|
||||
blake2s(NULL, 0, test_buf, data_len, guarded_hash, out_len);
|
||||
blake2s(NULL, 0, data, data_len, hash, out_len);
|
||||
blake2s(NULL, 0, data, data_len, guarded_hash, out_len);
|
||||
KUNIT_ASSERT_MEMEQ(test, hash, guarded_hash, out_len);
|
||||
}
|
||||
}
|
||||
@@ -124,8 +127,6 @@ static struct kunit_case blake2s_test_cases[] = {
|
||||
static struct kunit_suite blake2s_test_suite = {
|
||||
.name = "blake2s",
|
||||
.test_cases = blake2s_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(blake2s_test_suite);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include "test-utils.h"
|
||||
|
||||
struct chacha20poly1305_testvec {
|
||||
const u8 *input, *output, *assoc, *nonce, *key;
|
||||
@@ -8890,11 +8890,8 @@ static void test_chacha20poly1305(struct kunit *test)
|
||||
bool ret;
|
||||
struct scatterlist sg_src[3];
|
||||
|
||||
computed_output = kunit_kmalloc(test, MAXIMUM_TEST_BUFFER_LEN,
|
||||
GFP_KERNEL);
|
||||
input = kunit_kmalloc(test, MAXIMUM_TEST_BUFFER_LEN, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, computed_output);
|
||||
KUNIT_ASSERT_NOT_NULL(test, input);
|
||||
computed_output = alloc_buf(test, MAXIMUM_TEST_BUFFER_LEN);
|
||||
input = alloc_buf(test, MAXIMUM_TEST_BUFFER_LEN);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(chacha20poly1305_enc_vectors); ++i) {
|
||||
memset(computed_output, 0, MAXIMUM_TEST_BUFFER_LEN);
|
||||
|
||||
@@ -39,17 +39,18 @@ static void ghash_withtestkey(const u8 *data, size_t len,
|
||||
*/
|
||||
static void test_ghash_allones_key_and_message(struct kunit *test)
|
||||
{
|
||||
const size_t max_len = 4096;
|
||||
u8 *data = alloc_buf(test, max_len);
|
||||
struct ghash_key key;
|
||||
struct ghash_ctx hashofhashes_ctx;
|
||||
u8 hash[GHASH_BLOCK_SIZE];
|
||||
|
||||
static_assert(TEST_BUF_LEN >= 4096);
|
||||
memset(test_buf, 0xff, 4096);
|
||||
memset(data, 0xff, max_len);
|
||||
|
||||
ghash_preparekey(&key, test_buf);
|
||||
ghash_preparekey(&key, data);
|
||||
ghash_init(&hashofhashes_ctx, &key);
|
||||
for (size_t len = 0; len <= 4096; len += 16) {
|
||||
ghash(&key, test_buf, len, hash);
|
||||
for (size_t len = 0; len <= max_len; len += 16) {
|
||||
ghash(&key, data, len, hash);
|
||||
ghash_update(&hashofhashes_ctx, hash, sizeof(hash));
|
||||
}
|
||||
ghash_final(&hashofhashes_ctx, hash);
|
||||
@@ -68,7 +69,7 @@ static void check_key_consistency(struct kunit *test,
|
||||
const struct ghash_key *key1,
|
||||
const struct ghash_key *key2)
|
||||
{
|
||||
u8 *data = test_buf;
|
||||
u8 *data = alloc_buf(test, MAX_LEN_FOR_KEY_CHECK);
|
||||
u8 hash1[GHASH_BLOCK_SIZE];
|
||||
u8 hash2[GHASH_BLOCK_SIZE];
|
||||
|
||||
@@ -88,10 +89,10 @@ static void check_key_consistency(struct kunit *test,
|
||||
static void test_ghash_with_guarded_key(struct kunit *test)
|
||||
{
|
||||
u8 raw_key[GHASH_BLOCK_SIZE];
|
||||
u8 *guarded_raw_key = &test_buf[TEST_BUF_LEN - sizeof(raw_key)];
|
||||
u8 *guarded_raw_key = alloc_guarded_buf(test, sizeof(raw_key));
|
||||
struct ghash_key key1, key2;
|
||||
struct ghash_key *guarded_key =
|
||||
(struct ghash_key *)&test_buf[TEST_BUF_LEN - sizeof(key1)];
|
||||
alloc_guarded_buf(test, sizeof(*guarded_key));
|
||||
|
||||
/* Prepare with regular buffers. */
|
||||
rand_bytes(raw_key, sizeof(raw_key));
|
||||
@@ -116,14 +117,14 @@ static void test_ghash_with_minimally_aligned_key(struct kunit *test)
|
||||
{
|
||||
u8 raw_key[GHASH_BLOCK_SIZE];
|
||||
struct ghash_key key;
|
||||
const size_t align = __alignof__(struct ghash_key);
|
||||
u8 *key_buf = alloc_buf(test, sizeof(struct ghash_key) + 3 * align);
|
||||
struct ghash_key *minaligned_key =
|
||||
(struct ghash_key *)&test_buf[MAX_LEN_FOR_KEY_CHECK +
|
||||
__alignof__(struct ghash_key)];
|
||||
(struct ghash_key *)(PTR_ALIGN(key_buf, 2 * align) + align);
|
||||
|
||||
KUNIT_ASSERT_TRUE(test, IS_ALIGNED((uintptr_t)minaligned_key,
|
||||
__alignof__(struct ghash_key)));
|
||||
KUNIT_ASSERT_TRUE(test, !IS_ALIGNED((uintptr_t)minaligned_key,
|
||||
2 * __alignof__(struct ghash_key)));
|
||||
KUNIT_ASSERT_TRUE(test, IS_ALIGNED((uintptr_t)minaligned_key, align));
|
||||
KUNIT_ASSERT_TRUE(test,
|
||||
!IS_ALIGNED((uintptr_t)minaligned_key, 2 * align));
|
||||
|
||||
rand_bytes(raw_key, sizeof(raw_key));
|
||||
ghash_preparekey(&key, raw_key);
|
||||
@@ -164,12 +165,7 @@ static int ghash_suite_init(struct kunit_suite *suite)
|
||||
|
||||
rand_bytes_seeded_from_len(raw_key, sizeof(raw_key));
|
||||
ghash_preparekey(&test_key, raw_key);
|
||||
return hash_suite_init(suite);
|
||||
}
|
||||
|
||||
static void ghash_suite_exit(struct kunit_suite *suite)
|
||||
{
|
||||
hash_suite_exit(suite);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct kunit_case ghash_test_cases[] = {
|
||||
@@ -186,7 +182,6 @@ static struct kunit_suite ghash_test_suite = {
|
||||
.name = "ghash",
|
||||
.test_cases = ghash_test_cases,
|
||||
.suite_init = ghash_suite_init,
|
||||
.suite_exit = ghash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(ghash_test_suite);
|
||||
|
||||
|
||||
@@ -7,93 +7,7 @@
|
||||
*/
|
||||
#include <kunit/run-in-irq-context.h>
|
||||
#include <kunit/test.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
/* test_buf is a guarded buffer, i.e. &test_buf[TEST_BUF_LEN] is not mapped. */
|
||||
#define TEST_BUF_LEN 16384
|
||||
static u8 *test_buf;
|
||||
|
||||
static u8 *orig_test_buf;
|
||||
|
||||
static u64 random_seed;
|
||||
|
||||
/*
|
||||
* This is a simple linear congruential generator. It is used only for testing,
|
||||
* which does not require cryptographically secure random numbers. A hard-coded
|
||||
* algorithm is used instead of <linux/prandom.h> so that it matches the
|
||||
* algorithm used by the test vector generation script. This allows the input
|
||||
* data in random test vectors to be concisely stored as just the seed.
|
||||
*/
|
||||
static u32 rand32(void)
|
||||
{
|
||||
random_seed = (random_seed * 25214903917 + 11) & ((1ULL << 48) - 1);
|
||||
return random_seed >> 16;
|
||||
}
|
||||
|
||||
static void rand_bytes(u8 *out, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++)
|
||||
out[i] = rand32();
|
||||
}
|
||||
|
||||
static void rand_bytes_seeded_from_len(u8 *out, size_t len)
|
||||
{
|
||||
random_seed = len;
|
||||
rand_bytes(out, len);
|
||||
}
|
||||
|
||||
static bool rand_bool(void)
|
||||
{
|
||||
return rand32() % 2;
|
||||
}
|
||||
|
||||
/* Generate a random length, preferring small lengths. */
|
||||
static size_t rand_length(size_t max_len)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
switch (rand32() % 3) {
|
||||
case 0:
|
||||
len = rand32() % 128;
|
||||
break;
|
||||
case 1:
|
||||
len = rand32() % 3072;
|
||||
break;
|
||||
default:
|
||||
len = rand32();
|
||||
break;
|
||||
}
|
||||
return len % (max_len + 1);
|
||||
}
|
||||
|
||||
static size_t rand_offset(size_t max_offset)
|
||||
{
|
||||
return min(rand32() % 128, max_offset);
|
||||
}
|
||||
|
||||
static int hash_suite_init(struct kunit_suite *suite)
|
||||
{
|
||||
/*
|
||||
* Allocate the test buffer using vmalloc() with a page-aligned length
|
||||
* so that it is immediately followed by a guard page. This allows
|
||||
* buffer overreads to be detected, even in assembly code.
|
||||
*/
|
||||
size_t alloc_len = round_up(TEST_BUF_LEN, PAGE_SIZE);
|
||||
|
||||
orig_test_buf = vmalloc(alloc_len);
|
||||
if (!orig_test_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
test_buf = orig_test_buf + alloc_len - TEST_BUF_LEN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hash_suite_exit(struct kunit_suite *suite)
|
||||
{
|
||||
vfree(orig_test_buf);
|
||||
orig_test_buf = NULL;
|
||||
test_buf = NULL;
|
||||
}
|
||||
#include "test-utils.h"
|
||||
|
||||
/*
|
||||
* Test the hash function against a list of test vectors.
|
||||
@@ -104,14 +18,16 @@ static void hash_suite_exit(struct kunit_suite *suite)
|
||||
*/
|
||||
static void test_hash_test_vectors(struct kunit *test)
|
||||
{
|
||||
const size_t max_len = 16384;
|
||||
u8 *data = alloc_buf(test, max_len);
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(hash_testvecs); i++) {
|
||||
size_t data_len = hash_testvecs[i].data_len;
|
||||
u8 actual_hash[HASH_SIZE];
|
||||
|
||||
KUNIT_ASSERT_LE(test, data_len, TEST_BUF_LEN);
|
||||
rand_bytes_seeded_from_len(test_buf, data_len);
|
||||
|
||||
HASH(test_buf, data_len, actual_hash);
|
||||
KUNIT_ASSERT_LE(test, data_len, max_len);
|
||||
rand_bytes_seeded_from_len(data, data_len);
|
||||
HASH(data, data_len, actual_hash);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(
|
||||
test, actual_hash, hash_testvecs[i].digest, HASH_SIZE,
|
||||
"Wrong result with test vector %zu; data_len=%zu", i,
|
||||
@@ -127,14 +43,15 @@ static void test_hash_test_vectors(struct kunit *test)
|
||||
*/
|
||||
static void test_hash_all_lens_up_to_4096(struct kunit *test)
|
||||
{
|
||||
const size_t max_len = 4096;
|
||||
u8 *data = alloc_buf(test, max_len);
|
||||
struct HASH_CTX ctx;
|
||||
u8 hash[HASH_SIZE];
|
||||
|
||||
static_assert(TEST_BUF_LEN >= 4096);
|
||||
rand_bytes_seeded_from_len(test_buf, 4096);
|
||||
rand_bytes_seeded_from_len(data, max_len);
|
||||
HASH_INIT(&ctx);
|
||||
for (size_t len = 0; len <= 4096; len++) {
|
||||
HASH(test_buf, len, hash);
|
||||
for (size_t len = 0; len <= max_len; len++) {
|
||||
HASH(data, len, hash);
|
||||
HASH_UPDATE(&ctx, hash, HASH_SIZE);
|
||||
}
|
||||
HASH_FINAL(&ctx, hash);
|
||||
@@ -147,6 +64,9 @@ static void test_hash_all_lens_up_to_4096(struct kunit *test)
|
||||
*/
|
||||
static void test_hash_incremental_updates(struct kunit *test)
|
||||
{
|
||||
const size_t max_len = 16384;
|
||||
u8 *data = alloc_guarded_buf(test, max_len);
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
size_t total_len, offset;
|
||||
struct HASH_CTX ctx;
|
||||
@@ -155,12 +75,12 @@ static void test_hash_incremental_updates(struct kunit *test)
|
||||
size_t num_parts = 0;
|
||||
size_t remaining_len, cur_offset;
|
||||
|
||||
total_len = rand_length(TEST_BUF_LEN);
|
||||
offset = rand_offset(TEST_BUF_LEN - total_len);
|
||||
rand_bytes(&test_buf[offset], total_len);
|
||||
total_len = rand_length(max_len);
|
||||
offset = rand_offset(max_len - total_len);
|
||||
rand_bytes(&data[offset], total_len);
|
||||
|
||||
/* Compute the hash value in one shot. */
|
||||
HASH(&test_buf[offset], total_len, hash1);
|
||||
HASH(&data[offset], total_len, hash1);
|
||||
|
||||
/*
|
||||
* Compute the hash value incrementally, using a randomly
|
||||
@@ -172,13 +92,13 @@ static void test_hash_incremental_updates(struct kunit *test)
|
||||
while (rand_bool()) {
|
||||
size_t part_len = rand_length(remaining_len);
|
||||
|
||||
HASH_UPDATE(&ctx, &test_buf[cur_offset], part_len);
|
||||
HASH_UPDATE(&ctx, &data[cur_offset], part_len);
|
||||
num_parts++;
|
||||
cur_offset += part_len;
|
||||
remaining_len -= part_len;
|
||||
}
|
||||
if (remaining_len != 0 || rand_bool()) {
|
||||
HASH_UPDATE(&ctx, &test_buf[cur_offset], remaining_len);
|
||||
HASH_UPDATE(&ctx, &data[cur_offset], remaining_len);
|
||||
num_parts++;
|
||||
}
|
||||
HASH_FINAL(&ctx, hash2);
|
||||
@@ -197,11 +117,13 @@ static void test_hash_incremental_updates(struct kunit *test)
|
||||
*/
|
||||
static void test_hash_buffer_overruns(struct kunit *test)
|
||||
{
|
||||
const size_t max_tested_len = TEST_BUF_LEN - sizeof(struct HASH_CTX);
|
||||
void *const buf_end = &test_buf[TEST_BUF_LEN];
|
||||
const size_t buf_len = 16384;
|
||||
u8 *buf = alloc_guarded_buf(test, buf_len);
|
||||
void *const buf_end = &buf[buf_len];
|
||||
const size_t max_tested_len = buf_len - sizeof(struct HASH_CTX);
|
||||
struct HASH_CTX *guarded_ctx = buf_end - sizeof(*guarded_ctx);
|
||||
|
||||
rand_bytes(test_buf, TEST_BUF_LEN);
|
||||
rand_bytes(buf, buf_len);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
size_t len = rand_length(max_tested_len);
|
||||
@@ -215,14 +137,14 @@ static void test_hash_buffer_overruns(struct kunit *test)
|
||||
HASH_FINAL(&ctx, hash);
|
||||
|
||||
/* Check for overruns of the hash value buffer. */
|
||||
HASH(test_buf, len, buf_end - HASH_SIZE);
|
||||
HASH(buf, len, buf_end - HASH_SIZE);
|
||||
HASH_INIT(&ctx);
|
||||
HASH_UPDATE(&ctx, test_buf, len);
|
||||
HASH_UPDATE(&ctx, buf, len);
|
||||
HASH_FINAL(&ctx, buf_end - HASH_SIZE);
|
||||
|
||||
/* Check for overuns of the hash context. */
|
||||
/* Check for overruns of the hash context. */
|
||||
HASH_INIT(guarded_ctx);
|
||||
HASH_UPDATE(guarded_ctx, test_buf, len);
|
||||
HASH_UPDATE(guarded_ctx, buf, len);
|
||||
HASH_FINAL(guarded_ctx, hash);
|
||||
}
|
||||
}
|
||||
@@ -233,30 +155,32 @@ static void test_hash_buffer_overruns(struct kunit *test)
|
||||
*/
|
||||
static void test_hash_overlaps(struct kunit *test)
|
||||
{
|
||||
const size_t max_tested_len = TEST_BUF_LEN - HASH_SIZE;
|
||||
const size_t buf_len = 16384;
|
||||
u8 *buf = alloc_guarded_buf(test, buf_len);
|
||||
const size_t max_tested_len = buf_len - HASH_SIZE;
|
||||
struct HASH_CTX ctx;
|
||||
u8 hash[HASH_SIZE];
|
||||
|
||||
rand_bytes(test_buf, TEST_BUF_LEN);
|
||||
rand_bytes(buf, buf_len);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
size_t len = rand_length(max_tested_len);
|
||||
size_t offset = HASH_SIZE + rand_offset(max_tested_len - len);
|
||||
bool left_end = rand_bool();
|
||||
u8 *ovl_hash = left_end ? &test_buf[offset] :
|
||||
&test_buf[offset + len - HASH_SIZE];
|
||||
u8 *ovl_hash = left_end ? &buf[offset] :
|
||||
&buf[offset + len - HASH_SIZE];
|
||||
|
||||
HASH(&test_buf[offset], len, hash);
|
||||
HASH(&test_buf[offset], len, ovl_hash);
|
||||
HASH(&buf[offset], len, hash);
|
||||
HASH(&buf[offset], len, ovl_hash);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(
|
||||
test, hash, ovl_hash, HASH_SIZE,
|
||||
"Overlap test 1 failed with len=%zu offset=%zu left_end=%d",
|
||||
len, offset, left_end);
|
||||
|
||||
/* Repeat the above test, but this time use init+update+final */
|
||||
HASH(&test_buf[offset], len, hash);
|
||||
HASH(&buf[offset], len, hash);
|
||||
HASH_INIT(&ctx);
|
||||
HASH_UPDATE(&ctx, &test_buf[offset], len);
|
||||
HASH_UPDATE(&ctx, &buf[offset], len);
|
||||
HASH_FINAL(&ctx, ovl_hash);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(
|
||||
test, hash, ovl_hash, HASH_SIZE,
|
||||
@@ -264,10 +188,10 @@ static void test_hash_overlaps(struct kunit *test)
|
||||
len, offset, left_end);
|
||||
|
||||
/* Test modifying the source data after it was used. */
|
||||
HASH(&test_buf[offset], len, hash);
|
||||
HASH(&buf[offset], len, hash);
|
||||
HASH_INIT(&ctx);
|
||||
HASH_UPDATE(&ctx, &test_buf[offset], len);
|
||||
rand_bytes(&test_buf[offset], len);
|
||||
HASH_UPDATE(&ctx, &buf[offset], len);
|
||||
rand_bytes(&buf[offset], len);
|
||||
HASH_FINAL(&ctx, ovl_hash);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(
|
||||
test, hash, ovl_hash, HASH_SIZE,
|
||||
@@ -282,20 +206,22 @@ static void test_hash_overlaps(struct kunit *test)
|
||||
*/
|
||||
static void test_hash_alignment_consistency(struct kunit *test)
|
||||
{
|
||||
const size_t max_len = 16384;
|
||||
u8 *data = alloc_guarded_buf(test, max_len);
|
||||
u8 hash1[128 + HASH_SIZE];
|
||||
u8 hash2[128 + HASH_SIZE];
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
size_t len = rand_length(TEST_BUF_LEN);
|
||||
size_t data_offs1 = rand_offset(TEST_BUF_LEN - len);
|
||||
size_t data_offs2 = rand_offset(TEST_BUF_LEN - len);
|
||||
size_t len = rand_length(max_len);
|
||||
size_t data_offs1 = rand_offset(max_len - len);
|
||||
size_t data_offs2 = rand_offset(max_len - len);
|
||||
size_t hash_offs1 = rand_offset(128);
|
||||
size_t hash_offs2 = rand_offset(128);
|
||||
|
||||
rand_bytes(&test_buf[data_offs1], len);
|
||||
HASH(&test_buf[data_offs1], len, &hash1[hash_offs1]);
|
||||
memmove(&test_buf[data_offs2], &test_buf[data_offs1], len);
|
||||
HASH(&test_buf[data_offs2], len, &hash2[hash_offs2]);
|
||||
rand_bytes(&data[data_offs1], len);
|
||||
HASH(&data[data_offs1], len, &hash1[hash_offs1]);
|
||||
memmove(&data[data_offs2], &data[data_offs1], len);
|
||||
HASH(&data[data_offs2], len, &hash2[hash_offs2]);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(
|
||||
test, &hash1[hash_offs1], &hash2[hash_offs2], HASH_SIZE,
|
||||
"Alignment consistency test failed with len=%zu data_offs=(%zu,%zu) hash_offs=(%zu,%zu)",
|
||||
@@ -308,11 +234,14 @@ static void test_hash_ctx_zeroization(struct kunit *test)
|
||||
{
|
||||
static const u8 zeroes[sizeof(struct HASH_CTX)];
|
||||
struct HASH_CTX ctx;
|
||||
const size_t data_len = 128;
|
||||
u8 *data = alloc_buf(test, data_len);
|
||||
u8 hash[HASH_SIZE];
|
||||
|
||||
rand_bytes(test_buf, 128);
|
||||
rand_bytes(data, data_len);
|
||||
HASH_INIT(&ctx);
|
||||
HASH_UPDATE(&ctx, test_buf, 128);
|
||||
HASH_FINAL(&ctx, test_buf);
|
||||
HASH_UPDATE(&ctx, data, data_len);
|
||||
HASH_FINAL(&ctx, hash);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(test, &ctx, zeroes, sizeof(ctx),
|
||||
"Hash context was not zeroized by finalization");
|
||||
}
|
||||
@@ -321,6 +250,7 @@ static void test_hash_ctx_zeroization(struct kunit *test)
|
||||
#define IRQ_TEST_NUM_BUFFERS 3 /* matches max concurrency level */
|
||||
|
||||
struct hash_irq_test1_state {
|
||||
u8 *data;
|
||||
u8 expected_hashes[IRQ_TEST_NUM_BUFFERS][HASH_SIZE];
|
||||
atomic_t seqno;
|
||||
};
|
||||
@@ -336,7 +266,8 @@ static bool hash_irq_test1_func(void *state_)
|
||||
u32 i = (u32)atomic_inc_return(&state->seqno) % IRQ_TEST_NUM_BUFFERS;
|
||||
u8 actual_hash[HASH_SIZE];
|
||||
|
||||
HASH(&test_buf[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN, actual_hash);
|
||||
HASH(&state->data[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN,
|
||||
actual_hash);
|
||||
return memcmp(actual_hash, state->expected_hashes[i], HASH_SIZE) == 0;
|
||||
}
|
||||
|
||||
@@ -346,12 +277,14 @@ static bool hash_irq_test1_func(void *state_)
|
||||
*/
|
||||
static void test_hash_interrupt_context_1(struct kunit *test)
|
||||
{
|
||||
const size_t total_data_len = IRQ_TEST_NUM_BUFFERS * IRQ_TEST_DATA_LEN;
|
||||
struct hash_irq_test1_state state = {};
|
||||
|
||||
/* Prepare some test messages and compute the expected hash of each. */
|
||||
rand_bytes(test_buf, IRQ_TEST_NUM_BUFFERS * IRQ_TEST_DATA_LEN);
|
||||
state.data = alloc_buf(test, total_data_len);
|
||||
rand_bytes(state.data, total_data_len);
|
||||
for (int i = 0; i < IRQ_TEST_NUM_BUFFERS; i++)
|
||||
HASH(&test_buf[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN,
|
||||
HASH(&state.data[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN,
|
||||
state.expected_hashes[i]);
|
||||
|
||||
kunit_run_irq_test(test, hash_irq_test1_func, 100000, &state);
|
||||
@@ -365,6 +298,8 @@ struct hash_irq_test2_hash_ctx {
|
||||
};
|
||||
|
||||
struct hash_irq_test2_state {
|
||||
u8 *data;
|
||||
size_t data_len;
|
||||
struct hash_irq_test2_hash_ctx ctxs[IRQ_TEST_NUM_BUFFERS];
|
||||
u8 expected_hash[HASH_SIZE];
|
||||
u16 update_lens[32];
|
||||
@@ -397,7 +332,7 @@ static bool hash_irq_test2_func(void *state_)
|
||||
ctx->step++;
|
||||
} else if (ctx->step < state->num_steps - 1) {
|
||||
/* Update step */
|
||||
HASH_UPDATE(&ctx->hash_ctx, &test_buf[ctx->offset],
|
||||
HASH_UPDATE(&ctx->hash_ctx, &state->data[ctx->offset],
|
||||
state->update_lens[ctx->step - 1]);
|
||||
ctx->offset += state->update_lens[ctx->step - 1];
|
||||
ctx->step++;
|
||||
@@ -405,7 +340,7 @@ static bool hash_irq_test2_func(void *state_)
|
||||
/* Final step */
|
||||
u8 actual_hash[HASH_SIZE];
|
||||
|
||||
if (WARN_ON_ONCE(ctx->offset != TEST_BUF_LEN))
|
||||
if (WARN_ON_ONCE(ctx->offset != state->data_len))
|
||||
ret = false;
|
||||
HASH_FINAL(&ctx->hash_ctx, actual_hash);
|
||||
if (memcmp(actual_hash, state->expected_hash, HASH_SIZE) != 0)
|
||||
@@ -426,20 +361,23 @@ static bool hash_irq_test2_func(void *state_)
|
||||
*/
|
||||
static void test_hash_interrupt_context_2(struct kunit *test)
|
||||
{
|
||||
const size_t data_len = 16384;
|
||||
struct hash_irq_test2_state *state;
|
||||
int remaining = TEST_BUF_LEN;
|
||||
size_t remaining = data_len;
|
||||
|
||||
state = kunit_kzalloc(test, sizeof(*state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, state);
|
||||
state->data_len = data_len;
|
||||
state->data = alloc_buf(test, data_len);
|
||||
|
||||
rand_bytes(test_buf, TEST_BUF_LEN);
|
||||
HASH(test_buf, TEST_BUF_LEN, state->expected_hash);
|
||||
rand_bytes(state->data, data_len);
|
||||
HASH(state->data, data_len, state->expected_hash);
|
||||
|
||||
/*
|
||||
* Generate a list of update lengths to use. Ensure that it contains
|
||||
* multiple entries but is limited to a maximum length.
|
||||
*/
|
||||
static_assert(TEST_BUF_LEN / 4096 > 1);
|
||||
KUNIT_ASSERT_GT(test, data_len / 4096, 1);
|
||||
for (state->num_steps = 0;
|
||||
state->num_steps < ARRAY_SIZE(state->update_lens) - 1 && remaining;
|
||||
state->num_steps++) {
|
||||
@@ -485,21 +423,23 @@ static void test_hash_interrupt_context_2(struct kunit *test)
|
||||
*/
|
||||
static void test_hmac(struct kunit *test)
|
||||
{
|
||||
const size_t max_data_len = 4096;
|
||||
const size_t max_key_len = 293;
|
||||
const size_t outer_key_len = 32;
|
||||
u8 *data = alloc_guarded_buf(test, max_data_len);
|
||||
u8 *raw_key = alloc_guarded_buf(test, max_key_len);
|
||||
static const u8 zeroes[sizeof(struct HMAC_CTX)];
|
||||
u8 *raw_key;
|
||||
struct HMAC_KEY key;
|
||||
struct HMAC_CTX ctx;
|
||||
u8 mac[HASH_SIZE];
|
||||
u8 mac2[HASH_SIZE];
|
||||
|
||||
static_assert(TEST_BUF_LEN >= 4096 + 293);
|
||||
rand_bytes_seeded_from_len(test_buf, 4096);
|
||||
raw_key = &test_buf[4096];
|
||||
rand_bytes_seeded_from_len(data, max_data_len);
|
||||
rand_bytes_seeded_from_len(raw_key, outer_key_len);
|
||||
|
||||
rand_bytes_seeded_from_len(raw_key, 32);
|
||||
HMAC_PREPAREKEY(&key, raw_key, 32);
|
||||
HMAC_PREPAREKEY(&key, raw_key, outer_key_len);
|
||||
HMAC_INIT(&ctx, &key);
|
||||
for (size_t data_len = 0; data_len <= 4096; data_len++) {
|
||||
for (size_t data_len = 0; data_len <= max_data_len; data_len++) {
|
||||
/*
|
||||
* Cycle through key lengths as well. Somewhat arbitrarily go
|
||||
* up to 293, which is somewhat larger than the largest hash
|
||||
@@ -507,17 +447,17 @@ static void test_hmac(struct kunit *test)
|
||||
* hashed down to one block); going higher would not be useful.
|
||||
* To reduce correlation with data_len, use a prime number here.
|
||||
*/
|
||||
size_t key_len = data_len % 293;
|
||||
size_t key_len = data_len % max_key_len;
|
||||
|
||||
HMAC_UPDATE(&ctx, test_buf, data_len);
|
||||
HMAC_UPDATE(&ctx, data, data_len);
|
||||
|
||||
rand_bytes_seeded_from_len(raw_key, key_len);
|
||||
HMAC_USINGRAWKEY(raw_key, key_len, test_buf, data_len, mac);
|
||||
HMAC_USINGRAWKEY(raw_key, key_len, data, data_len, mac);
|
||||
HMAC_UPDATE(&ctx, mac, HASH_SIZE);
|
||||
|
||||
/* Verify that HMAC() is consistent with HMAC_USINGRAWKEY(). */
|
||||
HMAC_PREPAREKEY(&key, raw_key, key_len);
|
||||
HMAC(&key, test_buf, data_len, mac2);
|
||||
HMAC(&key, data, data_len, mac2);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(
|
||||
test, mac, mac2, HASH_SIZE,
|
||||
"HMAC gave different results with raw and prepared keys");
|
||||
@@ -540,14 +480,17 @@ static void benchmark_hash(struct kunit *test)
|
||||
1, 16, 64, 127, 128, 200, 256,
|
||||
511, 512, 1024, 3173, 4096, 16384,
|
||||
};
|
||||
const size_t max_len = 16384;
|
||||
u8 *data = alloc_buf(test, max_len);
|
||||
u8 hash[HASH_SIZE];
|
||||
|
||||
if (!IS_ENABLED(CONFIG_CRYPTO_LIB_BENCHMARK))
|
||||
kunit_skip(test, "not enabled");
|
||||
|
||||
/* Warm-up */
|
||||
for (size_t i = 0; i < 10000000; i += TEST_BUF_LEN)
|
||||
HASH(test_buf, TEST_BUF_LEN, hash);
|
||||
memset(data, 0, max_len);
|
||||
for (size_t i = 0; i < 10000000; i += max_len)
|
||||
HASH(data, max_len, hash);
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(lens_to_test); i++) {
|
||||
size_t len = lens_to_test[i];
|
||||
@@ -555,11 +498,11 @@ static void benchmark_hash(struct kunit *test)
|
||||
size_t num_iters = 10000000 / (len + 128);
|
||||
u64 t;
|
||||
|
||||
KUNIT_ASSERT_LE(test, len, TEST_BUF_LEN);
|
||||
KUNIT_ASSERT_LE(test, len, max_len);
|
||||
preempt_disable();
|
||||
t = ktime_get_ns();
|
||||
for (size_t j = 0; j < num_iters; j++)
|
||||
HASH(test_buf, len, hash);
|
||||
HASH(data, len, hash);
|
||||
t = ktime_get_ns() - t;
|
||||
preempt_enable();
|
||||
kunit_info(test, "len=%zu: %llu MB/s", len,
|
||||
|
||||
@@ -30,8 +30,6 @@ static struct kunit_case hash_test_cases[] = {
|
||||
static struct kunit_suite hash_test_suite = {
|
||||
.name = "md5",
|
||||
.test_cases = hash_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(hash_test_suite);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <kunit/test.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/unaligned.h>
|
||||
#include "test-utils.h"
|
||||
|
||||
#define Q 8380417 /* The prime q = 2^23 - 2^13 + 1 */
|
||||
|
||||
@@ -60,14 +61,6 @@ static void do_mldsa_and_assert_success(struct kunit *test,
|
||||
KUNIT_ASSERT_EQ(test, err, 0);
|
||||
}
|
||||
|
||||
static u8 *kunit_kmemdup_or_fail(struct kunit *test, const u8 *src, size_t len)
|
||||
{
|
||||
u8 *dst = kunit_kmalloc(test, len, GFP_KERNEL);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, dst);
|
||||
return memcpy(dst, src, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that changing coefficients in a valid signature's z vector results in
|
||||
* the following behavior from mldsa_verify():
|
||||
@@ -83,7 +76,7 @@ static u8 *kunit_kmemdup_or_fail(struct kunit *test, const u8 *src, size_t len)
|
||||
static void test_mldsa_z_range(struct kunit *test,
|
||||
const struct mldsa_testvector *tv)
|
||||
{
|
||||
u8 *sig = kunit_kmemdup_or_fail(test, tv->sig, tv->sig_len);
|
||||
u8 *sig = memdup_buf(test, tv->sig, tv->sig_len);
|
||||
const int lambda = params[tv->alg].lambda;
|
||||
const s32 gamma1 = params[tv->alg].gamma1;
|
||||
const int beta = params[tv->alg].beta;
|
||||
@@ -146,7 +139,7 @@ static void test_mldsa_bad_hints(struct kunit *test,
|
||||
{
|
||||
const int omega = params[tv->alg].omega;
|
||||
const int k = params[tv->alg].k;
|
||||
u8 *sig = kunit_kmemdup_or_fail(test, tv->sig, tv->sig_len);
|
||||
u8 *sig = memdup_buf(test, tv->sig, tv->sig_len);
|
||||
/* Pointer to the encoded hint vector in the signature */
|
||||
u8 *hintvec = &sig[tv->sig_len - omega - k];
|
||||
u8 h;
|
||||
@@ -202,9 +195,9 @@ static void test_mldsa_mutation(struct kunit *test,
|
||||
const int msg_len = tv->msg_len;
|
||||
const int pk_len = tv->pk_len;
|
||||
const int num_iter = 200;
|
||||
u8 *sig = kunit_kmemdup_or_fail(test, tv->sig, sig_len);
|
||||
u8 *msg = kunit_kmemdup_or_fail(test, tv->msg, msg_len);
|
||||
u8 *pk = kunit_kmemdup_or_fail(test, tv->pk, pk_len);
|
||||
u8 *sig = memdup_buf(test, tv->sig, sig_len);
|
||||
u8 *msg = memdup_buf(test, tv->msg, msg_len);
|
||||
u8 *pk = memdup_buf(test, tv->pk, pk_len);
|
||||
|
||||
/* Initially the signature is valid. */
|
||||
do_mldsa_and_assert_success(test, tv);
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
#include <crypto/nh.h>
|
||||
#include <kunit/test.h>
|
||||
#include "nh-testvecs.h"
|
||||
#include "test-utils.h"
|
||||
|
||||
static void test_nh(struct kunit *test)
|
||||
{
|
||||
u32 *key = kunit_kmalloc(test, NH_KEY_BYTES, GFP_KERNEL);
|
||||
u32 *key = memdup_buf(test, nh_test_key, NH_KEY_BYTES);
|
||||
__le64 hash[NH_NUM_PASSES];
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, key);
|
||||
memcpy(key, nh_test_key, NH_KEY_BYTES);
|
||||
le32_to_cpu_array(key, NH_KEY_WORDS);
|
||||
|
||||
nh(key, nh_test_msg, 16, hash);
|
||||
|
||||
@@ -46,12 +46,7 @@ static void poly1305_withtestkey(const u8 *data, size_t len,
|
||||
static int poly1305_suite_init(struct kunit_suite *suite)
|
||||
{
|
||||
rand_bytes_seeded_from_len(test_key, POLY1305_KEY_SIZE);
|
||||
return hash_suite_init(suite);
|
||||
}
|
||||
|
||||
static void poly1305_suite_exit(struct kunit_suite *suite)
|
||||
{
|
||||
hash_suite_exit(suite);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,19 +76,20 @@ static void poly1305_suite_exit(struct kunit_suite *suite)
|
||||
*/
|
||||
static void test_poly1305_allones_keys_and_message(struct kunit *test)
|
||||
{
|
||||
const size_t max_len = 4096;
|
||||
u8 *data = alloc_buf(test, max_len);
|
||||
struct poly1305_desc_ctx mac_ctx, macofmacs_ctx;
|
||||
u8 mac[POLY1305_DIGEST_SIZE];
|
||||
|
||||
static_assert(TEST_BUF_LEN >= 4096);
|
||||
memset(test_buf, 0xff, 4096);
|
||||
memset(data, 0xff, max_len);
|
||||
|
||||
poly1305_init(&mac_ctx, test_buf);
|
||||
poly1305_init(&macofmacs_ctx, test_buf);
|
||||
poly1305_init(&mac_ctx, data);
|
||||
poly1305_init(&macofmacs_ctx, data);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
for (size_t len = 0; len <= 4096; len += 16) {
|
||||
for (size_t len = 0; len <= max_len; len += 16) {
|
||||
struct poly1305_desc_ctx tmp_ctx;
|
||||
|
||||
poly1305_update(&mac_ctx, test_buf, len);
|
||||
poly1305_update(&mac_ctx, data, len);
|
||||
tmp_ctx = mac_ctx;
|
||||
poly1305_final(&tmp_ctx, mac);
|
||||
poly1305_update(&macofmacs_ctx, mac,
|
||||
@@ -157,7 +153,6 @@ static struct kunit_suite poly1305_test_suite = {
|
||||
.name = "poly1305",
|
||||
.test_cases = poly1305_test_cases,
|
||||
.suite_init = poly1305_suite_init,
|
||||
.suite_exit = poly1305_suite_exit,
|
||||
};
|
||||
kunit_test_suite(poly1305_test_suite);
|
||||
|
||||
|
||||
@@ -66,17 +66,18 @@ static void test_polyval_rfc8452_testvec(struct kunit *test)
|
||||
*/
|
||||
static void test_polyval_allones_key_and_message(struct kunit *test)
|
||||
{
|
||||
const size_t max_len = 4096;
|
||||
u8 *data = alloc_buf(test, max_len);
|
||||
struct polyval_key key;
|
||||
struct polyval_ctx hashofhashes_ctx;
|
||||
u8 hash[POLYVAL_BLOCK_SIZE];
|
||||
|
||||
static_assert(TEST_BUF_LEN >= 4096);
|
||||
memset(test_buf, 0xff, 4096);
|
||||
memset(data, 0xff, max_len);
|
||||
|
||||
polyval_preparekey(&key, test_buf);
|
||||
polyval_preparekey(&key, data);
|
||||
polyval_init(&hashofhashes_ctx, &key);
|
||||
for (size_t len = 0; len <= 4096; len += 16) {
|
||||
polyval(&key, test_buf, len, hash);
|
||||
for (size_t len = 0; len <= max_len; len += 16) {
|
||||
polyval(&key, data, len, hash);
|
||||
polyval_update(&hashofhashes_ctx, hash, sizeof(hash));
|
||||
}
|
||||
polyval_final(&hashofhashes_ctx, hash);
|
||||
@@ -95,7 +96,7 @@ static void check_key_consistency(struct kunit *test,
|
||||
const struct polyval_key *key1,
|
||||
const struct polyval_key *key2)
|
||||
{
|
||||
u8 *data = test_buf;
|
||||
u8 *data = alloc_buf(test, MAX_LEN_FOR_KEY_CHECK);
|
||||
u8 hash1[POLYVAL_BLOCK_SIZE];
|
||||
u8 hash2[POLYVAL_BLOCK_SIZE];
|
||||
|
||||
@@ -115,10 +116,10 @@ static void check_key_consistency(struct kunit *test,
|
||||
static void test_polyval_with_guarded_key(struct kunit *test)
|
||||
{
|
||||
u8 raw_key[POLYVAL_BLOCK_SIZE];
|
||||
u8 *guarded_raw_key = &test_buf[TEST_BUF_LEN - sizeof(raw_key)];
|
||||
u8 *guarded_raw_key = alloc_guarded_buf(test, sizeof(raw_key));
|
||||
struct polyval_key key1, key2;
|
||||
struct polyval_key *guarded_key =
|
||||
(struct polyval_key *)&test_buf[TEST_BUF_LEN - sizeof(key1)];
|
||||
alloc_guarded_buf(test, sizeof(*guarded_key));
|
||||
|
||||
/* Prepare with regular buffers. */
|
||||
rand_bytes(raw_key, sizeof(raw_key));
|
||||
@@ -137,21 +138,20 @@ static void test_polyval_with_guarded_key(struct kunit *test)
|
||||
/*
|
||||
* Test that polyval_key only needs to be aligned to
|
||||
* __alignof__(struct polyval_key), i.e. 8 bytes. The assembly code may prefer
|
||||
* 16-byte or higher alignment, but it musn't require it.
|
||||
* 16-byte or higher alignment, but it mustn't require it.
|
||||
*/
|
||||
static void test_polyval_with_minimally_aligned_key(struct kunit *test)
|
||||
{
|
||||
u8 raw_key[POLYVAL_BLOCK_SIZE];
|
||||
struct polyval_key key;
|
||||
const size_t align = __alignof__(struct polyval_key);
|
||||
u8 *key_buf = alloc_buf(test, sizeof(struct polyval_key) + 3 * align);
|
||||
struct polyval_key *minaligned_key =
|
||||
(struct polyval_key *)&test_buf[MAX_LEN_FOR_KEY_CHECK +
|
||||
__alignof__(struct polyval_key)];
|
||||
(struct polyval_key *)(PTR_ALIGN(key_buf, 2 * align) + align);
|
||||
|
||||
KUNIT_ASSERT_TRUE(test, IS_ALIGNED((uintptr_t)minaligned_key,
|
||||
__alignof__(struct polyval_key)));
|
||||
KUNIT_ASSERT_TRUE(test, IS_ALIGNED((uintptr_t)minaligned_key, align));
|
||||
KUNIT_ASSERT_TRUE(test,
|
||||
!IS_ALIGNED((uintptr_t)minaligned_key,
|
||||
2 * __alignof__(struct polyval_key)));
|
||||
!IS_ALIGNED((uintptr_t)minaligned_key, 2 * align));
|
||||
|
||||
rand_bytes(raw_key, sizeof(raw_key));
|
||||
polyval_preparekey(&key, raw_key);
|
||||
@@ -192,12 +192,7 @@ static int polyval_suite_init(struct kunit_suite *suite)
|
||||
|
||||
rand_bytes_seeded_from_len(raw_key, sizeof(raw_key));
|
||||
polyval_preparekey(&test_key, raw_key);
|
||||
return hash_suite_init(suite);
|
||||
}
|
||||
|
||||
static void polyval_suite_exit(struct kunit_suite *suite)
|
||||
{
|
||||
hash_suite_exit(suite);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct kunit_case polyval_test_cases[] = {
|
||||
@@ -215,7 +210,6 @@ static struct kunit_suite polyval_test_suite = {
|
||||
.name = "polyval",
|
||||
.test_cases = polyval_test_cases,
|
||||
.suite_init = polyval_suite_init,
|
||||
.suite_exit = polyval_suite_exit,
|
||||
};
|
||||
kunit_test_suite(polyval_test_suite);
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@ static struct kunit_case hash_test_cases[] = {
|
||||
static struct kunit_suite hash_test_suite = {
|
||||
.name = "sha1",
|
||||
.test_cases = hash_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(hash_test_suite);
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@ static struct kunit_case hash_test_cases[] = {
|
||||
static struct kunit_suite hash_test_suite = {
|
||||
.name = "sha224",
|
||||
.test_cases = hash_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(hash_test_suite);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
#include <crypto/sha2.h>
|
||||
#include "sha256-testvecs.h"
|
||||
#include "test-utils.h"
|
||||
|
||||
/* Generate the HASH_KUNIT_CASES using hash-test-template.h. */
|
||||
#define HASH sha256
|
||||
@@ -22,26 +23,6 @@
|
||||
#define HMAC_USINGRAWKEY hmac_sha256_usingrawkey
|
||||
#include "hash-test-template.h"
|
||||
|
||||
static void free_guarded_buf(void *buf)
|
||||
{
|
||||
vfree(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a KUnit-managed buffer that has length @len bytes immediately
|
||||
* followed by an unmapped page, and assert that the allocation succeeds.
|
||||
*/
|
||||
static void *alloc_guarded_buf(struct kunit *test, size_t len)
|
||||
{
|
||||
size_t full_len = round_up(len, PAGE_SIZE);
|
||||
void *buf = vmalloc(full_len);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, buf);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, free_guarded_buf, buf));
|
||||
return buf + full_len - len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for sha256_finup_2x(). Specifically, choose various data lengths and
|
||||
* salt lengths, and for each one, verify that sha256_finup_2x() produces the
|
||||
@@ -105,19 +86,20 @@ static void test_sha256_finup_2x(struct kunit *test)
|
||||
static void test_sha256_finup_2x_defaultctx(struct kunit *test)
|
||||
{
|
||||
const size_t data_len = 128;
|
||||
u8 *data = alloc_buf(test, 2 * data_len);
|
||||
struct sha256_ctx ctx;
|
||||
u8 hash1_a[SHA256_DIGEST_SIZE];
|
||||
u8 hash2_a[SHA256_DIGEST_SIZE];
|
||||
u8 hash1_b[SHA256_DIGEST_SIZE];
|
||||
u8 hash2_b[SHA256_DIGEST_SIZE];
|
||||
|
||||
rand_bytes(test_buf, 2 * data_len);
|
||||
rand_bytes(data, 2 * data_len);
|
||||
|
||||
sha256_init(&ctx);
|
||||
sha256_finup_2x(&ctx, test_buf, &test_buf[data_len], data_len, hash1_a,
|
||||
sha256_finup_2x(&ctx, data, &data[data_len], data_len, hash1_a,
|
||||
hash2_a);
|
||||
|
||||
sha256_finup_2x(NULL, test_buf, &test_buf[data_len], data_len, hash1_b,
|
||||
sha256_finup_2x(NULL, data, &data[data_len], data_len, hash1_b,
|
||||
hash2_b);
|
||||
|
||||
KUNIT_ASSERT_MEMEQ(test, hash1_a, hash1_b, SHA256_DIGEST_SIZE);
|
||||
@@ -131,18 +113,19 @@ static void test_sha256_finup_2x_defaultctx(struct kunit *test)
|
||||
static void test_sha256_finup_2x_hugelen(struct kunit *test)
|
||||
{
|
||||
const size_t data_len = 4 * SHA256_BLOCK_SIZE;
|
||||
u8 *data = alloc_buf(test, data_len);
|
||||
struct sha256_ctx ctx = {};
|
||||
u8 expected_hash[SHA256_DIGEST_SIZE];
|
||||
u8 hash[SHA256_DIGEST_SIZE];
|
||||
|
||||
rand_bytes(test_buf, data_len);
|
||||
rand_bytes(data, data_len);
|
||||
for (size_t align = 0; align < SHA256_BLOCK_SIZE; align++) {
|
||||
sha256_init(&ctx);
|
||||
ctx.ctx.bytecount = 0x123456789abcd00 + align;
|
||||
|
||||
sha256_finup_2x(&ctx, test_buf, test_buf, data_len, hash, hash);
|
||||
sha256_finup_2x(&ctx, data, data, data_len, hash, hash);
|
||||
|
||||
sha256_update(&ctx, test_buf, data_len);
|
||||
sha256_update(&ctx, data, data_len);
|
||||
sha256_final(&ctx, expected_hash);
|
||||
|
||||
KUNIT_ASSERT_MEMEQ(test, hash, expected_hash,
|
||||
@@ -161,6 +144,7 @@ static void benchmark_sha256_finup_2x(struct kunit *test)
|
||||
static const size_t salt_lens_to_test[] = { 0, 32, 64 };
|
||||
const size_t data_len = 4096;
|
||||
const size_t num_iters = 4096;
|
||||
u8 *data = alloc_buf(test, data_len * 2);
|
||||
struct sha256_ctx ctx;
|
||||
u8 hash1[SHA256_DIGEST_SIZE];
|
||||
u8 hash2[SHA256_DIGEST_SIZE];
|
||||
@@ -170,12 +154,12 @@ static void benchmark_sha256_finup_2x(struct kunit *test)
|
||||
if (!sha256_finup_2x_is_optimized())
|
||||
kunit_skip(test, "not relevant");
|
||||
|
||||
rand_bytes(test_buf, data_len * 2);
|
||||
rand_bytes(data, data_len * 2);
|
||||
|
||||
/* Warm-up */
|
||||
for (size_t i = 0; i < num_iters; i++)
|
||||
sha256_finup_2x(NULL, &test_buf[0], &test_buf[data_len],
|
||||
data_len, hash1, hash2);
|
||||
sha256_finup_2x(NULL, &data[0], &data[data_len], data_len,
|
||||
hash1, hash2);
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(salt_lens_to_test); i++) {
|
||||
size_t salt_len = salt_lens_to_test[i];
|
||||
@@ -186,12 +170,12 @@ static void benchmark_sha256_finup_2x(struct kunit *test)
|
||||
* not measured; we're just interested in sha256_finup_2x().
|
||||
*/
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, test_buf, salt_len);
|
||||
sha256_update(&ctx, data, salt_len);
|
||||
|
||||
preempt_disable();
|
||||
t0 = ktime_get_ns();
|
||||
for (size_t j = 0; j < num_iters; j++)
|
||||
sha256_finup_2x(&ctx, &test_buf[0], &test_buf[data_len],
|
||||
sha256_finup_2x(&ctx, &data[0], &data[data_len],
|
||||
data_len, hash1, hash2);
|
||||
t1 = ktime_get_ns();
|
||||
preempt_enable();
|
||||
@@ -215,8 +199,6 @@ static struct kunit_case hash_test_cases[] = {
|
||||
static struct kunit_suite hash_test_suite = {
|
||||
.name = "sha256",
|
||||
.test_cases = hash_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(hash_test_suite);
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@ static struct kunit_case hash_test_cases[] = {
|
||||
static struct kunit_suite hash_test_suite = {
|
||||
.name = "sha384",
|
||||
.test_cases = hash_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(hash_test_suite);
|
||||
|
||||
|
||||
@@ -273,12 +273,10 @@ static void test_shake_all_lens_up_to_4096(struct kunit *test)
|
||||
{
|
||||
struct sha3_ctx main_ctx;
|
||||
const size_t max_len = 4096;
|
||||
u8 *const in = test_buf;
|
||||
u8 *const out = &test_buf[TEST_BUF_LEN - max_len];
|
||||
u8 *const in = alloc_buf(test, max_len);
|
||||
u8 *const out = alloc_buf(test, max_len);
|
||||
u8 main_hash[SHA3_256_DIGEST_SIZE];
|
||||
|
||||
KUNIT_ASSERT_LE(test, 2 * max_len, TEST_BUF_LEN);
|
||||
|
||||
rand_bytes_seeded_from_len(in, max_len);
|
||||
for (int alg = 0; alg < 2; alg++) {
|
||||
sha3_256_init(&main_ctx);
|
||||
@@ -309,12 +307,8 @@ static void test_shake_all_lens_up_to_4096(struct kunit *test)
|
||||
static void test_shake_multiple_squeezes(struct kunit *test)
|
||||
{
|
||||
const size_t max_len = 512;
|
||||
u8 *ref_out;
|
||||
|
||||
KUNIT_ASSERT_GE(test, TEST_BUF_LEN, 2 * max_len);
|
||||
|
||||
ref_out = kunit_kzalloc(test, max_len, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, ref_out);
|
||||
u8 *buf = alloc_buf(test, max_len);
|
||||
u8 *ref_out = alloc_buf(test, max_len);
|
||||
|
||||
for (int i = 0; i < 2000; i++) {
|
||||
const int alg = rand32() % 2;
|
||||
@@ -322,8 +316,8 @@ static void test_shake_multiple_squeezes(struct kunit *test)
|
||||
const size_t out_len = rand_length(max_len);
|
||||
const size_t in_offs = rand_offset(max_len - in_len);
|
||||
const size_t out_offs = rand_offset(max_len - out_len);
|
||||
u8 *const in = &test_buf[in_offs];
|
||||
u8 *const out = &test_buf[out_offs];
|
||||
u8 *const in = &buf[in_offs];
|
||||
u8 *const out = &buf[out_offs];
|
||||
struct shake_ctx ctx;
|
||||
size_t remaining_len, j, num_parts;
|
||||
|
||||
@@ -368,16 +362,12 @@ static void test_shake_multiple_squeezes(struct kunit *test)
|
||||
static void test_shake_with_guarded_bufs(struct kunit *test)
|
||||
{
|
||||
const size_t max_len = 512;
|
||||
u8 *reg_buf;
|
||||
|
||||
KUNIT_ASSERT_GE(test, TEST_BUF_LEN, max_len);
|
||||
|
||||
reg_buf = kunit_kzalloc(test, max_len, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, reg_buf);
|
||||
u8 *buf = alloc_guarded_buf(test, max_len);
|
||||
u8 *reg_buf = alloc_buf(test, max_len);
|
||||
|
||||
for (int alg = 0; alg < 2; alg++) {
|
||||
for (size_t len = 0; len <= max_len; len++) {
|
||||
u8 *guarded_buf = &test_buf[TEST_BUF_LEN - len];
|
||||
u8 *guarded_buf = &buf[max_len - len];
|
||||
|
||||
rand_bytes(reg_buf, len);
|
||||
memcpy(guarded_buf, reg_buf, len);
|
||||
@@ -413,8 +403,6 @@ static struct kunit_case sha3_test_cases[] = {
|
||||
static struct kunit_suite sha3_test_suite = {
|
||||
.name = "sha3",
|
||||
.test_cases = sha3_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(sha3_test_suite);
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@ static struct kunit_case hash_test_cases[] = {
|
||||
static struct kunit_suite hash_test_suite = {
|
||||
.name = "sha512",
|
||||
.test_cases = hash_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(hash_test_suite);
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@ static struct kunit_case sm3_test_cases[] = {
|
||||
static struct kunit_suite sm3_test_suite = {
|
||||
.name = "sm3",
|
||||
.test_cases = sm3_test_cases,
|
||||
.suite_init = hash_suite_init,
|
||||
.suite_exit = hash_suite_exit,
|
||||
};
|
||||
kunit_test_suite(sm3_test_suite);
|
||||
|
||||
|
||||
111
lib/crypto/tests/test-utils.h
Normal file
111
lib/crypto/tests/test-utils.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Test utility functions shared by the crypto library tests.
|
||||
*
|
||||
* For now this is simply a header that's included into the KUnit test suites
|
||||
* that need it. If this gets too large it could be made its own translation
|
||||
* unit and libcrypto_test_utils module, but that seems overkill for now.
|
||||
*/
|
||||
#ifndef LIB_CRYPTO_TEST_UTILS_H
|
||||
#define LIB_CRYPTO_TEST_UTILS_H
|
||||
|
||||
#include <kunit/test.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
static u64 random_seed;
|
||||
|
||||
static __maybe_unused void action_free_guarded_buf(void *buf)
|
||||
{
|
||||
vfree(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a KUnit-managed buffer that has length @size bytes (> 0) immediately
|
||||
* followed by an unmapped page, and assert that the allocation succeeds.
|
||||
*/
|
||||
static __maybe_unused void *alloc_guarded_buf(struct kunit *test, size_t size)
|
||||
{
|
||||
size_t full_size = round_up(size, PAGE_SIZE);
|
||||
void *buf = vmalloc(full_size);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, buf);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, action_free_guarded_buf,
|
||||
buf));
|
||||
return buf + full_size - size;
|
||||
}
|
||||
|
||||
static __maybe_unused void *alloc_buf(struct kunit *test, size_t size)
|
||||
{
|
||||
void *buf = kunit_kmalloc(test, size, GFP_KERNEL);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static __maybe_unused void *memdup_buf(struct kunit *test, const void *src,
|
||||
size_t size)
|
||||
{
|
||||
void *dst = alloc_buf(test, size);
|
||||
|
||||
return memcpy(dst, src, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a simple linear congruential generator. It is used only for testing,
|
||||
* which does not require cryptographically secure random numbers. A hard-coded
|
||||
* algorithm is used instead of <linux/prandom.h> so that it matches the
|
||||
* algorithm used by the test vector generation script. This allows the input
|
||||
* data in random test vectors to be concisely stored as just the seed.
|
||||
*/
|
||||
static __maybe_unused u32 rand32(void)
|
||||
{
|
||||
random_seed = (random_seed * 25214903917 + 11) & ((1ULL << 48) - 1);
|
||||
return random_seed >> 16;
|
||||
}
|
||||
|
||||
static __maybe_unused void rand_bytes(u8 *out, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++)
|
||||
out[i] = rand32();
|
||||
}
|
||||
|
||||
static __maybe_unused void rand_bytes_seeded_from_len(u8 *out, size_t len)
|
||||
{
|
||||
random_seed = len;
|
||||
rand_bytes(out, len);
|
||||
}
|
||||
|
||||
static __maybe_unused bool rand_bool(void)
|
||||
{
|
||||
return rand32() % 2;
|
||||
}
|
||||
|
||||
/* Generate a random length, preferring small lengths. */
|
||||
static __maybe_unused size_t rand_length(size_t max_len)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
switch (rand32() % 3) {
|
||||
case 0:
|
||||
len = rand32() % 128;
|
||||
break;
|
||||
case 1:
|
||||
len = rand32() % 3072;
|
||||
break;
|
||||
default:
|
||||
len = rand32();
|
||||
break;
|
||||
}
|
||||
return len % (max_len + 1);
|
||||
}
|
||||
|
||||
static __maybe_unused size_t rand_offset(size_t max_offset)
|
||||
{
|
||||
return min(rand32() % 128, max_offset);
|
||||
}
|
||||
|
||||
#endif /* LIB_CRYPTO_TEST_UTILS_H */
|
||||
69
scripts/crypto/gen-aead-testvecs.py
Executable file
69
scripts/crypto/gen-aead-testvecs.py
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/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)
|
||||
elif alg == "aes-gcm":
|
||||
key_len = [16, 24, 32][data_len % 3]
|
||||
key = rand_bytes(key_len)
|
||||
nonce = rand_bytes(12)
|
||||
tag_len = [4, 8, 12, 13, 14, 15, 16][data_len % 7]
|
||||
gcm = cryptography.hazmat.primitives.ciphers.aead.AESGCM(key)
|
||||
# python-cryptography supports only 16-byte GCM tags. However, in
|
||||
# GCM, shorter tags are simply truncated. Do that below.
|
||||
ct_and_tag = gcm.encrypt(nonce, pt, ad)[: data_len + tag_len]
|
||||
|
||||
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", "aes-gcm"):
|
||||
sys.stderr.write("Usage: gen-aead-testvecs.py [aes-ccm|aes-gcm]\n")
|
||||
sys.exit(1)
|
||||
|
||||
gen_monte_carlo_checksum(sys.argv[1])
|
||||
@@ -1,46 +1,148 @@
|
||||
#!/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.
|
||||
#
|
||||
# Copyright 2025 Google LLC
|
||||
|
||||
import cryptography.hazmat.primitives.ciphers
|
||||
import cryptography.hazmat.primitives.ciphers.aead
|
||||
import cryptography.hazmat.primitives.cmac
|
||||
import hashlib
|
||||
import hmac
|
||||
|
||||
fips_test_data = b"fips test data\0\0"
|
||||
fips_test_key = b"fips test key\0\0\0"
|
||||
|
||||
def print_static_u8_array_definition(name, value):
|
||||
print('')
|
||||
print(f'static const u8 {name}[] __initconst __maybe_unused = {{')
|
||||
def print_static_u8_array_definition(file, name, value):
|
||||
print("", file=file)
|
||||
print(f"static const u8 {name}[] __initconst __maybe_unused = {{", file=file)
|
||||
for i in range(0, len(value), 8):
|
||||
line = '\t' + ''.join(f'0x{b:02x}, ' for b in value[i:i+8])
|
||||
print(f'{line.rstrip()}')
|
||||
print('};')
|
||||
line = "\t" + "".join(f"0x{b:02x}, " for b in value[i : i + 8])
|
||||
print(f"{line.rstrip()}", file=file)
|
||||
print("};", file=file)
|
||||
|
||||
print('/* SPDX-License-Identifier: GPL-2.0-or-later */')
|
||||
print(f'/* This file was generated by: gen-fips-testvecs.py */')
|
||||
print()
|
||||
print('#include <linux/fips.h>')
|
||||
|
||||
print_static_u8_array_definition("fips_test_data", fips_test_data)
|
||||
print_static_u8_array_definition("fips_test_key", fips_test_key)
|
||||
def print_header(file):
|
||||
print("/* SPDX-License-Identifier: GPL-2.0-or-later */", file=file)
|
||||
print("/* This file was generated by: gen-fips-testvecs.py */", file=file)
|
||||
print("/* clang-format off */", file=file)
|
||||
print("", file=file)
|
||||
print("#include <linux/fips.h>", file=file)
|
||||
|
||||
for alg in 'sha1', 'sha256', 'sha512':
|
||||
ctx = hmac.new(fips_test_key, digestmod=alg)
|
||||
ctx.update(fips_test_data)
|
||||
print_static_u8_array_definition(f'fips_test_hmac_{alg}_value', ctx.digest())
|
||||
|
||||
print_static_u8_array_definition(f'fips_test_sha3_256_value',
|
||||
hashlib.sha3_256(fips_test_data).digest())
|
||||
def gen_aes_test_data(file):
|
||||
fips_test_data = b"fips test data\0\0"
|
||||
fips_test_ad = b"fips test ad\0\0\0\0"
|
||||
fips_test_iv = b"fips test iv\0\0\0\0"
|
||||
fips_test_key = b"fips test key\0\0\0"
|
||||
fips_test_xts_key = b"key1" + (b"\0" * 12) + b"key2" + (b"\0" * 12)
|
||||
|
||||
aes = cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_test_key)
|
||||
aes_cmac = 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())
|
||||
print_header(file)
|
||||
print_static_u8_array_definition(file, "fips_test_data", fips_test_data)
|
||||
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)
|
||||
|
||||
aes = cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_test_key)
|
||||
|
||||
# AES-CMAC
|
||||
aes_cmac = 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()
|
||||
)
|
||||
|
||||
# AES-ECB
|
||||
cipher = cryptography.hazmat.primitives.ciphers.Cipher(
|
||||
aes, cryptography.hazmat.primitives.ciphers.modes.ECB()
|
||||
)
|
||||
encryptor = cipher.encryptor()
|
||||
ctext = encryptor.update(fips_test_data) + encryptor.finalize()
|
||||
print_static_u8_array_definition(file, "fips_test_aes_ecb_ctext", ctext)
|
||||
|
||||
# AES-CBC
|
||||
cipher = cryptography.hazmat.primitives.ciphers.Cipher(
|
||||
aes, cryptography.hazmat.primitives.ciphers.modes.CBC(fips_test_iv)
|
||||
)
|
||||
encryptor = cipher.encryptor()
|
||||
ctext = encryptor.update(fips_test_data) + encryptor.finalize()
|
||||
print_static_u8_array_definition(file, "fips_test_aes_cbc_ctext", ctext)
|
||||
|
||||
# AES-CBC-CTS
|
||||
cipher = cryptography.hazmat.primitives.ciphers.Cipher(
|
||||
aes, cryptography.hazmat.primitives.ciphers.modes.CBC(fips_test_iv)
|
||||
)
|
||||
encryptor = cipher.encryptor()
|
||||
ctext = encryptor.update(fips_test_data * 2) + encryptor.finalize()
|
||||
ctext = ctext[16:32] + ctext[0:16]
|
||||
print_static_u8_array_definition(file, "fips_test_aes_cbc_cts_ctext", ctext)
|
||||
|
||||
# AES-CTR
|
||||
cipher = cryptography.hazmat.primitives.ciphers.Cipher(
|
||||
aes, cryptography.hazmat.primitives.ciphers.modes.CTR(fips_test_iv)
|
||||
)
|
||||
encryptor = cipher.encryptor()
|
||||
ctext = encryptor.update(fips_test_data) + encryptor.finalize()
|
||||
print_static_u8_array_definition(file, "fips_test_aes_ctr_ctext", ctext)
|
||||
|
||||
# AES-XTS
|
||||
cipher = cryptography.hazmat.primitives.ciphers.Cipher(
|
||||
cryptography.hazmat.primitives.ciphers.algorithms.AES(fips_test_xts_key),
|
||||
cryptography.hazmat.primitives.ciphers.modes.XTS(fips_test_iv),
|
||||
)
|
||||
encryptor = cipher.encryptor()
|
||||
ctext = encryptor.update(fips_test_data) + encryptor.finalize()
|
||||
print_static_u8_array_definition(file, "fips_test_aes_xts_ctext", ctext)
|
||||
|
||||
# AES-GCM
|
||||
cipher = cryptography.hazmat.primitives.ciphers.aead.AESGCM(fips_test_key)
|
||||
ct_and_tag = cipher.encrypt(
|
||||
nonce=fips_test_iv[:12], data=fips_test_data, associated_data=fips_test_ad
|
||||
)
|
||||
print_static_u8_array_definition(
|
||||
file, "fips_test_aes_gcm_ctext_and_tag", ct_and_tag
|
||||
)
|
||||
|
||||
# AES-CCM
|
||||
cipher = cryptography.hazmat.primitives.ciphers.aead.AESCCM(
|
||||
fips_test_key, tag_length=16
|
||||
)
|
||||
ct_and_tag = cipher.encrypt(
|
||||
nonce=fips_test_iv[:13], data=fips_test_data, associated_data=fips_test_ad
|
||||
)
|
||||
print_static_u8_array_definition(
|
||||
file, "fips_test_aes_ccm_ctext_and_tag", ct_and_tag
|
||||
)
|
||||
|
||||
|
||||
def gen_sha_test_data(file):
|
||||
fips_test_data = b"fips test data\0\0"
|
||||
fips_test_key = b"fips test key\0\0\0"
|
||||
|
||||
print_header(file)
|
||||
print_static_u8_array_definition(file, "fips_test_data", fips_test_data)
|
||||
print_static_u8_array_definition(file, "fips_test_key", fips_test_key)
|
||||
|
||||
for alg in "sha1", "sha256", "sha512":
|
||||
ctx = hmac.new(fips_test_key, digestmod=alg)
|
||||
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 = "lib/crypto/fips-aes.h"
|
||||
with open(filename, "w") as file:
|
||||
print(f"Generating {filename}")
|
||||
gen_aes_test_data(file)
|
||||
|
||||
filename = "lib/crypto/fips-sha.h"
|
||||
with open(filename, "w") as file:
|
||||
print(f"Generating {filename}")
|
||||
gen_sha_test_data(file)
|
||||
|
||||
Reference in New Issue
Block a user