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 KUnit test suites for SHA-3, BLAKE2b, and POLYVAL. These are the
   algorithms that have new crypto library interfaces this cycle.

 - Remove the crypto_shash POLYVAL tests. They're no longer needed
   because POLYVAL support was removed from crypto_shash. Better POLYVAL
   test coverage is now provided via the KUnit test suite.

* tag 'libcrypto-tests-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux:
  crypto: testmgr - Remove polyval tests
  lib/crypto: tests: Add KUnit tests for POLYVAL
  lib/crypto: tests: Add additional SHAKE tests
  lib/crypto: tests: Add SHA3 kunit tests
  lib/crypto: tests: Add KUnit tests for BLAKE2b
This commit is contained in:
Linus Torvalds
2025-12-02 18:20:06 -08:00
13 changed files with 1682 additions and 198 deletions

View File

@@ -107,6 +107,17 @@ Once all the desired output has been extracted, zeroize the context::
void shake_zeroize_ctx(struct shake_ctx *ctx);
Testing
=======
To test the SHA-3 code, use sha3_kunit (CONFIG_CRYPTO_LIB_SHA3_KUNIT_TEST).
Since the SHA-3 algorithms are FIPS-approved, when the kernel is booted in FIPS
mode the SHA-3 library also performs a simple self-test. This is purely to meet
a FIPS requirement. Normal testing done by kernel developers and integrators
should use the much more comprehensive KUnit test suite instead.
References
==========

View File

@@ -1690,10 +1690,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
ret = min(ret, tcrypt_test("ccm(sm4)"));
break;
case 57:
ret = min(ret, tcrypt_test("polyval"));
break;
case 58:
ret = min(ret, tcrypt_test("gcm(aria)"));
break;

View File

@@ -5370,12 +5370,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.alg = "pkcs1pad(rsa)",
.test = alg_test_null,
.fips_allowed = 1,
}, {
.alg = "polyval",
.test = alg_test_hash,
.suite = {
.hash = __VECS(polyval_tv_template)
}
}, {
.alg = "rfc3686(ctr(aes))",
.test = alg_test_skcipher,

View File

@@ -36235,177 +36235,6 @@ static const struct cipher_testvec aes_xctr_tv_template[] = {
};
/*
* Test vectors generated using https://github.com/google/hctr2
*
* To ensure compatibility with RFC 8452, some tests were sourced from
* https://datatracker.ietf.org/doc/html/rfc8452
*/
static const struct hash_testvec polyval_tv_template[] = {
{ // From RFC 8452
.key = "\x31\x07\x28\xd9\x91\x1f\x1f\x38"
"\x37\xb2\x43\x16\xc3\xfa\xb9\xa0",
.plaintext = "\x65\x78\x61\x6d\x70\x6c\x65\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x48\x65\x6c\x6c\x6f\x20\x77\x6f"
"\x72\x6c\x64\x00\x00\x00\x00\x00"
"\x38\x00\x00\x00\x00\x00\x00\x00"
"\x58\x00\x00\x00\x00\x00\x00\x00",
.digest = "\xad\x7f\xcf\x0b\x51\x69\x85\x16"
"\x62\x67\x2f\x3c\x5f\x95\x13\x8f",
.psize = 48,
.ksize = 16,
},
{ // From RFC 8452
.key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
"\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
.plaintext = "\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00",
.digest = "\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00",
.psize = 16,
.ksize = 16,
},
{ // From RFC 8452
.key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
"\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
.plaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x40\x00\x00\x00\x00\x00\x00\x00",
.digest = "\xeb\x93\xb7\x74\x09\x62\xc5\xe4"
"\x9d\x2a\x90\xa7\xdc\x5c\xec\x74",
.psize = 32,
.ksize = 16,
},
{ // From RFC 8452
.key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
"\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
.plaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x02\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x03\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x80\x01\x00\x00\x00\x00\x00\x00",
.digest = "\x81\x38\x87\x46\xbc\x22\xd2\x6b"
"\x2a\xbc\x3d\xcb\x15\x75\x42\x22",
.psize = 64,
.ksize = 16,
},
{ // From RFC 8452
.key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
"\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
.plaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x02\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x03\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x04\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x02\x00\x00\x00\x00\x00\x00",
.digest = "\x1e\x39\xb6\xd3\x34\x4d\x34\x8f"
"\x60\x44\xf8\x99\x35\xd1\xcf\x78",
.psize = 80,
.ksize = 16,
},
{ // From RFC 8452
.key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
"\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
.plaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x02\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x03\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x04\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x05\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x08\x00\x00\x00\x00\x00\x00\x00"
"\x00\x02\x00\x00\x00\x00\x00\x00",
.digest = "\xff\xcd\x05\xd5\x77\x0f\x34\xad"
"\x92\x67\xf0\xa5\x99\x94\xb1\x5a",
.psize = 96,
.ksize = 16,
},
{ // Random ( 1)
.key = "\x90\xcc\xac\xee\xba\xd7\xd4\x68"
"\x98\xa6\x79\x70\xdf\x66\x15\x6c",
.plaintext = "",
.digest = "\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00",
.psize = 0,
.ksize = 16,
},
{ // Random ( 1)
.key = "\xc1\x45\x71\xf0\x30\x07\x94\xe7"
"\x3a\xdd\xe4\xc6\x19\x2d\x02\xa2",
.plaintext = "\xc1\x5d\x47\xc7\x4c\x7c\x5e\x07"
"\x85\x14\x8f\x79\xcc\x73\x83\xf7"
"\x35\xb8\xcb\x73\x61\xf0\x53\x31"
"\xbf\x84\xde\xb6\xde\xaf\xb0\xb8"
"\xb7\xd9\x11\x91\x89\xfd\x1e\x4c"
"\x84\x4a\x1f\x2a\x87\xa4\xaf\x62"
"\x8d\x7d\x58\xf6\x43\x35\xfc\x53"
"\x8f\x1a\xf6\x12\xe1\x13\x3f\x66"
"\x91\x4b\x13\xd6\x45\xfb\xb0\x7a"
"\xe0\x8b\x8e\x99\xf7\x86\x46\x37"
"\xd1\x22\x9e\x52\xf3\x3f\xd9\x75"
"\x2c\x2c\xc6\xbb\x0e\x08\x14\x29"
"\xe8\x50\x2f\xd8\xbe\xf4\xe9\x69"
"\x4a\xee\xf7\xae\x15\x65\x35\x1e",
.digest = "\x00\x4f\x5d\xe9\x3b\xc0\xd6\x50"
"\x3e\x38\x73\x86\xc6\xda\xca\x7f",
.psize = 112,
.ksize = 16,
},
{ // Random ( 1)
.key = "\x37\xbe\x68\x16\x50\xb9\x4e\xb0"
"\x47\xde\xe2\xbd\xde\xe4\x48\x09",
.plaintext = "\x87\xfc\x68\x9f\xff\xf2\x4a\x1e"
"\x82\x3b\x73\x8f\xc1\xb2\x1b\x7a"
"\x6c\x4f\x81\xbc\x88\x9b\x6c\xa3"
"\x9c\xc2\xa5\xbc\x14\x70\x4c\x9b"
"\x0c\x9f\x59\x92\x16\x4b\x91\x3d"
"\x18\x55\x22\x68\x12\x8c\x63\xb2"
"\x51\xcb\x85\x4b\xd2\xae\x0b\x1c"
"\x5d\x28\x9d\x1d\xb1\xc8\xf0\x77"
"\xe9\xb5\x07\x4e\x06\xc8\xee\xf8"
"\x1b\xed\x72\x2a\x55\x7d\x16\xc9"
"\xf2\x54\xe7\xe9\xe0\x44\x5b\x33"
"\xb1\x49\xee\xff\x43\xfb\x82\xcd"
"\x4a\x70\x78\x81\xa4\x34\x36\xe8"
"\x4c\x28\x54\xa6\x6c\xc3\x6b\x78"
"\xe7\xc0\x5d\xc6\x5d\x81\xab\x70"
"\x08\x86\xa1\xfd\xf4\x77\x55\xfd"
"\xa3\xe9\xe2\x1b\xdf\x99\xb7\x80"
"\xf9\x0a\x4f\x72\x4a\xd3\xaf\xbb"
"\xb3\x3b\xeb\x08\x58\x0f\x79\xce"
"\xa5\x99\x05\x12\x34\xd4\xf4\x86"
"\x37\x23\x1d\xc8\x49\xc0\x92\xae"
"\xa6\xac\x9b\x31\x55\xed\x15\xc6"
"\x05\x17\x37\x8d\x90\x42\xe4\x87"
"\x89\x62\x88\x69\x1c\x6a\xfd\xe3"
"\x00\x2b\x47\x1a\x73\xc1\x51\xc2"
"\xc0\x62\x74\x6a\x9e\xb2\xe5\x21"
"\xbe\x90\xb5\xb0\x50\xca\x88\x68"
"\xe1\x9d\x7a\xdf\x6c\xb7\xb9\x98"
"\xee\x28\x62\x61\x8b\xd1\x47\xf9"
"\x04\x7a\x0b\x5d\xcd\x2b\x65\xf5"
"\x12\xa3\xfe\x1a\xaa\x2c\x78\x42"
"\xb8\xbe\x7d\x74\xeb\x59\xba\xba",
.digest = "\xae\x11\xd4\x60\x2a\x5f\x9e\x42"
"\x89\x04\xc2\x34\x8d\x55\x94\x0a",
.psize = 256,
.ksize = 16,
},
};
/*
* Test vectors generated using https://github.com/google/hctr2
*/

View File

@@ -1,5 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later
config CRYPTO_LIB_BLAKE2B_KUNIT_TEST
tristate "KUnit tests for BLAKE2b" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
select CRYPTO_LIB_BENCHMARK_VISIBLE
select CRYPTO_LIB_BLAKE2B
help
KUnit tests for the BLAKE2b cryptographic hash function.
config CRYPTO_LIB_BLAKE2S_KUNIT_TEST
tristate "KUnit tests for BLAKE2s" if !KUNIT_ALL_TESTS
depends on KUNIT
@@ -38,6 +47,15 @@ config CRYPTO_LIB_POLY1305_KUNIT_TEST
help
KUnit tests for the Poly1305 library functions.
config CRYPTO_LIB_POLYVAL_KUNIT_TEST
tristate "KUnit tests for POLYVAL" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
select CRYPTO_LIB_BENCHMARK_VISIBLE
select CRYPTO_LIB_POLYVAL
help
KUnit tests for the POLYVAL library functions.
config CRYPTO_LIB_SHA1_KUNIT_TEST
tristate "KUnit tests for SHA-1" if !KUNIT_ALL_TESTS
depends on KUNIT
@@ -72,6 +90,17 @@ config CRYPTO_LIB_SHA512_KUNIT_TEST
KUnit tests for the SHA-384 and SHA-512 cryptographic hash functions
and their corresponding HMACs.
config CRYPTO_LIB_SHA3_KUNIT_TEST
tristate "KUnit tests for SHA-3" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
select CRYPTO_LIB_BENCHMARK_VISIBLE
select CRYPTO_LIB_SHA3
help
KUnit tests for the SHA3 cryptographic hash and XOF functions,
including SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128 and
SHAKE256.
config CRYPTO_LIB_BENCHMARK_VISIBLE
bool

View File

@@ -1,9 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-or-later
obj-$(CONFIG_CRYPTO_LIB_BLAKE2B_KUNIT_TEST) += blake2b_kunit.o
obj-$(CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST) += blake2s_kunit.o
obj-$(CONFIG_CRYPTO_LIB_CURVE25519_KUNIT_TEST) += curve25519_kunit.o
obj-$(CONFIG_CRYPTO_LIB_MD5_KUNIT_TEST) += md5_kunit.o
obj-$(CONFIG_CRYPTO_LIB_POLY1305_KUNIT_TEST) += poly1305_kunit.o
obj-$(CONFIG_CRYPTO_LIB_POLYVAL_KUNIT_TEST) += polyval_kunit.o
obj-$(CONFIG_CRYPTO_LIB_SHA1_KUNIT_TEST) += sha1_kunit.o
obj-$(CONFIG_CRYPTO_LIB_SHA256_KUNIT_TEST) += sha224_kunit.o sha256_kunit.o
obj-$(CONFIG_CRYPTO_LIB_SHA512_KUNIT_TEST) += sha384_kunit.o sha512_kunit.o
obj-$(CONFIG_CRYPTO_LIB_SHA3_KUNIT_TEST) += sha3_kunit.o

View File

@@ -0,0 +1,342 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py blake2b */
static const struct {
size_t data_len;
u8 digest[BLAKE2B_HASH_SIZE];
} hash_testvecs[] = {
{
.data_len = 0,
.digest = {
0x78, 0x6a, 0x02, 0xf7, 0x42, 0x01, 0x59, 0x03,
0xc6, 0xc6, 0xfd, 0x85, 0x25, 0x52, 0xd2, 0x72,
0x91, 0x2f, 0x47, 0x40, 0xe1, 0x58, 0x47, 0x61,
0x8a, 0x86, 0xe2, 0x17, 0xf7, 0x1f, 0x54, 0x19,
0xd2, 0x5e, 0x10, 0x31, 0xaf, 0xee, 0x58, 0x53,
0x13, 0x89, 0x64, 0x44, 0x93, 0x4e, 0xb0, 0x4b,
0x90, 0x3a, 0x68, 0x5b, 0x14, 0x48, 0xb7, 0x55,
0xd5, 0x6f, 0x70, 0x1a, 0xfe, 0x9b, 0xe2, 0xce,
},
},
{
.data_len = 1,
.digest = {
0x6f, 0x2e, 0xcc, 0x83, 0x53, 0xa3, 0x20, 0x16,
0x5b, 0xda, 0xd0, 0x04, 0xd3, 0xcb, 0xe4, 0x37,
0x5b, 0xf0, 0x84, 0x36, 0xe1, 0xad, 0x45, 0xcc,
0x4d, 0x7f, 0x09, 0x68, 0xb2, 0x62, 0x93, 0x7f,
0x72, 0x32, 0xe8, 0xa7, 0x2f, 0x1f, 0x6f, 0xc6,
0x14, 0xd6, 0x70, 0xae, 0x0c, 0xf0, 0xf3, 0xce,
0x64, 0x4d, 0x22, 0xdf, 0xc7, 0xa7, 0xf8, 0xa8,
0x18, 0x23, 0xd8, 0x6c, 0xaf, 0x65, 0xa2, 0x54,
},
},
{
.data_len = 2,
.digest = {
0x04, 0x13, 0xe2, 0x10, 0xbe, 0x65, 0xde, 0xce,
0x61, 0xa8, 0xe0, 0xd6, 0x35, 0xb1, 0xb8, 0x88,
0xd2, 0xea, 0x45, 0x3a, 0xe1, 0x8d, 0x94, 0xb5,
0x66, 0x06, 0x98, 0x96, 0x39, 0xf8, 0x0e, 0xcb,
0x34, 0xa6, 0xa8, 0x17, 0xfe, 0x56, 0xbc, 0xa9,
0x5e, 0x1b, 0xb1, 0xde, 0x3c, 0xc7, 0x78, 0x4f,
0x39, 0xc6, 0xfc, 0xa8, 0xb3, 0x27, 0x66, 0x3e,
0x4e, 0xb5, 0x5d, 0x08, 0x89, 0xee, 0xd1, 0xe0,
},
},
{
.data_len = 3,
.digest = {
0x2b, 0x4a, 0xa3, 0x4e, 0x2b, 0x7a, 0x47, 0x20,
0x30, 0x5b, 0x09, 0x17, 0x3a, 0xf4, 0xcc, 0xf0,
0xf7, 0x7b, 0x97, 0x68, 0x98, 0x9f, 0x4f, 0x09,
0x46, 0x25, 0xe7, 0xd6, 0x53, 0x6b, 0xf9, 0x68,
0x48, 0x12, 0x44, 0x8c, 0x9a, 0xc8, 0xd4, 0x42,
0xeb, 0x2c, 0x5f, 0x41, 0xba, 0x17, 0xd0, 0xc3,
0xad, 0xfd, 0xfb, 0x42, 0x33, 0xcb, 0x08, 0x5d,
0xd2, 0x5c, 0x3d, 0xde, 0x87, 0x4d, 0xd6, 0xe4,
},
},
{
.data_len = 16,
.digest = {
0xbf, 0x40, 0xf2, 0x38, 0x44, 0x8e, 0x24, 0x5e,
0xbc, 0x67, 0xbb, 0xf0, 0x10, 0x9a, 0x79, 0xbb,
0x36, 0x55, 0xce, 0xd2, 0xba, 0x04, 0x0d, 0xe8,
0x30, 0x29, 0x5c, 0x2a, 0xa6, 0x3a, 0x4f, 0x37,
0xac, 0x5f, 0xd4, 0x13, 0xa2, 0xf4, 0xfe, 0x80,
0x61, 0xd7, 0x58, 0x66, 0x0c, 0x7f, 0xa2, 0x56,
0x6b, 0x52, 0x7c, 0x22, 0x73, 0x7f, 0x17, 0xaa,
0x91, 0x5a, 0x22, 0x06, 0xd9, 0x00, 0x48, 0x12,
},
},
{
.data_len = 32,
.digest = {
0x41, 0x04, 0x65, 0x93, 0x81, 0x9a, 0x20, 0x0a,
0x00, 0x60, 0x00, 0x64, 0x4c, 0x04, 0x3d, 0xe0,
0x6b, 0x17, 0x0c, 0xe1, 0x0e, 0x28, 0x8b, 0xa0,
0x76, 0xd2, 0x79, 0xb0, 0x33, 0x60, 0x61, 0x27,
0xf2, 0x64, 0xf1, 0x8a, 0xe5, 0x3e, 0xaa, 0x37,
0x60, 0xad, 0x2d, 0x75, 0x13, 0xae, 0xd8, 0x9e,
0xec, 0xe0, 0xe4, 0x40, 0x2f, 0x59, 0x44, 0xb0,
0x66, 0x7a, 0x68, 0x38, 0xce, 0x21, 0x99, 0x2a,
},
},
{
.data_len = 48,
.digest = {
0x19, 0x6f, 0x9d, 0xc7, 0x87, 0x12, 0x5c, 0xa3,
0xe2, 0xd3, 0xf1, 0x82, 0xec, 0xf3, 0x55, 0x9c,
0x86, 0xd1, 0x6d, 0xde, 0xcf, 0x5b, 0xec, 0x4c,
0x43, 0x25, 0x85, 0x90, 0xef, 0xe8, 0xe3, 0x5f,
0x2c, 0x3a, 0x84, 0x07, 0xb8, 0x55, 0xfd, 0x5e,
0xa4, 0x45, 0xf2, 0xac, 0xe4, 0xbd, 0xc7, 0x96,
0x80, 0x59, 0x3e, 0xc9, 0xb1, 0x60, 0xb1, 0x2b,
0x17, 0x49, 0x7d, 0x3e, 0x7d, 0x4d, 0x70, 0x24,
},
},
{
.data_len = 49,
.digest = {
0x73, 0x72, 0xd5, 0x0a, 0x97, 0xb4, 0x7d, 0xdb,
0x05, 0x14, 0x8e, 0x40, 0xc2, 0x9a, 0x8a, 0x74,
0x4b, 0xda, 0x7e, 0xfc, 0x97, 0x57, 0x23, 0x39,
0xdc, 0x57, 0x09, 0x13, 0x24, 0xfc, 0xf3, 0x23,
0x55, 0x48, 0xdd, 0xe5, 0x07, 0x9a, 0x6f, 0x7b,
0x62, 0xea, 0x4d, 0x79, 0xb4, 0xb9, 0xc5, 0x86,
0xc0, 0x34, 0xd6, 0xd2, 0x6c, 0xc3, 0x94, 0xfb,
0x34, 0xd6, 0x62, 0xae, 0xb8, 0x99, 0xf1, 0x38,
},
},
{
.data_len = 63,
.digest = {
0x42, 0x3a, 0xe3, 0xa2, 0xae, 0x5a, 0x28, 0xce,
0xf1, 0x3c, 0x97, 0xc2, 0x34, 0xf6, 0xb5, 0x1e,
0xfc, 0x31, 0xb4, 0x04, 0x61, 0xb7, 0x54, 0x0b,
0x0d, 0x1a, 0x22, 0x9c, 0x04, 0x67, 0x5c, 0x4c,
0x75, 0x1b, 0x10, 0x0b, 0x99, 0xe2, 0xb1, 0x5e,
0x5d, 0x4b, 0x7a, 0xe6, 0xf6, 0xb5, 0x62, 0xee,
0x2d, 0x44, 0x57, 0xb2, 0x96, 0x73, 0x5e, 0xb9,
0x6a, 0xb2, 0xb3, 0x16, 0xa3, 0xd9, 0x6a, 0x60,
},
},
{
.data_len = 64,
.digest = {
0x50, 0xb9, 0xbe, 0xb2, 0x69, 0x07, 0x45, 0x5b,
0x59, 0xde, 0x8d, 0xbf, 0x08, 0xdc, 0x2e, 0x7f,
0x93, 0x29, 0xc1, 0x91, 0xe8, 0x74, 0x03, 0x89,
0x20, 0xfb, 0xb2, 0x4b, 0xe8, 0x68, 0x6f, 0xe1,
0xb4, 0x30, 0xbe, 0x11, 0x3c, 0x43, 0x19, 0x66,
0x72, 0x78, 0xb7, 0xf4, 0xe9, 0x09, 0x18, 0x4e,
0xae, 0x4a, 0x24, 0xe0, 0x6f, 0x44, 0x02, 0xe3,
0xfd, 0xda, 0xb3, 0x3e, 0x3c, 0x6d, 0x54, 0x2e,
},
},
{
.data_len = 65,
.digest = {
0xd6, 0xf2, 0xa9, 0x61, 0x3f, 0xce, 0x2a, 0x68,
0x19, 0x86, 0xff, 0xd1, 0xee, 0x89, 0x3b, 0xa4,
0x10, 0x9a, 0x91, 0x50, 0x35, 0x48, 0x9e, 0xf5,
0x9c, 0x95, 0xe0, 0xfb, 0x92, 0x0f, 0xa8, 0xf7,
0x6c, 0x43, 0x85, 0xf1, 0x6e, 0x11, 0x4e, 0x67,
0x78, 0xd7, 0x53, 0x25, 0x0c, 0xf8, 0xce, 0x38,
0x74, 0x08, 0xb0, 0x3c, 0x53, 0x20, 0x4d, 0xc4,
0x9a, 0xf5, 0x78, 0xe8, 0x41, 0x8f, 0xed, 0x1f,
},
},
{
.data_len = 127,
.digest = {
0xe8, 0xb2, 0xc5, 0xa7, 0xf5, 0xfa, 0xee, 0xa0,
0x57, 0xba, 0x58, 0xf9, 0x0a, 0xf2, 0x64, 0x16,
0xa8, 0xa6, 0x03, 0x85, 0x3b, 0xb8, 0x6f, 0xca,
0x76, 0xc3, 0xa1, 0x2b, 0xec, 0xef, 0xc4, 0x66,
0x11, 0xdf, 0x03, 0x85, 0x9d, 0x0c, 0x37, 0x7b,
0xa9, 0x7b, 0x44, 0xfb, 0x11, 0x8f, 0x3f, 0x71,
0xcd, 0x81, 0x43, 0x2e, 0x71, 0x5c, 0x54, 0x9f,
0xca, 0x0f, 0x01, 0x91, 0xca, 0xaa, 0x93, 0xe9,
},
},
{
.data_len = 128,
.digest = {
0x05, 0x8e, 0x9d, 0xdc, 0xe9, 0x36, 0x3e, 0x73,
0x63, 0x59, 0x69, 0x81, 0x0b, 0x8c, 0xc7, 0x9e,
0xcc, 0xe7, 0x9c, 0x19, 0x54, 0xa7, 0x2f, 0x86,
0xb5, 0xea, 0xae, 0x6d, 0xfe, 0x4e, 0x6e, 0x83,
0x8d, 0x1a, 0x1c, 0x70, 0x3f, 0x34, 0xa1, 0x04,
0x59, 0xd1, 0xbb, 0xaa, 0x58, 0xf7, 0xce, 0xfb,
0x86, 0x66, 0x22, 0xfc, 0x78, 0x74, 0x6e, 0x85,
0xf1, 0x59, 0x7d, 0x9e, 0x1c, 0x3b, 0xc6, 0x65,
},
},
{
.data_len = 129,
.digest = {
0x6b, 0x1f, 0x7c, 0x9a, 0x65, 0x7f, 0x09, 0x61,
0xe5, 0x04, 0x9a, 0xf1, 0x4b, 0x36, 0x8e, 0x41,
0x86, 0xcf, 0x86, 0x19, 0xd8, 0xc9, 0x34, 0x70,
0x67, 0xd1, 0x03, 0x72, 0x12, 0xf7, 0x27, 0x92,
0x2e, 0x3d, 0x2b, 0x54, 0x9a, 0x48, 0xa4, 0xc2,
0x61, 0xea, 0x6a, 0xe8, 0xdd, 0x07, 0x41, 0x85,
0x58, 0x6d, 0xcd, 0x12, 0x0d, 0xbc, 0xb1, 0x23,
0xb2, 0xdb, 0x24, 0x1f, 0xc4, 0xa7, 0xae, 0xda,
},
},
{
.data_len = 256,
.digest = {
0x50, 0xd8, 0xdc, 0xb2, 0x50, 0x24, 0x7a, 0x49,
0xb1, 0x00, 0x73, 0x16, 0x1f, 0xce, 0xf9, 0xe8,
0x77, 0x0a, 0x27, 0x74, 0xc7, 0xeb, 0xf0, 0x62,
0xb9, 0xf3, 0x24, 0xa6, 0x03, 0x18, 0x40, 0xde,
0x9b, 0x1d, 0xa8, 0xd0, 0xbf, 0x66, 0xa3, 0xc1,
0x31, 0x04, 0x95, 0xc7, 0xc3, 0xb7, 0x11, 0xe2,
0x1e, 0x31, 0x49, 0x98, 0x06, 0xab, 0xf0, 0xe6,
0x5c, 0xac, 0x88, 0x28, 0x0b, 0x3d, 0xb2, 0xc2,
},
},
{
.data_len = 511,
.digest = {
0xd4, 0x2b, 0x6b, 0x9e, 0xfc, 0x44, 0xc0, 0x90,
0x64, 0x77, 0x5d, 0xf3, 0x44, 0xb6, 0x92, 0x8f,
0x80, 0xe2, 0xe4, 0x9b, 0xaf, 0x49, 0x04, 0xea,
0x29, 0xf7, 0x4a, 0x33, 0x3f, 0xc7, 0x3b, 0xab,
0xa1, 0x71, 0x7f, 0xa2, 0x8e, 0x03, 0xa0, 0xd6,
0xa7, 0xcd, 0xe0, 0xf8, 0xd7, 0x3b, 0xa4, 0x0d,
0x84, 0x79, 0x12, 0x72, 0x3f, 0x8e, 0x48, 0x35,
0x76, 0x4f, 0x56, 0xe9, 0x21, 0x40, 0x19, 0xbe,
},
},
{
.data_len = 513,
.digest = {
0x84, 0xd4, 0xd8, 0x6c, 0x60, 0x3d, 0x6e, 0xfd,
0x84, 0xb7, 0xdf, 0xba, 0x13, 0x5e, 0x07, 0x94,
0x5b, 0x6b, 0x62, 0x1d, 0x82, 0x02, 0xa7, 0xb3,
0x21, 0xdf, 0x42, 0x20, 0x85, 0xa8, 0x6f, 0x30,
0xf7, 0x03, 0xba, 0x66, 0x0e, 0xa6, 0x42, 0x21,
0x37, 0xe8, 0xed, 0x5b, 0x22, 0xf5, 0x4e, 0xa5,
0xe5, 0x80, 0x1b, 0x47, 0xf0, 0x49, 0xb3, 0xe5,
0x6e, 0xd9, 0xd9, 0x95, 0x3d, 0x2e, 0x42, 0x13,
},
},
{
.data_len = 1000,
.digest = {
0x71, 0x17, 0xab, 0x93, 0xfe, 0x3b, 0xa4, 0xe6,
0xcb, 0xb0, 0xea, 0x95, 0xe7, 0x1a, 0x01, 0xc0,
0x12, 0x33, 0xfe, 0xcc, 0x79, 0x15, 0xae, 0x56,
0xd2, 0x70, 0x44, 0x60, 0x54, 0x42, 0xa8, 0x69,
0x7e, 0xc3, 0x90, 0xa0, 0x0c, 0x63, 0x39, 0xff,
0x55, 0x53, 0xb8, 0x46, 0xef, 0x06, 0xcb, 0xba,
0x73, 0xf4, 0x76, 0x22, 0xf1, 0x60, 0x98, 0xbc,
0xbf, 0x76, 0x95, 0x85, 0x13, 0x1d, 0x11, 0x3b,
},
},
{
.data_len = 3333,
.digest = {
0x3a, 0xaa, 0x85, 0xa0, 0x8c, 0x8e, 0xe1, 0x9c,
0x9b, 0x43, 0x72, 0x7f, 0x40, 0x88, 0x3b, 0xd1,
0xc4, 0xd8, 0x2b, 0x69, 0xa6, 0x74, 0x47, 0x69,
0x5f, 0x7d, 0xab, 0x75, 0xa9, 0xf9, 0x88, 0x54,
0xce, 0x57, 0xcc, 0x9d, 0xac, 0x13, 0x91, 0xdb,
0x6d, 0x5c, 0xd8, 0xf4, 0x35, 0xc9, 0x30, 0xf0,
0x4b, 0x91, 0x25, 0xab, 0x92, 0xa8, 0xc8, 0x6f,
0xa0, 0xeb, 0x71, 0x56, 0x95, 0xab, 0xfd, 0xd7,
},
},
{
.data_len = 4096,
.digest = {
0xe1, 0xe9, 0xbe, 0x6c, 0x96, 0xe2, 0xe8, 0xa6,
0x53, 0xcd, 0x79, 0x77, 0x57, 0x51, 0x2f, 0xb2,
0x9f, 0xfc, 0x09, 0xaa, 0x2c, 0xbc, 0x6c, 0x5f,
0xb0, 0xf2, 0x12, 0x39, 0x54, 0xd7, 0x27, 0xf8,
0x33, 0x5d, 0xd4, 0x8a, 0xca, 0xd8, 0x2e, 0xbb,
0x02, 0x82, 0xca, 0x1b, 0x54, 0xfa, 0xd6, 0xf4,
0x49, 0x63, 0xfc, 0xc8, 0x73, 0xd4, 0x26, 0x8d,
0x4f, 0x1c, 0x56, 0xa7, 0xf4, 0x58, 0x6f, 0x51,
},
},
{
.data_len = 4128,
.digest = {
0xf2, 0xf6, 0xe1, 0x16, 0x98, 0x69, 0x74, 0x5f,
0x6c, 0xc4, 0x9d, 0x34, 0xa2, 0x84, 0x5d, 0x47,
0xac, 0x39, 0xe0, 0x14, 0x2d, 0x78, 0xfa, 0x27,
0xd5, 0x18, 0xaf, 0x26, 0x89, 0xa4, 0x69, 0xd3,
0x56, 0xde, 0xfe, 0x4b, 0x9f, 0x0c, 0x9d, 0x5a,
0x9a, 0x73, 0x3e, 0x3c, 0x76, 0x4b, 0x96, 0xca,
0x49, 0xda, 0x05, 0x8c, 0x53, 0xbb, 0x85, 0x89,
0x60, 0xc7, 0xe0, 0xb3, 0x51, 0x18, 0xd2, 0xd2,
},
},
{
.data_len = 4160,
.digest = {
0xfc, 0x5c, 0xcf, 0xbf, 0x29, 0xe3, 0x01, 0xef,
0x4b, 0x40, 0x70, 0x01, 0xca, 0x4d, 0x46, 0xce,
0xa9, 0x95, 0x5d, 0xb4, 0xf1, 0x79, 0x29, 0xdb,
0xac, 0x32, 0x3d, 0xd9, 0x60, 0x9e, 0x6b, 0xb8,
0x28, 0x62, 0xb7, 0x4a, 0xbb, 0x33, 0xb9, 0xd0,
0x83, 0xe0, 0xd7, 0x5a, 0x2d, 0x01, 0x4c, 0x61,
0x9e, 0x7d, 0x2d, 0x2d, 0x60, 0x29, 0x5e, 0x60,
0x10, 0xb7, 0x41, 0x00, 0x3f, 0xe5, 0xf7, 0x52,
},
},
{
.data_len = 4224,
.digest = {
0xf8, 0xe5, 0x4b, 0xe5, 0x89, 0xf9, 0x1b, 0x43,
0xbb, 0x65, 0x3d, 0xa0, 0xb4, 0xdc, 0x04, 0x26,
0x68, 0x15, 0xae, 0x4d, 0xd6, 0x03, 0xb7, 0x27,
0x06, 0x8c, 0x2a, 0x82, 0x51, 0x96, 0xbf, 0x83,
0x38, 0x96, 0x21, 0x8a, 0xd9, 0xf9, 0x4e, 0x38,
0xc6, 0xb3, 0xbd, 0xfe, 0xd3, 0x49, 0x90, 0xbc,
0xa1, 0x77, 0xd0, 0xa0, 0x3c, 0x2b, 0x4e, 0x10,
0x34, 0xc3, 0x17, 0x85, 0x3d, 0xec, 0xa8, 0x05,
},
},
{
.data_len = 16384,
.digest = {
0x38, 0x56, 0xaf, 0x83, 0x68, 0x9c, 0xba, 0xe3,
0xec, 0x51, 0xf5, 0xf4, 0x93, 0x48, 0x1d, 0xe6,
0xad, 0xa8, 0x8c, 0x70, 0x2a, 0xd9, 0xaa, 0x43,
0x04, 0x40, 0x95, 0xc1, 0xe6, 0x8a, 0xf5, 0x01,
0x6b, 0x79, 0xd9, 0xb4, 0xd0, 0x1d, 0x93, 0x26,
0xfe, 0xf5, 0x07, 0x57, 0xda, 0x08, 0x0a, 0x82,
0xc9, 0x17, 0x13, 0x5b, 0x9e, 0x11, 0x96, 0xa5,
0xd0, 0x92, 0xcd, 0xf1, 0xa3, 0x5b, 0x43, 0x21,
},
},
};
static const u8 hash_testvec_consolidated[BLAKE2B_HASH_SIZE] = {
0xa4, 0xf8, 0xf6, 0xa1, 0x36, 0x89, 0xc0, 0x2a,
0xc3, 0x42, 0x32, 0x71, 0xe5, 0xea, 0x14, 0x77,
0xf3, 0x99, 0x91, 0x87, 0x49, 0xc2, 0x8d, 0xa5,
0x2f, 0xed, 0x01, 0x35, 0x39, 0x64, 0x09, 0x25,
0xe3, 0xa8, 0x50, 0x97, 0x35, 0x8b, 0xf5, 0x19,
0x1e, 0xd5, 0x9f, 0x03, 0x0b, 0x65, 0x55, 0x0e,
0xa0, 0xb7, 0xda, 0x18, 0x7b, 0x7f, 0x88, 0x55,
0x1f, 0xdb, 0x82, 0x6b, 0x98, 0x90, 0x1c, 0xdd,
};
static const u8 blake2b_keyed_testvec_consolidated[BLAKE2B_HASH_SIZE] = {
0x2b, 0x89, 0x36, 0x3a, 0x36, 0xe4, 0x18, 0x38,
0xc4, 0x5b, 0x5c, 0xa5, 0x9a, 0xed, 0xf2, 0xee,
0x5a, 0xb6, 0x82, 0x6c, 0x63, 0xf2, 0x29, 0x57,
0xc7, 0xd5, 0x32, 0x27, 0xba, 0x88, 0xb1, 0xab,
0xf2, 0x2a, 0xc1, 0xea, 0xf3, 0x91, 0x89, 0x66,
0x47, 0x1e, 0x5b, 0xc6, 0x98, 0x12, 0xe9, 0x25,
0xbf, 0x72, 0xd2, 0x3f, 0x88, 0x97, 0x17, 0x51,
0xed, 0x96, 0xfb, 0xe9, 0xca, 0x52, 0x42, 0xc9,
};

View File

@@ -0,0 +1,133 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2025 Google LLC
*/
#include <crypto/blake2b.h>
#include "blake2b-testvecs.h"
/*
* The following are compatibility functions that present BLAKE2b as an unkeyed
* hash function that produces hashes of fixed length BLAKE2B_HASH_SIZE, so that
* hash-test-template.h can be reused to test it.
*/
static void blake2b_default(const u8 *data, size_t len,
u8 out[BLAKE2B_HASH_SIZE])
{
blake2b(NULL, 0, data, len, out, BLAKE2B_HASH_SIZE);
}
static void blake2b_init_default(struct blake2b_ctx *ctx)
{
blake2b_init(ctx, BLAKE2B_HASH_SIZE);
}
/*
* Generate the HASH_KUNIT_CASES using hash-test-template.h. These test BLAKE2b
* with a key length of 0 and a hash length of BLAKE2B_HASH_SIZE.
*/
#define HASH blake2b_default
#define HASH_CTX blake2b_ctx
#define HASH_SIZE BLAKE2B_HASH_SIZE
#define HASH_INIT blake2b_init_default
#define HASH_UPDATE blake2b_update
#define HASH_FINAL blake2b_final
#include "hash-test-template.h"
/*
* BLAKE2b specific test case which tests all possible combinations of key
* length and hash length.
*/
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;
struct blake2b_ctx main_ctx;
u8 main_hash[BLAKE2B_HASH_SIZE];
rand_bytes_seeded_from_len(data, data_len);
blake2b_init(&main_ctx, BLAKE2B_HASH_SIZE);
for (int key_len = 0; key_len <= BLAKE2B_KEY_SIZE; key_len++) {
rand_bytes_seeded_from_len(key, key_len);
for (int out_len = 1; out_len <= BLAKE2B_HASH_SIZE; out_len++) {
blake2b(key, key_len, data, data_len, hash, out_len);
blake2b_update(&main_ctx, hash, out_len);
}
}
blake2b_final(&main_ctx, main_hash);
KUNIT_ASSERT_MEMEQ(test, main_hash, blake2b_keyed_testvec_consolidated,
BLAKE2B_HASH_SIZE);
}
/*
* BLAKE2b specific test case which tests using a guarded buffer for all allowed
* key lengths. Also tests both blake2b() and blake2b_init_key().
*/
static void test_blake2b_with_guarded_key_buf(struct kunit *test)
{
const size_t data_len = 100;
rand_bytes(test_buf, 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 hash1[BLAKE2B_HASH_SIZE];
u8 hash2[BLAKE2B_HASH_SIZE];
struct blake2b_ctx ctx;
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);
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_final(&ctx, hash2);
KUNIT_ASSERT_MEMEQ(test, hash1, hash2, BLAKE2B_HASH_SIZE);
}
}
/*
* BLAKE2b specific test case which tests using a guarded output buffer for all
* allowed output lengths.
*/
static void test_blake2b_with_guarded_out_buf(struct kunit *test)
{
const size_t data_len = 100;
rand_bytes(test_buf, 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];
blake2b(NULL, 0, test_buf, data_len, hash, out_len);
blake2b(NULL, 0, test_buf, data_len, guarded_hash, out_len);
KUNIT_ASSERT_MEMEQ(test, hash, guarded_hash, out_len);
}
}
static struct kunit_case blake2b_test_cases[] = {
HASH_KUNIT_CASES,
KUNIT_CASE(test_blake2b_all_key_and_hash_lens),
KUNIT_CASE(test_blake2b_with_guarded_key_buf),
KUNIT_CASE(test_blake2b_with_guarded_out_buf),
KUNIT_CASE(benchmark_hash),
{},
};
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);
MODULE_DESCRIPTION("KUnit tests and benchmark for BLAKE2b");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,186 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py polyval */
static const struct {
size_t data_len;
u8 digest[POLYVAL_DIGEST_SIZE];
} hash_testvecs[] = {
{
.data_len = 0,
.digest = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
{
.data_len = 1,
.digest = {
0xb5, 0x51, 0x69, 0x89, 0xd4, 0x3c, 0x59, 0xca,
0x6a, 0x1c, 0x2a, 0xe9, 0xa1, 0x9c, 0x6c, 0x83,
},
},
{
.data_len = 2,
.digest = {
0xf4, 0x50, 0xaf, 0x07, 0xda, 0x42, 0xa7, 0x41,
0x4d, 0x24, 0x88, 0x87, 0xe3, 0x40, 0x73, 0x7c,
},
},
{
.data_len = 3,
.digest = {
0x9e, 0x88, 0x78, 0x71, 0x4c, 0x55, 0x87, 0xe8,
0xb4, 0x96, 0x3d, 0x56, 0xc8, 0xb2, 0xe1, 0x68,
},
},
{
.data_len = 16,
.digest = {
0x9e, 0x81, 0x37, 0x8f, 0x49, 0xf7, 0xa2, 0xe4,
0x04, 0x45, 0x12, 0x78, 0x45, 0x42, 0x27, 0xad,
},
},
{
.data_len = 32,
.digest = {
0x60, 0x19, 0xd0, 0xa4, 0xf0, 0xde, 0x9e, 0xe7,
0x6a, 0x89, 0x1a, 0xea, 0x80, 0x14, 0xa9, 0xa3,
},
},
{
.data_len = 48,
.digest = {
0x0c, 0xa2, 0x70, 0x4d, 0x7c, 0x89, 0xac, 0x41,
0xc2, 0x9e, 0x0d, 0x07, 0x07, 0x6a, 0x7f, 0xd5,
},
},
{
.data_len = 49,
.digest = {
0x91, 0xd3, 0xa9, 0x5c, 0x79, 0x3d, 0x6b, 0x84,
0x99, 0x54, 0xa7, 0xb4, 0x06, 0x66, 0xfd, 0x1c,
},
},
{
.data_len = 63,
.digest = {
0x29, 0x37, 0xb8, 0xe5, 0xd8, 0x27, 0x4d, 0xfb,
0x83, 0x4f, 0x67, 0xf7, 0xf9, 0xc1, 0x0a, 0x9d,
},
},
{
.data_len = 64,
.digest = {
0x17, 0xa9, 0x06, 0x2c, 0xf3, 0xe8, 0x2e, 0xa6,
0x6b, 0xb2, 0x1f, 0x5d, 0x94, 0x3c, 0x02, 0xa2,
},
},
{
.data_len = 65,
.digest = {
0x7c, 0x80, 0x74, 0xd7, 0xa1, 0x37, 0x30, 0x64,
0x3b, 0xa4, 0xa3, 0x98, 0xde, 0x47, 0x10, 0x23,
},
},
{
.data_len = 127,
.digest = {
0x27, 0x3a, 0xcf, 0xf5, 0xaf, 0x9f, 0xd8, 0xd8,
0x2d, 0x6a, 0x91, 0xfb, 0xb8, 0xfa, 0xbe, 0x0c,
},
},
{
.data_len = 128,
.digest = {
0x97, 0x6e, 0xc4, 0xbe, 0x6b, 0x15, 0xa6, 0x7c,
0xc4, 0xa2, 0xb8, 0x0a, 0x0e, 0x9c, 0xc7, 0x3a,
},
},
{
.data_len = 129,
.digest = {
0x2b, 0xc3, 0x98, 0xba, 0x6e, 0x42, 0xf8, 0x18,
0x85, 0x69, 0x15, 0x37, 0x10, 0x60, 0xe6, 0xac,
},
},
{
.data_len = 256,
.digest = {
0x88, 0x21, 0x77, 0x89, 0xd7, 0x93, 0x90, 0xfc,
0xf3, 0xb0, 0xe3, 0xfb, 0x14, 0xe2, 0xcf, 0x74,
},
},
{
.data_len = 511,
.digest = {
0x66, 0x3d, 0x3e, 0x08, 0xa0, 0x49, 0x81, 0x68,
0x3e, 0x3b, 0xc8, 0x80, 0x55, 0xd4, 0x15, 0xe9,
},
},
{
.data_len = 513,
.digest = {
0x05, 0xf5, 0x06, 0x66, 0xe7, 0x11, 0x08, 0x84,
0xff, 0x94, 0x50, 0x85, 0x65, 0x95, 0x2a, 0x20,
},
},
{
.data_len = 1000,
.digest = {
0xd3, 0xa0, 0x51, 0x69, 0xb5, 0x38, 0xae, 0x1b,
0xe1, 0xa2, 0x89, 0xc6, 0x8d, 0x2b, 0x62, 0x37,
},
},
{
.data_len = 3333,
.digest = {
0x37, 0x6d, 0x6a, 0x14, 0xdc, 0xa5, 0x37, 0xfc,
0xfe, 0x67, 0x76, 0xb2, 0x64, 0x68, 0x64, 0x05,
},
},
{
.data_len = 4096,
.digest = {
0xe3, 0x12, 0x0c, 0x58, 0x46, 0x45, 0x27, 0x7a,
0x0e, 0xa2, 0xfa, 0x2c, 0x35, 0x73, 0x6c, 0x94,
},
},
{
.data_len = 4128,
.digest = {
0x63, 0x0d, 0xa1, 0xbc, 0x6e, 0x3e, 0xd3, 0x1d,
0x28, 0x52, 0xd2, 0xf4, 0x30, 0x2d, 0xff, 0xc4,
},
},
{
.data_len = 4160,
.digest = {
0xb2, 0x91, 0x49, 0xe2, 0x02, 0x98, 0x00, 0x79,
0x71, 0xb9, 0xd7, 0xd4, 0xb5, 0x94, 0x6d, 0x7d,
},
},
{
.data_len = 4224,
.digest = {
0x58, 0x96, 0x48, 0x69, 0x05, 0x17, 0xe1, 0x6d,
0xbc, 0xf2, 0x3d, 0x10, 0x96, 0x00, 0x74, 0x58,
},
},
{
.data_len = 16384,
.digest = {
0x99, 0x3c, 0xcb, 0x4d, 0x64, 0xc9, 0xa9, 0x41,
0x52, 0x93, 0xfd, 0x65, 0xc4, 0xcc, 0xa5, 0xe5,
},
},
};
static const u8 hash_testvec_consolidated[POLYVAL_DIGEST_SIZE] = {
0xdf, 0x68, 0x52, 0x99, 0x92, 0xc3, 0xe8, 0x88,
0x29, 0x13, 0xc8, 0x35, 0x67, 0xa3, 0xd3, 0xad,
};
static const u8 polyval_allones_hashofhashes[POLYVAL_DIGEST_SIZE] = {
0xd5, 0xf7, 0xfd, 0xb2, 0xa6, 0xef, 0x0b, 0x85,
0x0d, 0x0a, 0x06, 0x10, 0xbc, 0x64, 0x94, 0x73,
};

View File

@@ -0,0 +1,223 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2025 Google LLC
*/
#include <crypto/polyval.h>
#include "polyval-testvecs.h"
/*
* A fixed key used when presenting POLYVAL as an unkeyed hash function in order
* to reuse hash-test-template.h. At the beginning of the test suite, this is
* initialized to a key prepared from bytes generated from a fixed seed.
*/
static struct polyval_key test_key;
static void polyval_init_withtestkey(struct polyval_ctx *ctx)
{
polyval_init(ctx, &test_key);
}
static void polyval_withtestkey(const u8 *data, size_t len,
u8 out[POLYVAL_BLOCK_SIZE])
{
polyval(&test_key, data, len, out);
}
/* Generate the HASH_KUNIT_CASES using hash-test-template.h. */
#define HASH polyval_withtestkey
#define HASH_CTX polyval_ctx
#define HASH_SIZE POLYVAL_BLOCK_SIZE
#define HASH_INIT polyval_init_withtestkey
#define HASH_UPDATE polyval_update
#define HASH_FINAL polyval_final
#include "hash-test-template.h"
/*
* Test an example from RFC8452 ("AES-GCM-SIV: Nonce Misuse-Resistant
* Authenticated Encryption") to ensure compatibility with that.
*/
static void test_polyval_rfc8452_testvec(struct kunit *test)
{
static const u8 raw_key[POLYVAL_BLOCK_SIZE] =
"\x31\x07\x28\xd9\x91\x1f\x1f\x38"
"\x37\xb2\x43\x16\xc3\xfa\xb9\xa0";
static const u8 data[48] =
"\x65\x78\x61\x6d\x70\x6c\x65\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x48\x65\x6c\x6c\x6f\x20\x77\x6f"
"\x72\x6c\x64\x00\x00\x00\x00\x00"
"\x38\x00\x00\x00\x00\x00\x00\x00"
"\x58\x00\x00\x00\x00\x00\x00\x00";
static const u8 expected_hash[POLYVAL_BLOCK_SIZE] =
"\xad\x7f\xcf\x0b\x51\x69\x85\x16"
"\x62\x67\x2f\x3c\x5f\x95\x13\x8f";
u8 hash[POLYVAL_BLOCK_SIZE];
struct polyval_key key;
polyval_preparekey(&key, raw_key);
polyval(&key, data, sizeof(data), hash);
KUNIT_ASSERT_MEMEQ(test, hash, expected_hash, sizeof(hash));
}
/*
* Test a key and messages containing all one bits. This is useful to detect
* overflow bugs in implementations that emulate carryless multiplication using
* a series of standard multiplications with the bits spread out.
*/
static void test_polyval_allones_key_and_message(struct kunit *test)
{
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);
polyval_preparekey(&key, test_buf);
polyval_init(&hashofhashes_ctx, &key);
for (size_t len = 0; len <= 4096; len += 16) {
polyval(&key, test_buf, len, hash);
polyval_update(&hashofhashes_ctx, hash, sizeof(hash));
}
polyval_final(&hashofhashes_ctx, hash);
KUNIT_ASSERT_MEMEQ(test, hash, polyval_allones_hashofhashes,
sizeof(hash));
}
#define MAX_LEN_FOR_KEY_CHECK 1024
/*
* Given two prepared keys which should be identical (but may differ in
* alignment and/or whether they are followed by a guard page or not), verify
* that they produce consistent results on various data lengths.
*/
static void check_key_consistency(struct kunit *test,
const struct polyval_key *key1,
const struct polyval_key *key2)
{
u8 *data = test_buf;
u8 hash1[POLYVAL_BLOCK_SIZE];
u8 hash2[POLYVAL_BLOCK_SIZE];
rand_bytes(data, MAX_LEN_FOR_KEY_CHECK);
KUNIT_ASSERT_MEMEQ(test, key1, key2, sizeof(*key1));
for (int i = 0; i < 100; i++) {
size_t len = rand_length(MAX_LEN_FOR_KEY_CHECK);
polyval(key1, data, len, hash1);
polyval(key2, data, len, hash2);
KUNIT_ASSERT_MEMEQ(test, hash1, hash2, sizeof(hash1));
}
}
/* Test that no buffer overreads occur on either raw_key or polyval_key. */
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)];
struct polyval_key key1, key2;
struct polyval_key *guarded_key =
(struct polyval_key *)&test_buf[TEST_BUF_LEN - sizeof(key1)];
/* Prepare with regular buffers. */
rand_bytes(raw_key, sizeof(raw_key));
polyval_preparekey(&key1, raw_key);
/* Prepare with guarded raw_key, then check that it works. */
memcpy(guarded_raw_key, raw_key, sizeof(raw_key));
polyval_preparekey(&key2, guarded_raw_key);
check_key_consistency(test, &key1, &key2);
/* Prepare guarded polyval_key, then check that it works. */
polyval_preparekey(guarded_key, raw_key);
check_key_consistency(test, &key1, guarded_key);
}
/*
* 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.
*/
static void test_polyval_with_minimally_aligned_key(struct kunit *test)
{
u8 raw_key[POLYVAL_BLOCK_SIZE];
struct polyval_key key;
struct polyval_key *minaligned_key =
(struct polyval_key *)&test_buf[MAX_LEN_FOR_KEY_CHECK +
__alignof__(struct polyval_key)];
KUNIT_ASSERT_TRUE(test, IS_ALIGNED((uintptr_t)minaligned_key,
__alignof__(struct polyval_key)));
KUNIT_ASSERT_TRUE(test,
!IS_ALIGNED((uintptr_t)minaligned_key,
2 * __alignof__(struct polyval_key)));
rand_bytes(raw_key, sizeof(raw_key));
polyval_preparekey(&key, raw_key);
polyval_preparekey(minaligned_key, raw_key);
check_key_consistency(test, &key, minaligned_key);
}
struct polyval_irq_test_state {
struct polyval_key expected_key;
u8 raw_key[POLYVAL_BLOCK_SIZE];
};
static bool polyval_irq_test_func(void *state_)
{
struct polyval_irq_test_state *state = state_;
struct polyval_key key;
polyval_preparekey(&key, state->raw_key);
return memcmp(&key, &state->expected_key, sizeof(key)) == 0;
}
/*
* Test that polyval_preparekey() produces the same output regardless of whether
* FPU or vector registers are usable when it is called.
*/
static void test_polyval_preparekey_in_irqs(struct kunit *test)
{
struct polyval_irq_test_state state;
rand_bytes(state.raw_key, sizeof(state.raw_key));
polyval_preparekey(&state.expected_key, state.raw_key);
kunit_run_irq_test(test, polyval_irq_test_func, 20000, &state);
}
static int polyval_suite_init(struct kunit_suite *suite)
{
u8 raw_key[POLYVAL_BLOCK_SIZE];
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);
}
static struct kunit_case polyval_test_cases[] = {
HASH_KUNIT_CASES,
KUNIT_CASE(test_polyval_rfc8452_testvec),
KUNIT_CASE(test_polyval_allones_key_and_message),
KUNIT_CASE(test_polyval_with_guarded_key),
KUNIT_CASE(test_polyval_with_minimally_aligned_key),
KUNIT_CASE(test_polyval_preparekey_in_irqs),
KUNIT_CASE(benchmark_hash),
{},
};
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);
MODULE_DESCRIPTION("KUnit tests and benchmark for POLYVAL");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,249 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha3 */
/* SHA3-256 test vectors */
static const struct {
size_t data_len;
u8 digest[SHA3_256_DIGEST_SIZE];
} hash_testvecs[] = {
{
.data_len = 0,
.digest = {
0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66,
0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62,
0xf5, 0x80, 0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa,
0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a,
},
},
{
.data_len = 1,
.digest = {
0x11, 0x03, 0xe7, 0x84, 0x51, 0x50, 0x86, 0x35,
0x71, 0x8a, 0x70, 0xe3, 0xc4, 0x26, 0x7b, 0x21,
0x02, 0x13, 0xa0, 0x81, 0xe8, 0xe6, 0x14, 0x25,
0x07, 0x34, 0xe5, 0xc5, 0x40, 0x06, 0xf2, 0x8b,
},
},
{
.data_len = 2,
.digest = {
0x2f, 0x6f, 0x6d, 0x47, 0x48, 0x52, 0x11, 0xb9,
0xe4, 0x3d, 0xc8, 0x71, 0xcf, 0xb2, 0xee, 0xae,
0x5b, 0xf4, 0x12, 0x84, 0x5b, 0x1c, 0xec, 0x6c,
0xc1, 0x66, 0x88, 0xaa, 0xc3, 0x40, 0xbd, 0x7e,
},
},
{
.data_len = 3,
.digest = {
0xec, 0x02, 0xe8, 0x81, 0x4f, 0x84, 0x41, 0x69,
0x06, 0xd8, 0xdc, 0x1d, 0x01, 0x78, 0xd7, 0xcb,
0x39, 0xdf, 0xd3, 0x12, 0x1c, 0x99, 0xfd, 0xf3,
0x5c, 0x83, 0xc9, 0xc2, 0x7a, 0x7b, 0x6a, 0x05,
},
},
{
.data_len = 16,
.digest = {
0xff, 0x6f, 0xc3, 0x41, 0xc3, 0x5f, 0x34, 0x6d,
0xa7, 0xdf, 0x3e, 0xc2, 0x8b, 0x29, 0xb6, 0xf1,
0xf8, 0x67, 0xfd, 0xcd, 0xb1, 0x9f, 0x38, 0x08,
0x1d, 0x8d, 0xd9, 0xc2, 0x43, 0x66, 0x18, 0x6c,
},
},
{
.data_len = 32,
.digest = {
0xe4, 0xb1, 0x06, 0x17, 0xf8, 0x8b, 0x91, 0x95,
0xe7, 0x57, 0x66, 0xac, 0x08, 0xb2, 0x03, 0x3e,
0xf7, 0x84, 0x1f, 0xe3, 0x25, 0xa3, 0x11, 0xd2,
0x11, 0xa4, 0x78, 0x74, 0x2a, 0x43, 0x20, 0xa5,
},
},
{
.data_len = 48,
.digest = {
0xeb, 0x57, 0x5f, 0x20, 0xa3, 0x6b, 0xc7, 0xb4,
0x66, 0x2a, 0xa0, 0x30, 0x3b, 0x52, 0x00, 0xc9,
0xce, 0x6a, 0xd8, 0x1e, 0xbe, 0xed, 0xa1, 0xd1,
0xbe, 0x63, 0xc7, 0xe1, 0xe2, 0x66, 0x67, 0x0c,
},
},
{
.data_len = 49,
.digest = {
0xf0, 0x67, 0xad, 0x66, 0xbe, 0xec, 0x5a, 0xfd,
0x29, 0xd2, 0x4f, 0x1d, 0xb2, 0x24, 0xb8, 0x90,
0x05, 0x28, 0x0e, 0x66, 0x67, 0x74, 0x2d, 0xee,
0x66, 0x25, 0x11, 0xd1, 0x76, 0xa2, 0xfc, 0x3a,
},
},
{
.data_len = 63,
.digest = {
0x57, 0x56, 0x21, 0xb3, 0x2d, 0x2d, 0xe1, 0x9d,
0xbf, 0x2c, 0x82, 0xa8, 0xad, 0x7e, 0x6c, 0x46,
0xfb, 0x30, 0xeb, 0xce, 0xcf, 0xed, 0x2d, 0x65,
0xe7, 0xe4, 0x96, 0x69, 0xe0, 0x48, 0xd2, 0xb6,
},
},
{
.data_len = 64,
.digest = {
0x7b, 0xba, 0x67, 0x15, 0xe5, 0x21, 0xc4, 0x69,
0xd3, 0xef, 0x5c, 0x97, 0x9f, 0x5b, 0xba, 0x9c,
0xfa, 0x55, 0x64, 0xec, 0xb5, 0x37, 0x53, 0x1b,
0x3f, 0x4c, 0x0a, 0xed, 0x51, 0x98, 0x2b, 0x52,
},
},
{
.data_len = 65,
.digest = {
0x44, 0xb6, 0x6b, 0x83, 0x09, 0x83, 0x55, 0x83,
0xde, 0x1f, 0xcc, 0x33, 0xef, 0xdc, 0x05, 0xbb,
0x3b, 0x63, 0x76, 0x45, 0xe4, 0x8e, 0x14, 0x7a,
0x2d, 0xae, 0x90, 0xce, 0x68, 0xc3, 0xa4, 0xf2,
},
},
{
.data_len = 127,
.digest = {
0x50, 0x3e, 0x99, 0x4e, 0x28, 0x2b, 0xc9, 0xf4,
0xf5, 0xeb, 0x2b, 0x16, 0x04, 0x2d, 0xf5, 0xbe,
0xc0, 0x91, 0x41, 0x2a, 0x8e, 0x69, 0x5e, 0x39,
0x53, 0x2c, 0xc1, 0x18, 0xa5, 0xeb, 0xd8, 0xda,
},
},
{
.data_len = 128,
.digest = {
0x90, 0x0b, 0xa6, 0x92, 0x84, 0x30, 0xaf, 0xee,
0x38, 0x59, 0x83, 0x83, 0xe9, 0xfe, 0xab, 0x86,
0x79, 0x1b, 0xcd, 0xe7, 0x0a, 0x0f, 0x58, 0x53,
0x36, 0xab, 0x12, 0xe1, 0x5c, 0x97, 0xc1, 0xfb,
},
},
{
.data_len = 129,
.digest = {
0x2b, 0x52, 0x1e, 0x54, 0xbe, 0x38, 0x4c, 0x3e,
0x73, 0x37, 0x18, 0xf5, 0x25, 0x2c, 0xc8, 0xc7,
0xda, 0x7e, 0xb6, 0x47, 0x9d, 0xf4, 0x46, 0xce,
0xfa, 0x80, 0x20, 0x6b, 0xbd, 0xfd, 0x2a, 0xd8,
},
},
{
.data_len = 256,
.digest = {
0x45, 0xf0, 0xf5, 0x9b, 0xd9, 0x91, 0x26, 0xd5,
0x91, 0x3b, 0xf8, 0x87, 0x8b, 0x34, 0x02, 0x31,
0x64, 0xab, 0xf4, 0x1c, 0x6e, 0x34, 0x72, 0xdf,
0x32, 0x6d, 0xe5, 0xd2, 0x67, 0x5e, 0x86, 0x93,
},
},
{
.data_len = 511,
.digest = {
0xb3, 0xaf, 0x71, 0x64, 0xfa, 0xd4, 0xf1, 0x07,
0x38, 0xef, 0x04, 0x8e, 0x89, 0xf4, 0x02, 0xd2,
0xa5, 0xaf, 0x3b, 0xf5, 0x67, 0x56, 0xcf, 0xa9,
0x8e, 0x43, 0xf5, 0xb5, 0xe3, 0x91, 0x8e, 0xe7,
},
},
{
.data_len = 513,
.digest = {
0x51, 0xac, 0x0a, 0x65, 0xb7, 0x96, 0x20, 0xcf,
0x88, 0xf6, 0x97, 0x35, 0x89, 0x0d, 0x31, 0x0f,
0xbe, 0x17, 0xbe, 0x62, 0x03, 0x67, 0xc0, 0xee,
0x4f, 0xc1, 0xe3, 0x7f, 0x6f, 0xab, 0xac, 0xb4,
},
},
{
.data_len = 1000,
.digest = {
0x7e, 0xea, 0xa8, 0xd7, 0xde, 0x20, 0x1b, 0x58,
0x24, 0xd8, 0x26, 0x40, 0x36, 0x5f, 0x3f, 0xaa,
0xe5, 0x5a, 0xea, 0x98, 0x58, 0xd4, 0xd6, 0xfc,
0x20, 0x4c, 0x5c, 0x4f, 0xaf, 0x56, 0xc7, 0xc3,
},
},
{
.data_len = 3333,
.digest = {
0x61, 0xb1, 0xb1, 0x3e, 0x0e, 0x7e, 0x90, 0x3d,
0x31, 0x54, 0xbd, 0xc9, 0x0d, 0x53, 0x62, 0xf1,
0xcd, 0x18, 0x80, 0xf9, 0x91, 0x75, 0x41, 0xb3,
0x51, 0x39, 0x57, 0xa7, 0xa8, 0x1e, 0xfb, 0xc9,
},
},
{
.data_len = 4096,
.digest = {
0xab, 0x29, 0xda, 0x10, 0xc4, 0x11, 0x2d, 0x5c,
0xd1, 0xce, 0x1c, 0x95, 0xfa, 0xc6, 0xc7, 0xb0,
0x1b, 0xd1, 0xdc, 0x6f, 0xa0, 0x9d, 0x1b, 0x23,
0xfb, 0x6e, 0x90, 0x97, 0xd0, 0x75, 0x44, 0x7a,
},
},
{
.data_len = 4128,
.digest = {
0x02, 0x45, 0x95, 0xf4, 0x19, 0xb5, 0x93, 0x29,
0x90, 0xf2, 0x63, 0x3f, 0x89, 0xe8, 0xa5, 0x31,
0x76, 0xf2, 0x89, 0x79, 0x66, 0xd3, 0x96, 0xdf,
0x33, 0xd1, 0xa6, 0x17, 0x73, 0xb1, 0xd0, 0x45,
},
},
{
.data_len = 4160,
.digest = {
0xd1, 0x8e, 0x22, 0xea, 0x44, 0x87, 0x6e, 0x9d,
0xfb, 0x36, 0x02, 0x20, 0x63, 0xb7, 0x69, 0x45,
0x25, 0x41, 0x69, 0xe0, 0x9b, 0x87, 0xcf, 0xa3,
0x51, 0xbb, 0xfc, 0x8d, 0xf7, 0x29, 0xa7, 0xea,
},
},
{
.data_len = 4224,
.digest = {
0x11, 0x86, 0x7d, 0x84, 0xf9, 0x8c, 0x6e, 0xc4,
0x64, 0x36, 0xc6, 0xf3, 0x42, 0x92, 0x31, 0x2b,
0x1e, 0x12, 0xe6, 0x4d, 0xbe, 0xfa, 0x77, 0x3f,
0x89, 0x41, 0x33, 0x58, 0x1c, 0x98, 0x16, 0x0a,
},
},
{
.data_len = 16384,
.digest = {
0xb2, 0xba, 0x0c, 0x8c, 0x9d, 0xbb, 0x1e, 0xb0,
0x03, 0xb5, 0xdf, 0x4f, 0xf5, 0x35, 0xdb, 0xec,
0x60, 0xf2, 0x5b, 0xb6, 0xd0, 0x49, 0xd3, 0xed,
0x55, 0xc0, 0x7a, 0xd7, 0xaf, 0xa1, 0xea, 0x53,
},
},
};
static const u8 hash_testvec_consolidated[SHA3_256_DIGEST_SIZE] = {
0x3b, 0x33, 0x67, 0xf8, 0xea, 0x92, 0x78, 0x62,
0xdd, 0xbe, 0x72, 0x15, 0xbd, 0x6f, 0xfa, 0xe5,
0x5e, 0xab, 0x9f, 0xb1, 0xe4, 0x23, 0x7c, 0x2c,
0x80, 0xcf, 0x09, 0x75, 0xf8, 0xe2, 0xfa, 0x30,
};
/* SHAKE test vectors */
static const u8 shake128_testvec_consolidated[SHA3_256_DIGEST_SIZE] = {
0x89, 0x88, 0x3a, 0x44, 0xec, 0xfe, 0x3c, 0xeb,
0x2f, 0x1c, 0x1d, 0xda, 0x9e, 0x36, 0x64, 0xf0,
0x85, 0x4c, 0x49, 0x12, 0x76, 0x5a, 0x4d, 0xe7,
0xa8, 0xfd, 0xcd, 0xbe, 0x45, 0xb4, 0x6f, 0xb0,
};
static const u8 shake256_testvec_consolidated[SHA3_256_DIGEST_SIZE] = {
0x5a, 0xfd, 0x66, 0x62, 0x5c, 0x37, 0x2b, 0x41,
0x77, 0x1c, 0x01, 0x5d, 0x64, 0x7c, 0x63, 0x7a,
0x7c, 0x76, 0x9e, 0xa8, 0xd1, 0xb0, 0x8e, 0x02,
0x16, 0x9b, 0xfe, 0x0e, 0xb5, 0xd8, 0x6a, 0xb5,
};

View File

@@ -0,0 +1,422 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#include <crypto/sha3.h>
#include "sha3-testvecs.h"
#define HASH sha3_256
#define HASH_CTX sha3_ctx
#define HASH_SIZE SHA3_256_DIGEST_SIZE
#define HASH_INIT sha3_256_init
#define HASH_UPDATE sha3_update
#define HASH_FINAL sha3_final
#include "hash-test-template.h"
/*
* Sample message and the output generated for various algorithms by passing it
* into "openssl sha3-224" etc..
*/
static const u8 test_sha3_sample[] =
"The quick red fox jumped over the lazy brown dog!\n"
"The quick red fox jumped over the lazy brown dog!\n"
"The quick red fox jumped over the lazy brown dog!\n"
"The quick red fox jumped over the lazy brown dog!\n";
static const u8 test_sha3_224[8 + SHA3_224_DIGEST_SIZE + 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
0xd6, 0xe8, 0xd8, 0x80, 0xfa, 0x42, 0x80, 0x70,
0x7e, 0x7f, 0xd7, 0xd2, 0xd7, 0x7a, 0x35, 0x65,
0xf0, 0x0b, 0x4f, 0x9f, 0x2a, 0x33, 0xca, 0x0a,
0xef, 0xa6, 0x4c, 0xb8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
};
static const u8 test_sha3_256[8 + SHA3_256_DIGEST_SIZE + 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
0xdb, 0x3b, 0xb0, 0xb8, 0x8d, 0x15, 0x78, 0xe5,
0x78, 0x76, 0x8e, 0x39, 0x7e, 0x89, 0x86, 0xb9,
0x14, 0x3a, 0x1e, 0xe7, 0x96, 0x7c, 0xf3, 0x25,
0x70, 0xbd, 0xc3, 0xa9, 0xae, 0x63, 0x71, 0x1d,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
};
static const u8 test_sha3_384[8 + SHA3_384_DIGEST_SIZE + 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
0x2d, 0x4b, 0x29, 0x85, 0x19, 0x94, 0xaa, 0x31,
0x9b, 0x04, 0x9d, 0x6e, 0x79, 0x66, 0xc7, 0x56,
0x8a, 0x2e, 0x99, 0x84, 0x06, 0xcf, 0x10, 0x2d,
0xec, 0xf0, 0x03, 0x04, 0x1f, 0xd5, 0x99, 0x63,
0x2f, 0xc3, 0x2b, 0x0d, 0xd9, 0x45, 0xf7, 0xbb,
0x0a, 0xc3, 0x46, 0xab, 0xfe, 0x4d, 0x94, 0xc2,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
};
static const u8 test_sha3_512[8 + SHA3_512_DIGEST_SIZE + 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
0xdd, 0x71, 0x3b, 0x44, 0xb6, 0x6c, 0xd7, 0x78,
0xe7, 0x93, 0xa1, 0x4c, 0xd7, 0x24, 0x16, 0xf1,
0xfd, 0xa2, 0x82, 0x4e, 0xed, 0x59, 0xe9, 0x83,
0x15, 0x38, 0x89, 0x7d, 0x39, 0x17, 0x0c, 0xb2,
0xcf, 0x12, 0x80, 0x78, 0xa1, 0x78, 0x41, 0xeb,
0xed, 0x21, 0x4c, 0xa4, 0x4a, 0x5f, 0x30, 0x1a,
0x70, 0x98, 0x4f, 0x14, 0xa2, 0xd1, 0x64, 0x1b,
0xc2, 0x0a, 0xff, 0x3b, 0xe8, 0x26, 0x41, 0x8f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
};
static const u8 test_shake128[8 + SHAKE128_DEFAULT_SIZE + 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
0x41, 0xd6, 0xb8, 0x9c, 0xf8, 0xe8, 0x54, 0xf2,
0x5c, 0xde, 0x51, 0x12, 0xaf, 0x9e, 0x0d, 0x91,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
};
static const u8 test_shake256[8 + SHAKE256_DEFAULT_SIZE + 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
0xab, 0x06, 0xd4, 0xf9, 0x8b, 0xfd, 0xb2, 0xc4,
0xfe, 0xf1, 0xcc, 0xe2, 0x40, 0x45, 0xdd, 0x15,
0xcb, 0xdd, 0x02, 0x8d, 0xb7, 0x9f, 0x1e, 0x67,
0xd6, 0x7f, 0x98, 0x5e, 0x1b, 0x19, 0xf8, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
};
static void test_sha3_224_basic(struct kunit *test)
{
u8 out[8 + SHA3_224_DIGEST_SIZE + 8];
BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_224));
memset(out, 0, sizeof(out));
sha3_224(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_224, sizeof(test_sha3_224),
"SHA3-224 gives wrong output");
}
static void test_sha3_256_basic(struct kunit *test)
{
u8 out[8 + SHA3_256_DIGEST_SIZE + 8];
BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_256));
memset(out, 0, sizeof(out));
sha3_256(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_256, sizeof(test_sha3_256),
"SHA3-256 gives wrong output");
}
static void test_sha3_384_basic(struct kunit *test)
{
u8 out[8 + SHA3_384_DIGEST_SIZE + 8];
BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_384));
memset(out, 0, sizeof(out));
sha3_384(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_384, sizeof(test_sha3_384),
"SHA3-384 gives wrong output");
}
static void test_sha3_512_basic(struct kunit *test)
{
u8 out[8 + SHA3_512_DIGEST_SIZE + 8];
BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_512));
memset(out, 0, sizeof(out));
sha3_512(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_512, sizeof(test_sha3_512),
"SHA3-512 gives wrong output");
}
static void test_shake128_basic(struct kunit *test)
{
u8 out[8 + SHAKE128_DEFAULT_SIZE + 8];
BUILD_BUG_ON(sizeof(out) != sizeof(test_shake128));
memset(out, 0, sizeof(out));
shake128(test_sha3_sample, sizeof(test_sha3_sample) - 1,
out + 8, sizeof(out) - 16);
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128, sizeof(test_shake128),
"SHAKE128 gives wrong output");
}
static void test_shake256_basic(struct kunit *test)
{
u8 out[8 + SHAKE256_DEFAULT_SIZE + 8];
BUILD_BUG_ON(sizeof(out) != sizeof(test_shake256));
memset(out, 0, sizeof(out));
shake256(test_sha3_sample, sizeof(test_sha3_sample) - 1,
out + 8, sizeof(out) - 16);
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256),
"SHAKE256 gives wrong output");
}
/*
* Usable NIST tests.
*
* From: https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
*/
static const u8 test_nist_1600_sample[] = {
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3
};
static const u8 test_shake128_nist_0[] = {
0x7f, 0x9c, 0x2b, 0xa4, 0xe8, 0x8f, 0x82, 0x7d,
0x61, 0x60, 0x45, 0x50, 0x76, 0x05, 0x85, 0x3e
};
static const u8 test_shake128_nist_1600[] = {
0x13, 0x1a, 0xb8, 0xd2, 0xb5, 0x94, 0x94, 0x6b,
0x9c, 0x81, 0x33, 0x3f, 0x9b, 0xb6, 0xe0, 0xce,
};
static const u8 test_shake256_nist_0[] = {
0x46, 0xb9, 0xdd, 0x2b, 0x0b, 0xa8, 0x8d, 0x13,
0x23, 0x3b, 0x3f, 0xeb, 0x74, 0x3e, 0xeb, 0x24,
0x3f, 0xcd, 0x52, 0xea, 0x62, 0xb8, 0x1b, 0x82,
0xb5, 0x0c, 0x27, 0x64, 0x6e, 0xd5, 0x76, 0x2f
};
static const u8 test_shake256_nist_1600[] = {
0xcd, 0x8a, 0x92, 0x0e, 0xd1, 0x41, 0xaa, 0x04,
0x07, 0xa2, 0x2d, 0x59, 0x28, 0x86, 0x52, 0xe9,
0xd9, 0xf1, 0xa7, 0xee, 0x0c, 0x1e, 0x7c, 0x1c,
0xa6, 0x99, 0x42, 0x4d, 0xa8, 0x4a, 0x90, 0x4d,
};
static void test_shake128_nist(struct kunit *test)
{
u8 out[SHAKE128_DEFAULT_SIZE];
shake128("", 0, out, sizeof(out));
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128_nist_0, sizeof(out),
"SHAKE128 gives wrong output for NIST.0");
shake128(test_nist_1600_sample, sizeof(test_nist_1600_sample),
out, sizeof(out));
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128_nist_1600, sizeof(out),
"SHAKE128 gives wrong output for NIST.1600");
}
static void test_shake256_nist(struct kunit *test)
{
u8 out[SHAKE256_DEFAULT_SIZE];
shake256("", 0, out, sizeof(out));
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256_nist_0, sizeof(out),
"SHAKE256 gives wrong output for NIST.0");
shake256(test_nist_1600_sample, sizeof(test_nist_1600_sample),
out, sizeof(out));
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256_nist_1600, sizeof(out),
"SHAKE256 gives wrong output for NIST.1600");
}
static void shake(int alg, const u8 *in, size_t in_len, u8 *out, size_t out_len)
{
if (alg == 0)
shake128(in, in_len, out, out_len);
else
shake256(in, in_len, out, out_len);
}
static void shake_init(struct shake_ctx *ctx, int alg)
{
if (alg == 0)
shake128_init(ctx);
else
shake256_init(ctx);
}
/*
* Test each of SHAKE128 and SHAKE256 with all input lengths 0 through 4096, for
* both input and output. The input and output lengths cycle through the values
* together, so we do 4096 tests total. To verify all the SHAKE outputs,
* compute and verify the SHA3-256 digest of all of them concatenated together.
*/
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 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);
for (size_t in_len = 0; in_len <= max_len; in_len++) {
size_t out_len = (in_len * 293) % (max_len + 1);
shake(alg, in, in_len, out, out_len);
sha3_update(&main_ctx, out, out_len);
}
sha3_final(&main_ctx, main_hash);
if (alg == 0)
KUNIT_ASSERT_MEMEQ_MSG(test, main_hash,
shake128_testvec_consolidated,
sizeof(main_hash),
"shake128() gives wrong output");
else
KUNIT_ASSERT_MEMEQ_MSG(test, main_hash,
shake256_testvec_consolidated,
sizeof(main_hash),
"shake256() gives wrong output");
}
}
/*
* Test that a sequence of SHAKE squeezes gives the same output as a single
* squeeze of the same total length.
*/
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);
for (int i = 0; i < 2000; i++) {
const int alg = rand32() % 2;
const size_t in_len = rand_length(max_len);
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];
struct shake_ctx ctx;
size_t remaining_len, j, num_parts;
rand_bytes(in, in_len);
rand_bytes(out, out_len);
/* Compute the output using the one-shot function. */
shake(alg, in, in_len, ref_out, out_len);
/* Compute the output using a random sequence of squeezes. */
shake_init(&ctx, alg);
shake_update(&ctx, in, in_len);
remaining_len = out_len;
j = 0;
num_parts = 0;
while (rand_bool()) {
size_t part_len = rand_length(remaining_len);
shake_squeeze(&ctx, &out[j], part_len);
num_parts++;
j += part_len;
remaining_len -= part_len;
}
if (remaining_len != 0 || rand_bool()) {
shake_squeeze(&ctx, &out[j], remaining_len);
num_parts++;
}
/* Verify that the outputs are the same. */
KUNIT_ASSERT_MEMEQ_MSG(
test, out, ref_out, out_len,
"Multi-squeeze test failed with in_len=%zu in_offs=%zu out_len=%zu out_offs=%zu num_parts=%zu alg=%d",
in_len, in_offs, out_len, out_offs, num_parts, alg);
}
}
/*
* Test that SHAKE operations on buffers immediately followed by an unmapped
* page work as expected. This catches out-of-bounds memory accesses even if
* they occur in assembly code.
*/
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);
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];
rand_bytes(reg_buf, len);
memcpy(guarded_buf, reg_buf, len);
shake(alg, reg_buf, len, reg_buf, len);
shake(alg, guarded_buf, len, guarded_buf, len);
KUNIT_ASSERT_MEMEQ_MSG(
test, reg_buf, guarded_buf, len,
"Guard page test failed with len=%zu alg=%d",
len, alg);
}
}
}
static struct kunit_case sha3_test_cases[] = {
HASH_KUNIT_CASES,
KUNIT_CASE(test_sha3_224_basic),
KUNIT_CASE(test_sha3_256_basic),
KUNIT_CASE(test_sha3_384_basic),
KUNIT_CASE(test_sha3_512_basic),
KUNIT_CASE(test_shake128_basic),
KUNIT_CASE(test_shake256_basic),
KUNIT_CASE(test_shake128_nist),
KUNIT_CASE(test_shake256_nist),
KUNIT_CASE(test_shake_all_lens_up_to_4096),
KUNIT_CASE(test_shake_multiple_squeezes),
KUNIT_CASE(test_shake_with_guarded_bufs),
KUNIT_CASE(benchmark_hash),
{},
};
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);
MODULE_DESCRIPTION("KUnit tests and benchmark for SHA3");
MODULE_LICENSE("GPL");

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Script that generates test vectors for the given cryptographic hash function.
# Script that generates test vectors for the given hash function.
#
# Copyright 2025 Google LLC
@@ -50,11 +50,42 @@ class Poly1305:
m = (self.h + self.s) % 2**128
return m.to_bytes(16, byteorder='little')
POLYVAL_POLY = sum((1 << i) for i in [128, 127, 126, 121, 0])
POLYVAL_BLOCK_SIZE = 16
# A straightforward, unoptimized implementation of POLYVAL.
# Reference: https://datatracker.ietf.org/doc/html/rfc8452
class Polyval:
def __init__(self, key):
assert len(key) == 16
self.h = int.from_bytes(key, byteorder='little')
self.acc = 0
# Note: this supports partial blocks only at the end.
def update(self, data):
for i in range(0, len(data), 16):
# acc += block
self.acc ^= int.from_bytes(data[i:i+16], byteorder='little')
# acc = (acc * h * x^-128) mod POLYVAL_POLY
product = 0
for j in range(128):
if (self.h & (1 << j)) != 0:
product ^= self.acc << j
if (product & (1 << j)) != 0:
product ^= POLYVAL_POLY << j
self.acc = product >> 128
return self
def digest(self):
return self.acc.to_bytes(16, byteorder='little')
def hash_init(alg):
if alg == 'poly1305':
# Use a fixed random key here, to present Poly1305 as an unkeyed hash.
# This allows all the test cases for unkeyed hashes to work on Poly1305.
return Poly1305(rand_bytes(POLY1305_KEY_SIZE))
if alg == 'polyval':
return Polyval(rand_bytes(POLYVAL_BLOCK_SIZE))
return hashlib.new(alg)
def hash_update(ctx, data):
@@ -85,9 +116,9 @@ def print_c_struct_u8_array_field(name, value):
print('\t\t},')
def alg_digest_size_const(alg):
if alg == 'blake2s':
return 'BLAKE2S_HASH_SIZE'
return f'{alg.upper()}_DIGEST_SIZE'
if alg.startswith('blake2'):
return f'{alg.upper()}_HASH_SIZE'
return f'{alg.upper().replace('-', '_')}_DIGEST_SIZE'
def gen_unkeyed_testvecs(alg):
print('')
@@ -111,6 +142,18 @@ def gen_unkeyed_testvecs(alg):
f'hash_testvec_consolidated[{alg_digest_size_const(alg)}]',
hash_final(ctx))
def gen_additional_sha3_testvecs():
max_len = 4096
in_data = rand_bytes(max_len)
for alg in ['shake128', 'shake256']:
ctx = hashlib.new('sha3-256')
for in_len in range(max_len + 1):
out_len = (in_len * 293) % (max_len + 1)
out = hashlib.new(alg, data=in_data[:in_len]).digest(out_len)
ctx.update(out)
print_static_u8_array_definition(f'{alg}_testvec_consolidated[SHA3_256_DIGEST_SIZE]',
ctx.digest())
def gen_hmac_testvecs(alg):
ctx = hmac.new(rand_bytes(32), digestmod=alg)
data = rand_bytes(4096)
@@ -124,19 +167,22 @@ def gen_hmac_testvecs(alg):
f'hmac_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]',
ctx.digest())
BLAKE2S_KEY_SIZE = 32
BLAKE2S_HASH_SIZE = 32
def gen_additional_blake2s_testvecs():
def gen_additional_blake2_testvecs(alg):
if alg == 'blake2s':
(max_key_size, max_hash_size) = (32, 32)
elif alg == 'blake2b':
(max_key_size, max_hash_size) = (64, 64)
else:
raise ValueError(f'Unsupported alg: {alg}')
hashes = b''
for key_len in range(BLAKE2S_KEY_SIZE + 1):
for out_len in range(1, BLAKE2S_HASH_SIZE + 1):
h = hashlib.blake2s(digest_size=out_len, key=rand_bytes(key_len))
for key_len in range(max_key_size + 1):
for out_len in range(1, max_hash_size + 1):
h = hashlib.new(alg, digest_size=out_len, key=rand_bytes(key_len))
h.update(rand_bytes(100))
hashes += h.digest()
print_static_u8_array_definition(
'blake2s_keyed_testvec_consolidated[BLAKE2S_HASH_SIZE]',
compute_hash('blake2s', hashes))
f'{alg}_keyed_testvec_consolidated[{alg_digest_size_const(alg)}]',
compute_hash(alg, hashes))
def gen_additional_poly1305_testvecs():
key = b'\xff' * POLY1305_KEY_SIZE
@@ -150,19 +196,40 @@ def gen_additional_poly1305_testvecs():
'poly1305_allones_macofmacs[POLY1305_DIGEST_SIZE]',
Poly1305(key).update(data).digest())
def gen_additional_polyval_testvecs():
key = b'\xff' * POLYVAL_BLOCK_SIZE
hashes = b''
for data_len in range(0, 4097, 16):
hashes += Polyval(key).update(b'\xff' * data_len).digest()
print_static_u8_array_definition(
'polyval_allones_hashofhashes[POLYVAL_DIGEST_SIZE]',
Polyval(key).update(hashes).digest())
if len(sys.argv) != 2:
sys.stderr.write('Usage: gen-hash-testvecs.py ALGORITHM\n')
sys.stderr.write('ALGORITHM may be any supported by Python hashlib, or poly1305.\n')
sys.stderr.write('ALGORITHM may be any supported by Python hashlib; or poly1305, polyval, or sha3.\n')
sys.stderr.write('Example: gen-hash-testvecs.py sha512\n')
sys.exit(1)
alg = sys.argv[1]
print('/* SPDX-License-Identifier: GPL-2.0-or-later */')
print(f'/* This file was generated by: {sys.argv[0]} {" ".join(sys.argv[1:])} */')
gen_unkeyed_testvecs(alg)
if alg == 'blake2s':
gen_additional_blake2s_testvecs()
if alg.startswith('blake2'):
gen_unkeyed_testvecs(alg)
gen_additional_blake2_testvecs(alg)
elif alg == 'poly1305':
gen_unkeyed_testvecs(alg)
gen_additional_poly1305_testvecs()
elif alg == 'polyval':
gen_unkeyed_testvecs(alg)
gen_additional_polyval_testvecs()
elif alg == 'sha3':
print()
print('/* SHA3-256 test vectors */')
gen_unkeyed_testvecs('sha3-256')
print()
print('/* SHAKE test vectors */')
gen_additional_sha3_testvecs()
else:
gen_unkeyed_testvecs(alg)
gen_hmac_testvecs(alg)