From patchwork Mon Sep 2 10:58:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikko Rapeli X-Patchwork-Id: 48574 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4057CD342A for ; Mon, 2 Sep 2024 10:58:48 +0000 (UTC) Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) by mx.groups.io with SMTP id smtpd.web10.36073.1725274723518718857 for ; Mon, 02 Sep 2024 03:58:43 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=QqVD8ql4; spf=pass (domain: linaro.org, ip: 209.85.167.53, mailfrom: mikko.rapeli@linaro.org) Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-5334c018913so3765073e87.0 for ; Mon, 02 Sep 2024 03:58:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1725274722; x=1725879522; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mJ/knW2N7PVRDDB5R+brL7z9Erq/BRnXkTj06+QJIXc=; b=QqVD8ql4G0pLkZlZzaggMYSH3D96PogPNEozquem1RoBb4QjGAsArpSE/WNoiuYa+C BuctJb355zEE5IG3NeMT7pVu9dIIyW5yszyaZ5qflNiD8oALDY8v8ZF8KdpPumlVbc/t 5ky42lVklG5U61w4aMOtAtHtfub1N7tSQ1Ixn2RoW21upsi1Kbx/XweU9Wlcn+eRrI1R Ts5m57n80x+oF6OietydkYHokoNV1boz0y/rlKdUTW3kxj4SrB21er0roBN7Yiae+j+x h60RbTfqrccNzXLRqQ/ZBbhm3bfeuFIJBRgGU35/CNn5FS5EiMEIAhsRF0/airCyNTl1 7eYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725274722; x=1725879522; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mJ/knW2N7PVRDDB5R+brL7z9Erq/BRnXkTj06+QJIXc=; b=ng3ZSpHw8JdDXAhY0/FxP+fO1JTbG0NmwkBL6959B4Elytk4FoDa1muMpbPDXf5Z/5 TCh0XLs4R5NHu8NoTzjG6v9++5D2/yTAJ5T5T6GbXQauBUm7PjmBCGxnubcRRLNXyzKO y9vhA1banijIKet54nJzZQ4fjt5N1eQc6i1duvBvMoXC71ImUpOiaQuQv+VlWGKqM9OT mgt0GUB7uBlCiIRiH6Jzub8TLBHuZ0cPcC3OJFlRkghumapvr25882idCjuqP8wMSq8q 0tprneBwN/h643WpGK/bNSGfCKfPSvPKNqEB5+ZcGlUi/K//C/MKvDAaqt7jDTxA1pRt zpEw== X-Gm-Message-State: AOJu0YzrpQHPvHKaf1FlUw/Z1bW8KO0HrtCumGbrfY5JLRNHIydByMO6 Trtc0Jls5RDtnt4D+3DhQ8G8CLt/0unPyXm3un/I0XPcttSfMQxmMqixlAnZnptwQlmNpxcIjMG QGSo= X-Google-Smtp-Source: AGHT+IGPsKM9F1aJxdHEI6r6HYZs/iTb07l2SymJ5Z+7OepFBKO5S7HCVN8LnVWj/JVnzvedzWqYLQ== X-Received: by 2002:a05:6512:118e:b0:530:dfab:930c with SMTP id 2adb3069b0e04-53546b34ddcmr6049103e87.28.1725274721284; Mon, 02 Sep 2024 03:58:41 -0700 (PDT) Received: from localhost.localdomain (87-100-245-199.bb.dnainternet.fi. [87.100.245.199]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-535407ac5e9sm1599036e87.100.2024.09.02.03.58.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Sep 2024 03:58:40 -0700 (PDT) From: Mikko Rapeli To: openembedded-core@lists.openembedded.org Cc: Mikko Rapeli Subject: [PATCH 1/2] systemd-boot-native: add runtime dependency to python3-pefile-native Date: Mon, 2 Sep 2024 13:58:24 +0300 Message-ID: <20240902105825.40177-2-mikko.rapeli@linaro.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240902105825.40177-1-mikko.rapeli@linaro.org> References: <20240902105825.40177-1-mikko.rapeli@linaro.org> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 02 Sep 2024 10:58:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/204091 It's needed to run the ukify script. Signed-off-by: Mikko Rapeli --- meta/recipes-core/systemd/systemd-boot-native_256.5.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meta/recipes-core/systemd/systemd-boot-native_256.5.bb b/meta/recipes-core/systemd/systemd-boot-native_256.5.bb index 73db59b14e..58db408dcf 100644 --- a/meta/recipes-core/systemd/systemd-boot-native_256.5.bb +++ b/meta/recipes-core/systemd/systemd-boot-native_256.5.bb @@ -13,3 +13,5 @@ addtask install after do_unpack PACKAGES = "${PN}" FILES:${PN} = "${bindir}/ukify" + +RDEPENDS:${PN} += "python3-pefile-native" From patchwork Mon Sep 2 10:58:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikko Rapeli X-Patchwork-Id: 48573 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8AE0FCA0ED3 for ; Mon, 2 Sep 2024 10:58:48 +0000 (UTC) Received: from mail-lf1-f50.google.com (mail-lf1-f50.google.com [209.85.167.50]) by mx.groups.io with SMTP id smtpd.web11.36228.1725274725588448878 for ; Mon, 02 Sep 2024 03:58:45 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=XPgTHxwn; spf=pass (domain: linaro.org, ip: 209.85.167.50, mailfrom: mikko.rapeli@linaro.org) Received: by mail-lf1-f50.google.com with SMTP id 2adb3069b0e04-533488ffaf7so5551562e87.0 for ; Mon, 02 Sep 2024 03:58:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1725274724; x=1725879524; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JLGKwgHEtu4PR03fovX+veMRztK7J/Ns38T9qQPPQC8=; b=XPgTHxwnAyKXA9I6hZahIslwOH7T8fSFvGLgFhLVc+I0GpwBxuWk56u/vS9AjGKQnt kMKb6g5D4fdeOK/HW0chj5xBHCLT28ud1mNLlRoyLZizHec7rwHiaqK98laT+ko49h08 89Tno5Rk6yM6ibnw/4WVx+K7wycbMB+lhwZdXG7l1L1hvppx73aBbla8f1bs4j3OZ3US h53+ss5sIXHpLcZj/IizQZ7TNDS1HDdBW5bTsO8WrCZH1dIS1/iRfK/bS1Zr+Dv2VoXp eq6W0GS+R+MWkLxHLcZ9S4HLLxEbiETGM86UlqDLk1Ug9x5oAb5nHm/B5mxP7JOkMQtt pYRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725274724; x=1725879524; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JLGKwgHEtu4PR03fovX+veMRztK7J/Ns38T9qQPPQC8=; b=LIG+6DJ7IUOSQNWsqA3O/yvalC9A+ZTuoGZJGApsmy0OWVy/lbzUIM+Db7BqXK4PHr vsdWm/sWZK02tuw8DiQpvL1SO4f7edgmytZ+FQHzjzQGwI10UsCr+lkKEeaG1wRYt7bp HBblxlfwvqZwHpe91+fVkdT9sQcwx6gV8wqPux5j/HDmJBQzsxAwcbtysODwyHJuI8Lk 5WcuFDX6vVOMz2JyEcOW5B6u6LaqxE5zYLQsjR/Q1ni+VWGwP1AblDDO8MtbAK5mRIZa /qLCgO4sQawGQ8HJvRvqqqxJe3dBY6wFS+6Og41JbFiBbCkBk0ykR2fQ3zkRSdHlvFY2 AVFA== X-Gm-Message-State: AOJu0YwpxAz0eGz/J0jlTPHfc6CE/kMxizR8nr1qy3v49TUYQOvu1zTD JIDJwFvciLSCBOopRuTnjUNjcQW3JktDFQ4odVGBHXqMdjbPsbE1oavYaQ9c74kWsfFD0M7DZls 61kg= X-Google-Smtp-Source: AGHT+IEG5yorvIARsNFx4moP6v3stNhjYdFHM++FNjVmQWTwenRE7fFaBausE80Ln0Sn+szeiRCdcA== X-Received: by 2002:a05:6512:1282:b0:52e:91ff:4709 with SMTP id 2adb3069b0e04-53546b2574fmr7070794e87.21.1725274723102; Mon, 02 Sep 2024 03:58:43 -0700 (PDT) Received: from localhost.localdomain (87-100-245-199.bb.dnainternet.fi. [87.100.245.199]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-535407ac5e9sm1599036e87.100.2024.09.02.03.58.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Sep 2024 03:58:42 -0700 (PDT) From: Mikko Rapeli To: openembedded-core@lists.openembedded.org Cc: Michelle Lin , Erik Schilling , Mikko Rapeli Subject: [PATCH 2/2] uki.bbclass: add class for building Unified Kernel Images (UKI) Date: Mon, 2 Sep 2024 13:58:25 +0300 Message-ID: <20240902105825.40177-3-mikko.rapeli@linaro.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240902105825.40177-1-mikko.rapeli@linaro.org> References: <20240902105825.40177-1-mikko.rapeli@linaro.org> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 02 Sep 2024 10:58:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/204092 From: Michelle Lin 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 Acked-by: Erik Schilling Signed-off-by: Mikko Rapeli --- 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