All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heiko Schocher <hs@nabladev.com>
To: U-Boot Mailing List <u-boot@lists.denx.de>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	Heiko Schocher <hs@nabladev.com>,
	Alif Zakuan Yuslaimi <alif.zakuan.yuslaimi@altera.com>,
	Anshul Dalal <anshuld@ti.com>,
	Arturs Artamonovs <arturs.artamonovs@analog.com>,
	Casey Connolly <casey.connolly@linaro.org>,
	Dinesh Maniyam <dinesh.maniyam@altera.com>,
	Greg Malysa <malysagreg@gmail.com>,
	Heinrich Schuchardt <xypron.glpk@gmx.de>,
	Ibai Erkiaga <ibai.erkiaga-elorza@amd.com>,
	Jaehoon Chung <jh80.chung@samsung.com>,
	Jerome Forissier <jerome.forissier@linaro.org>,
	"Kory Maincent (TI.com)" <kory.maincent@bootlin.com>,
	Marek Vasut <marek.vasut@mailbox.org>,
	Martin Schwan <m.schwan@phytec.de>,
	Mattijs Korpershoek <mkorpershoek@kernel.org>,
	Michael Trimarchi <michael@amarulasolutions.com>,
	Michal Simek <michal.simek@amd.com>,
	Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>,
	Nathan Barrett-Morrison <nathan.morrison@timesys.com>,
	Oliver Gaskell <Oliver.Gaskell@analog.com>,
	Paul Barker <paul.barker.ct@bp.renesas.com>,
	Peng Fan <peng.fan@nxp.com>,
	Peter Robinson <pbrobinson@gmail.com>,
	Quentin Schulz <quentin.schulz@cherry.de>,
	Simon Glass <sjg@chromium.org>,
	Stefan Roese <stefan.roese@mailbox.org>,
	Sumit Garg <sumit.garg@kernel.org>, Tom Rini <trini@konsulko.com>,
	Utsav Agarwal <utsav.agarwal@analog.com>,
	Vasileios Bimpikas <vasileios.bimpikas@analog.com>,
	Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>,
	briansune <briansune@gmail.com>
Subject: [PATCH v3 3/6] lib: sm3: implement U-Boot parts
Date: Tue, 18 Nov 2025 05:30:39 +0100	[thread overview]
Message-ID: <20251118043042.27726-4-hs@nabladev.com> (raw)
In-Reply-To: <20251118043042.27726-1-hs@nabladev.com>

add the U-Boot specific parts for the SM3 hash
implementation:

Signed-off-by: Heiko Schocher <hs@nabladev.com>
---

Changes in v3:
New in version 3 as Ilias recommended to split linux
and U-boot changes.

 MAINTAINERS          |   1 +
 boot/Kconfig         |   1 +
 cmd/Kconfig          |  15 ++++++
 cmd/Makefile         |   1 +
 cmd/sm3sum.c         |  48 +++++++++++++++++
 common/hash.c        |  42 ++++++++++++++-
 include/u-boot/sm3.h |   8 +++
 lib/sm3.c            | 125 +++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 240 insertions(+), 1 deletion(-)
 create mode 100644 cmd/sm3sum.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e1d79206e50..dc62990a090 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1689,6 +1689,7 @@ F:	test/lib/slre.c
 SM3
 M:	Heiko Schocher <hs@nabladev.com>
 S:	Maintained
+F:	cmd/sm3sum.c
 F:	include/u-boot/sm3.h
 F:	lib/sm3.c
 
diff --git a/boot/Kconfig b/boot/Kconfig
index 85f4d468069..76cc628c9bd 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -1042,6 +1042,7 @@ config MEASURED_BOOT
 	select SHA256
 	select SHA384
 	select SHA512
+	select SM3
 	help
 	  This option enables measurement of the boot process when booting
 	  without UEFI . Measurement involves creating cryptographic hashes
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 5b9c13d85e7..8e3efff2bee 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -264,6 +264,21 @@ config CMD_SBI
 	help
 	  Display information about the SBI implementation.
 
+config CMD_SM3SUM
+	bool "sm3sum"
+	select SM3
+	select HASH
+	help
+	  Compute SM3 checksum.
+	  add SM3 hash functionality
+
+config SM3SUM_VERIFY
+	bool "sm3sum -v"
+	depends on CMD_SM3SUM
+	help
+	  Add for the sm3sum command the -v option
+	  to verify data against an SM3 checksum.
+
 config CMD_SMBIOS
 	bool "smbios"
 	depends on SMBIOS
diff --git a/cmd/Makefile b/cmd/Makefile
index 25479907797..642042cfe00 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -177,6 +177,7 @@ obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
 obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o
 obj-$(CONFIG_CMD_SPI) += spi.o
 obj-$(CONFIG_CMD_STRINGS) += strings.o
