mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 0/2] PBL: add support for optimized sha256
@ 2026-07-27 12:59 Sascha Hauer
  2026-07-27 12:59 ` [PATCH v2 1/2] PBL: add pbl_sha256() Sascha Hauer
  2026-07-27 12:59 ` [PATCH v2 2/2] ARM: pbl: add PBL support for crypto extensions Sascha Hauer
  0 siblings, 2 replies; 3+ messages in thread
From: Sascha Hauer @ 2026-07-27 12:59 UTC (permalink / raw)
  To: BAREBOX

When chainloading a full barebox from the PBL we have to verify the
loaded image with sha256. This can take some time for bigger image, so
add support for optimized implementations and ad the ARM64 Crypto
Extensions as a first implementation

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Changes in v2:
- drop ARMv8 specific comment in generic file
- Use static SHA256_DIGEST_SIZE in function prototype
- Link to v1: https://lore.barebox.org/20260709-pbl-sha256-v1-0-453800909579@pengutronix.de

---
Sascha Hauer (2):
      PBL: add pbl_sha256()
      ARM: pbl: add PBL support for crypto extensions

 arch/arm/crypto/Makefile       |  3 +--
 arch/arm/crypto/sha2-ce-glue.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 include/crypto/pbl-sha.h       | 14 ++++++++++++++
 pbl/Makefile                   |  1 +
 pbl/decomp.c                   |  6 +-----
 pbl/sha256.c                   | 28 +++++++++++++++++++++++++++
 6 files changed, 89 insertions(+), 7 deletions(-)
---
base-commit: 8057f993993040fdd3bea1c42cf8e37af5b6f5d3
change-id: 20260709-pbl-sha256-b60f9893126e

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




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

* [PATCH v2 1/2] PBL: add pbl_sha256()
  2026-07-27 12:59 [PATCH v2 0/2] PBL: add support for optimized sha256 Sascha Hauer
@ 2026-07-27 12:59 ` Sascha Hauer
  2026-07-27 12:59 ` [PATCH v2 2/2] ARM: pbl: add PBL support for crypto extensions Sascha Hauer
  1 sibling, 0 replies; 3+ messages in thread
From: Sascha Hauer @ 2026-07-27 12:59 UTC (permalink / raw)
  To: BAREBOX

The PBL open-codes SHA-256 as sha256_init()/sha256_update()/sha256_final()
wherever it needs to hash a blob, which always uses the generic C transform.
Add pbl_sha256(), a one-shot helper that hides this behind a single call and
is free to pick the best transform available in the PBL. For now it only
wraps the generic C implementation; an accelerated path is added on top in a
later commit.

Convert pbl_barebox_verify() in pbl/decomp.c to the new helper as the first
user.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/crypto/pbl-sha.h |  4 ++++
 pbl/Makefile             |  1 +
 pbl/decomp.c             |  6 +-----
 pbl/sha256.c             | 25 +++++++++++++++++++++++++
 4 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/include/crypto/pbl-sha.h b/include/crypto/pbl-sha.h
index 7d323ab479..2508448ab4 100644
--- a/include/crypto/pbl-sha.h
+++ b/include/crypto/pbl-sha.h
@@ -3,6 +3,7 @@
 
 #define __PBL_SHA_H_
 
+#include <crypto/sha.h>
 #include <digest.h>
 #include <types.h>
 
@@ -10,4 +11,7 @@ int sha256_init(struct digest *desc);
 int sha256_update(struct digest *desc, const void *data, unsigned long len);
 int sha256_final(struct digest *desc, u8 *out);
 
+/* One-shot SHA-256 that picks the best transform available in the PBL. */
+void pbl_sha256(const void *buf, size_t len, u8 out[SHA256_DIGEST_SIZE]);
+
 #endif /* __PBL-SHA_H_ */
diff --git a/pbl/Makefile b/pbl/Makefile
index 45cfbf5fba..4506f192fe 100644
--- a/pbl/Makefile
+++ b/pbl/Makefile
@@ -6,6 +6,7 @@
 pbl-y += misc.o
 pbl-y += string.o
 pbl-y += malloc.o
+pbl-y += sha256.o
 pbl-$(CONFIG_HAVE_IMAGE_COMPRESSION) += decomp.o
 pbl-$(CONFIG_LIBFDT) += fdt.o
 pbl-$(CONFIG_PBL_CONSOLE) += console.o
diff --git a/pbl/decomp.c b/pbl/decomp.c
index 1539a6b67e..2b3c35012f 100644
--- a/pbl/decomp.c
+++ b/pbl/decomp.c
@@ -58,8 +58,6 @@ extern unsigned char sha_sum_end[];
 int pbl_barebox_verify(const void *compressed_start, unsigned int len,
 		       const void *hash, unsigned int hash_len)
 {
-	struct sha256_state sha_state = { 0 };
-	struct digest d = { .ctx = &sha_state };
 	char computed_hash[SHA256_DIGEST_SIZE];
 	int i;
 	const char *char_hash = hash;
@@ -67,9 +65,7 @@ int pbl_barebox_verify(const void *compressed_start, unsigned int len,
 	if (hash_len != SHA256_DIGEST_SIZE)
 		return -1;
 
-	sha256_init(&d);
-	sha256_update(&d, compressed_start, len);
-	sha256_final(&d, computed_hash);
+	pbl_sha256(compressed_start, len, computed_hash);
 	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
 		puts_ll("CH ");
 
diff --git a/pbl/sha256.c b/pbl/sha256.c
new file mode 100644
index 0000000000..853d6bcbf6
--- /dev/null
+++ b/pbl/sha256.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * pbl_sha256() - one-shot SHA-256 for the PBL, picking the best available
+ * implementation.
+ */
+
+#include <common.h>
+#include <crypto/sha.h>
+#include <crypto/pbl-sha.h>
+#include <digest.h>
+
+static void pbl_sha256_generic(const void *buf, size_t len, u8 *out)
+{
+	struct sha256_state state = { };
+	struct digest d = { .ctx = &state, .length = SHA256_DIGEST_SIZE };
+
+	sha256_init(&d);
+	sha256_update(&d, buf, len);
+	sha256_final(&d, out);
+}
+
+void pbl_sha256(const void *buf, size_t len, u8 out[static SHA256_DIGEST_SIZE])
+{
+	pbl_sha256_generic(buf, len, out);
+}

-- 
2.47.3




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

* [PATCH v2 2/2] ARM: pbl: add PBL support for crypto extensions
  2026-07-27 12:59 [PATCH v2 0/2] PBL: add support for optimized sha256 Sascha Hauer
  2026-07-27 12:59 ` [PATCH v2 1/2] PBL: add pbl_sha256() Sascha Hauer
@ 2026-07-27 12:59 ` Sascha Hauer
  1 sibling, 0 replies; 3+ messages in thread
From: Sascha Hauer @ 2026-07-27 12:59 UTC (permalink / raw)
  To: BAREBOX

Hashing large blobs in the PBL with the generic C SHA-256 transform is slow;
ARMv8 provides optional Crypto Extensions (sha256h/sha256h2/sha256su0/
sha256su1) that do the transform roughly 100x faster, and barebox proper
already uses them via arch/arm/crypto/sha2-ce-glue.c.

Reuse that driver in the PBL. Build sha2-ce-glue.c and the shared
sha2-ce-core.S transform for the PBL as well (obj-pbl-) and have the glue
additionally provide pbl_sha256_ce(), a one-shot hash that drives the asm
core directly without the digest API or NEON save/restore, neither of which
exist in the PBL. Like the digest registration it gates on
ID_AA64ISAR0_EL1.SHA2 and returns -EOPNOTSUPP when the extensions are
absent, so pbl_sha256() transparently falls back to the generic C transform.

Assisted-by: Claude Opus 4.8
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/crypto/Makefile       |  3 +--
 arch/arm/crypto/sha2-ce-glue.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 include/crypto/pbl-sha.h       | 10 ++++++++++
 pbl/sha256.c                   |  3 +++
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
index 55b3ac0538..976c175b71 100644
--- a/arch/arm/crypto/Makefile
+++ b/arch/arm/crypto/Makefile
@@ -12,8 +12,7 @@ sha256-arm-y	:= sha256-core.o sha256_glue.o
 obj-$(CONFIG_DIGEST_SHA1_ARM64_CE) += sha1-ce.o
 sha1-ce-y := sha1-ce-glue.o sha1-ce-core.o
 
-obj-$(CONFIG_DIGEST_SHA256_ARM64_CE) += sha2-ce.o
-sha2-ce-y := sha2-ce-glue.o sha2-ce-core.o
+obj-pbl-$(CONFIG_DIGEST_SHA256_ARM64_CE) += sha2-ce-glue.o sha2-ce-core.o
 
 quiet_cmd_perl = PERL    $@
       cmd_perl = $(PERL) $(<) > $(@)
diff --git a/arch/arm/crypto/sha2-ce-glue.c b/arch/arm/crypto/sha2-ce-glue.c
index 8479b3c60c..4ccf1b86cb 100644
--- a/arch/arm/crypto/sha2-ce-glue.c
+++ b/arch/arm/crypto/sha2-ce-glue.c
@@ -10,6 +10,7 @@
 #include <init.h>
 #include <crypto/sha.h>
 #include <crypto/sha256_base.h>
+#include <crypto/pbl-sha.h>
 #include <crypto/internal.h>
 #include <linux/linkage.h>
 #include <asm/byteorder.h>
@@ -33,6 +34,49 @@ extern const u32 sha256_ce_offsetof_finalize;
 asmlinkage int sha2_ce_transform(struct sha256_ce_state *sst, u8 const *src,
 				 int blocks);
 
+/*
+ * In the PBL there is no digest API and no NEON save/restore; expose a
+ * one-shot pbl_sha256_ce() that pbl_sha256() calls in preference to the
+ * generic C transform.
+ */
+static void pbl_sha2_ce_transform(struct sha256_state *sst, u8 const *src,
+				  int blocks)
+{
+	struct sha256_ce_state *s =
+		container_of(sst, struct sha256_ce_state, sst);
+
+	/* finalize == 0: C does the padding via sha256_base_do_finalize(). */
+	s->finalize = 0;
+	while (blocks) {
+		int rem = sha2_ce_transform(s, src, blocks);
+
+		src += (blocks - rem) * SHA256_BLOCK_SIZE;
+		blocks = rem;
+	}
+}
+
+int pbl_sha256_ce(const void *buf, size_t len, u8 out[SHA256_DIGEST_SIZE])
+{
+	struct sha256_ce_state s;
+	struct digest d = { .ctx = &s, .length = SHA256_DIGEST_SIZE };
+
+	/*
+	 * The Crypto Extensions are optional on ARMv8 and sha256h & co. trap
+	 * as undefined without them, so gate on ID_AA64ISAR0_EL1.SHA2 like the
+	 * digest registration below does and let the caller fall back to
+	 * generic C.
+	 */
+	if (!(read_sysreg(ID_AA64ISAR0_EL1) & ID_AA64ISAR0_EL1_SHA2_MASK))
+		return -EOPNOTSUPP;
+
+	sha256_base_init(&d);
+	sha256_base_do_update(&d, buf, len, pbl_sha2_ce_transform);
+	sha256_base_do_finalize(&d, pbl_sha2_ce_transform);
+	sha256_base_finish(&d, out);
+
+	return 0;
+}
+
 static void __sha2_ce_transform(struct sha256_state *sst, u8 const *src,
 				int blocks)
 {
diff --git a/include/crypto/pbl-sha.h b/include/crypto/pbl-sha.h
index 2508448ab4..3ccd5151e1 100644
--- a/include/crypto/pbl-sha.h
+++ b/include/crypto/pbl-sha.h
@@ -14,4 +14,14 @@ int sha256_final(struct digest *desc, u8 *out);
 /* One-shot SHA-256 that picks the best transform available in the PBL. */
 void pbl_sha256(const void *buf, size_t len, u8 out[SHA256_DIGEST_SIZE]);
 
+#ifdef CONFIG_DIGEST_SHA256_ARM64_CE
+/* ARMv8 Crypto Extensions transform; returns -EOPNOTSUPP if unavailable. */
+int pbl_sha256_ce(const void *buf, size_t len, u8 out[SHA256_DIGEST_SIZE]);
+#else
+static inline int pbl_sha256_ce(const void *buf, size_t len, u8 out[SHA256_DIGEST_SIZE])
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
 #endif /* __PBL-SHA_H_ */
diff --git a/pbl/sha256.c b/pbl/sha256.c
index 853d6bcbf6..04cc64a77d 100644
--- a/pbl/sha256.c
+++ b/pbl/sha256.c
@@ -21,5 +21,8 @@ static void pbl_sha256_generic(const void *buf, size_t len, u8 *out)
 
 void pbl_sha256(const void *buf, size_t len, u8 out[static SHA256_DIGEST_SIZE])
 {
+	if (!pbl_sha256_ce(buf, len, out))
+		return;
+
 	pbl_sha256_generic(buf, len, out);
 }

-- 
2.47.3




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

end of thread, other threads:[~2026-07-27 13:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-27 12:59 [PATCH v2 0/2] PBL: add support for optimized sha256 Sascha Hauer
2026-07-27 12:59 ` [PATCH v2 1/2] PBL: add pbl_sha256() Sascha Hauer
2026-07-27 12:59 ` [PATCH v2 2/2] ARM: pbl: add PBL support for crypto extensions Sascha Hauer

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