All of lore.kernel.org
 help / color / mirror / Atom feed
From: Igor Opaniuk <igor.opaniuk@gmail.com>
To: u-boot@lists.u-boot-project.org
Cc: Tom Rini <trini@konsulko.com>,
	 Mattijs Korpershoek <mkorpershoek@kernel.org>,
	 Peter Robinson <pbrobinson@gmail.com>,
	 Quentin Schulz <quentin.schulz@cherry.de>,
	Johan Jonker <jbx6244@gmail.com>,
	 Igor Opaniuk <igor.opaniuk@gmail.com>
Subject: [PATCH 1/4] avb: make the AVB root key source pluggable
Date: Mon, 27 Jul 2026 19:14:13 +0200	[thread overview]
Message-ID: <20260727-avb-root-key-pluggable-v1-1-7e27b2b92cc0@gmail.com> (raw)
In-Reply-To: <20260727-avb-root-key-pluggable-v1-0-7e27b2b92cc0@gmail.com>

AVB's whole chain of trust reduces to a single public key, and that key is
currently hard-coded in U-Boot as the AVB reference/test key, whose private
half is public. That is fine for bring-up but unusable for a locked
product, which must anchor its root of trust in something an attacker
cannot swap out -- a hash fused into the SoC, a secure element -- rather
than a blob compiled into the bootloader.

Make the source of the trusted key digest selectable so a board can decide
where its root of trust lives, without touching the verification logic and
with any lookup failure treated as untrusted. The built-in key remains the
default, so existing users are unaffected; the sources a production device
actually needs are added in the following patches.

Signed-off-by: Igor Opaniuk <igor.opaniuk@gmail.com>
---
 common/Kconfig       | 18 ++++++++++++++++++
 common/avb_verify.c  | 36 +++++++++++++++++++++++++++++++++---
 include/avb_verify.h | 19 +++++++++++++++++++
 3 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 345be4b8ca1..654e78b7b7a 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -881,6 +881,7 @@ config AVB_VERIFY
 	depends on MMC
 	depends on PARTITION_UUIDS
 	depends on FASTBOOT
+	select SHA256
 	help
 	  This option enables compilation of bootloader-dependent operations,
 	  used by Android Verified Boot 2.0 library (libavb). Includes:
@@ -904,6 +905,23 @@ config AVB_BUF_SIZE
 	  AVB requires a buffer for memory transactions. This variable defines the
 	  buffer size.
 
+choice
+	prompt "Source of the trusted AVB root public key"
+	default AVB_ROOT_KEY_BUILTIN
+	help
+	  Selects where validate_vbmeta_public_key() obtains the trusted root
+	  key digest that the vbmeta signing key is compared against. This is
+	  the root of trust for the whole AVB chain.
+
+config AVB_ROOT_KEY_BUILTIN
+	bool "Built-in key hard-coded in avb_verify.c"
+	help
+	  Use the avb_root_pub[] blob compiled into U-Boot. By default this is
+	  the AVB reference/test key and is intended for development only;
+	  replace the blob for production use.
+
+endchoice
+
 endif # AVB_VERIFY
 
 config SCP03
diff --git a/common/avb_verify.c b/common/avb_verify.c
index 76c523fd0ba..7c6baa33ed8 100644
--- a/common/avb_verify.c
+++ b/common/avb_verify.c
@@ -11,7 +11,9 @@
 #include <part.h>
 #include <tee.h>
 #include <tee/optee_ta_avb.h>
+#include <u-boot/sha256.h>
 
+#if CONFIG_IS_ENABLED(AVB_ROOT_KEY_BUILTIN)
 static const unsigned char avb_root_pub[1032] = {
 	0x0, 0x0, 0x10, 0x0, 0x55, 0xd9, 0x4, 0xad, 0xd8, 0x4,
 	0xaf, 0xe3, 0xd3, 0x84, 0x6c, 0x7e, 0xd, 0x89, 0x3d, 0xc2,
@@ -118,6 +120,7 @@ static const unsigned char avb_root_pub[1032] = {
 	0xe1, 0x74, 0xa1, 0xa3, 0x99, 0xa0, 0x85, 0x9e, 0xf1, 0xac,
 	0xd8, 0x7e,
 };
+#endif /* AVB_ROOT_KEY_BUILTIN */
 
 const char *str_avb_io_error(AvbIOResult res)
 {
@@ -654,14 +657,26 @@ static AvbIOResult validate_vbmeta_public_key(AvbOps *ops,
 					      public_key_metadata_length,
 					      bool *out_key_is_trusted)
 {
+	u8 key_digest[SHA256_SUM_LEN];
+	u8 trusted_digest[SHA256_SUM_LEN];
+	AvbIOResult rc;
+
 	if (!public_key_length || !public_key_data || !out_key_is_trusted)
 		return AVB_IO_RESULT_ERROR_IO;
 
+	/* Default deny: only flip to trusted on a positive digest match. */
 	*out_key_is_trusted = false;
-	if (public_key_length != sizeof(avb_root_pub))
-		return AVB_IO_RESULT_ERROR_IO;
 
-	if (memcmp(avb_root_pub, public_key_data, public_key_length) == 0)
+	/* Digest of the key embedded in the (untrusted) vbmeta. */
+	sha256_csum_wd(public_key_data, public_key_length, key_digest,
+		       CHUNKSZ_SHA256);
+
+	/* Digest of the trusted root key from the configured source. */
+	rc = avb_read_root_key_digest(ops, trusted_digest);
+	if (rc != AVB_IO_RESULT_OK)
+		return rc;
+
+	if (avb_safe_memcmp(key_digest, trusted_digest, sizeof(key_digest)) == 0)
 		*out_key_is_trusted = true;
 
 	return AVB_IO_RESULT_OK;
@@ -1040,6 +1055,21 @@ free_name:
 }
 #endif
 
+/**
+ * ============================================================================
+ * AVB root key digest providers (selected via CONFIG_AVB_ROOT_KEY_*)
+ * ============================================================================
+ */
+#if CONFIG_IS_ENABLED(AVB_ROOT_KEY_BUILTIN)
+AvbIOResult avb_read_root_key_digest(AvbOps *ops, uint8_t *digest)
+{
+	sha256_csum_wd(avb_root_pub, sizeof(avb_root_pub), digest,
+		       CHUNKSZ_SHA256);
+
+	return AVB_IO_RESULT_OK;
+}
+#endif
+
 /**
  * ============================================================================
  * AVB2.0 AvbOps alloc/initialisation/free
diff --git a/include/avb_verify.h b/include/avb_verify.h
index 5d998b5a302..66655aab871 100644
--- a/include/avb_verify.h
+++ b/include/avb_verify.h
@@ -47,6 +47,25 @@ enum mmc_io_type {
 AvbOps *avb_ops_alloc(int boot_device);
 void avb_ops_free(AvbOps *ops);
 
+/**
+ * avb_read_root_key_digest() - get the SHA-256 digest of the trusted AVB
+ * root public key
+ *
+ * This is the root of trust for AVB: validate_vbmeta_public_key() hashes the
+ * key embedded in the (untrusted) vbmeta and compares it against the digest
+ * returned here. The provider is selected via CONFIG_AVB_ROOT_KEY_* and, for
+ * CONFIG_AVB_ROOT_KEY_BOARD, may be overridden by a SoC/board specific strong
+ * definition (e.g. reading a hash fused into OTP).
+ *
+ * @ops: AvbOps, contains AVB ops handlers (needed by the TEE provider)
+ * @digest: output buffer of AVB_SHA256_DIGEST_SIZE bytes
+ *
+ * @return:
+ *      AVB_IO_RESULT_OK on success (@digest populated)
+ *      any other AvbIOResult fails verification closed (key not trusted)
+ */
+AvbIOResult avb_read_root_key_digest(AvbOps *ops, uint8_t *digest);
+
 char *avb_set_state(AvbOps *ops, enum avb_boot_state boot_state);
 char *avb_set_enforce_verity(const char *cmdline);
 char *avb_set_ignore_corruption(const char *cmdline);

-- 
2.53.0


  reply	other threads:[~2026-07-27 17:14 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-27 17:14 [PATCH 0/4] avb: make the AVB root key source pluggable Igor Opaniuk
2026-07-27 17:14 ` Igor Opaniuk [this message]
2026-08-10  9:41   ` [PATCH 1/4] " Mattijs Korpershoek
2026-07-27 17:14 ` [PATCH 2/4] avb: add OP-TEE root key digest provider Igor Opaniuk
2026-08-10  9:43   ` Mattijs Korpershoek
2026-07-27 17:14 ` [PATCH 3/4] avb: add board-specific root key provider Igor Opaniuk
2026-08-10  9:44   ` Mattijs Korpershoek
2026-07-27 17:14 ` [PATCH 4/4] doc: android: document the AVB root key source Igor Opaniuk
2026-08-10  9:46   ` Mattijs Korpershoek

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=20260727-avb-root-key-pluggable-v1-1-7e27b2b92cc0@gmail.com \
    --to=igor.opaniuk@gmail.com \
    --cc=jbx6244@gmail.com \
    --cc=mkorpershoek@kernel.org \
    --cc=pbrobinson@gmail.com \
    --cc=quentin.schulz@cherry.de \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.u-boot-project.org \
    /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.