diff options
| -rw-r--r-- | meta-oe/classes/discoverable-disk-image.bbclass | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/meta-oe/classes/discoverable-disk-image.bbclass b/meta-oe/classes/discoverable-disk-image.bbclass new file mode 100644 index 0000000000..1f3a7b08e1 --- /dev/null +++ b/meta-oe/classes/discoverable-disk-image.bbclass | |||
| @@ -0,0 +1,137 @@ | |||
| 1 | ## | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | # | ||
| 7 | # Discoverable Disk Image (DDI) | ||
| 8 | # | ||
| 9 | # "DDIs (Discoverable Disk Images) are self-describing file system | ||
| 10 | # images that follow the DPS ( Discoverable Partitions Specification), | ||
| 11 | # wrapped in a GPT partition table, that may contain root (or /usr/) | ||
| 12 | # filesystems for bootable OS images, system extensions, configuration | ||
| 13 | # extensions, portable services, containers and more, and shall be | ||
| 14 | # protected by signed dm-verity all combined into one. They are | ||
| 15 | # designed to be composable and stackable, and provide security by | ||
| 16 | # default." | ||
| 17 | # https://uapi-group.org/specifications/specs/discoverable_disk_image/ | ||
| 18 | # https://uapi-group.org/specifications/specs/discoverable_partitions_specification/ | ||
| 19 | # https://www.freedesktop.org/software/systemd/man/latest/systemd.image-policy.html | ||
| 20 | |||
| 21 | # To be able to use discoverable-disk-images with a | ||
| 22 | # root-verity-sig or usr-verity-sig configuration: | ||
| 23 | # - systemd needs to include the PACKAGECONFIG 'cryptsetup', and | ||
| 24 | # - the kernel needs the following features enabled: | ||
| 25 | # CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y | ||
| 26 | # CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y | ||
| 27 | # CONFIG_EROFS_FS=y | ||
| 28 | # CONFIG_EROFS_FS_XATTR=y | ||
| 29 | # CONFIG_EROFS_FS_ZIP=y | ||
| 30 | # CONFIG_EROFS_FS_ZIP_LZMA=y | ||
| 31 | # CONFIG_INTEGRITY_SIGNATURE=y | ||
| 32 | # CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y | ||
| 33 | # CONFIG_INTEGRITY_PLATFORM_KEYRING=y | ||
| 34 | # CONFIG_SYSTEM_BLACKLIST_KEYRING=y | ||
| 35 | # CONFIG_SYSTEM_BLACKLIST_HASH_LIST="" | ||
| 36 | # CONFIG_SIGNATURE=y | ||
| 37 | |||
| 38 | # To sign DDIs, a key and certificate need to be provided by setting | ||
| 39 | # the variables: | ||
| 40 | # REPART_PRIVATE_KEY | ||
| 41 | # private key so sign the verity-hash | ||
| 42 | # REPART_PRIVATE_KEY_SOURCE | ||
| 43 | # optional, can be "engine:pkcs11" when using a (soft)hsm | ||
| 44 | # REPART_CERTIFICATE | ||
| 45 | # corresponding public certificate, in .pem format | ||
| 46 | # | ||
| 47 | |||
| 48 | # For signature verification, systemd-sysext expects the matching | ||
| 49 | # certificate to reside in /etc/verity.d as PEM formated .crt file. | ||
| 50 | # | ||
| 51 | # To enforce loading of only signed extension images, an appropriate | ||
| 52 | # image policy has to be passed to systemd-sysext, e.g.: | ||
| 53 | # systemd-sysext --image-policy='root=signed+absent:usr=signed+absent:=unused+absent' merge | ||
| 54 | |||
| 55 | # 'systemd-dissect' can be used to inspect, manually mount, ... a DDI. | ||
| 56 | |||
| 57 | inherit image | ||
| 58 | |||
| 59 | IMAGE_FSTYPES = "ddi" | ||
| 60 | |||
| 61 | DEPENDS += " \ | ||
| 62 | systemd-repart-native \ | ||
| 63 | erofs-utils-native \ | ||
| 64 | openssl-native \ | ||
| 65 | " | ||
| 66 | |||
| 67 | # systemd-repart --make-ddi takes one of "sysext", "confext" or "portable", | ||
| 68 | # which it then takes and looks up definitions in the host os; which we need | ||
| 69 | # to divert to the sysroot-native by setting '--definitions=' instead. | ||
| 70 | # The chosen DDI_TYPE influences which parts of the rootfs are copied into | ||
| 71 | # the ddi by systemd-repart: | ||
| 72 | # sysext: /usr (and if it exists: /opt) | ||
| 73 | # confext: /etc | ||
| 74 | # portable: / | ||
| 75 | # For details see systemd/repart/definitions/${REPART_DDI_TYPE}.repart.d/* | ||
| 76 | REPART_DDI_TYPE ?= "sysext" | ||
| 77 | |||
| 78 | REPART_DDI_EXTENSION ?= "ddi" | ||
| 79 | |||
| 80 | # systemd-repart creates temporary directoryies under /var/tmp/.#repartXXXXXXX/, | ||
| 81 | # to estimate partition size etc. Since files are copied there from the image/rootfs | ||
| 82 | # folder - which are owned by pseudo-root - this temporary location has to be | ||
| 83 | # added to the directories handled by pseudo; otherwise calls to e.g. | ||
| 84 | # fchown(0,0) inside systemd git/src/shared/copy.c end up failing. | ||
| 85 | PSEUDO_INCLUDE_PATHS .= ",/var/tmp/" | ||
| 86 | |||
| 87 | oe_image_systemd_repart_make_ddi() { | ||
| 88 | |||
| 89 | local additional_args="" | ||
| 90 | |||
| 91 | if [ -n "${REPART_PRIVATE_KEY}" ] | ||
| 92 | then | ||
| 93 | if [ -n "${REPART_PRIVATE_KEY_SOURCE}" ] | ||
| 94 | then | ||
| 95 | additional_args="$additional_args --private-key-source=${REPART_PRIVATE_KEY_SOURCE}" | ||
| 96 | fi | ||
| 97 | additional_args="$additional_args --private-key=${REPART_PRIVATE_KEY}" | ||
| 98 | fi | ||
| 99 | |||
| 100 | if [ -n "${REPART_CERTIFICATE}" ] | ||
| 101 | then | ||
| 102 | additional_args="$additional_args --certificate=${REPART_CERTIFICATE}" | ||
| 103 | fi | ||
| 104 | |||
| 105 | # map architectures to systemd's expected values | ||
| 106 | local systemd_arch="${TARGET_ARCH}" | ||
| 107 | case "${systemd_arch}" in | ||
| 108 | aarch64) | ||
| 109 | systemd_arch=arm64 | ||
| 110 | ;; | ||
| 111 | x86_64) | ||
| 112 | systemd_arch=x86-64 | ||
| 113 | ;; | ||
| 114 | esac | ||
| 115 | |||
| 116 | # prepare system-repart configuration | ||
| 117 | mkdir -p ${B}/definitions.repart.d | ||
| 118 | cp ${STAGING_LIBDIR_NATIVE}/systemd/repart/definitions/${REPART_DDI_TYPE}.repart.d/* ${B}/definitions.repart.d/ | ||
| 119 | # enable erofs compression | ||
| 120 | sed -i "/^Compression/d" ${B}/definitions.repart.d/10-root.conf | ||
| 121 | echo "Compression=lzma\nCompressionLevel=3" >> ${B}/definitions.repart.d/10-root.conf | ||
| 122 | # disable verity signature partition creation, if no key is provided | ||
| 123 | if [ -z "${REPART_PRIVATE_KEY}" ]; then | ||
| 124 | rm ${B}/definitions.repart.d/30-root-verity-sig.conf | ||
| 125 | fi | ||
| 126 | |||
| 127 | systemd-repart \ | ||
| 128 | --definitions="${B}/definitions.repart.d/" \ | ||
| 129 | --copy-source="${IMAGE_ROOTFS}" \ | ||
| 130 | --empty=create --size=auto --dry-run=no --offline=yes \ | ||
| 131 | --architecture="${systemd_arch}" \ | ||
| 132 | --json=pretty --no-pager $additional_args \ | ||
| 133 | "${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${REPART_DDI_EXTENSION}" | ||
| 134 | } | ||
| 135 | |||
| 136 | IMAGE_CMD:ddi = "oe_image_systemd_repart_make_ddi" | ||
| 137 | do_image_ddi[deptask] += "do_unpack" | ||
