hash-test-template.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Test cases for hash functions, including a benchmark. This is included by
  4. * KUnit test suites that want to use it. See sha512_kunit.c for an example.
  5. *
  6. * Copyright 2025 Google LLC
  7. */
  8. #include <kunit/run-in-irq-context.h>
  9. #include <kunit/test.h>
  10. #include <linux/vmalloc.h>
  11. /* test_buf is a guarded buffer, i.e. &test_buf[TEST_BUF_LEN] is not mapped. */
  12. #define TEST_BUF_LEN 16384
  13. static u8 *test_buf;
  14. static u8 *orig_test_buf;
  15. static u64 random_seed;
  16. /*
  17. * This is a simple linear congruential generator. It is used only for testing,
  18. * which does not require cryptographically secure random numbers. A hard-coded
  19. * algorithm is used instead of <linux/prandom.h> so that it matches the
  20. * algorithm used by the test vector generation script. This allows the input
  21. * data in random test vectors to be concisely stored as just the seed.
  22. */
  23. static u32 rand32(void)
  24. {
  25. random_seed = (random_seed * 25214903917 + 11) & ((1ULL << 48) - 1);
  26. return random_seed >> 16;
  27. }
  28. static void rand_bytes(u8 *out, size_t len)
  29. {
  30. for (size_t i = 0; i < len; i++)
  31. out[i] = rand32();
  32. }
  33. static void rand_bytes_seeded_from_len(u8 *out, size_t len)
  34. {
  35. random_seed = len;
  36. rand_bytes(out, len);
  37. }
  38. static bool rand_bool(void)
  39. {
  40. return rand32() % 2;
  41. }
  42. /* Generate a random length, preferring small lengths. */
  43. static size_t rand_length(size_t max_len)
  44. {
  45. size_t len;
  46. switch (rand32() % 3) {
  47. case 0:
  48. len = rand32() % 128;
  49. break;
  50. case 1:
  51. len = rand32() % 3072;
  52. break;
  53. default:
  54. len = rand32();
  55. break;
  56. }
  57. return len % (max_len + 1);
  58. }
  59. static size_t rand_offset(size_t max_offset)
  60. {
  61. return min(rand32() % 128, max_offset);
  62. }
  63. static int hash_suite_init(struct kunit_suite *suite)
  64. {
  65. /*
  66. * Allocate the test buffer using vmalloc() with a page-aligned length
  67. * so that it is immediately followed by a guard page. This allows
  68. * buffer overreads to be detected, even in assembly code.
  69. */
  70. size_t alloc_len = round_up(TEST_BUF_LEN, PAGE_SIZE);
  71. orig_test_buf = vmalloc(alloc_len);
  72. if (!orig_test_buf)
  73. return -ENOMEM;
  74. test_buf = orig_test_buf + alloc_len - TEST_BUF_LEN;
  75. return 0;
  76. }
  77. static void hash_suite_exit(struct kunit_suite *suite)
  78. {
  79. vfree(orig_test_buf);
  80. orig_test_buf = NULL;
  81. test_buf = NULL;
  82. }
  83. /*
  84. * Test the hash function against a list of test vectors.
  85. *
  86. * Note that it's only necessary to run each test vector in one way (e.g.,
  87. * one-shot instead of incremental), since consistency between different ways of
  88. * using the APIs is verified by other test cases.
  89. */
  90. static void test_hash_test_vectors(struct kunit *test)
  91. {
  92. for (size_t i = 0; i < ARRAY_SIZE(hash_testvecs); i++) {
  93. size_t data_len = hash_testvecs[i].data_len;
  94. u8 actual_hash[HASH_SIZE];
  95. KUNIT_ASSERT_LE(test, data_len, TEST_BUF_LEN);
  96. rand_bytes_seeded_from_len(test_buf, data_len);
  97. HASH(test_buf, data_len, actual_hash);
  98. KUNIT_ASSERT_MEMEQ_MSG(
  99. test, actual_hash, hash_testvecs[i].digest, HASH_SIZE,
  100. "Wrong result with test vector %zu; data_len=%zu", i,
  101. data_len);
  102. }
  103. }
  104. /*
  105. * Test that the hash function produces correct results for *every* length up to
  106. * 4096 bytes. To do this, generate seeded random data, then calculate a hash
  107. * value for each length 0..4096, then hash the hash values. Verify just the
  108. * final hash value, which should match only when all hash values were correct.
  109. */
  110. static void test_hash_all_lens_up_to_4096(struct kunit *test)
  111. {
  112. struct HASH_CTX ctx;
  113. u8 hash[HASH_SIZE];
  114. static_assert(TEST_BUF_LEN >= 4096);
  115. rand_bytes_seeded_from_len(test_buf, 4096);
  116. HASH_INIT(&ctx);
  117. for (size_t len = 0; len <= 4096; len++) {
  118. HASH(test_buf, len, hash);
  119. HASH_UPDATE(&ctx, hash, HASH_SIZE);
  120. }
  121. HASH_FINAL(&ctx, hash);
  122. KUNIT_ASSERT_MEMEQ(test, hash, hash_testvec_consolidated, HASH_SIZE);
  123. }
  124. /*
  125. * Test that the hash function produces the same result with a one-shot
  126. * computation as it does with an incremental computation.
  127. */
  128. static void test_hash_incremental_updates(struct kunit *test)
  129. {
  130. for (int i = 0; i < 1000; i++) {
  131. size_t total_len, offset;
  132. struct HASH_CTX ctx;
  133. u8 hash1[HASH_SIZE];
  134. u8 hash2[HASH_SIZE];
  135. size_t num_parts = 0;
  136. size_t remaining_len, cur_offset;
  137. total_len = rand_length(TEST_BUF_LEN);
  138. offset = rand_offset(TEST_BUF_LEN - total_len);
  139. rand_bytes(&test_buf[offset], total_len);
  140. /* Compute the hash value in one shot. */
  141. HASH(&test_buf[offset], total_len, hash1);
  142. /*
  143. * Compute the hash value incrementally, using a randomly
  144. * selected sequence of update lengths that sum to total_len.
  145. */
  146. HASH_INIT(&ctx);
  147. remaining_len = total_len;
  148. cur_offset = offset;
  149. while (rand_bool()) {
  150. size_t part_len = rand_length(remaining_len);
  151. HASH_UPDATE(&ctx, &test_buf[cur_offset], part_len);
  152. num_parts++;
  153. cur_offset += part_len;
  154. remaining_len -= part_len;
  155. }
  156. if (remaining_len != 0 || rand_bool()) {
  157. HASH_UPDATE(&ctx, &test_buf[cur_offset], remaining_len);
  158. num_parts++;
  159. }
  160. HASH_FINAL(&ctx, hash2);
  161. /* Verify that the two hash values are the same. */
  162. KUNIT_ASSERT_MEMEQ_MSG(
  163. test, hash1, hash2, HASH_SIZE,
  164. "Incremental test failed with total_len=%zu num_parts=%zu offset=%zu",
  165. total_len, num_parts, offset);
  166. }
  167. }
  168. /*
  169. * Test that the hash function does not overrun any buffers. Uses a guard page
  170. * to catch buffer overruns even if they occur in assembly code.
  171. */
  172. static void test_hash_buffer_overruns(struct kunit *test)
  173. {
  174. const size_t max_tested_len = TEST_BUF_LEN - sizeof(struct HASH_CTX);
  175. void *const buf_end = &test_buf[TEST_BUF_LEN];
  176. struct HASH_CTX *guarded_ctx = buf_end - sizeof(*guarded_ctx);
  177. rand_bytes(test_buf, TEST_BUF_LEN);
  178. for (int i = 0; i < 100; i++) {
  179. size_t len = rand_length(max_tested_len);
  180. struct HASH_CTX ctx;
  181. u8 hash[HASH_SIZE];
  182. /* Check for overruns of the data buffer. */
  183. HASH(buf_end - len, len, hash);
  184. HASH_INIT(&ctx);
  185. HASH_UPDATE(&ctx, buf_end - len, len);
  186. HASH_FINAL(&ctx, hash);
  187. /* Check for overruns of the hash value buffer. */
  188. HASH(test_buf, len, buf_end - HASH_SIZE);
  189. HASH_INIT(&ctx);
  190. HASH_UPDATE(&ctx, test_buf, len);
  191. HASH_FINAL(&ctx, buf_end - HASH_SIZE);
  192. /* Check for overuns of the hash context. */
  193. HASH_INIT(guarded_ctx);
  194. HASH_UPDATE(guarded_ctx, test_buf, len);
  195. HASH_FINAL(guarded_ctx, hash);
  196. }
  197. }
  198. /*
  199. * Test that the caller is permitted to alias the output digest and source data
  200. * buffer, and also modify the source data buffer after it has been used.
  201. */
  202. static void test_hash_overlaps(struct kunit *test)
  203. {
  204. const size_t max_tested_len = TEST_BUF_LEN - HASH_SIZE;
  205. struct HASH_CTX ctx;
  206. u8 hash[HASH_SIZE];
  207. rand_bytes(test_buf, TEST_BUF_LEN);
  208. for (int i = 0; i < 100; i++) {
  209. size_t len = rand_length(max_tested_len);
  210. size_t offset = HASH_SIZE + rand_offset(max_tested_len - len);
  211. bool left_end = rand_bool();
  212. u8 *ovl_hash = left_end ? &test_buf[offset] :
  213. &test_buf[offset + len - HASH_SIZE];
  214. HASH(&test_buf[offset], len, hash);
  215. HASH(&test_buf[offset], len, ovl_hash);
  216. KUNIT_ASSERT_MEMEQ_MSG(
  217. test, hash, ovl_hash, HASH_SIZE,
  218. "Overlap test 1 failed with len=%zu offset=%zu left_end=%d",
  219. len, offset, left_end);
  220. /* Repeat the above test, but this time use init+update+final */
  221. HASH(&test_buf[offset], len, hash);
  222. HASH_INIT(&ctx);
  223. HASH_UPDATE(&ctx, &test_buf[offset], len);
  224. HASH_FINAL(&ctx, ovl_hash);
  225. KUNIT_ASSERT_MEMEQ_MSG(
  226. test, hash, ovl_hash, HASH_SIZE,
  227. "Overlap test 2 failed with len=%zu offset=%zu left_end=%d",
  228. len, offset, left_end);
  229. /* Test modifying the source data after it was used. */
  230. HASH(&test_buf[offset], len, hash);
  231. HASH_INIT(&ctx);
  232. HASH_UPDATE(&ctx, &test_buf[offset], len);
  233. rand_bytes(&test_buf[offset], len);
  234. HASH_FINAL(&ctx, ovl_hash);
  235. KUNIT_ASSERT_MEMEQ_MSG(
  236. test, hash, ovl_hash, HASH_SIZE,
  237. "Overlap test 3 failed with len=%zu offset=%zu left_end=%d",
  238. len, offset, left_end);
  239. }
  240. }
  241. /*
  242. * Test that if the same data is hashed at different alignments in memory, the
  243. * results are the same.
  244. */
  245. static void test_hash_alignment_consistency(struct kunit *test)
  246. {
  247. u8 hash1[128 + HASH_SIZE];
  248. u8 hash2[128 + HASH_SIZE];
  249. for (int i = 0; i < 100; i++) {
  250. size_t len = rand_length(TEST_BUF_LEN);
  251. size_t data_offs1 = rand_offset(TEST_BUF_LEN - len);
  252. size_t data_offs2 = rand_offset(TEST_BUF_LEN - len);
  253. size_t hash_offs1 = rand_offset(128);
  254. size_t hash_offs2 = rand_offset(128);
  255. rand_bytes(&test_buf[data_offs1], len);
  256. HASH(&test_buf[data_offs1], len, &hash1[hash_offs1]);
  257. memmove(&test_buf[data_offs2], &test_buf[data_offs1], len);
  258. HASH(&test_buf[data_offs2], len, &hash2[hash_offs2]);
  259. KUNIT_ASSERT_MEMEQ_MSG(
  260. test, &hash1[hash_offs1], &hash2[hash_offs2], HASH_SIZE,
  261. "Alignment consistency test failed with len=%zu data_offs=(%zu,%zu) hash_offs=(%zu,%zu)",
  262. len, data_offs1, data_offs2, hash_offs1, hash_offs2);
  263. }
  264. }
  265. /* Test that HASH_FINAL zeroizes the context. */
  266. static void test_hash_ctx_zeroization(struct kunit *test)
  267. {
  268. static const u8 zeroes[sizeof(struct HASH_CTX)];
  269. struct HASH_CTX ctx;
  270. rand_bytes(test_buf, 128);
  271. HASH_INIT(&ctx);
  272. HASH_UPDATE(&ctx, test_buf, 128);
  273. HASH_FINAL(&ctx, test_buf);
  274. KUNIT_ASSERT_MEMEQ_MSG(test, &ctx, zeroes, sizeof(ctx),
  275. "Hash context was not zeroized by finalization");
  276. }
  277. #define IRQ_TEST_DATA_LEN 256
  278. #define IRQ_TEST_NUM_BUFFERS 3 /* matches max concurrency level */
  279. struct hash_irq_test1_state {
  280. u8 expected_hashes[IRQ_TEST_NUM_BUFFERS][HASH_SIZE];
  281. atomic_t seqno;
  282. };
  283. /*
  284. * Compute the hash of one of the test messages and verify that it matches the
  285. * expected hash from @state->expected_hashes. To increase the chance of
  286. * detecting problems, cycle through multiple messages.
  287. */
  288. static bool hash_irq_test1_func(void *state_)
  289. {
  290. struct hash_irq_test1_state *state = state_;
  291. u32 i = (u32)atomic_inc_return(&state->seqno) % IRQ_TEST_NUM_BUFFERS;
  292. u8 actual_hash[HASH_SIZE];
  293. HASH(&test_buf[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN, actual_hash);
  294. return memcmp(actual_hash, state->expected_hashes[i], HASH_SIZE) == 0;
  295. }
  296. /*
  297. * Test that if hashes are computed in task, softirq, and hardirq context
  298. * concurrently, then all results are as expected.
  299. */
  300. static void test_hash_interrupt_context_1(struct kunit *test)
  301. {
  302. struct hash_irq_test1_state state = {};
  303. /* Prepare some test messages and compute the expected hash of each. */
  304. rand_bytes(test_buf, IRQ_TEST_NUM_BUFFERS * IRQ_TEST_DATA_LEN);
  305. for (int i = 0; i < IRQ_TEST_NUM_BUFFERS; i++)
  306. HASH(&test_buf[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN,
  307. state.expected_hashes[i]);
  308. kunit_run_irq_test(test, hash_irq_test1_func, 100000, &state);
  309. }
  310. struct hash_irq_test2_hash_ctx {
  311. struct HASH_CTX hash_ctx;
  312. atomic_t in_use;
  313. int offset;
  314. int step;
  315. };
  316. struct hash_irq_test2_state {
  317. struct hash_irq_test2_hash_ctx ctxs[IRQ_TEST_NUM_BUFFERS];
  318. u8 expected_hash[HASH_SIZE];
  319. u16 update_lens[32];
  320. int num_steps;
  321. };
  322. static bool hash_irq_test2_func(void *state_)
  323. {
  324. struct hash_irq_test2_state *state = state_;
  325. struct hash_irq_test2_hash_ctx *ctx;
  326. bool ret = true;
  327. for (ctx = &state->ctxs[0]; ctx < &state->ctxs[ARRAY_SIZE(state->ctxs)];
  328. ctx++) {
  329. if (atomic_cmpxchg(&ctx->in_use, 0, 1) == 0)
  330. break;
  331. }
  332. if (WARN_ON_ONCE(ctx == &state->ctxs[ARRAY_SIZE(state->ctxs)])) {
  333. /*
  334. * This should never happen, as the number of contexts is equal
  335. * to the maximum concurrency level of kunit_run_irq_test().
  336. */
  337. return false;
  338. }
  339. if (ctx->step == 0) {
  340. /* Init step */
  341. HASH_INIT(&ctx->hash_ctx);
  342. ctx->offset = 0;
  343. ctx->step++;
  344. } else if (ctx->step < state->num_steps - 1) {
  345. /* Update step */
  346. HASH_UPDATE(&ctx->hash_ctx, &test_buf[ctx->offset],
  347. state->update_lens[ctx->step - 1]);
  348. ctx->offset += state->update_lens[ctx->step - 1];
  349. ctx->step++;
  350. } else {
  351. /* Final step */
  352. u8 actual_hash[HASH_SIZE];
  353. if (WARN_ON_ONCE(ctx->offset != TEST_BUF_LEN))
  354. ret = false;
  355. HASH_FINAL(&ctx->hash_ctx, actual_hash);
  356. if (memcmp(actual_hash, state->expected_hash, HASH_SIZE) != 0)
  357. ret = false;
  358. ctx->step = 0;
  359. }
  360. atomic_set_release(&ctx->in_use, 0);
  361. return ret;
  362. }
  363. /*
  364. * Test that if hashes are computed in task, softirq, and hardirq context
  365. * concurrently, *including doing different parts of the same incremental
  366. * computation in different contexts*, then all results are as expected.
  367. * Besides detecting bugs similar to those that test_hash_interrupt_context_1
  368. * can detect, this test case can also detect bugs where hash function
  369. * implementations don't correctly handle these mixed incremental computations.
  370. */
  371. static void test_hash_interrupt_context_2(struct kunit *test)
  372. {
  373. struct hash_irq_test2_state *state;
  374. int remaining = TEST_BUF_LEN;
  375. state = kunit_kzalloc(test, sizeof(*state), GFP_KERNEL);
  376. KUNIT_ASSERT_NOT_NULL(test, state);
  377. rand_bytes(test_buf, TEST_BUF_LEN);
  378. HASH(test_buf, TEST_BUF_LEN, state->expected_hash);
  379. /*
  380. * Generate a list of update lengths to use. Ensure that it contains
  381. * multiple entries but is limited to a maximum length.
  382. */
  383. static_assert(TEST_BUF_LEN / 4096 > 1);
  384. for (state->num_steps = 0;
  385. state->num_steps < ARRAY_SIZE(state->update_lens) - 1 && remaining;
  386. state->num_steps++) {
  387. state->update_lens[state->num_steps] =
  388. rand_length(min(remaining, 4096));
  389. remaining -= state->update_lens[state->num_steps];
  390. }
  391. if (remaining)
  392. state->update_lens[state->num_steps++] = remaining;
  393. state->num_steps += 2; /* for init and final */
  394. kunit_run_irq_test(test, hash_irq_test2_func, 250000, state);
  395. }
  396. #define UNKEYED_HASH_KUNIT_CASES \
  397. KUNIT_CASE(test_hash_test_vectors), \
  398. KUNIT_CASE(test_hash_all_lens_up_to_4096), \
  399. KUNIT_CASE(test_hash_incremental_updates), \
  400. KUNIT_CASE(test_hash_buffer_overruns), \
  401. KUNIT_CASE(test_hash_overlaps), \
  402. KUNIT_CASE(test_hash_alignment_consistency), \
  403. KUNIT_CASE(test_hash_ctx_zeroization), \
  404. KUNIT_CASE(test_hash_interrupt_context_1), \
  405. KUNIT_CASE(test_hash_interrupt_context_2)
  406. /* benchmark_hash is omitted so that the suites can put it last. */
  407. #ifdef HMAC
  408. /*
  409. * Test the corresponding HMAC variant.
  410. *
  411. * This test case is fairly short, since HMAC is just a simple C wrapper around
  412. * the underlying unkeyed hash function, which is already well-tested by the
  413. * other test cases. It's not useful to test things like data alignment or
  414. * interrupt context again for HMAC, nor to have a long list of test vectors.
  415. *
  416. * Thus, just do a single consolidated test, which covers all data lengths up to
  417. * 4096 bytes and all key lengths up to 292 bytes. For each data length, select
  418. * a key length, generate the inputs from a seed, and compute the HMAC value.
  419. * Concatenate all these HMAC values together, and compute the HMAC of that.
  420. * Verify that value. If this fails, then the HMAC implementation is wrong.
  421. * This won't show which specific input failed, but that should be fine. Any
  422. * failure would likely be non-input-specific or also show in the unkeyed tests.
  423. */
  424. static void test_hmac(struct kunit *test)
  425. {
  426. static const u8 zeroes[sizeof(struct HMAC_CTX)];
  427. u8 *raw_key;
  428. struct HMAC_KEY key;
  429. struct HMAC_CTX ctx;
  430. u8 mac[HASH_SIZE];
  431. u8 mac2[HASH_SIZE];
  432. static_assert(TEST_BUF_LEN >= 4096 + 293);
  433. rand_bytes_seeded_from_len(test_buf, 4096);
  434. raw_key = &test_buf[4096];
  435. rand_bytes_seeded_from_len(raw_key, 32);
  436. HMAC_PREPAREKEY(&key, raw_key, 32);
  437. HMAC_INIT(&ctx, &key);
  438. for (size_t data_len = 0; data_len <= 4096; data_len++) {
  439. /*
  440. * Cycle through key lengths as well. Somewhat arbitrarily go
  441. * up to 293, which is somewhat larger than the largest hash
  442. * block size (which is the size at which the key starts being
  443. * hashed down to one block); going higher would not be useful.
  444. * To reduce correlation with data_len, use a prime number here.
  445. */
  446. size_t key_len = data_len % 293;
  447. HMAC_UPDATE(&ctx, test_buf, data_len);
  448. rand_bytes_seeded_from_len(raw_key, key_len);
  449. HMAC_USINGRAWKEY(raw_key, key_len, test_buf, data_len, mac);
  450. HMAC_UPDATE(&ctx, mac, HASH_SIZE);
  451. /* Verify that HMAC() is consistent with HMAC_USINGRAWKEY(). */
  452. HMAC_PREPAREKEY(&key, raw_key, key_len);
  453. HMAC(&key, test_buf, data_len, mac2);
  454. KUNIT_ASSERT_MEMEQ_MSG(
  455. test, mac, mac2, HASH_SIZE,
  456. "HMAC gave different results with raw and prepared keys");
  457. }
  458. HMAC_FINAL(&ctx, mac);
  459. KUNIT_EXPECT_MEMEQ_MSG(test, mac, hmac_testvec_consolidated, HASH_SIZE,
  460. "HMAC gave wrong result");
  461. KUNIT_EXPECT_MEMEQ_MSG(test, &ctx, zeroes, sizeof(ctx),
  462. "HMAC context was not zeroized by finalization");
  463. }
  464. #define HASH_KUNIT_CASES UNKEYED_HASH_KUNIT_CASES, KUNIT_CASE(test_hmac)
  465. #else
  466. #define HASH_KUNIT_CASES UNKEYED_HASH_KUNIT_CASES
  467. #endif
  468. /* Benchmark the hash function on various data lengths. */
  469. static void benchmark_hash(struct kunit *test)
  470. {
  471. static const size_t lens_to_test[] = {
  472. 1, 16, 64, 127, 128, 200, 256,
  473. 511, 512, 1024, 3173, 4096, 16384,
  474. };
  475. u8 hash[HASH_SIZE];
  476. if (!IS_ENABLED(CONFIG_CRYPTO_LIB_BENCHMARK))
  477. kunit_skip(test, "not enabled");
  478. /* Warm-up */
  479. for (size_t i = 0; i < 10000000; i += TEST_BUF_LEN)
  480. HASH(test_buf, TEST_BUF_LEN, hash);
  481. for (size_t i = 0; i < ARRAY_SIZE(lens_to_test); i++) {
  482. size_t len = lens_to_test[i];
  483. /* The '+ 128' tries to account for per-message overhead. */
  484. size_t num_iters = 10000000 / (len + 128);
  485. u64 t;
  486. KUNIT_ASSERT_LE(test, len, TEST_BUF_LEN);
  487. preempt_disable();
  488. t = ktime_get_ns();
  489. for (size_t j = 0; j < num_iters; j++)
  490. HASH(test_buf, len, hash);
  491. t = ktime_get_ns() - t;
  492. preempt_enable();
  493. kunit_info(test, "len=%zu: %llu MB/s", len,
  494. div64_u64((u64)len * num_iters * 1000, t ?: 1));
  495. }
  496. }