Skip to content

wolfBoot: add Yocto/OE secure bootloader recipes#164

Open
dgarske wants to merge 1 commit intowolfSSL:masterfrom
dgarske:wolfboot_bb
Open

wolfBoot: add Yocto/OE secure bootloader recipes#164
dgarske wants to merge 1 commit intowolfSSL:masterfrom
dgarske:wolfboot_bb

Conversation

@dgarske
Copy link
Copy Markdown
Contributor

@dgarske dgarske commented Apr 14, 2026

Summary

  • Add wolfBoot secure boot recipes to meta-wolfssl: cross-compilation of
    wolfboot.elf, native signing/keygen tools, and RSA4096+SHA3-384 FIT image
    signing
  • Add xilinx-bootbin bbappend to replace U-Boot with wolfBoot in BOOT.BIN
    on AMD/Xilinx ZynqMP (opt-in via WOLFBOOT_ENABLE="1")
  • User-supplied signing key workflow (WOLFBOOT_SIGNING_KEY) keeps private key
    material out of sstate and deploy artifacts

New files

File Purpose
recipes-wolfssl/wolfboot/wolfboot.inc Shared SRC_URI, LICENSE, pinned SRCREVs for wolfBoot + wolfSSL
recipes-wolfssl/wolfboot/wolfboot_git.bb Cross-compiles wolfboot.elf; seeds .config from config/examples/${WOLFBOOT_CONFIG}
recipes-wolfssl/wolfboot/wolfboot-keytools-native_git.bb Native wolfboot-keygen and wolfboot-sign utilities
recipes-wolfssl/wolfboot/wolfboot-signed-image.bb Signs kernel FIT image, deploys image_v<N>_signed.bin
recipes-wolfssl/wolfboot/README.md Usage guide: key provisioning, quick start, ZynqMP caveats
recipes-bsp/bootbin/xilinx-bootbin_%.bbappend Swaps U-Boot for wolfBoot in BOOT.BIN (ZynqMP only, gated)
conf/layer.conf (modified) BBFILES globs, BBFILES_DYNAMIC for bootbin, PREFERRED_PROVIDER

Key design points

  1. Signing key isolation -- WOLFBOOT_SIGNING_KEY is a user-supplied
    absolute path to a pre-generated RSA4096 DER private key. Recipes never
    auto-generate or deploy private key material. Public key is derived at build
    time and compiled into wolfboot.elf via src/keystore.c.

  2. Bare-metal cross-compilation -- wolfboot_git.bb uses raw make
    (not oe_runmake) and unsets CFLAGS/LDFLAGS to avoid Yocto host
    flags leaking into the freestanding bootloader build. KEYGEN_TOOL is
    overridden to point at the native keygen, preventing the Makefile from
    trying to cross-compile and execute an AArch64 keygen binary on x86_64.

  3. Conditional bootbin override -- The bbappend only activates when
    WOLFBOOT_ENABLE="1" is set in configuration. Uses BBFILES_DYNAMIC
    so the layer doesn't hard-depend on meta-xilinx-tools.

  4. Overridable SRCREVs -- wolfboot.inc uses weak assignment (?=) for
    SRCREVs so downstream users can pin to specific commits via local.conf
    without patching the layer.

@dgarske dgarske self-assigned this Apr 14, 2026
Copilot AI review requested due to automatic review settings April 14, 2026 21:59
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces initial Yocto/OpenEmbedded support for wolfBoot inside meta-wolfssl, including recipes to build the bootloader, host-side key/sign tools, and a helper recipe/bbappend to produce and consume signed FIT images (notably for ZynqMP boot flows).

Changes:

  • Add wolfboot.inc and recipes to build wolfboot.elf, build native key/sign tooling, and sign the kernel FIT image.
  • Add a xilinx-bootbin bbappend to swap the SSBL in BOOT.BIN to wolfBoot when explicitly opted in via EXTRA_IMAGEDEPENDS.
  • Register the new recipe globs and PREFERRED_PROVIDER_wolfboot in conf/layer.conf.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
