public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/1] lib/crypto: tests: KUnit test-suite for AES
@ 2026-01-19 12:12 Holger Dengler
  2026-01-19 12:12 ` [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests " Holger Dengler
  0 siblings, 1 reply; 7+ messages in thread
From: Holger Dengler @ 2026-01-19 12:12 UTC (permalink / raw)
  To: Eric Biggers, David Laight
  Cc: Ard Biesheuvel, Jason A . Donenfeld, Herbert Xu,
	Harald Freudenberger, Holger Dengler, linux-kernel, linux-crypto

The following patch adds a kunit tests for the aes library.

Changes since v1 [1]:
- move information from cover-letter to commit message
- remove unused struct buf
- add reference to the KAT source
- restructure the benchmark
  - reduce the number of iterations for warm-up and benchmark
  - measure each aes operation and take the minimal measurement for the
    bandwidth calculation
  - normalize bandwidth to MB (power of 10) instead of MiB (power of 2)

Changes since RFC [2]:
- reorder entries in Kconfig/Makefile alphabetically
- fail (instead of skip) in case of failures in key preparation
- replace local constant definitions
- replace macros with helper functions

[1] https://lore.kernel.org/linux-crypto/20260115183831.72010-1-dengler@linux.ibm.com
[2] https://lore.kernel.org/linux-crypto/20260114153138.4896-1-dengler@linux.ibm.com

Example output of the aes_kunit test-suite:

[  316.380919] KTAP version 1
[  316.380923] 1..1
[  316.380964]     KTAP version 1
[  316.380965]     # Subtest: aes
[  316.380966]     # module: aes_kunit
[  316.380968]     1..9
[  316.381071]     ok 1 test_aes128_encrypt
[  316.381129]     ok 2 test_aes128_decrypt
[  316.381186]     ok 3 test_aes192_encrypt
[  316.381248]     ok 4 test_aes192_decrypt
[  316.381309]     ok 5 test_aes256_encrypt
[  316.381367]     ok 6 test_aes256_decrypt
[  316.381411]     # benchmark_aes128: enc (len=16): 500 MB/s
[  316.381414]     # benchmark_aes128: dec (len=16): 500 MB/s
[  316.381447]     ok 7 benchmark_aes128
[  316.381491]     # benchmark_aes192: enc (len=16): 500 MB/s
[  316.381494]     # benchmark_aes192: dec (len=16): 484 MB/s
[  316.381529]     ok 8 benchmark_aes192
[  316.381572]     # benchmark_aes256: enc (len=16): 484 MB/s
[  316.381574]     # benchmark_aes256: dec (len=16): 484 MB/s
[  316.381608]     ok 9 benchmark_aes256
[  316.381610] # aes: pass:9 fail:0 skip:0 total:9
[  316.381612] # Totals: pass:9 fail:0 skip:0 total:9
[  316.381614] ok 1 aes

Holger Dengler (1):
  lib/crypto: tests: Add KUnit tests for AES

 lib/crypto/tests/Kconfig        |  12 +++
 lib/crypto/tests/Makefile       |   1 +
 lib/crypto/tests/aes-testvecs.h |  77 ++++++++++++++++
 lib/crypto/tests/aes_kunit.c    | 150 ++++++++++++++++++++++++++++++++
 4 files changed, 240 insertions(+)
 create mode 100644 lib/crypto/tests/aes-testvecs.h
 create mode 100644 lib/crypto/tests/aes_kunit.c


base-commit: 47753e09a15d9fd7cdf114550510f4f2af9333ec
-- 
2.51.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests for AES
  2026-01-19 12:12 [PATCH v2 0/1] lib/crypto: tests: KUnit test-suite for AES Holger Dengler
@ 2026-01-19 12:12 ` Holger Dengler
  2026-01-19 16:39   ` kernel test robot
                     ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Holger Dengler @ 2026-01-19 12:12 UTC (permalink / raw)
  To: Eric Biggers, David Laight
  Cc: Ard Biesheuvel, Jason A . Donenfeld, Herbert Xu,
	Harald Freudenberger, Holger Dengler, linux-kernel, linux-crypto

Add a KUnit test suite for AES library functions, including KAT and
benchmarks. The functional tests do a very minimal verification of the
AES operation for each key-size. The benchmarks, which are also part
of the test-suite, can be used to get some rough performance
measurements of the AES operations. The key preparation API
performance is not covered by the benchmarks.

Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
---
 lib/crypto/tests/Kconfig        |  12 +++
 lib/crypto/tests/Makefile       |   1 +
 lib/crypto/tests/aes-testvecs.h |  77 ++++++++++++++++
 lib/crypto/tests/aes_kunit.c    | 150 ++++++++++++++++++++++++++++++++
 4 files changed, 240 insertions(+)
 create mode 100644 lib/crypto/tests/aes-testvecs.h
 create mode 100644 lib/crypto/tests/aes_kunit.c

diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig
index 4970463ea0aa..8ac06b6e2f12 100644
--- a/lib/crypto/tests/Kconfig
+++ b/lib/crypto/tests/Kconfig
@@ -1,5 +1,17 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
+config CRYPTO_LIB_AES_KUNIT_TEST
+	tristate "KUnit tests for AES" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
+	select CRYPTO_LIB_BENCHMARK_VISIBLE
+	select CRYPTO_LIB_AES
+	help
+	  KUnit tests for the AES library functions, including known answer
+	  tests and benchmarks for encrypt/decrypt with all key sizes. The
+	  test suite does not contain any key generation test, nor any error
+	  cases.
+
 config CRYPTO_LIB_BLAKE2B_KUNIT_TEST
 	tristate "KUnit tests for BLAKE2b" if !KUNIT_ALL_TESTS
 	depends on KUNIT
diff --git a/lib/crypto/tests/Makefile b/lib/crypto/tests/Makefile
index f4262379f56c..e0a30bdc02ac 100644
--- a/lib/crypto/tests/Makefile
+++ b/lib/crypto/tests/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
+obj-$(CONFIG_CRYPTO_LIB_AES_KUNIT_TEST) += aes_kunit.o
 obj-$(CONFIG_CRYPTO_LIB_BLAKE2B_KUNIT_TEST) += blake2b_kunit.o
 obj-$(CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST) += blake2s_kunit.o
 obj-$(CONFIG_CRYPTO_LIB_CURVE25519_KUNIT_TEST) += curve25519_kunit.o
diff --git a/lib/crypto/tests/aes-testvecs.h b/lib/crypto/tests/aes-testvecs.h
new file mode 100644
index 000000000000..fd52d8ad7760
--- /dev/null
+++ b/lib/crypto/tests/aes-testvecs.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _AES_TESTVECS_H
+#define _AES_TESTVECS_H
+
+#include <crypto/aes.h>
+
+struct aes_testvector {
+	u8 plain[AES_BLOCK_SIZE];
+	u8 cipher[AES_BLOCK_SIZE];
+	struct {
+		size_t len;
+		u8 b[32];
+	} key;
+};
+
+/*
+ * KAT test vectors from NIST.
+ * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/aes_ecb.pdf
+ */
+static const struct aes_testvector aes128_kat = {
+	.plain = {
+		0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+		0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+	},
+	.cipher = {
+		0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
+		0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
+	},
+	.key = {
+		.len = 16,
+		.b = {
+			0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+			0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+		},
+	},
+};
+
+static const struct aes_testvector aes192_kat = {
+	.plain = {
+		0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+		0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+	},
+	.cipher = {
+		0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f,
+		0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc,
+	},
+	.key = {
+		.len = 24,
+		.b = {
+			0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
+			0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
+			0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
+		},
+	},
+};
+
+static const struct aes_testvector aes256_kat = {
+	.plain = {
+		0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+		0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+	},
+	.cipher = {
+		0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
+		0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8,
+	},
+	.key = {
+		.len = 32,
+		.b = {
+			0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
+			0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
+			0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
+			0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
+		},
+	},
+};
+
+#endif /* _AES_TESTVECS_H */
diff --git a/lib/crypto/tests/aes_kunit.c b/lib/crypto/tests/aes_kunit.c
new file mode 100644
index 000000000000..8110d3718085
--- /dev/null
+++ b/lib/crypto/tests/aes_kunit.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <kunit/test.h>
+#include <linux/preempt.h>
+#include "aes-testvecs.h"
+
+static void test_aes(struct kunit *test, const struct aes_testvector *tv,
+		     bool enc)
+{
+	struct aes_key aes_key;
+	u8 out[AES_BLOCK_SIZE];
+	const u8 *input, *expect;
+	int rc;
+
+	rc = aes_preparekey(&aes_key, tv->key.b, tv->key.len);
+	KUNIT_ASSERT_EQ(test, 0, rc);
+
+	if (enc) {
+		input = tv->plain;
+		expect = tv->cipher;
+		aes_encrypt(&aes_key, out, input);
+	} else {
+		input = tv->cipher;
+		expect = tv->plain;
+		aes_decrypt(&aes_key, out, input);
+	}
+	KUNIT_ASSERT_MEMEQ(test, out, expect, sizeof(out));
+}
+
+static __always_inline u64 time_aes_op(bool encrypt, struct aes_key *aes_key,
+				       u8 *out, const u8 *in)
+{
+	void (*aes_op)(const struct aes_key *key, u8 *out, const u8 *in);
+	u64 t;
+
+	aes_op = encrypt ? &aes_encrypt : &aes_decrypt;
+
+	preempt_disable();
+	t = ktime_get_ns();
+	aes_op(aes_key, out, in);
+	t = ktime_get_ns() - t;
+	preempt_enable();
+
+	return t;
+}
+
+static void benchmark_aes(struct kunit *test, const struct aes_testvector *tv)
+{
+	const size_t num_iters = 100;
+	struct aes_key aes_key;
+	u8 out[AES_BLOCK_SIZE];
+	u64 t, t_enc, t_dec;
+	int rc;
+
+	if (!IS_ENABLED(CONFIG_CRYPTO_LIB_BENCHMARK))
+		kunit_skip(test, "not enabled");
+
+	rc = aes_preparekey(&aes_key, tv->key.b, tv->key.len);
+	KUNIT_ASSERT_EQ(test, 0, rc);
+
+	/* warm-up */
+	for (size_t i = 0; i < num_iters; i++) {
+		aes_encrypt(&aes_key, out, tv->plain);
+		aes_decrypt(&aes_key, out, tv->cipher);
+	}
+
+	t_enc = NSEC_PER_SEC;
+	t_dec = NSEC_PER_SEC;
+	for (size_t i = 0; i < num_iters; i++) {
+		t = time_aes_op(true, &aes_key, out, tv->plain);
+		t_enc = MIN_T(u64, t, t_enc);
+
+		t = time_aes_op(false, &aes_key, out, tv->cipher);
+		t_dec = MIN_T(u64, t, t_dec);
+	}
+
+	kunit_info(test, "enc (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
+		   div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
+			     (t_enc ?: 1)));
+	kunit_info(test, "dec (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
+		   div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
+			     (t_dec ?: 1)));
+}
+
+static void test_aes128_encrypt(struct kunit *test)
+{
+	test_aes(test, &aes128_kat, true);
+}
+
+static void test_aes128_decrypt(struct kunit *test)
+{
+	test_aes(test, &aes128_kat, false);
+}
+
+static void test_aes192_encrypt(struct kunit *test)
+{
+	test_aes(test, &aes192_kat, true);
+}
+
+static void test_aes192_decrypt(struct kunit *test)
+{
+	test_aes(test, &aes192_kat, false);
+}
+
+static void test_aes256_encrypt(struct kunit *test)
+{
+	test_aes(test, &aes256_kat, true);
+}
+
+static void test_aes256_decrypt(struct kunit *test)
+{
+	test_aes(test, &aes256_kat, false);
+}
+
+static void benchmark_aes128(struct kunit *test)
+{
+	benchmark_aes(test, &aes128_kat);
+}
+
+static void benchmark_aes192(struct kunit *test)
+{
+	benchmark_aes(test, &aes192_kat);
+}
+
+static void benchmark_aes256(struct kunit *test)
+{
+	benchmark_aes(test, &aes256_kat);
+}
+
+static struct kunit_case aes_test_cases[] = {
+	KUNIT_CASE(test_aes128_encrypt),
+	KUNIT_CASE(test_aes128_decrypt),
+	KUNIT_CASE(test_aes192_encrypt),
+	KUNIT_CASE(test_aes192_decrypt),
+	KUNIT_CASE(test_aes256_encrypt),
+	KUNIT_CASE(test_aes256_decrypt),
+	KUNIT_CASE(benchmark_aes128),
+	KUNIT_CASE(benchmark_aes192),
+	KUNIT_CASE(benchmark_aes256),
+	{},
+};
+
+static struct kunit_suite aes_test_suite = {
+	.name = "aes",
+	.test_cases = aes_test_cases,
+};
+
+kunit_test_suite(aes_test_suite);
+
+MODULE_DESCRIPTION("KUnit tests and benchmark AES library");
+MODULE_LICENSE("GPL");
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests for AES
  2026-01-19 12:12 ` [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests " Holger Dengler
@ 2026-01-19 16:39   ` kernel test robot
  2026-01-19 17:22   ` kernel test robot
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2026-01-19 16:39 UTC (permalink / raw)
  To: Holger Dengler, Eric Biggers, David Laight
  Cc: oe-kbuild-all, Ard Biesheuvel, Jason A . Donenfeld, Herbert Xu,
	Harald Freudenberger, Holger Dengler, linux-kernel, linux-crypto

Hi Holger,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 47753e09a15d9fd7cdf114550510f4f2af9333ec]

