Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/lib/crypto/tests/sha3_kunit.c
38184 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*/
6
#include <crypto/sha3.h>
7
#include "sha3-testvecs.h"
8
9
#define HASH sha3_256
10
#define HASH_CTX sha3_ctx
11
#define HASH_SIZE SHA3_256_DIGEST_SIZE
12
#define HASH_INIT sha3_256_init
13
#define HASH_UPDATE sha3_update
14
#define HASH_FINAL sha3_final
15
#include "hash-test-template.h"
16
17
/*
18
* Sample message and the output generated for various algorithms by passing it
19
* into "openssl sha3-224" etc..
20
*/
21
static const u8 test_sha3_sample[] =
22
"The quick red fox jumped over the lazy brown dog!\n"
23
"The quick red fox jumped over the lazy brown dog!\n"
24
"The quick red fox jumped over the lazy brown dog!\n"
25
"The quick red fox jumped over the lazy brown dog!\n";
26
27
static const u8 test_sha3_224[8 + SHA3_224_DIGEST_SIZE + 8] = {
28
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
29
0xd6, 0xe8, 0xd8, 0x80, 0xfa, 0x42, 0x80, 0x70,
30
0x7e, 0x7f, 0xd7, 0xd2, 0xd7, 0x7a, 0x35, 0x65,
31
0xf0, 0x0b, 0x4f, 0x9f, 0x2a, 0x33, 0xca, 0x0a,
32
0xef, 0xa6, 0x4c, 0xb8,
33
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
34
};
35
36
static const u8 test_sha3_256[8 + SHA3_256_DIGEST_SIZE + 8] = {
37
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
38
0xdb, 0x3b, 0xb0, 0xb8, 0x8d, 0x15, 0x78, 0xe5,
39
0x78, 0x76, 0x8e, 0x39, 0x7e, 0x89, 0x86, 0xb9,
40
0x14, 0x3a, 0x1e, 0xe7, 0x96, 0x7c, 0xf3, 0x25,
41
0x70, 0xbd, 0xc3, 0xa9, 0xae, 0x63, 0x71, 0x1d,
42
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
43
};
44
45
static const u8 test_sha3_384[8 + SHA3_384_DIGEST_SIZE + 8] = {
46
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
47
0x2d, 0x4b, 0x29, 0x85, 0x19, 0x94, 0xaa, 0x31,
48
0x9b, 0x04, 0x9d, 0x6e, 0x79, 0x66, 0xc7, 0x56,
49
0x8a, 0x2e, 0x99, 0x84, 0x06, 0xcf, 0x10, 0x2d,
50
0xec, 0xf0, 0x03, 0x04, 0x1f, 0xd5, 0x99, 0x63,
51
0x2f, 0xc3, 0x2b, 0x0d, 0xd9, 0x45, 0xf7, 0xbb,
52
0x0a, 0xc3, 0x46, 0xab, 0xfe, 0x4d, 0x94, 0xc2,
53
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
54
};
55
56
static const u8 test_sha3_512[8 + SHA3_512_DIGEST_SIZE + 8] = {
57
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
58
0xdd, 0x71, 0x3b, 0x44, 0xb6, 0x6c, 0xd7, 0x78,
59
0xe7, 0x93, 0xa1, 0x4c, 0xd7, 0x24, 0x16, 0xf1,
60
0xfd, 0xa2, 0x82, 0x4e, 0xed, 0x59, 0xe9, 0x83,
61
0x15, 0x38, 0x89, 0x7d, 0x39, 0x17, 0x0c, 0xb2,
62
0xcf, 0x12, 0x80, 0x78, 0xa1, 0x78, 0x41, 0xeb,
63
0xed, 0x21, 0x4c, 0xa4, 0x4a, 0x5f, 0x30, 0x1a,
64
0x70, 0x98, 0x4f, 0x14, 0xa2, 0xd1, 0x64, 0x1b,
65
0xc2, 0x0a, 0xff, 0x3b, 0xe8, 0x26, 0x41, 0x8f,
66
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
67
};
68
69
static const u8 test_shake128[8 + SHAKE128_DEFAULT_SIZE + 8] = {
70
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
71
0x41, 0xd6, 0xb8, 0x9c, 0xf8, 0xe8, 0x54, 0xf2,
72
0x5c, 0xde, 0x51, 0x12, 0xaf, 0x9e, 0x0d, 0x91,
73
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
74
};
75
76
static const u8 test_shake256[8 + SHAKE256_DEFAULT_SIZE + 8] = {
77
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
78
0xab, 0x06, 0xd4, 0xf9, 0x8b, 0xfd, 0xb2, 0xc4,
79
0xfe, 0xf1, 0xcc, 0xe2, 0x40, 0x45, 0xdd, 0x15,
80
0xcb, 0xdd, 0x02, 0x8d, 0xb7, 0x9f, 0x1e, 0x67,
81
0xd6, 0x7f, 0x98, 0x5e, 0x1b, 0x19, 0xf8, 0x01,
82
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
83
};
84
85
static void test_sha3_224_basic(struct kunit *test)
86
{
87
u8 out[8 + SHA3_224_DIGEST_SIZE + 8];
88
89
BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_224));
90
91
memset(out, 0, sizeof(out));
92
sha3_224(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
93
94
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_224, sizeof(test_sha3_224),
95
"SHA3-224 gives wrong output");
96
}
97
98
static void test_sha3_256_basic(struct kunit *test)
99
{
100
u8 out[8 + SHA3_256_DIGEST_SIZE + 8];
101
102
BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_256));
103
104
memset(out, 0, sizeof(out));
105
sha3_256(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
106
107
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_256, sizeof(test_sha3_256),
108
"SHA3-256 gives wrong output");
109
}
110
111
static void test_sha3_384_basic(struct kunit *test)
112
{
113
u8 out[8 + SHA3_384_DIGEST_SIZE + 8];
114
115
BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_384));
116
117
memset(out, 0, sizeof(out));
118
sha3_384(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
119
120
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_384, sizeof(test_sha3_384),
121
"SHA3-384 gives wrong output");
122
}
123
124
static void test_sha3_512_basic(struct kunit *test)
125
{
126
u8 out[8 + SHA3_512_DIGEST_SIZE + 8];
127
128
BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_512));
129
130
memset(out, 0, sizeof(out));
131
sha3_512(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
132
133
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_512, sizeof(test_sha3_512),
134
"SHA3-512 gives wrong output");
135
}
136
137
static void test_shake128_basic(struct kunit *test)
138
{
139
u8 out[8 + SHAKE128_DEFAULT_SIZE + 8];
140
141
BUILD_BUG_ON(sizeof(out) != sizeof(test_shake128));
142
143
memset(out, 0, sizeof(out));
144
shake128(test_sha3_sample, sizeof(test_sha3_sample) - 1,
145
out + 8, sizeof(out) - 16);
146
147
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128, sizeof(test_shake128),
148
"SHAKE128 gives wrong output");
149
}
150
151
static void test_shake256_basic(struct kunit *test)
152
{
153
u8 out[8 + SHAKE256_DEFAULT_SIZE + 8];
154
155
BUILD_BUG_ON(sizeof(out) != sizeof(test_shake256));
156
157
memset(out, 0, sizeof(out));
158
shake256(test_sha3_sample, sizeof(test_sha3_sample) - 1,
159
out + 8, sizeof(out) - 16);
160
161
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256),
162
"SHAKE256 gives wrong output");
163
}
164
165
/*
166
* Usable NIST tests.
167
*
168
* From: https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
169
*/
170
static const u8 test_nist_1600_sample[] = {
171
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
172
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
173
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
174
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
175
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
176
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
177
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
178
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
179
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
180
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
181
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
182
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
183
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
184
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
185
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
186
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
187
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
188
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
189
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
190
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
191
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
192
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
193
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
194
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
195
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3
196
};
197
198
static const u8 test_shake128_nist_0[] = {
199
0x7f, 0x9c, 0x2b, 0xa4, 0xe8, 0x8f, 0x82, 0x7d,
200
0x61, 0x60, 0x45, 0x50, 0x76, 0x05, 0x85, 0x3e
201
};
202
203
static const u8 test_shake128_nist_1600[] = {
204
0x13, 0x1a, 0xb8, 0xd2, 0xb5, 0x94, 0x94, 0x6b,
205
0x9c, 0x81, 0x33, 0x3f, 0x9b, 0xb6, 0xe0, 0xce,
206
};
207
208
static const u8 test_shake256_nist_0[] = {
209
0x46, 0xb9, 0xdd, 0x2b, 0x0b, 0xa8, 0x8d, 0x13,
210
0x23, 0x3b, 0x3f, 0xeb, 0x74, 0x3e, 0xeb, 0x24,
211
0x3f, 0xcd, 0x52, 0xea, 0x62, 0xb8, 0x1b, 0x82,
212
0xb5, 0x0c, 0x27, 0x64, 0x6e, 0xd5, 0x76, 0x2f
213
};
214
215
static const u8 test_shake256_nist_1600[] = {
216
0xcd, 0x8a, 0x92, 0x0e, 0xd1, 0x41, 0xaa, 0x04,
217
0x07, 0xa2, 0x2d, 0x59, 0x28, 0x86, 0x52, 0xe9,
218
0xd9, 0xf1, 0xa7, 0xee, 0x0c, 0x1e, 0x7c, 0x1c,
219
0xa6, 0x99, 0x42, 0x4d, 0xa8, 0x4a, 0x90, 0x4d,
220
};
221
222
static void test_shake128_nist(struct kunit *test)
223
{
224
u8 out[SHAKE128_DEFAULT_SIZE];
225
226
shake128("", 0, out, sizeof(out));
227
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128_nist_0, sizeof(out),
228
"SHAKE128 gives wrong output for NIST.0");
229
230
shake128(test_nist_1600_sample, sizeof(test_nist_1600_sample),
231
out, sizeof(out));
232
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128_nist_1600, sizeof(out),
233
"SHAKE128 gives wrong output for NIST.1600");
234
}
235
236
static void test_shake256_nist(struct kunit *test)
237
{
238
u8 out[SHAKE256_DEFAULT_SIZE];
239
240
shake256("", 0, out, sizeof(out));
241
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256_nist_0, sizeof(out),
242
"SHAKE256 gives wrong output for NIST.0");
243
244
shake256(test_nist_1600_sample, sizeof(test_nist_1600_sample),
245
out, sizeof(out));
246
KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256_nist_1600, sizeof(out),
247
"SHAKE256 gives wrong output for NIST.1600");
248
}
249
250
static void shake(int alg, const u8 *in, size_t in_len, u8 *out, size_t out_len)
251
{
252
if (alg == 0)
253
shake128(in, in_len, out, out_len);
254
else
255
shake256(in, in_len, out, out_len);
256
}
257
258
static void shake_init(struct shake_ctx *ctx, int alg)
259
{
260
if (alg == 0)
261
shake128_init(ctx);
262
else
263
shake256_init(ctx);
264
}
265
266
/*
267
* Test each of SHAKE128 and SHAKE256 with all input lengths 0 through 4096, for
268
* both input and output. The input and output lengths cycle through the values
269
* together, so we do 4096 tests total. To verify all the SHAKE outputs,
270
* compute and verify the SHA3-256 digest of all of them concatenated together.
271
*/
272
static void test_shake_all_lens_up_to_4096(struct kunit *test)
273
{
274
struct sha3_ctx main_ctx;
275
const size_t max_len = 4096;
276
u8 *const in = test_buf;
277
u8 *const out = &test_buf[TEST_BUF_LEN - max_len];
278
u8 main_hash[SHA3_256_DIGEST_SIZE];
279
280
KUNIT_ASSERT_LE(test, 2 * max_len, TEST_BUF_LEN);
281
282
rand_bytes_seeded_from_len(in, max_len);
283
for (int alg = 0; alg < 2; alg++) {
284
sha3_256_init(&main_ctx);
285
for (size_t in_len = 0; in_len <= max_len; in_len++) {
286
size_t out_len = (in_len * 293) % (max_len + 1);
287
288
shake(alg, in, in_len, out, out_len);
289
sha3_update(&main_ctx, out, out_len);
290
}
291
sha3_final(&main_ctx, main_hash);
292
if (alg == 0)
293
KUNIT_ASSERT_MEMEQ_MSG(test, main_hash,
294
shake128_testvec_consolidated,
295
sizeof(main_hash),
296
"shake128() gives wrong output");
297
else
298
KUNIT_ASSERT_MEMEQ_MSG(test, main_hash,
299
shake256_testvec_consolidated,
300
sizeof(main_hash),
301
"shake256() gives wrong output");
302
}
303
}
304
305
/*
306
* Test that a sequence of SHAKE squeezes gives the same output as a single
307
* squeeze of the same total length.
308
*/
309
static void test_shake_multiple_squeezes(struct kunit *test)
310
{
311
const size_t max_len = 512;
312
u8 *ref_out;
313
314
KUNIT_ASSERT_GE(test, TEST_BUF_LEN, 2 * max_len);
315
316
ref_out = kunit_kzalloc(test, max_len, GFP_KERNEL);
317
KUNIT_ASSERT_NOT_NULL(test, ref_out);
318
319
for (int i = 0; i < 2000; i++) {
320
const int alg = rand32() % 2;
321
const size_t in_len = rand_length(max_len);
322
const size_t out_len = rand_length(max_len);
323
const size_t in_offs = rand_offset(max_len - in_len);
324
const size_t out_offs = rand_offset(max_len - out_len);
325
u8 *const in = &test_buf[in_offs];
326
u8 *const out = &test_buf[out_offs];
327
struct shake_ctx ctx;
328
size_t remaining_len, j, num_parts;
329
330
rand_bytes(in, in_len);
331
rand_bytes(out, out_len);
332
333
/* Compute the output using the one-shot function. */
334
shake(alg, in, in_len, ref_out, out_len);
335
336
/* Compute the output using a random sequence of squeezes. */
337
shake_init(&ctx, alg);
338
shake_update(&ctx, in, in_len);
339
remaining_len = out_len;
340
j = 0;
341
num_parts = 0;
342
while (rand_bool()) {
343
size_t part_len = rand_length(remaining_len);
344
345
shake_squeeze(&ctx, &out[j], part_len);
346
num_parts++;
347
j += part_len;
348
remaining_len -= part_len;
349
}
350
if (remaining_len != 0 || rand_bool()) {
351
shake_squeeze(&ctx, &out[j], remaining_len);
352
num_parts++;
353
}
354
355
/* Verify that the outputs are the same. */
356
KUNIT_ASSERT_MEMEQ_MSG(
357
test, out, ref_out, out_len,
358
"Multi-squeeze test failed with in_len=%zu in_offs=%zu out_len=%zu out_offs=%zu num_parts=%zu alg=%d",
359
in_len, in_offs, out_len, out_offs, num_parts, alg);
360
}
361
}
362
363
/*
364
* Test that SHAKE operations on buffers immediately followed by an unmapped
365
* page work as expected. This catches out-of-bounds memory accesses even if
366
* they occur in assembly code.
367
*/
368
static void test_shake_with_guarded_bufs(struct kunit *test)
369
{
370
const size_t max_len = 512;
371
u8 *reg_buf;
372
373
KUNIT_ASSERT_GE(test, TEST_BUF_LEN, max_len);
374
375
reg_buf = kunit_kzalloc(test, max_len, GFP_KERNEL);
376
KUNIT_ASSERT_NOT_NULL(test, reg_buf);
377
378
for (int alg = 0; alg < 2; alg++) {
379
for (size_t len = 0; len <= max_len; len++) {
380
u8 *guarded_buf = &test_buf[TEST_BUF_LEN - len];
381
382
rand_bytes(reg_buf, len);
383
memcpy(guarded_buf, reg_buf, len);
384
385
shake(alg, reg_buf, len, reg_buf, len);
386
shake(alg, guarded_buf, len, guarded_buf, len);
387
388
KUNIT_ASSERT_MEMEQ_MSG(
389
test, reg_buf, guarded_buf, len,
390
"Guard page test failed with len=%zu alg=%d",
391
len, alg);
392
}
393
}
394
}
395
396
static struct kunit_case sha3_test_cases[] = {
397
HASH_KUNIT_CASES,
398
KUNIT_CASE(test_sha3_224_basic),
399
KUNIT_CASE(test_sha3_256_basic),
400
KUNIT_CASE(test_sha3_384_basic),
401
KUNIT_CASE(test_sha3_512_basic),
402
KUNIT_CASE(test_shake128_basic),
403
KUNIT_CASE(test_shake256_basic),
404
KUNIT_CASE(test_shake128_nist),
405
KUNIT_CASE(test_shake256_nist),
406
KUNIT_CASE(test_shake_all_lens_up_to_4096),
407
KUNIT_CASE(test_shake_multiple_squeezes),
408
KUNIT_CASE(test_shake_with_guarded_bufs),
409
KUNIT_CASE(benchmark_hash),
410
{},
411
};
412
413
static struct kunit_suite sha3_test_suite = {
414
.name = "sha3",
415
.test_cases = sha3_test_cases,
416
.suite_init = hash_suite_init,
417
.suite_exit = hash_suite_exit,
418
};
419
kunit_test_suite(sha3_test_suite);
420
421
MODULE_DESCRIPTION("KUnit tests and benchmark for SHA3");
422
MODULE_LICENSE("GPL");
423
424