recipes-wolfssl/wolfboot/wolfboot_git.bb Cross-compiles wolfboot.elf, generates keys, and deploys artifacts.
recipes-wolfssl/wolfboot/wolfboot.inc Shared source/Licensing include with git fetch of wolfBoot + wolfSSL side-by-side.
recipes-wolfssl/wolfboot/wolfboot-signed-image.bb Signs the kernel FIT image and deploys a versioned signed binary.
recipes-wolfssl/wolfboot/wolfboot-keytools-native_git.bb Builds and installs wolfboot-keygen / wolfboot-sign as native tools.
recipes-wolfssl/wolfboot/README.md Documents layer usage, workflow, and ZynqMP caveats.
recipes-bsp/bootbin/xilinx-bootbin_%.bbappend Conditionally rewrites the BIF to use wolfboot.elf as SSBL on ZynqMP.
conf/layer.conf Adds new BBFILES globs and sets PREFERRED_PROVIDER_wolfboot.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread recipes-wolfssl/wolfboot/wolfboot.inc Outdated
Comment thread recipes-wolfssl/wolfboot/wolfboot_git.bb Outdated
Comment thread recipes-wolfssl/wolfboot/wolfboot_git.bb Outdated
Comment thread recipes-wolfssl/wolfboot/wolfboot-keytools-native_git.bb Outdated
Comment thread recipes-bsp/bootbin/xilinx-bootbin_%.bbappend Outdated
Copilot AI review requested due to automatic review settings April 15, 2026 22:23
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread recipes-wolfssl/wolfboot/README.md
Comment thread recipes-wolfssl/wolfboot/wolfboot_git.bb Outdated
Comment thread recipes-wolfssl/wolfboot/wolfboot-signed-image.bb Outdated
Comment thread recipes-wolfssl/wolfboot/wolfboot-signed-image.bb Outdated
Comment thread recipes-bsp/bootbin/xilinx-bootbin_%.bbappend
Copilot AI review requested due to automatic review settings April 16, 2026 17:32
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +95 to +101
if [ -z "${WOLFBOOT_PUBLIC_KEY}" ] || [ ! -f "${WOLFBOOT_PUBLIC_KEY}" ]; then
openssl rsa -in ${WOLFBOOT_SIGNING_KEY} -inform DER -pubout -outform DER \
-out ${S}/wolfboot_signing_public_key.der
PUBKEY_FOR_MAKE=${S}/wolfboot_signing_public_key.der
else
PUBKEY_FOR_MAKE=${WOLFBOOT_PUBLIC_KEY}
fi
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do_compile() derives a public key using the openssl CLI, but the recipe doesn’t declare a dependency on openssl-native. This can fail on build hosts without an openssl binary in PATH. Add an explicit native dependency (or switch to using the already-built wolfboot-keygen tool for public-key derivation) to make the build reproducible.

Copilot uses AI. Check for mistakes.
Comment on lines +105 to +117
# KEYGEN_TOOL override: wolfBoot's Makefile otherwise tries to build
# tools/keytools/keygen using the target cross-compiler and then run
# the resulting AArch64 binary on the x86_64 build host. Point it at
# the native keygen from wolfboot-keytools-native instead.
NATIVE_KEYGEN="$(command -v wolfboot-keygen)"
make wolfboot.elf \
CROSS_COMPILE=${TARGET_PREFIX} \
CC="${TARGET_PREFIX}gcc $SYSROOT_FLAG" \
LD="${TARGET_PREFIX}gcc $SYSROOT_FLAG" \
USER_PRIVATE_KEY="${WOLFBOOT_SIGNING_KEY}" \
USER_PUBLIC_KEY="$PUBKEY_FOR_MAKE" \
KEYGEN_TOOL="$NATIVE_KEYGEN" \
V=1
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KEYGEN_TOOL is set via command -v wolfboot-keygen, which depends on PATH and could accidentally pick up a host-installed binary (or resolve to empty and make will fall back to building/running the target keygen). Prefer pointing directly at the staged native tool path (and fail early if it’s missing) so the build is deterministic.

