From: Srish Srinivasan <ssrish@linux.ibm.com>
To: grub-devel@gnu.org
Cc: daniel.kiper@oracle.com, development@efficientek.com,
sudhakar@linux.ibm.com, sridharm@linux.ibm.com,
ssrish@linux.ibm.com
Subject: [PATCH v4] tests: add functional tests for ecb/cbc helpers
Date: Fri, 2 Jan 2026 15:57:31 +0530 [thread overview]
Message-ID: <20260102102731.482190-1-ssrish@linux.ibm.com> (raw)
Test the following helper functions using AES with 128, 192, and
256 bit keys:
grub_crypto_ecb_encrypt
grub_crypto_ecb_decrypt
grub_crypto_cbc_encrypt
grub_crypto_cbc_decrypt
Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Glenn Washburn <development@efficientek.com>
---
v3->v4: Minor code rearrangement in docs/grub.texi
v2->v3: Make file naming and documentation style more generic
docs/grub.texi | 5 +
grub-core/Makefile.core.def | 5 +
grub-core/tests/crypto_cipher_mode_test.c | 197 +++++++++++++++++++
grub-core/tests/crypto_cipher_mode_vectors.h | 135 +++++++++++++
grub-core/tests/lib/functional_test.c | 1 +
5 files changed, 343 insertions(+)
create mode 100644 grub-core/tests/crypto_cipher_mode_test.c
create mode 100644 grub-core/tests/crypto_cipher_mode_vectors.h
diff --git a/docs/grub.texi b/docs/grub.texi
index 7181009b6..c948e1ee7 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -4078,6 +4078,7 @@ Modules can be loaded via the @command{insmod} (@pxref{insmod}) command.
* cpio_be_module::
* cpuid_module::
* crc64_module::
+* crypto_cipher_mode_test_module::
* crypto_module::
* cryptodisk_module::
* cs5536_module::
@@ -4610,6 +4611,10 @@ various CPU features. @xref{cpuid} for more information.
@section crc64
This module provides support for the CRC64 operation.
+@node crypto_cipher_mode_test_module
+@section crypto_cipher_mode_test
+This module performs various cipher mode encryption/decryption tests
+
@node crypto_module
@section crypto
This module provides library support for various base cryptography operations
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index fa4bc54aa..0cf155128 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2272,6 +2272,11 @@ module = {
common = tests/argon2_test.c;
};
+module = {
+ name = crypto_cipher_mode_test;
+ common = tests/crypto_cipher_mode_test.c;
+};
+
module = {
name = legacy_password_test;
common = tests/legacy_password_test.c;
diff --git a/grub-core/tests/crypto_cipher_mode_test.c b/grub-core/tests/crypto_cipher_mode_test.c
new file mode 100644
index 000000000..68f316421
--- /dev/null
+++ b/grub-core/tests/crypto_cipher_mode_test.c
@@ -0,0 +1,197 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2025 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/test.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/crypto.h>
+
+#include "crypto_cipher_mode_vectors.h"
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+/* Perform cipher lookup, handle init, and key setting. */
+static grub_crypto_cipher_handle_t
+handle_init (struct vector vec, grub_crypto_cipher_handle_t handle)
+{
+ gcry_err_code_t err;
+
+ const gcry_cipher_spec_t *cipher = grub_crypto_lookup_cipher_by_name (vec.cipher);
+ grub_test_assert (cipher != NULL, "\n%s: cipher lookup failed for %s", vec.mode, vec.cipher);
+ if (cipher == NULL)
+ return NULL;
+
+ handle = grub_crypto_cipher_open (cipher);
+ grub_test_assert (handle != NULL, "\n%s: handle init failed for %s", vec.mode, vec.cipher);
+ if (handle == NULL)
+ return NULL;
+
+ err = grub_crypto_cipher_set_key (handle, (grub_uint8_t *) vec.key, vec.keylen);
+ grub_test_assert (err == GPG_ERR_NO_ERROR, "\n%s: key set of size %d failed for %s with err = %d",
+ vec.mode, vec.keylen, vec.cipher, err);
+ if (err != GPG_ERR_NO_ERROR)
+ {
+ grub_crypto_cipher_close (handle);
+ return NULL;
+ }
+
+ return handle;
+}
+
+static void
+ecb_test (struct vector vec)
+{
+ gcry_err_code_t gcry_err;
+ grub_crypto_cipher_handle_t handle = NULL;
+ grub_uint8_t *plaintext = NULL, *ciphertext = NULL;
+ grub_int32_t rc;
+
+ handle = handle_init (vec, handle);
+ if (handle == NULL)
+ return;
+
+ /* Test encryption. */
+ ciphertext = grub_zalloc (vec.plen);
+ grub_test_assert (ciphertext != NULL, "\necb: ciphertext buffer allocation failed");
+ if (ciphertext == NULL)
+ goto out_handle;
+
+ gcry_err = grub_crypto_ecb_encrypt (handle, ciphertext, vec.ptext, vec.plen);
+ grub_test_assert (gcry_err == GPG_ERR_NO_ERROR, "\necb: encryption failed with err = %d",
+ gcry_err);
+ if (gcry_err != GPG_ERR_NO_ERROR)
+ goto out_ct;
+
+ rc = grub_memcmp (ciphertext, vec.ctext, vec.plen);
+ grub_test_assert (rc == 0, "\necb: ciphertext mismatch after encryption");
+ if (rc != 0)
+ goto out_ct;
+
+ /* Test decryption. */
+ plaintext = grub_zalloc (vec.plen);
+ grub_test_assert (plaintext != NULL, "\necb: plaintext buffer allocation failed");
+ if (plaintext == NULL)
+ goto out_ct;
+
+ gcry_err = grub_crypto_ecb_decrypt (handle, plaintext, ciphertext, vec.plen);
+ grub_test_assert (gcry_err == GPG_ERR_NO_ERROR, "\necb: decryption failed failed with err = %d",
+ gcry_err);
+ if (gcry_err != GPG_ERR_NO_ERROR)
+ goto out_pt;
+
+ rc = grub_memcmp (plaintext, vec.ptext, vec.plen);
+ grub_test_assert (rc == 0, "\necb: plaintext mismatch after decryption");
+
+out_pt:
+ grub_free(plaintext);
+out_ct:
+ grub_free(ciphertext);
+out_handle:
+ grub_crypto_cipher_close(handle);
+}
+
+static void
+cbc_test (struct vector vec)
+{
+ gcry_err_code_t gcry_err;
+ grub_crypto_cipher_handle_t handle = NULL;
+ grub_uint8_t *plaintext = NULL, *ciphertext = NULL;
+ grub_uint32_t *iv = NULL;
+ grub_int32_t rc;
+
+ handle = handle_init (vec, handle);
+ if (handle == NULL)
+ return;
+
+ /* Test Encryption */
+ iv = grub_malloc(vec.ivlen);
+ grub_test_assert (iv != NULL, "\ncbc: IV buffer allocation failed");
+ if (iv == NULL)
+ goto out_handle;
+
+ grub_memcpy (iv, vec.iv_in, vec.ivlen);
+
+ ciphertext = grub_zalloc (vec.plen);
+ grub_test_assert (ciphertext != NULL, "\ncbc: ciphertext buffer allocation failed");
+ if (ciphertext == NULL)
+ goto out_iv;
+
+ gcry_err = grub_crypto_cbc_encrypt (handle, ciphertext, vec.ptext, vec.plen, iv);
+ grub_test_assert (gcry_err == GPG_ERR_NO_ERROR, "\ncbc: encryption failed with err = %d",
+ gcry_err);
+ if (gcry_err != GPG_ERR_NO_ERROR)
+ goto out_ct;
+
+ rc = grub_memcmp (ciphertext, vec.ctext, vec.plen);
+ grub_test_assert (rc == 0, "\ncbc: ciphertext mismatch after encryption");
+ if (rc != 0)
+ goto out_ct;
+
+ rc = grub_memcmp (iv, vec.iv_out, vec.ivlen);
+ grub_test_assert (rc == 0, "\ncbc: IV out mismatch after encryption");
+ if (rc != 0)
+ goto out_ct;
+
+ /* Test Decryption */
+ grub_memcpy (iv, vec.iv_in, vec.ivlen);
+
+ plaintext = grub_zalloc (vec.plen);
+ grub_test_assert (plaintext != NULL, "\ncbc: plaintext buffer allocation failed");
+ if (plaintext == NULL)
+ goto out_ct;
+
+ gcry_err = grub_crypto_cbc_decrypt (handle, plaintext, ciphertext, vec.plen, iv);
+ grub_test_assert (gcry_err == GPG_ERR_NO_ERROR, "\ncbc: decryption failed with err = %d",
+ gcry_err);
+ if (gcry_err != GPG_ERR_NO_ERROR)
+ goto out_pt;
+
+ rc = grub_memcmp (plaintext, vec.ptext, vec.plen);
+ grub_test_assert (rc == 0, "\ncbc: plaintext mismatch after decryption");
+
+out_pt:
+ grub_free(plaintext);
+out_ct:
+ grub_free(ciphertext);
+out_iv:
+ grub_free(iv);
+out_handle:
+ grub_crypto_cipher_close(handle);
+}
+
+static void
+crypto_cipher_mode_test (void)
+{
+ grub_size_t i;
+
+ for (i = 0; i < ARRAY_SIZE (vecs); i++)
+ {
+ if (grub_strcmp (vecs[i].mode, "ecb") == 0)
+ ecb_test(vecs[i]);
+ else if (grub_strcmp (vecs[i].mode, "cbc") == 0)
+ cbc_test(vecs[i]);
+ else
+ {
+ grub_test_assert(0, "\n%s mode unsupported for testing", vecs[i].mode);
+ return;
+ }
+ }
+}
+
+/* Register example_test method as a functional test. */
+GRUB_FUNCTIONAL_TEST (crypto_cipher_mode_test, crypto_cipher_mode_test);
diff --git a/grub-core/tests/crypto_cipher_mode_vectors.h b/grub-core/tests/crypto_cipher_mode_vectors.h
new file mode 100644
index 000000000..8ef948b46
--- /dev/null
+++ b/grub-core/tests/crypto_cipher_mode_vectors.h
@@ -0,0 +1,135 @@
+struct vector
+{
+ const char *cipher;
+ const char *mode;
+ const char *key;
+ grub_uint32_t keylen;
+ const char *ptext;
+ grub_uint32_t plen;
+ const char *ctext;
+ const char *iv_in;
+ const char *iv_out;
+ grub_uint32_t ivlen;
+} vecs[] = {
+ {
+ .cipher = "aes",
+ .mode = "ecb",
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .keylen = 16,
+ .ptext = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .plen = 16,
+ .ctext = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+ "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a",
+ },
+ {
+ .cipher = "aes",
+ .mode = "ecb",
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17",
+ .keylen = 24,
+ .ptext = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .plen = 16,
+ .ctext = "\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+ "\x6e\xaf\x70\xa0\xec\x0d\x71\x91",
+ },
+ {
+ .cipher = "aes",
+ .mode = "ecb",
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .keylen = 32,
+ .ptext = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .plen = 16,
+ .ctext = "\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+ "\xea\xfc\x49\x90\x4b\x49\x60\x89",
+ },
+ {
+ .cipher = "aes",
+ .mode = "cbc",
+ .key = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+ "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+ .keylen = 16,
+ .ptext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .plen = 32,
+ .ctext = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
+ "\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
+ "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
+ "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
+ .iv_in = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+ "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+ .iv_out = "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
+ "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
+ .ivlen = 16,
+ },
+ {
+ .cipher = "aes",
+ .mode = "cbc",
+ .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+ "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ .keylen = 24,
+ .ptext = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .plen = 64,
+ .ctext = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
+ "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
+ "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
+ "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
+ "\x57\x1b\x24\x20\x12\xfb\x7a\xe0"
+ "\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
+ "\x08\xb0\xe2\x79\x88\x59\x88\x81"
+ "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
+ .iv_in = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .iv_out = "\x08\xb0\xe2\x79\x88\x59\x88\x81"
+ "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
+ .ivlen = 16,
+ },
+ {
+ .cipher = "aes",
+ .mode = "cbc",
+ .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+ "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+ "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ .keylen = 32,
+ .ptext = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .plen = 64,
+ .ctext = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba"
+ "\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
+ "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d"
+ "\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
+ "\x39\xf2\x33\x69\xa9\xd9\xba\xcf"
+ "\xa5\x30\xe2\x63\x04\x23\x14\x61"
+ "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
+ "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
+ .iv_in = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .iv_out = "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
+ "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
+ .ivlen = 16,
+ },
+};
diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c
index 776934e1f..4214332df 100644
--- a/grub-core/tests/lib/functional_test.c
+++ b/grub-core/tests/lib/functional_test.c
@@ -82,6 +82,7 @@ grub_functional_all_tests (grub_extcmd_context_t ctxt __attribute__ ((unused)),
grub_dl_load ("shift_test");
grub_dl_load ("asn1_test");
grub_dl_load ("argon2_test");
+ grub_dl_load ("crypto_cipher_mode_test");
FOR_LIST_ELEMENTS (test, grub_test_list)
ok = !grub_test_run (test) && ok;
--
2.52.0
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
next reply other threads:[~2026-01-02 10:28 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-02 10:27 Srish Srinivasan [this message]
2026-01-02 20:13 ` [PATCH v4] tests: add functional tests for ecb/cbc helpers Glenn Washburn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260102102731.482190-1-ssrish@linux.ibm.com \
--to=ssrish@linux.ibm.com \
--cc=daniel.kiper@oracle.com \
--cc=development@efficientek.com \
--cc=grub-devel@gnu.org \
--cc=sridharm@linux.ibm.com \
--cc=sudhakar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.