Should this also have a wic based selftest or some other way to ensure it
works?

Alex

On Mon 2. Sep 2024 at 12.58, Mikko Rapeli via lists.openembedded.org
<[email protected]> wrote:

> From: Michelle Lin <[email protected]>
>
> This class calls systemd ukify tool, which will combine
> kernel/initrd/stub components to build the UKI. To sign the UKI
> (i.e. SecureBoot), the keys/cert files can be specified
> in a configuration file or UEFI binary signing can be done
> via separate steps, see qemuarm64-secureboot in meta-arm.
> UKIs are loaded by UEFI firmware on target which can improve
> security by loading only correctly signed kernel, initrd and kernel
> command line.
>
> Using systemd-measure to pre-calculate TPM PCR values and sign them is
> not supported since that requires a TPM device on the build host. Thus
> "ConditionSecurity=measured-uki" default from systemd 256 does not work
> but "ConditionSecurity=tpm2" in combination with secure boot will.
> These can be used to boot securely into systemd-boot, kernel, kernel
> command line and initrd which then securely mounts a read-only dm-verity
> /usr partition and creates a TPM encrypted read-write / rootfs.
>
> Tested via qemuarm64-secureboot in meta-arm with
> https://lists.yoctoproject.org/g/meta-arm/topic/patch_v3_02_13/108031399
> and a few more changes needed, will be posted separately.
>
> Signed-off-by: Michelle Lin <[email protected]>
> Acked-by: Erik Schilling <[email protected]>
> Signed-off-by: Mikko Rapeli <[email protected]>
> ---
>  meta/classes-recipe/uki.bbclass | 158 ++++++++++++++++++++++++++++++++
>  1 file changed, 158 insertions(+)
>  create mode 100644 meta/classes-recipe/uki.bbclass
>
> diff --git a/meta/classes-recipe/uki.bbclass
> b/meta/classes-recipe/uki.bbclass
> new file mode 100644
> index 0000000000..8d4bf317fe
> --- /dev/null
> +++ b/meta/classes-recipe/uki.bbclass
> @@ -0,0 +1,158 @@
> +# Unified kernel image (UKI) class
> +#
> +# This bbclass merges kernel, initrd etc as a UKI standard UEFI binary,
> +# to be loaded with UEFI firmware on target. SecureBoot signing is
> +# supported via add ons. TPM PCR pre-calculation is not supported since
> +# systemd-measure tooling is meant to run on target, not in cross compile
> +# environment.
> +#
> +# See:
> +# https://www.freedesktop.org/software/systemd/man/latest/ukify.html
> +# https://uapi-group.org/specifications/specs/unified_kernel_image/
> +#
> +# The UKI is composed from
> +#   - an UEFI stub
> +#     The linux kernel can generate a UEFI stub, however the one from
> systemd-boot can fetch
> +#     the command line from a separate section of the EFI application,
> avoiding the need to
> +#     rebuild the kernel.
> +#   - the kernel
> +#   - an initramfs
> +#   - other metadata (e.g. PCR measurements)
> +#
> +# Usage instructions:
> +#   - requires UEFI compatible firmware on target, e.g.
> qemuarm64-secureboot from meta-arm
> +#   - Distro config:
> +#     INIT_MANAGER = "systemd"
> +#     DISTRO_FEATURES += "systemd"
> +#     DISTRO_FEATURES_NATIVE += "systemd"
> +#     DISTRO_FEATURES += "efi"
> +#     DISTRO_FEATURES += "uki"
> +#     INITRAMFS_IMAGE ?= "core-image-minimal-initramfs"
> +#     HOSTTOOLS += "getent ping"
> +#     EFI_PROVIDER = "systemd-boot"
> +#   - image recipe:
> +#     INHERIT_UKI = "${@bb.utils.contains('DISTRO_FEATURES', 'uki',
> 'uki', '', d)}"
> +#     inherit ${INHERIT_UKI}
> +#   - qemuboot/runqemu changes in image recipe:
> +#     # Detected by passing kernel parameter
> +#     QB_KERNEL_ROOT = ""
> +#     # kernel is in the image, should not be loaded separately
> +#     QB_DEFAULT_KERNEL = "none"
> +#   - for UEFI secure boot, systemd-boot, uki and linux kernel need
> +#     to be signed with sbsign (recipe available from meta-secure-core,
> +#     see also qemuarm64-secureboot from meta-arm)
> +
> +DEPENDS += "\
> +    systemd \
> +    systemd-boot \
> +    systemd-boot-native \
> +    virtual/${TARGET_PREFIX}binutils \
> +    virtual/kernel \
> +"
> +
> +REQUIRED_DISTRO_FEATURES += "usrmerge systemd uki"
> +
> +inherit features_check image-artifact-names
> +require ../conf/image-uefi.conf
> +
> +INITRAMFS_IMAGE ?= "core-image-minimal-initramfs"
> +
> +INITRD_ARCHIVE ?= "${INITRAMFS_IMAGE}-${MACHINE}.${INITRAMFS_FSTYPES}"
> +
> +do_image_complete[depends] += "${INITRAMFS_IMAGE}:do_image_complete"
> +
> +UKIFY_CMD ?= "ukify build"
> +UKI_CONFIG_FILE ?= "${UNPACKDIR}/uki.conf"
> +UKI_FILENAME ?= "uki.efi"
> +UKI_CMDLINE ?= "rootwait root=/dev/vda2"
> +
> +IMAGE_EFI_BOOT_FILES ?= "${UKI_FILENAME};EFI/Linux/${UKI_FILENAME}"
> +
> +do_uki[depends] += " \
> +                        systemd-boot:do_deploy \
> +                        virtual/kernel:do_deploy \
> +                     "
> +do_uki[depends] += "${@ '${INITRAMFS_IMAGE}:do_image_complete' if
> d.getVar('INITRAMFS_IMAGE') else ''}"
> +
> +# ensure that the build directory is empty everytime we generate a
> newly-created uki
> +do_uki[cleandirs] = "${B}"
> +# influence the build directory at the start of the builds
> +do_uki[dirs] = "${B}"
> +
> +# we want to allow specifying files in SRC_URI, such as for signing the
> UKI
> +python () {
> +    d.delVarFlag("do_fetch","noexec")
> +    d.delVarFlag("do_unpack","noexec")
> +}
> +
> +# main task
> +python do_uki() {
> +    import glob
> +    import bb.process
> +
> +    # Construct the ukify command
> +    ukify_cmd = d.getVar('UKIFY_CMD')
> +
> +    deploy_dir_image = d.getVar('DEPLOY_DIR_IMAGE')
> +
> +    # initrd
> +    initramfs_image = "%s" % (d.getVar('INITRD_ARCHIVE'))
> +    ukify_cmd += " --initrd=%s" % os.path.join(deploy_dir_image,
> initramfs_image)
> +
> +    deploy_dir_image = d.getVar('DEPLOY_DIR_IMAGE')
> +
> +    # Kernel
> +    if d.getVar('KERNEL_IMAGETYPE'):
> +        kernel = "%s/%s" % (deploy_dir_image,
> d.getVar('KERNEL_IMAGETYPE'))
> +        kernel_version = d.getVar('KERNEL_VERSION')
> +        if not os.path.exists(kernel):
> +            bb.fatal(f"ERROR: cannot find {kernel}.")
> +
> +        ukify_cmd += " --linux=%s --uname %s" % (kernel, kernel_version)
> +    else:
> +        bb.fatal("ERROR - Required argument: KERNEL")
> +
> +    # Command line
> +    cmdline = d.getVar('UKI_CMDLINE')
> +    if cmdline:
> +        ukify_cmd += " --cmdline='%s'" % cmdline
> +
> +    # Architecture
> +    target_arch = d.getVar('EFI_ARCH')
> +    if target_arch:
> +        ukify_cmd += " --efi-arch %s" % target_arch
> +
> +    # systemd stubs from deploy
> +    stub = "%s/linux%s.efi.stub" % (d.getVar('DEPLOY_DIR_IMAGE'),
> target_arch)
> +    if not os.path.exists(stub):
> +        bb.fatal(f"ERROR: cannot find {stub}.")
> +    ukify_cmd += " --stub %s" % stub
> +
> +    # Add option for dtb
> +    if d.getVar('KERNEL_DEVICETREE'):
> +        for dtb in d.getVar('KERNEL_DEVICETREE').split():
> +            dtb_path = "%s/%s" % (deploy_dir_image, dtb)
> +            if not os.path.exists(dtb_path):
> +                bb.fatal(f"ERROR: cannot find {dtb_path}.")
> +            ukify_cmd += " --devicetree %s" % dtb_path
> +
> +    # Add option to pass a config file the UKI
> +    if os.path.exists(d.getVar('UKI_CONFIG_FILE')):
> +        ukify_cmd += " --config=%s" % d.getVar('UKI_CONFIG_FILE')
> +
> +    # Tools
> +    ukify_cmd += " --tools=%s%s/lib/systemd/tools" %
> (d.getVar("RECIPE_SYSROOT_NATIVE"), d.getVar("prefix"))
> +
> +    # TODO: tpm2 measure for secure boot, depends on systemd-native and
> TPM tooling
> +    # needed in systemd > 254 to fulfill ConditionSecurity=measured-uki
> +    # Requires TPM device on build host, thus not supported at build time.
> +    #ukify_cmd += " --measure"
> +
> +    # Custom UKI name
> +    output = " --output=%s/%s" % (d.getVar('DEPLOY_DIR_IMAGE'),
> d.getVar('UKI_FILENAME'))
> +    ukify_cmd += " %s" % output
> +
> +    # Run the ukify command
> +    bb.process.run(ukify_cmd, shell=True)
> +}
> +addtask uki after do_rootfs before do_deploy do_image_complete
> do_image_wic
> --
> 2.34.1
>
>
> 
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#204095): 
https://lists.openembedded.org/g/openembedded-core/message/204095
Mute This Topic: https://lists.openembedded.org/mt/108224526/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to