Copilot uses AI. Check for mistakes.
Comment on lines +31 to +33
# (DER format). If unset, wolfBoot's keygen derives the public key from the
# private key in-memory to populate src/keystore.c. Only set this if you
# want to pin a public key independent of the private key file (e.g. HSM).
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment for WOLFBOOT_PUBLIC_KEY says wolfBoot’s keygen derives the public key from the private key when unset, but the recipe currently derives it using openssl rsa -pubout. Either adjust the comment to match the actual implementation or update the implementation to use wolfBoot’s keygen as described.

Suggested change
# (DER format). If unset, wolfBoot's keygen derives the public key from the
# private key in-memory to populate src/keystore.c. Only set this if you
# want to pin a public key independent of the private key file (e.g. HSM).
# (DER format). If unset, the recipe derives the public key from
# WOLFBOOT_SIGNING_KEY before populating src/keystore.c. Only set this if
# you want to pin a public key independent of the private key file
# (e.g. HSM).

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +108
of this README. The recipe:

- Stages the private key at `${S}/wolfboot_signing_private_key.der` so the
wolfBoot Makefile can derive the public half and compile it into
`wolfboot.elf` via `src/keystore.c`.
- Does **not** deploy the private key to `DEPLOY_DIR_IMAGE`. Only
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This README section says the recipe “stages the private key at ${S}/wolfboot_signing_private_key.der”, but the current implementation passes WOLFBOOT_SIGNING_KEY directly to the build/signing tools and does not copy it into ${S}. Update the documentation (or the recipe) so users don’t look for a non-existent staged file.

Suggested change
of this README. The recipe:
- Stages the private key at `${S}/wolfboot_signing_private_key.der` so the
wolfBoot Makefile can derive the public half and compile it into
`wolfboot.elf` via `src/keystore.c`.
- Does **not** deploy the private key to `DEPLOY_DIR_IMAGE`. Only
of this README. The recipes:
- Pass `WOLFBOOT_SIGNING_KEY` directly to the wolfBoot build/signing tools
so the public half can be derived and compiled into `wolfboot.elf` via
`src/keystore.c`.
- Do **not** stage or copy the private key into `${S}` as
`wolfboot_signing_private_key.der`, so users should not expect that file
to exist in the source tree.
- Do **not** deploy the private key to `DEPLOY_DIR_IMAGE`. Only

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +10
# Only activates when WOLFBOOT_ENABLE = "1" is set in configuration (e.g.
# local.conf or a machine .conf). Without that flag this bbappend is a
# no-op and xilinx-bootbin keeps using U-Boot.
#
# A dedicated variable is used here instead of inspecting EXTRA_IMAGEDEPENDS:
# EXTRA_IMAGEDEPENDS is frequently set inside image recipes, which are
# parsed in a different context than xilinx-bootbin, so the anonymous
# python() below would see an empty value and silently stay inert.
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description says the xilinx-bootbin bbappend “only activates when wolfboot-signed-image is in EXTRA_IMAGEDEPENDS”, but the implementation actually gates activation on WOLFBOOT_ENABLE = "1". Please update either the PR description/README or the bbappend logic so the activation condition is consistent and unambiguous for users.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 16, 2026 21:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +14 to +28
# NOTE: SRCREVs below are pinned to wolfSSL/wolfBoot master and
# wolfSSL/wolfssl master tips at the time of writing. Bump these as
# upstream evolves. Downstream users can override via local.conf:
# SRCREV_wolfboot:pn-wolfboot = "<sha>"
# SRCREV_wolfboot:pn-wolfboot-keytools-native = "<sha>"
# to pick up un-merged fixes (e.g. wolfSSL/wolfBoot#750 adds the ZynqMP
# hal_dts_fixup / MMU-cleanup-before-Linux / SDHCI cold-boot retry path
# needed for PetaLinux 2025.2 on ZCU102).
SRC_URI = " \
git://github.com/wolfssl/wolfBoot.git;protocol=https;branch=master;name=wolfboot;destsuffix=git \
git://github.com/wolfssl/wolfssl.git;protocol=https;branch=master;name=wolfssl;destsuffix=git/lib/wolfssl \
"
SRCREV_wolfboot ?= "58c2e044a606c1e077483aa09822bb0fa9127967"
SRCREV_wolfssl ?= "48a0347581ce83958ae965bf2f150e6b6de7e978"
SRCREV_FORMAT = "wolfboot_wolfssl"
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This layer generally pins Git fetches directly in SRC_URI using nobranch=1;rev=<sha> (e.g. recipes-wolfssl/wolfssl/wolfssl_5.9.1.bb:13, recipes-wolfssl/wolftpm/wolftpm_3.10.0.bb:15). Here SRC_URI specifies branch=master and uses weak SRCREV_* ?= ..., which can make fetches more brittle if the branch name changes and makes it easier to accidentally build against a different revision. Consider switching these URIs to nobranch=1;rev=${SRCREV_wolfboot} / rev=${SRCREV_wolfssl} (or hardcode rev= like the other recipes) and pin SRCREV_* with =.