url:    https://github.com/intel-lab-lkp/linux/commits/Holger-Dengler/lib-crypto-tests-Add-KUnit-tests-for-AES/20260119-201615
base:   47753e09a15d9fd7cdf114550510f4f2af9333ec
patch link:    https://lore.kernel.org/r/20260119121210.2662-2-dengler%40linux.ibm.com
patch subject: [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests for AES
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20260120/202601200047.d0uwB8zw-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260120/202601200047.d0uwB8zw-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601200047.d0uwB8zw-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from include/kunit/assert.h:13,
                    from include/kunit/test.h:12,
                    from lib/crypto/tests/aes_kunit.c:2:
   lib/crypto/tests/aes_kunit.c: In function 'benchmark_aes':
>> lib/crypto/tests/aes_kunit.c:77:45: warning: integer overflow in expression of type 'long int' results in '-1179869184' [-Woverflow]
      77 |                    div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
         |                                             ^
   include/linux/printk.h:484:33: note: in definition of macro 'printk_index_wrap'
     484 |                 _p_func(_fmt, ##__VA_ARGS__);                           \
         |                                 ^~~~~~~~~~~
   include/kunit/test.h:661:17: note: in expansion of macro 'printk'
     661 |                 printk(lvl fmt, ##__VA_ARGS__);                         \
         |                 ^~~~~~
   include/kunit/test.h:667:9: note: in expansion of macro 'kunit_log'
     667 |         kunit_log(lvl, test, KUNIT_SUBTEST_INDENT "# %s: " fmt,         \
         |         ^~~~~~~~~
   include/kunit/test.h:680:9: note: in expansion of macro 'kunit_printk'
     680 |         kunit_printk(KERN_INFO, test, fmt, ##__VA_ARGS__)
         |         ^~~~~~~~~~~~
   lib/crypto/tests/aes_kunit.c:76:9: note: in expansion of macro 'kunit_info'
      76 |         kunit_info(test, "enc (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
         |         ^~~~~~~~~~
>> lib/crypto/tests/aes_kunit.c:77:45: warning: integer overflow in expression of type 'long int' results in '-1179869184' [-Woverflow]
      77 |                    div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
         |                                             ^
   include/kunit/test.h:663:36: note: in definition of macro 'kunit_log'
     663 |                                  ##__VA_ARGS__);                        \
         |                                    ^~~~~~~~~~~
   include/kunit/test.h:680:9: note: in expansion of macro 'kunit_printk'
     680 |         kunit_printk(KERN_INFO, test, fmt, ##__VA_ARGS__)
         |         ^~~~~~~~~~~~
   lib/crypto/tests/aes_kunit.c:76:9: note: in expansion of macro 'kunit_info'
      76 |         kunit_info(test, "enc (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
         |         ^~~~~~~~~~
   lib/crypto/tests/aes_kunit.c:80:45: warning: integer overflow in expression of type 'long int' results in '-1179869184' [-Woverflow]
      80 |                    div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
         |                                             ^
   include/linux/printk.h:484:33: note: in definition of macro 'printk_index_wrap'
     484 |                 _p_func(_fmt, ##__VA_ARGS__);                           \
         |                                 ^~~~~~~~~~~
   include/kunit/test.h:661:17: note: in expansion of macro 'printk'
     661 |                 printk(lvl fmt, ##__VA_ARGS__);                         \
         |                 ^~~~~~
   include/kunit/test.h:667:9: note: in expansion of macro 'kunit_log'
     667 |         kunit_log(lvl, test, KUNIT_SUBTEST_INDENT "# %s: " fmt,         \
         |         ^~~~~~~~~
   include/kunit/test.h:680:9: note: in expansion of macro 'kunit_printk'
     680 |         kunit_printk(KERN_INFO, test, fmt, ##__VA_ARGS__)
         |         ^~~~~~~~~~~~
   lib/crypto/tests/aes_kunit.c:79:9: note: in expansion of macro 'kunit_info'
      79 |         kunit_info(test, "dec (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
         |         ^~~~~~~~~~
   lib/crypto/tests/aes_kunit.c:80:45: warning: integer overflow in expression of type 'long int' results in '-1179869184' [-Woverflow]
      80 |                    div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
         |                                             ^
   include/kunit/test.h:663:36: note: in definition of macro 'kunit_log'
     663 |                                  ##__VA_ARGS__);                        \
         |                                    ^~~~~~~~~~~
   include/kunit/test.h:680:9: note: in expansion of macro 'kunit_printk'
     680 |         kunit_printk(KERN_INFO, test, fmt, ##__VA_ARGS__)
         |         ^~~~~~~~~~~~
   lib/crypto/tests/aes_kunit.c:79:9: note: in expansion of macro 'kunit_info'
      79 |         kunit_info(test, "dec (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
         |         ^~~~~~~~~~


vim +77 lib/crypto/tests/aes_kunit.c

   > 2	#include <kunit/test.h>
     3	#include <linux/preempt.h>
     4	#include "aes-testvecs.h"
     5	
     6	static void test_aes(struct kunit *test, const struct aes_testvector *tv,
     7			     bool enc)
     8	{
     9		struct aes_key aes_key;
    10		u8 out[AES_BLOCK_SIZE];
    11		const u8 *input, *expect;
    12		int rc;
    13	
    14		rc = aes_preparekey(&aes_key, tv->key.b, tv->key.len);
    15		KUNIT_ASSERT_EQ(test, 0, rc);
    16	
    17		if (enc) {
    18			input = tv->plain;
    19			expect = tv->cipher;
    20			aes_encrypt(&aes_key, out, input);
    21		} else {
    22			input = tv->cipher;
    23			expect = tv->plain;
    24			aes_decrypt(&aes_key, out, input);
    25		}
    26		KUNIT_ASSERT_MEMEQ(test, out, expect, sizeof(out));
    27	}
    28	
    29	static __always_inline u64 time_aes_op(bool encrypt, struct aes_key *aes_key,
    30					       u8 *out, const u8 *in)
    31	{
    32		void (*aes_op)(const struct aes_key *key, u8 *out, const u8 *in);
    33		u64 t;
    34	
    35		aes_op = encrypt ? &aes_encrypt : &aes_decrypt;
    36	
    37		preempt_disable();
    38		t = ktime_get_ns();
    39		aes_op(aes_key, out, in);
    40		t = ktime_get_ns() - t;
    41		preempt_enable();
    42	
    43		return t;
    44	}
    45	
    46	static void benchmark_aes(struct kunit *test, const struct aes_testvector *tv)
    47	{
    48		const size_t num_iters = 100;
    49		struct aes_key aes_key;
    50		u8 out[AES_BLOCK_SIZE];
    51		u64 t, t_enc, t_dec;
    52		int rc;
    53	
    54		if (!IS_ENABLED(CONFIG_CRYPTO_LIB_BENCHMARK))
    55			kunit_skip(test, "not enabled");
    56	
    57		rc = aes_preparekey(&aes_key, tv->key.b, tv->key.len);
    58		KUNIT_ASSERT_EQ(test, 0, rc);
    59	
    60		/* warm-up */
    61		for (size_t i = 0; i < num_iters; i++) {
    62			aes_encrypt(&aes_key, out, tv->plain);
    63			aes_decrypt(&aes_key, out, tv->cipher);
    64		}
    65	
    66		t_enc = NSEC_PER_SEC;
    67		t_dec = NSEC_PER_SEC;
    68		for (size_t i = 0; i < num_iters; i++) {
    69			t = time_aes_op(true, &aes_key, out, tv->plain);
    70			t_enc = MIN_T(u64, t, t_enc);
    71	
    72			t = time_aes_op(false, &aes_key, out, tv->cipher);
    73			t_dec = MIN_T(u64, t, t_dec);
    74		}
    75	
    76		kunit_info(test, "enc (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
  > 77			   div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
    78				     (t_enc ?: 1)));
    79		kunit_info(test, "dec (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
    80			   div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
    81				     (t_dec ?: 1)));
    82	}
    83	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests for AES
  2026-01-19 12:12 ` [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests " Holger Dengler
  2026-01-19 16:39   ` kernel test robot
@ 2026-01-19 17:22   ` kernel test robot
  2026-01-19 20:31   ` kernel test robot
  2026-01-29  1:18   ` Eric Biggers
  3 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2026-01-19 17:22 UTC (permalink / raw)
  To: Holger Dengler, Eric Biggers, David Laight
  Cc: llvm, oe-kbuild-all, Ard Biesheuvel, Jason A . Donenfeld,
	Herbert Xu, Harald Freudenberger, Holger Dengler, linux-kernel,
	linux-crypto

Hi Holger,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 47753e09a15d9fd7cdf114550510f4f2af9333ec]

url:    https://github.com/intel-lab-lkp/linux/commits/Holger-Dengler/lib-crypto-tests-Add-KUnit-tests-for-AES/20260119-201615
base:   47753e09a15d9fd7cdf114550510f4f2af9333ec
patch link:    https://lore.kernel.org/r/20260119121210.2662-2-dengler%40linux.ibm.com
patch subject: [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests for AES
config: arm-randconfig-003-20260119 (https://download.01.org/0day-ci/archive/20260120/202601200149.4hhdN1QQ-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9b8addffa70cee5b2acc5454712d9cf78ce45710)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260120/202601200149.4hhdN1QQ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601200149.4hhdN1QQ-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> lib/crypto/tests/aes_kunit.c:77:31: warning: overflow in expression; result is -1'179'869'184 with type 'long' [-Winteger-overflow]
      77 |                    div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
         |                              ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
   include/kunit/test.h:680:39: note: expanded from macro 'kunit_info'
     680 |         kunit_printk(KERN_INFO, test, fmt, ##__VA_ARGS__)
         |                                              ^~~~~~~~~~~
   include/kunit/test.h:668:21: note: expanded from macro 'kunit_printk'
     668 |                   (test)->name, ##__VA_ARGS__)
         |                                   ^~~~~~~~~~~
   include/kunit/test.h:661:21: note: expanded from macro 'kunit_log'
     661 |                 printk(lvl fmt, ##__VA_ARGS__);                         \
         |                                   ^~~~~~~~~~~
   include/linux/printk.h:512:60: note: expanded from macro 'printk'
     512 | #define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__)
         |                                                            ^~~~~~~~~~~
   include/linux/printk.h:484:19: note: expanded from macro 'printk_index_wrap'
     484 |                 _p_func(_fmt, ##__VA_ARGS__);                           \
         |                                 ^~~~~~~~~~~
>> lib/crypto/tests/aes_kunit.c:77:31: warning: overflow in expression; result is -1'179'869'184 with type 'long' [-Winteger-overflow]
      77 |                    div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
         |                              ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
   include/kunit/test.h:680:39: note: expanded from macro 'kunit_info'
     680 |         kunit_printk(KERN_INFO, test, fmt, ##__VA_ARGS__)
         |                                              ^~~~~~~~~~~
   include/kunit/test.h:668:21: note: expanded from macro 'kunit_printk'
     668 |                   (test)->name, ##__VA_ARGS__)
         |                                   ^~~~~~~~~~~
   include/kunit/test.h:663:8: note: expanded from macro 'kunit_log'
     663 |                                  ##__VA_ARGS__);                        \
         |                                    ^~~~~~~~~~~
   lib/crypto/tests/aes_kunit.c:80:31: warning: overflow in expression; result is -1'179'869'184 with type 'long' [-Winteger-overflow]
      80 |                    div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
         |                              ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
   include/kunit/test.h:680:39: note: expanded from macro 'kunit_info'
     680 |         kunit_printk(KERN_INFO, test, fmt, ##__VA_ARGS__)
         |                                              ^~~~~~~~~~~
   include/kunit/test.h:668:21: note: expanded from macro 'kunit_printk'
     668 |                   (test)->name, ##__VA_ARGS__)
         |                                   ^~~~~~~~~~~
   include/kunit/test.h:661:21: note: expanded from macro 'kunit_log'
     661 |                 printk(lvl fmt, ##__VA_ARGS__);                         \
         |                                   ^~~~~~~~~~~
   include/linux/printk.h:512:60: note: expanded from macro 'printk'
     512 | #define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__)
         |                                                            ^~~~~~~~~~~
   include/linux/printk.h:484:19: note: expanded from macro 'printk_index_wrap'
     484 |                 _p_func(_fmt, ##__VA_ARGS__);                           \
         |                                 ^~~~~~~~~~~
   lib/crypto/tests/aes_kunit.c:80:31: warning: overflow in expression; result is -1'179'869'184 with type 'long' [-Winteger-overflow]
      80 |                    div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
         |                              ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
   include/kunit/test.h:680:39: note: expanded from macro 'kunit_info'
     680 |         kunit_printk(KERN_INFO, test, fmt, ##__VA_ARGS__)
         |                                              ^~~~~~~~~~~
   include/kunit/test.h:668:21: note: expanded from macro 'kunit_printk'
     668 |                   (test)->name, ##__VA_ARGS__)
         |                                   ^~~~~~~~~~~
   include/kunit/test.h:663:8: note: expanded from macro 'kunit_log'
     663 |                                  ##__VA_ARGS__);                        \
         |                                    ^~~~~~~~~~~
   4 warnings generated.


vim +77 lib/crypto/tests/aes_kunit.c

    45	
    46	static void benchmark_aes(struct kunit *test, const struct aes_testvector *tv)
    47	{
    48		const size_t num_iters = 100;
    49		struct aes_key aes_key;
    50		u8 out[AES_BLOCK_SIZE];
    51		u64 t, t_enc, t_dec;
    52		int rc;
    53	
    54		if (!IS_ENABLED(CONFIG_CRYPTO_LIB_BENCHMARK))
    55			kunit_skip(test, "not enabled");
    56	
    57		rc = aes_preparekey(&aes_key, tv->key.b, tv->key.len);
    58		KUNIT_ASSERT_EQ(test, 0, rc);
    59	
    60		/* warm-up */
    61		for (size_t i = 0; i < num_iters; i++) {
    62			aes_encrypt(&aes_key, out, tv->plain);
    63			aes_decrypt(&aes_key, out, tv->cipher);
    64		}
    65	
    66		t_enc = NSEC_PER_SEC;
    67		t_dec = NSEC_PER_SEC;
    68		for (size_t i = 0; i < num_iters; i++) {
    69			t = time_aes_op(true, &aes_key, out, tv->plain);
    70			t_enc = MIN_T(u64, t, t_enc);
    71	
    72			t = time_aes_op(false, &aes_key, out, tv->cipher);
    73			t_dec = MIN_T(u64, t, t_dec);
    74		}
    75	
    76		kunit_info(test, "enc (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
  > 77			   div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
    78				     (t_enc ?: 1)));
    79		kunit_info(test, "dec (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
    80			   div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
    81				     (t_dec ?: 1)));
    82	}
    83	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests for AES
  2026-01-19 12:12 ` [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests " Holger Dengler
  2026-01-19 16:39   ` kernel test robot
  2026-01-19 17:22   ` kernel test robot
@ 2026-01-19 20:31   ` kernel test robot
  2026-01-29  1:18   ` Eric Biggers
  3 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2026-01-19 20:31 UTC (permalink / raw)
  To: Holger Dengler, Eric Biggers, David Laight
  Cc: oe-kbuild-all, Ard Biesheuvel, Jason A . Donenfeld, Herbert Xu,
	Harald Freudenberger, Holger Dengler, linux-kernel, linux-crypto

Hi Holger,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 47753e09a15d9fd7cdf114550510f4f2af9333ec]

url:    https://github.com/intel-lab-lkp/linux/commits/Holger-Dengler/lib-crypto-tests-Add-KUnit-tests-for-AES/20260119-201615
base:   47753e09a15d9fd7cdf114550510f4f2af9333ec
patch link:    https://lore.kernel.org/r/20260119121210.2662-2-dengler%40linux.ibm.com
patch subject: [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests for AES
config: xtensa-randconfig-r133-20260120 (https://download.01.org/0day-ci/archive/20260120/202601200403.mo4FMAVa-lkp@intel.com/config)
compiler: xtensa-linux-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260120/202601200403.mo4FMAVa-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601200403.mo4FMAVa-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   lib/crypto/tests/aes_kunit.c: note: in included file (through arch/xtensa/include/asm/atomic.h, include/linux/atomic.h, include/linux/jump_label.h, ...):
   arch/xtensa/include/asm/processor.h:105:2: sparse: sparse: Unsupported xtensa ABI
   arch/xtensa/include/asm/processor.h:135:2: sparse: sparse: Unsupported Xtensa ABI
   lib/crypto/tests/aes_kunit.c:149:1: sparse: sparse: bad integer constant expression
   lib/crypto/tests/aes_kunit.c:149:1: sparse: sparse: static assertion failed: "MODULE_INFO(description, ...) contains embedded NUL byte"
   lib/crypto/tests/aes_kunit.c:150:1: sparse: sparse: bad integer constant expression
   lib/crypto/tests/aes_kunit.c:150:1: sparse: sparse: static assertion failed: "MODULE_INFO(file, ...) contains embedded NUL byte"
   lib/crypto/tests/aes_kunit.c:150:1: sparse: sparse: bad integer constant expression
   lib/crypto/tests/aes_kunit.c:150:1: sparse: sparse: static assertion failed: "MODULE_INFO(license, ...) contains embedded NUL byte"
>> lib/crypto/tests/aes_kunit.c:35:26: sparse: sparse: incompatible types in conditional expression (incompatible argument 1 (different base types)):
   lib/crypto/tests/aes_kunit.c:35:26: sparse:    void ( * )( ... )
   lib/crypto/tests/aes_kunit.c:35:26: sparse:    void ( * )( ... )
>> lib/crypto/tests/aes_kunit.c:35:26: sparse: sparse: incompatible types in conditional expression (incompatible argument 1 (different base types)):
   lib/crypto/tests/aes_kunit.c:35:26: sparse:    void ( * )( ... )
   lib/crypto/tests/aes_kunit.c:35:26: sparse:    void ( * )( ... )

vim +35 lib/crypto/tests/aes_kunit.c

    28	
    29	static __always_inline u64 time_aes_op(bool encrypt, struct aes_key *aes_key,
    30					       u8 *out, const u8 *in)
    31	{
    32		void (*aes_op)(const struct aes_key *key, u8 *out, const u8 *in);
    33		u64 t;
    34	
  > 35		aes_op = encrypt ? &aes_encrypt : &aes_decrypt;
    36	
    37		preempt_disable();
    38		t = ktime_get_ns();
    39		aes_op(aes_key, out, in);
    40		t = ktime_get_ns() - t;
    41		preempt_enable();
    42	
    43		return t;
    44	}
    45	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests for AES
  2026-01-19 12:12 ` [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests " Holger Dengler
                     ` (2 preceding siblings ...)
  2026-01-19 20:31   ` kernel test robot
@ 2026-01-29  1:18   ` Eric Biggers
  2026-01-30 10:54     ` Holger Dengler
  3 siblings, 1 reply; 7+ messages in thread
From: Eric Biggers @ 2026-01-29  1:18 UTC (permalink / raw)
  To: Holger Dengler
  Cc: David Laight, Ard Biesheuvel, Jason A . Donenfeld, Herbert Xu,
	Harald Freudenberger, linux-kernel, linux-crypto

On Mon, Jan 19, 2026 at 01:12:10PM +0100, Holger Dengler wrote:
> +static __always_inline u64 time_aes_op(bool encrypt, struct aes_key *aes_key,
> +				       u8 *out, const u8 *in)
> +{
> +	void (*aes_op)(const struct aes_key *key, u8 *out, const u8 *in);
> +	u64 t;
> +
> +	aes_op = encrypt ? &aes_encrypt : &aes_decrypt;
> +
> +	preempt_disable();
> +	t = ktime_get_ns();
> +	aes_op(aes_key, out, in);
> +	t = ktime_get_ns() - t;
> +	preempt_enable();
> +
> +	return t;
> +}
> +
> +static void benchmark_aes(struct kunit *test, const struct aes_testvector *tv)
> +{
> +	const size_t num_iters = 100;
> +	struct aes_key aes_key;
> +	u8 out[AES_BLOCK_SIZE];
> +	u64 t, t_enc, t_dec;
> +	int rc;
> +
> +	if (!IS_ENABLED(CONFIG_CRYPTO_LIB_BENCHMARK))
> +		kunit_skip(test, "not enabled");
> +
> +	rc = aes_preparekey(&aes_key, tv->key.b, tv->key.len);
> +	KUNIT_ASSERT_EQ(test, 0, rc);
> +
> +	/* warm-up */
> +	for (size_t i = 0; i < num_iters; i++) {
> +		aes_encrypt(&aes_key, out, tv->plain);
> +		aes_decrypt(&aes_key, out, tv->cipher);
> +	}
> +
> +	t_enc = NSEC_PER_SEC;
> +	t_dec = NSEC_PER_SEC;
> +	for (size_t i = 0; i < num_iters; i++) {
> +		t = time_aes_op(true, &aes_key, out, tv->plain);
> +		t_enc = MIN_T(u64, t, t_enc);
> +
> +		t = time_aes_op(false, &aes_key, out, tv->cipher);
> +		t_dec = MIN_T(u64, t, t_dec);
> +	}
> +
> +	kunit_info(test, "enc (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
> +		   div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
> +			     (t_enc ?: 1)));
> +	kunit_info(test, "dec (len=%zu): %llu MB/s", (size_t)AES_BLOCK_SIZE,
> +		   div64_u64(AES_BLOCK_SIZE * NSEC_PER_SEC / 1000000,
> +			     (t_dec ?: 1)));
> +}

"AES_BLOCK_SIZE * NSEC_PER_SEC" is missing a cast to u64, as reported by
the kernel test robot.

But also as discussed in v1, using ktime_get_ns() to time one AES block
en/decryption at a time doesn't really work.  Even on x86 which has a
high precision timer, it's spending longer getting the time than doing
the actual AES en/decryption.

You may have meant to use get_cycles() instead, which has less overhead.

However, not all architectures have a cycle counter.

So I recommend we go with the simple strategy that I suggested, and
which v1 had.  Just the number of iterations in v1 was way too high.

- Eric

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests for AES
  2026-01-29  1:18   ` Eric Biggers
@ 2026-01-30 10:54     ` Holger Dengler
  0 siblings, 0 replies; 7+ messages in thread
From: Holger Dengler @ 2026-01-30 10:54 UTC (permalink / raw)
  To: Eric Biggers
  Cc: David Laight, Ard Biesheuvel, Jason A . Donenfeld, Herbert Xu,
	Harald Freudenberger, linux-kernel, linux-crypto

On 29/01/2026 02:18, Eric Biggers wrote:
> "AES_BLOCK_SIZE * NSEC_PER_SEC" is missing a cast to u64, as reported by
> the kernel test robot.
> 
> But also as discussed in v1, using ktime_get_ns() to time one AES block
> en/decryption at a time doesn't really work.  Even on x86 which has a
> high precision timer, it's spending longer getting the time than doing
> the actual AES en/decryption.
> 
> You may have meant to use get_cycles() instead, which has less overhead.
> 
> However, not all architectures have a cycle counter.
> 
> So I recommend we go with the simple strategy that I suggested, and
> which v1 had.  Just the number of iterations in v1 was way too high.

Ok, I'll send a v3.

> 
> - Eric

-- 
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-01-30 10:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-19 12:12 [PATCH v2 0/1] lib/crypto: tests: KUnit test-suite for AES Holger Dengler
2026-01-19 12:12 ` [PATCH v2 1/1] lib/crypto: tests: Add KUnit tests " Holger Dengler
2026-01-19 16:39   ` kernel test robot
2026-01-19 17:22   ` kernel test robot
2026-01-19 20:31   ` kernel test robot
2026-01-29  1:18   ` Eric Biggers
2026-01-30 10:54     ` Holger Dengler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox