summaryrefslogtreecommitdiffstats
path: root/lib/tests/base64_kunit.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-24 08:46:03 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-24 08:46:03 -0700
commitcf9610f9116d55c5a66ef9f1faecacabd93a9322 (patch)
tree757a3d280760c654767631cab5ad8af2d86d1848 /lib/tests/base64_kunit.c
downloadlinux-stable-cf9610f9116d55c5a66ef9f1faecacabd93a9322.tar.gz
linux-stable-cf9610f9116d55c5a66ef9f1faecacabd93a9322.zip
Merge tag 'pinctrl-v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrlgrafted
Pull pin control updates from Linus Walleij: "Core changes: - Use the non-blocking mux_state_try_select() in the generic MUX pin control back-end - Free pin maps on pinctrl_generic_to_map() failure in the core helpers New hardware pin control: - Qualcomm Maili TLMM SoC, PMG1110 PMIC, and Eliza LPASS LPI TLMM SoC (this is for the low power audio, LPASS = Low Power Audio SubSystem portions) - Upboard support on top of the Intel pin controller - Apple T6030 and T6031 support (just compatible strings) - Samsung Exynos 8855 SoC - Mediatek MT6858 SoC - Rockchip RK3308B and RV1106 SoCs - Airoha EN7523 and AN7563 SoCs Improvements: - Qualcomm TLMM GPIOs are unconditionally marked as wakeup capable - Qualcomm improvements on top of the Qualcomm PDC (power domain controller) irqchip improvements from tglx:s tree - Qualcomm IPQ806x and IPQ9650 non-urgent pin grop fixups - The NPCM8xx driver has been put into shape fixing many pin and group definitions - Some non-urgent Tegra 264 pin assignments are fixed up - Some non-urgent fixups to Airoha AN7581 and AN7583 registers and pin assignments, missing features etc" * tag 'pinctrl-v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (130 commits) dt-bindings: pinctrl: Convert TI DA850 pupd to DT schema pinctrl: meson: sync some modify from A4 pinctrl: meson: a4: Add input enable pin configuration pinctrl: realtek: rtd1625: remove unused group name spdif_sel pinctrl: realtek: rtd1625: fix base_bit for VE4 GPIO 13 dt-bindings: pinctrl: microchip,pic32mzda-pinctrl: Convert to DT schema Revert "Merge branch 'ib-rsk7204' into devel" pinctrl: rockchip: Add RV1106 pinctrl support dt-bindings: pinctrl: rockchip: Add RV1106 compatible pinctrl: rockchip: Decode drive strength in the get function pinctrl: fix PINCTRL_GENERIC_MUX not always being selectable pinctrl: airoha: add support of an7563 SoC dt-bindings: pinctrl: airoha: add support of an7563 pin controller pinctrl: airoha: try to find chip scu node by phandle first pinctrl: airoha: add support of en7523 SoC dt-bindings: pinctrl: airoha: add support of en7523 pin controller pinctrl: airoha: an7583: add support for olt pinmux pinctrl: airoha: an7583: add support for pon_alt pinmux pinctrl: airoha: an7583: add support for npu_uart pinmux dt-bindings: pinctrl: airoha: an7583: add missed features ...
Diffstat (limited to 'lib/tests/base64_kunit.c')
-rw-r--r--lib/tests/base64_kunit.c294
1 files changed, 294 insertions, 0 deletions
diff --git a/lib/tests/base64_kunit.c b/lib/tests/base64_kunit.c
new file mode 100644
index 000000000..f7252070c
--- /dev/null
+++ b/lib/tests/base64_kunit.c
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * base64_kunit_test.c - KUnit tests for base64 encoding and decoding functions
+ *
+ * Copyright (c) 2025, Guan-Chun Wu <409411716@gms.tku.edu.tw>
+ */
+
+#include <kunit/test.h>
+#include <linux/base64.h>
+
+/* ---------- Benchmark helpers ---------- */
+static u64 bench_encode_ns(const u8 *data, int len, char *dst, int reps,
+ enum base64_variant variant)
+{
+ u64 t0, t1;
+
+ t0 = ktime_get_ns();
+ for (int i = 0; i < reps; i++)
+ base64_encode(data, len, dst, true, variant);
+ t1 = ktime_get_ns();
+
+ return div64_u64(t1 - t0, (u64)reps);
+}
+
+static u64 bench_decode_ns(const char *data, int len, u8 *dst, int reps,
+ enum base64_variant variant)
+{
+ u64 t0, t1;
+
+ t0 = ktime_get_ns();
+ for (int i = 0; i < reps; i++)
+ base64_decode(data, len, dst, true, variant);
+ t1 = ktime_get_ns();
+
+ return div64_u64(t1 - t0, (u64)reps);
+}
+
+static void run_perf_and_check(struct kunit *test, const char *label, int size,
+ enum base64_variant variant)
+{
+ const int reps = 1000;
+ size_t outlen = DIV_ROUND_UP(size, 3) * 4;
+ u8 *in = kmalloc(size, GFP_KERNEL);
+ char *enc = kmalloc(outlen, GFP_KERNEL);
+ u8 *decoded = kmalloc(size, GFP_KERNEL);
+
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, in);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, enc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, decoded);
+
+ get_random_bytes(in, size);
+ int enc_len = base64_encode(in, size, enc, true, variant);
+ int dec_len = base64_decode(enc, enc_len, decoded, true, variant);
+
+ /* correctness sanity check */
+ KUNIT_EXPECT_EQ(test, dec_len, size);
+ KUNIT_EXPECT_MEMEQ(test, decoded, in, size);
+
+ /* benchmark encode */
+
+ u64 t1 = bench_encode_ns(in, size, enc, reps, variant);
+
+ kunit_info(test, "[%s] encode run : %lluns", label, t1);
+
+ u64 t2 = bench_decode_ns(enc, enc_len, decoded, reps, variant);
+
+ kunit_info(test, "[%s] decode run : %lluns", label, t2);
+
+ kfree(in);
+ kfree(enc);
+ kfree(decoded);
+}
+
+static void base64_performance_tests(struct kunit *test)
+{
+ /* run on STD variant only */
+ run_perf_and_check(test, "64B", 64, BASE64_STD);
+ run_perf_and_check(test, "1KB", 1024, BASE64_STD);
+}
+
+/* ---------- Helpers for encode ---------- */
+static void expect_encode_ok(struct kunit *test, const u8 *src, int srclen,
+ const char *expected, bool padding,
+ enum base64_variant variant)
+{
+ char buf[128];
+ int encoded_len = base64_encode(src, srclen, buf, padding, variant);
+
+ buf[encoded_len] = '\0';
+
+ KUNIT_EXPECT_EQ(test, encoded_len, strlen(expected));
+ KUNIT_EXPECT_STREQ(test, buf, expected);
+}
+
+/* ---------- Helpers for decode ---------- */
+static void expect_decode_ok(struct kunit *test, const char *src,
+ const u8 *expected, int expected_len, bool padding,
+ enum base64_variant variant)
+{
+ u8 buf[128];
+ int decoded_len = base64_decode(src, strlen(src), buf, padding, variant);
+
+ KUNIT_EXPECT_EQ(test, decoded_len, expected_len);
+ KUNIT_EXPECT_MEMEQ(test, buf, expected, expected_len);
+}
+
+static void expect_decode_err(struct kunit *test, const char *src,
+ int srclen, bool padding,
+ enum base64_variant variant)
+{
+ u8 buf[64];
+ int decoded_len = base64_decode(src, srclen, buf, padding, variant);
+
+ KUNIT_EXPECT_EQ(test, decoded_len, -1);
+}
+
+/* ---------- Encode Tests ---------- */
+static void base64_std_encode_tests(struct kunit *test)
+{
+ /* With padding */
+ expect_encode_ok(test, (const u8 *)"", 0, "", true, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"f", 1, "Zg==", true, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"fo", 2, "Zm8=", true, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"foo", 3, "Zm9v", true, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"foob", 4, "Zm9vYg==", true, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"fooba", 5, "Zm9vYmE=", true, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"foobar", 6, "Zm9vYmFy", true, BASE64_STD);
+
+ /* Extra cases with padding */
+ expect_encode_ok(test, (const u8 *)"Hello, world!", 13, "SGVsbG8sIHdvcmxkIQ==",
+ true, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26,
+ "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=", true, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"abcdefghijklmnopqrstuvwxyz", 26,
+ "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=", true, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"0123456789+/", 12, "MDEyMzQ1Njc4OSsv",
+ true, BASE64_STD);
+
+ /* Without padding */
+ expect_encode_ok(test, (const u8 *)"", 0, "", false, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"f", 1, "Zg", false, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"fo", 2, "Zm8", false, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"foo", 3, "Zm9v", false, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"foob", 4, "Zm9vYg", false, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"fooba", 5, "Zm9vYmE", false, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"foobar", 6, "Zm9vYmFy", false, BASE64_STD);
+
+ /* Extra cases without padding */
+ expect_encode_ok(test, (const u8 *)"Hello, world!", 13, "SGVsbG8sIHdvcmxkIQ",
+ false, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26,
+ "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo", false, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"abcdefghijklmnopqrstuvwxyz", 26,
+ "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo", false, BASE64_STD);
+ expect_encode_ok(test, (const u8 *)"0123456789+/", 12, "MDEyMzQ1Njc4OSsv",
+ false, BASE64_STD);
+}
+
+/* ---------- Decode Tests ---------- */
+static void base64_std_decode_tests(struct kunit *test)
+{
+ /* -------- With padding --------*/
+ expect_decode_ok(test, "", (const u8 *)"", 0, true, BASE64_STD);
+ expect_decode_ok(test, "Zg==", (const u8 *)"f", 1, true, BASE64_STD);
+ expect_decode_ok(test, "Zm8=", (const u8 *)"fo", 2, true, BASE64_STD);
+ expect_decode_ok(test, "Zm9v", (const u8 *)"foo", 3, true, BASE64_STD);
+ expect_decode_ok(test, "Zm9vYg==", (const u8 *)"foob", 4, true, BASE64_STD);
+ expect_decode_ok(test, "Zm9vYmE=", (const u8 *)"fooba", 5, true, BASE64_STD);
+ expect_decode_ok(test, "Zm9vYmFy", (const u8 *)"foobar", 6, true, BASE64_STD);
+ expect_decode_ok(test, "SGVsbG8sIHdvcmxkIQ==", (const u8 *)"Hello, world!", 13,
+ true, BASE64_STD);
+ expect_decode_ok(test, "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=",
+ (const u8 *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26, true, BASE64_STD);
+ expect_decode_ok(test, "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=",
+ (const u8 *)"abcdefghijklmnopqrstuvwxyz", 26, true, BASE64_STD);
+
+ /* Error cases */
+ expect_decode_err(test, "Zg=!", 4, true, BASE64_STD);
+ expect_decode_err(test, "Zm$=", 4, true, BASE64_STD);
+ expect_decode_err(test, "Z===", 4, true, BASE64_STD);
+ expect_decode_err(test, "Zg", 2, true, BASE64_STD);
+ expect_decode_err(test, "Zm9v====", 8, true, BASE64_STD);
+ expect_decode_err(test, "Zm==A", 5, true, BASE64_STD);
+
+ {
+ char with_nul[4] = { 'Z', 'g', '\0', '=' };
+
+ expect_decode_err(test, with_nul, 4, true, BASE64_STD);
+ }
+
+ /* -------- Without padding --------*/
+ expect_decode_ok(test, "", (const u8 *)"", 0, false, BASE64_STD);
+ expect_decode_ok(test, "Zg", (const u8 *)"f", 1, false, BASE64_STD);
+ expect_decode_ok(test, "Zm8", (const u8 *)"fo", 2, false, BASE64_STD);
+ expect_decode_ok(test, "Zm9v", (const u8 *)"foo", 3, false, BASE64_STD);
+ expect_decode_ok(test, "Zm9vYg", (const u8 *)"foob", 4, false, BASE64_STD);
+ expect_decode_ok(test, "Zm9vYmE", (const u8 *)"fooba", 5, false, BASE64_STD);
+ expect_decode_ok(test, "Zm9vYmFy", (const u8 *)"foobar", 6, false, BASE64_STD);
+ expect_decode_ok(test, "TWFu", (const u8 *)"Man", 3, false, BASE64_STD);
+ expect_decode_ok(test, "SGVsbG8sIHdvcmxkIQ", (const u8 *)"Hello, world!", 13,
+ false, BASE64_STD);
+ expect_decode_ok(test, "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo",
+ (const u8 *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26, false, BASE64_STD);
+ expect_decode_ok(test, "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo",
+ (const u8 *)"abcdefghijklmnopqrstuvwxyz", 26, false, BASE64_STD);
+ expect_decode_ok(test, "MDEyMzQ1Njc4OSsv", (const u8 *)"0123456789+/", 12,
+ false, BASE64_STD);
+
+ /* Error cases */
+ expect_decode_err(test, "Zg=!", 4, false, BASE64_STD);
+ expect_decode_err(test, "Zm$=", 4, false, BASE64_STD);
+ expect_decode_err(test, "Z===", 4, false, BASE64_STD);
+ expect_decode_err(test, "Zg=", 3, false, BASE64_STD);
+ expect_decode_err(test, "Zm9v====", 8, false, BASE64_STD);
+ expect_decode_err(test, "Zm==v", 4, false, BASE64_STD);
+
+ {
+ char with_nul[4] = { 'Z', 'g', '\0', '=' };
+
+ expect_decode_err(test, with_nul, 4, false, BASE64_STD);
+ }
+}
+
+/* ---------- Variant tests (URLSAFE / IMAP) ---------- */
+static void base64_variant_tests(struct kunit *test)
+{
+ const u8 sample1[] = { 0x00, 0xfb, 0xff, 0x7f, 0x80 };
+ char std_buf[128], url_buf[128], imap_buf[128];
+ u8 back[128];
+ int n_std, n_url, n_imap, m;
+ int i;
+
+ n_std = base64_encode(sample1, sizeof(sample1), std_buf, false, BASE64_STD);
+ n_url = base64_encode(sample1, sizeof(sample1), url_buf, false, BASE64_URLSAFE);
+ std_buf[n_std] = '\0';
+ url_buf[n_url] = '\0';
+
+ for (i = 0; i < n_std; i++) {
+ if (std_buf[i] == '+')
+ std_buf[i] = '-';
+ else if (std_buf[i] == '/')
+ std_buf[i] = '_';
+ }
+ KUNIT_EXPECT_STREQ(test, std_buf, url_buf);
+
+ m = base64_decode(url_buf, n_url, back, false, BASE64_URLSAFE);
+ KUNIT_EXPECT_EQ(test, m, (int)sizeof(sample1));
+ KUNIT_EXPECT_MEMEQ(test, back, sample1, sizeof(sample1));
+
+ n_std = base64_encode(sample1, sizeof(sample1), std_buf, false, BASE64_STD);
+ n_imap = base64_encode(sample1, sizeof(sample1), imap_buf, false, BASE64_IMAP);
+ std_buf[n_std] = '\0';
+ imap_buf[n_imap] = '\0';
+
+ for (i = 0; i < n_std; i++)
+ if (std_buf[i] == '/')
+ std_buf[i] = ',';
+ KUNIT_EXPECT_STREQ(test, std_buf, imap_buf);
+
+ m = base64_decode(imap_buf, n_imap, back, false, BASE64_IMAP);
+ KUNIT_EXPECT_EQ(test, m, (int)sizeof(sample1));
+ KUNIT_EXPECT_MEMEQ(test, back, sample1, sizeof(sample1));
+
+ {
+ const char *bad = "Zg==";
+ u8 tmp[8];
+
+ m = base64_decode(bad, strlen(bad), tmp, false, BASE64_URLSAFE);
+ KUNIT_EXPECT_EQ(test, m, -1);
+
+ m = base64_decode(bad, strlen(bad), tmp, false, BASE64_IMAP);
+ KUNIT_EXPECT_EQ(test, m, -1);
+ }
+}
+
+/* ---------- Test registration ---------- */
+static struct kunit_case base64_test_cases[] = {
+ KUNIT_CASE(base64_performance_tests),
+ KUNIT_CASE(base64_std_encode_tests),
+ KUNIT_CASE(base64_std_decode_tests),
+ KUNIT_CASE(base64_variant_tests),
+ {}
+};
+
+static struct kunit_suite base64_test_suite = {
+ .name = "base64",
+ .test_cases = base64_test_cases,
+};
+
+kunit_test_suite(base64_test_suite);
+
+MODULE_AUTHOR("Guan-Chun Wu <409411716@gms.tku.edu.tw>");
+MODULE_DESCRIPTION("KUnit tests for Base64 encoding/decoding, including performance checks");
+MODULE_LICENSE("GPL");