Suggested change
# NOTE: SRCREVs below are pinned to wolfSSL/wolfBoot master and
# wolfSSL/wolfssl master tips at the time of writing. Bump these as
# upstream evolves. Downstream users can override via local.conf:
# SRCREV_wolfboot:pn-wolfboot = "<sha>"
# SRCREV_wolfboot:pn-wolfboot-keytools-native = "<sha>"
# to pick up un-merged fixes (e.g. wolfSSL/wolfBoot#750 adds the ZynqMP
# hal_dts_fixup / MMU-cleanup-before-Linux / SDHCI cold-boot retry path
# needed for PetaLinux 2025.2 on ZCU102).
SRC_URI = " \
git://github.com/wolfssl/wolfBoot.git;protocol=https;branch=master;name=wolfboot;destsuffix=git \
git://github.com/wolfssl/wolfssl.git;protocol=https;branch=master;name=wolfssl;destsuffix=git/lib/wolfssl \
"
SRCREV_wolfboot ?= "58c2e044a606c1e077483aa09822bb0fa9127967"
SRCREV_wolfssl ?= "48a0347581ce83958ae965bf2f150e6b6de7e978"
SRCREV_FORMAT = "wolfboot_wolfssl"
# NOTE: SRCREVs below are pinned to specific wolfBoot and wolfSSL commits
# at the time of writing. Bump these as upstream evolves. Downstream users
# can override via local.conf:
# SRCREV_wolfboot:pn-wolfboot = "<sha>"
# SRCREV_wolfboot:pn-wolfboot-keytools-native = "<sha>"
# to pick up un-merged fixes (e.g. wolfSSL/wolfBoot#750 adds the ZynqMP
# hal_dts_fixup / MMU-cleanup-before-Linux / SDHCI cold-boot retry path
# needed for PetaLinux 2025.2 on ZCU102).
SRC_URI = " \
git://github.com/wolfssl/wolfBoot.git;protocol=https;nobranch=1;rev=${SRCREV_wolfboot};name=wolfboot;destsuffix=git \
git://github.com/wolfssl/wolfssl.git;protocol=https;nobranch=1;rev=${SRCREV_wolfssl};name=wolfssl;destsuffix=git/lib/wolfssl \
"
SRCREV_wolfboot = "58c2e044a606c1e077483aa09822bb0fa9127967"
SRCREV_wolfssl = "48a0347581ce83958ae965bf2f150e6b6de7e978"

Copilot uses AI. Check for mistakes.
Comment on lines +80 to +83
wolfboot-sign --rsa4096 --sha3 \
${WOLFBOOT_FIT_IMAGE} \
${WOLFBOOT_SIGNING_KEY} \
${WOLFBOOT_IMAGE_VERSION}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wolfboot-sign is invoked with ${WOLFBOOT_SIGNING_KEY} unquoted. Since this is a user-supplied absolute path, quoting it (and other args) avoids failures when the path contains spaces or special characters.

Copilot uses AI. Check for mistakes.
# keytools-native provides wolfboot-keygen (used only when deriving the
# public half from a supplied private key) and wolfboot-sign (used by
# wolfboot-signed-image.bb for FIT image signing).
DEPENDS = "wolfboot-keytools-native"
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do_compile() invokes the host openssl binary to derive a public key, but the recipe doesn't depend on openssl-native. This can make builds non-reproducible or fail on hosts without openssl installed. Add openssl-native to DEPENDS (or otherwise ensure the openssl tool is provided by the build).

Suggested change
DEPENDS = "wolfboot-keytools-native"
DEPENDS = "wolfboot-keytools-native openssl-native"

Copilot uses AI. Check for mistakes.
@night1rider
Copy link
Copy Markdown
Contributor

Would it make sense for wolfBoot to use PROVIDES += "virtual/bootloader"?

That's BitBake's standard mechanism for swapping bootloaders - vanilla Yocto and PetaLinux default to U-Boot via PREFERRED_PROVIDER_virtual/bootloader. If wolfBoot participated, selecting it could be as simple as:

PREFERRED_PROVIDER_virtual/bootloader = "wolfboot"

Instead of WOLFBOOT_ENABLE = "1" + the bbappend.

I'm not sure exactly what artifacts/tasks BitBake expects from a virtual/bootloader provider (deploy outputs, IMAGE_BOOT_FILES entries, etc.), and ZynqMP complicates things since xilinx-bootbin references U-Boot by PN directly, but it could be worth exploring for non-Xilinx targets where wolfBoot would be the sole bootloader.

@dgarske dgarske changed the title wolfBoot: initial Yocto/OE recipes wolfBoot: add Yocto/OE secure bootloader recipes Apr 16, 2026
Add wolfBoot secure boot support to meta-wolfssl. Four new recipes
cross-compile wolfboot.elf, build host-side signing/keygen tools,
and sign kernel FIT images with RSA4096+SHA3-384 for verified boot.

New recipes:
  wolfboot.inc                    - shared SRC_URI, LICENSE, SRCREVs
  wolfboot_git.bb                 - cross-compiles wolfboot.elf from a
                                    user-selected config/examples/ template;
                                    embeds a user-supplied RSA4096 public key
  wolfboot-keytools-native_git.bb - native wolfboot-keygen / wolfboot-sign
  wolfboot-signed-image.bb        - signs kernel FIT with RSA4096+SHA3-384

Supporting files:
  xilinx-bootbin_%.bbappend       - replaces U-Boot with wolfBoot in BOOT.BIN
                                    on ZynqMP (gated by WOLFBOOT_ENABLE="1");
                                    uses BBFILES_DYNAMIC for meta-xilinx-tools
  conf/layer.conf                 - registers wolfboot BBFILES globs and
                                    PREFERRED_PROVIDER
  README.md                       - usage guide, key provisioning, ZynqMP notes

Design decisions:
- Signing key is user-supplied out-of-band (WOLFBOOT_SIGNING_KEY) to
  avoid leaking private key material through sstate or DEPLOY_DIR_IMAGE.
- wolfboot_git.bb uses raw make (not oe_runmake) because wolfBoot is a
  bare-metal bootloader with its own -nostdlib/-ffreestanding toolchain
  flags that conflict with Yocto's CC/CFLAGS/LDFLAGS injection.
- SRCREVs use weak assignment (?=) so downstream users can override via
  local.conf to track unreleased upstream fixes.

Tested on AMD/Xilinx ZCU102 hardware with PetaLinux 2025.2:
  FSBL -> PMU FW -> ATF -> wolfBoot (EL2) -> signed FIT -> Linux
  WOLFBOOT_CONFIG="zynqmp_sdcard.config"
  WOLFBOOT_LINUX_BOOTARGS_ROOT="/dev/mmcblk0p4"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants