xref: /linux/lib/crypto/tests/blake2b_kunit.c (revision 7fc2cd2e4b398c57c9cf961cfea05eadbf34c05c)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright 2025 Google LLC
4  */
5 #include <crypto/blake2b.h>
6 #include "blake2b-testvecs.h"
7 
8 /*
9  * The following are compatibility functions that present BLAKE2b as an unkeyed
10  * hash function that produces hashes of fixed length BLAKE2B_HASH_SIZE, so that
11  * hash-test-template.h can be reused to test it.
12  */
13 
14 static void blake2b_default(const u8 *data, size_t len,
15 			    u8 out[BLAKE2B_HASH_SIZE])
16 {
17 	blake2b(NULL, 0, data, len, out, BLAKE2B_HASH_SIZE);
18 }
19 
20 static void blake2b_init_default(struct blake2b_ctx *ctx)
21 {
22 	blake2b_init(ctx, BLAKE2B_HASH_SIZE);
23 }
24 
25 /*
26  * Generate the HASH_KUNIT_CASES using hash-test-template.h.  These test BLAKE2b
27  * with a key length of 0 and a hash length of BLAKE2B_HASH_SIZE.
28  */
29 #define HASH blake2b_default
30 #define HASH_CTX blake2b_ctx
31 #define HASH_SIZE BLAKE2B_HASH_SIZE
32 #define HASH_INIT blake2b_init_default
33 #define HASH_UPDATE blake2b_update
34 #define HASH_FINAL blake2b_final
35 #include "hash-test-template.h"
36 
37 /*
38  * BLAKE2b specific test case which tests all possible combinations of key
39  * length and hash length.
40  */
41 static void test_blake2b_all_key_and_hash_lens(struct kunit *test)
42 {
43 	const size_t data_len = 100;
44 	u8 *data = &test_buf[0];
45 	u8 *key = data + data_len;
46 	u8 *hash = key + BLAKE2B_KEY_SIZE;
47 	struct blake2b_ctx main_ctx;
48 	u8 main_hash[BLAKE2B_HASH_SIZE];
49 
50 	rand_bytes_seeded_from_len(data, data_len);
51 	blake2b_init(&main_ctx, BLAKE2B_HASH_SIZE);
52 	for (int key_len = 0; key_len <= BLAKE2B_KEY_SIZE; key_len++) {
53 		rand_bytes_seeded_from_len(key, key_len);
54 		for (int out_len = 1; out_len <= BLAKE2B_HASH_SIZE; out_len++) {
55 			blake2b(key, key_len, data, data_len, hash, out_len);
56 			blake2b_update(&main_ctx, hash, out_len);
57 		}
58 	}
59 	blake2b_final(&main_ctx, main_hash);
60 	KUNIT_ASSERT_MEMEQ(test, main_hash, blake2b_keyed_testvec_consolidated,
61 			   BLAKE2B_HASH_SIZE);
62 }
63 
64 /*
65  * BLAKE2b specific test case which tests using a guarded buffer for all allowed
66  * key lengths.  Also tests both blake2b() and blake2b_init_key().
67  */
68 static void test_blake2b_with_guarded_key_buf(struct kunit *test)
69 {
70 	const size_t data_len = 100;
71 
72 	rand_bytes(test_buf, data_len);
73 	for (int key_len = 0; key_len <= BLAKE2B_KEY_SIZE; key_len++) {
74 		u8 key[BLAKE2B_KEY_SIZE];
75 		u8 *guarded_key = &test_buf[TEST_BUF_LEN - key_len];
76 		u8 hash1[BLAKE2B_HASH_SIZE];
77 		u8 hash2[BLAKE2B_HASH_SIZE];
78 		struct blake2b_ctx ctx;
79 
80 		rand_bytes(key, key_len);
81 		memcpy(guarded_key, key, key_len);
82 
83 		blake2b(key, key_len, test_buf, data_len,
84 			hash1, BLAKE2B_HASH_SIZE);
85 		blake2b(guarded_key, key_len, test_buf, data_len,
86 			hash2, BLAKE2B_HASH_SIZE);
87 		KUNIT_ASSERT_MEMEQ(test, hash1, hash2, BLAKE2B_HASH_SIZE);
88 
89 		blake2b_init_key(&ctx, BLAKE2B_HASH_SIZE, guarded_key, key_len);
90 		blake2b_update(&ctx, test_buf, data_len);
91 		blake2b_final(&ctx, hash2);
92 		KUNIT_ASSERT_MEMEQ(test, hash1, hash2, BLAKE2B_HASH_SIZE);
93 	}
94 }
95 
96 /*
97  * BLAKE2b specific test case which tests using a guarded output buffer for all
98  * allowed output lengths.
99  */
100 static void test_blake2b_with_guarded_out_buf(struct kunit *test)
101 {
102 	const size_t data_len = 100;
103 
104 	rand_bytes(test_buf, data_len);
105 	for (int out_len = 1; out_len <= BLAKE2B_HASH_SIZE; out_len++) {
106 		u8 hash[BLAKE2B_HASH_SIZE];
107 		u8 *guarded_hash = &test_buf[TEST_BUF_LEN - out_len];
108 
109 		blake2b(NULL, 0, test_buf, data_len, hash, out_len);
110 		blake2b(NULL, 0, test_buf, data_len, guarded_hash, out_len);
111 		KUNIT_ASSERT_MEMEQ(test, hash, guarded_hash, out_len);
112 	}
113 }
114 
115 static struct kunit_case blake2b_test_cases[] = {
116 	HASH_KUNIT_CASES,
117 	KUNIT_CASE(test_blake2b_all_key_and_hash_lens),
118 	KUNIT_CASE(test_blake2b_with_guarded_key_buf),
119 	KUNIT_CASE(test_blake2b_with_guarded_out_buf),
120 	KUNIT_CASE(benchmark_hash),
121 	{},
122 };
123 
124 static struct kunit_suite blake2b_test_suite = {
125 	.name = "blake2b",
126 	.test_cases = blake2b_test_cases,
127 	.suite_init = hash_suite_init,
128 	.suite_exit = hash_suite_exit,
129 };
130 kunit_test_suite(blake2b_test_suite);
131 
132 MODULE_DESCRIPTION("KUnit tests and benchmark for BLAKE2b");
133 MODULE_LICENSE("GPL");
134