+obj-$(CONFIG_CMD_SM3SUM) += sm3sum.o
 obj-$(CONFIG_CMD_SMBIOS) += smbios.o
 obj-$(CONFIG_CMD_SMC) += smccc.o
 obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o
diff --git a/cmd/sm3sum.c b/cmd/sm3sum.c
new file mode 100644
index 00000000000..9044a322e22
--- /dev/null
+++ b/cmd/sm3sum.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2025
+ * Heiko Schocher, Nabladev Software Engineering, hs@nabladev.com
+ *
+ * based on code from cmd/md5sum.c
+ */
+
+#include <command.h>
+#include <env.h>
+#include <hash.h>
+
+static int do_sm3sum(struct cmd_tbl *cmdtp, int flag, int argc,
+		     char *const argv[])
+{
+	int flags = HASH_FLAG_ENV;
+	int ac;
+	char *const *av;
+
+	if (argc < 3)
+		return CMD_RET_USAGE;
+
+	av = argv + 1;
+	ac = argc - 1;
+	if (IS_ENABLED(CONFIG_SM3SUM_VERIFY) && strcmp(*av, "-v") == 0) {
+		flags |= HASH_FLAG_VERIFY;
+		av++;
+		ac--;
+	}
+
+	return hash_command("sm3_256", flags, cmdtp, flag, ac, av);
+}
+
+#if IS_ENABLED(CONFIG_SM3SUM_VERIFY)
+U_BOOT_CMD(sm3sum, 5, 1, do_sm3sum,
+	   "compute SM3 message digest",
+	   "address count [[*]sum]\n"
+	   "  - compute SM3 message digest [save to sum]\n"
+	   "sm3sum -v address count [*]sum\n"
+	   "  - verify sm3sum of memory area"
+);
+#else
+U_BOOT_CMD(sm3sum, 4, 1, do_sm3sum,
+	   "compute SM3 message digest",
+	   "address count [[*]sum]\n"
+	   "  - compute SM3 message digest [save to sum]"
+);
+#endif /* IS_ENABLED(CONFIG_SM3SUM_VERIFY) */
diff --git a/common/hash.c b/common/hash.c
index 0c45992d5c7..71c4bef5826 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -34,6 +34,7 @@
 #include <u-boot/sha256.h>
 #include <u-boot/sha512.h>
 #include <u-boot/md5.h>
+#include <u-boot/sm3.h>
 
 static int __maybe_unused hash_init_sha1(struct hash_algo *algo, void **ctxp)
 {
@@ -143,6 +144,34 @@ static int __maybe_unused hash_finish_sha512(struct hash_algo *algo, void *ctx,
 	return 0;
 }
 
+static int __maybe_unused hash_init_sm3(struct hash_algo *algo, void **ctxp)
+{
+	struct sm3_context *ctx = malloc(sizeof(struct sm3_context));
+
+	sm3_init(ctx);
+	*ctxp = ctx;
+	return 0;
+}
+
+static int __maybe_unused hash_update_sm3(struct hash_algo *algo, void *ctx,
+					  const void *buf, uint size,
+					  int is_last)
+{
+	sm3_update((struct sm3_context *)ctx, buf, size);
+	return 0;
+}
+
+static int __maybe_unused hash_finish_sm3(struct hash_algo *algo, void *ctx,
+					  void *dest_buf, int size)
+{
+	if (size < algo->digest_size)
+		return -1;
+
+	sm3_final((struct sm3_context *)ctx, dest_buf);
+	free(ctx);
+	return 0;
+}
+
 static int __maybe_unused hash_init_crc16_ccitt(struct hash_algo *algo,
 						void **ctxp)
 {
@@ -298,6 +327,17 @@ static struct hash_algo hash_algo[] = {
 #endif
 	},
 #endif
+#if CONFIG_IS_ENABLED(SM3)
+	{
+		.name		= "sm3_256",
+		.digest_size	= SM3_DIGEST_SIZE,
+		.chunk_size	= SM3_BLOCK_SIZE,
+		.hash_func_ws	= sm3_csum_wd,
+		.hash_init	= hash_init_sm3,
+		.hash_update	= hash_update_sm3,
+		.hash_finish	= hash_finish_sm3,
+	},
+#endif
 #if CONFIG_IS_ENABLED(CRC16)
 	{
 		.name		= "crc16-ccitt",
@@ -334,7 +374,7 @@ static struct hash_algo hash_algo[] = {
 #if CONFIG_IS_ENABLED(SHA256) || IS_ENABLED(CONFIG_CMD_SHA1SUM) || \
 	CONFIG_IS_ENABLED(CRC32_VERIFY) || IS_ENABLED(CONFIG_CMD_HASH) || \
 	CONFIG_IS_ENABLED(SHA384) || CONFIG_IS_ENABLED(SHA512) || \
-	IS_ENABLED(CONFIG_CMD_MD5SUM)
+	IS_ENABLED(CONFIG_CMD_MD5SUM) || CONFIG_IS_ENABLED(SM3)
 #define multi_hash()	1
 #else
 #define multi_hash()	0
diff --git a/include/u-boot/sm3.h b/include/u-boot/sm3.h
index de16684ca0a..b4ead96c776 100644
--- a/include/u-boot/sm3.h
+++ b/include/u-boot/sm3.h
@@ -24,4 +24,12 @@ struct sm3_context {
 	uint8_t buffer[SM3_BLOCK_SIZE];
 	int buflen;
 };
+
+void sm3_init(struct sm3_context *sctx);
+void sm3_update(struct sm3_context *sctx, const uint8_t *input, size_t ilen);
+void sm3_final(struct sm3_context *sctx, uint8_t output[SM3_DIGEST_SIZE]);
+void sm3_hash(const uint8_t *input, size_t ilen, uint8_t output[SM3_DIGEST_SIZE]);
+
+void sm3_csum_wd(const unsigned char *input, uint32_t len,
+		 unsigned char *output, unsigned int chunk_sz);
 #endif
diff --git a/lib/sm3.c b/lib/sm3.c
index bb994d187ef..2a4e825481d 100644
--- a/lib/sm3.c
+++ b/lib/sm3.c
@@ -185,3 +185,128 @@ static inline void sm3_block(struct sm3_context *sctx,
 		data += SM3_BLOCK_SIZE;
 	}
 }
+
+void sm3_init(struct sm3_context *sctx)
+{
+	memset(sctx, 0, sizeof(*sctx));
+
+	/* Load initial values */
+	sctx->state[0] = SM3_IVA;
+	sctx->state[1] = SM3_IVB;
+	sctx->state[2] = SM3_IVC;
+	sctx->state[3] = SM3_IVD;
+	sctx->state[4] = SM3_IVE;
+	sctx->state[5] = SM3_IVF;
+	sctx->state[6] = SM3_IVG;
+	sctx->state[7] = SM3_IVH;
+	sctx->count = 0;
+}
+
+void sm3_update(struct sm3_context *sctx, const uint8_t *input, size_t ilen)
+{
+	unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
+	u32 W[16];
+
+	sctx->count += ilen;
+
+	if ((partial + ilen) >= SM3_BLOCK_SIZE) {
+		int blocks;
+
+		if (partial) {
+			int p = SM3_BLOCK_SIZE - partial;
+
+			memcpy(sctx->buffer + partial, input, p);
+			input += p;
+			ilen -= p;
+
+			sm3_block(sctx, sctx->buffer, 1, W);
+		}
+
+		blocks = ilen / SM3_BLOCK_SIZE;
+		ilen %= SM3_BLOCK_SIZE;
+
+		if (blocks) {
+			sm3_block(sctx, input, blocks, W);
+			input += blocks * SM3_BLOCK_SIZE;
+		}
+
+		memset(W, 0, sizeof(W));
+
+		partial = 0;
+	}
+	if (ilen)
+		memcpy(sctx->buffer + partial, input, ilen);
+}
+
+void sm3_final(struct sm3_context *sctx, uint8_t output[SM3_DIGEST_SIZE])
+{
+	const int bit_offset = SM3_BLOCK_SIZE - sizeof(u64);
+	__be64 *bits = (__be64 *)(sctx->buffer + bit_offset);
+	__be32 *digest = (__be32 *)&output[0];
+	unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
+	u32 W[16];
+	int i;
+
+	sctx->buffer[partial++] = 0x80;
+	if (partial > bit_offset) {
+		memset(sctx->buffer + partial, 0, SM3_BLOCK_SIZE - partial);
+		partial = 0;
+
+		sm3_block(sctx, sctx->buffer, 1, W);
+	}
+
+	memset(sctx->buffer + partial, 0, bit_offset - partial);
+	*bits = cpu_to_be64(sctx->count << 3);
+	sm3_block(sctx, sctx->buffer, 1, W);
+
+	for (i = 0; i < 8; i++)
+		put_unaligned_be32(sctx->state[i], digest++);
+
+	/* Zeroize sensitive information. */
+	memset(W, 0, sizeof(W));
+	memset(sctx, 0, sizeof(*sctx));
+}
+
+/**
+ * sm3_hash - Calculate SM3 hash of input data
+ * @input: Input data
+ * @ilen: Input data length in bytes
+ * @output: Output buffer for hash (32 bytes)
+ */
+void sm3_hash(const uint8_t *input, size_t ilen, uint8_t output[SM3_DIGEST_SIZE])
+{
+	struct sm3_context sctx;
+
+	sm3_init(&sctx);
+	sm3_update(&sctx, input, ilen);
+	sm3_final(&sctx, output);
+}
+
+/**
+ * sm3_csum_wd - Calculate SM3 checksum on memory region using watchdog
+ * @addr: Starting address
+ * @len: Length in bytes
+ * @output: Output buffer for checksum (32 bytes)
+ * @flags: Flags for watchdog behavior
+ *
+ * This is the U-Boot API entry function for SM3 hash calculation
+ */
+void sm3_csum_wd(const unsigned char *input, uint32_t len,
+		 unsigned char *output, unsigned int chunk_sz)
+{
+	struct sm3_context ctx;
+	uint32_t chunk;
+
+	sm3_init(&ctx);
+
+	/* Process data in chunks, kicking watchdog between chunks */
+	while (len > 0) {
+		chunk = (len > chunk_sz) ? chunk_sz : len;
+		sm3_update(&ctx, input, chunk);
+		input += chunk;
+		len -= chunk;
+
+		schedule();
+	}
+	sm3_final(&ctx, output);
+}
-- 
2.20.1


  parent reply	other threads:[~2025-11-18  8:31 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-18  4:30 [PATCH v3 0/6] Add support for SM3 secure hash Heiko Schocher
2025-11-18  4:30 ` [PATCH v3 1/6] lib: Import rol32 function from Linux Heiko Schocher
2025-11-18  4:30 ` [PATCH v3 2/6] lib: import sm3 256 hash parts from linux Heiko Schocher
2025-11-19 11:02   ` Ilias Apalodimas
2025-11-18  4:30 ` Heiko Schocher [this message]
2025-11-18 10:30   ` [PATCH v3 3/6] lib: sm3: implement U-Boot parts Quentin Schulz
2025-11-19  7:13     ` Heiko Schocher
2025-11-18  4:30 ` [PATCH v3 4/6] test: cmd: hash: add unit test for sm3_256 Heiko Schocher
2025-11-18  4:30 ` [PATCH v3 5/6] tpm2: add sm3 256 hash support Heiko Schocher
2025-11-18  4:30 ` [PATCH v3 6/6] test: cmd: fix a typo in md5 test Heiko Schocher
2025-11-18 10:06 ` [PATCH v3 0/6] Add support for SM3 secure hash Ilias Apalodimas
2025-11-18 15:11 ` Raymond Mao
2025-11-19  5:40   ` Heiko Schocher
2025-11-19  7:18     ` Ilias Apalodimas
2025-12-04 19:31 ` Tom Rini
2025-12-05  5:03   ` Heiko Schocher
2025-12-05  7:24     ` Ilias Apalodimas
2025-12-05  8:02       ` Heiko Schocher
2025-12-05 14:11         ` Tom Rini
2025-12-08  9:07           ` Ilias Apalodimas
2025-12-08  9:26             ` Heiko Schocher

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=20251118043042.27726-4-hs@nabladev.com \
    --to=hs@nabladev.com \
    --cc=Oliver.Gaskell@analog.com \
    --cc=alif.zakuan.yuslaimi@altera.com \
    --cc=anshuld@ti.com \
    --cc=arturs.artamonovs@analog.com \
    --cc=briansune@gmail.com \
    --cc=casey.connolly@linaro.org \
    --cc=dinesh.maniyam@altera.com \
    --cc=ibai.erkiaga-elorza@amd.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=jerome.forissier@linaro.org \
    --cc=jh80.chung@samsung.com \
    --cc=kory.maincent@bootlin.com \
    --cc=m.schwan@phytec.de \
    --cc=malysagreg@gmail.com \
    --cc=marek.vasut@mailbox.org \
    --cc=michael@amarulasolutions.com \
    --cc=michal.simek@amd.com \
    --cc=mikhail.kshevetskiy@iopsys.eu \
    --cc=mkorpershoek@kernel.org \
    --cc=nathan.morrison@timesys.com \
    --cc=paul.barker.ct@bp.renesas.com \
    --cc=pbrobinson@gmail.com \
    --cc=peng.fan@nxp.com \
    --cc=quentin.schulz@cherry.de \
    --cc=sjg@chromium.org \
    --cc=stefan.roese@mailbox.org \
    --cc=sumit.garg@kernel.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    --cc=utsav.agarwal@analog.com \
    --cc=vasileios.bimpikas@analog.com \
    --cc=venkatesh.abbarapu@amd.com \
    --cc=xypron.glpk@gmx.de \
    /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.