| Message ID | 20260302144647.1705408-3-s-tripathi1@ti.com |
|---|---|
| State | Changes Requested |
| Delegated to: | Ryan Eatmon |
| Headers | show |
| Series | Add LUKS encryption with fTPM support | expand |
I'm going to call NAK on this whole patch. We have a ti-core-initramfs that we have been working towards sprucing up to be used for things just like this and any kernel modules required. We do not want to create a myriad of unique initramfs to support different features. We need to roll them all into ti-core-initramfs. On 3/2/2026 8:46 AM, Shiva Tripathi wrote: > Add ti-encrypted-boot-initramfs for LUKS encryption with TPM-sealed > keys. This provides full disk encryption using dm-crypt with keys > sealed by firmware TPM (fTPM) running in OP-TEE and stored in eMMC RPMB. > > The initramfs includes: > - Custom init script for in-place LUKS encryption on first boot > - TPM key sealing/unsealing using persistent handle 0x81080001 > - Support for cryptsetup, tpm2-tools, and OP-TEE client > - Automatic filesystem resize after encryption > > ti-encrypted-boot-initramfs builds when MACHINE_FEATURES contains > 'luks-encryption'. > > Signed-off-by: Shiva Tripathi <s-tripathi1@ti.com> > --- > .../initramfs-ti-encrypted-init/files/init | 324 ++++++++++++++++++ > .../initramfs-ti-encrypted-init_1.0.bb | 30 ++ > .../initramfs/ti-encrypted-boot-initramfs.bb | 50 +++ > 3 files changed, 404 insertions(+) > create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init > create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb > create mode 100644 meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb > > diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init > new file mode 100644 > index 00000000..6675b6ed > --- /dev/null > +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init > @@ -0,0 +1,324 @@ > +#!/usr/bin/busybox sh > +# TI SDK initramfs init script with LUKS2 + fTPM encryption support > + > +# Mount essential filesystems > +/usr/bin/busybox echo "Initializing system..." > +/usr/bin/busybox mount -t proc proc /proc > +/usr/bin/busybox mount -t sysfs sysfs /sys > +/usr/bin/busybox mount -t devtmpfs devtmpfs /dev > + > +# Configuration > +BOOT_DEV="/dev/mmcblk1p1" # Boot partition (FAT, unencrypted) > +ROOT_DEV="/dev/mmcblk1p2" # Root partition (will be encrypted) > +CRYPT_NAME="root_crypt" > +CRYPT_DEV="/dev/mapper/${CRYPT_NAME}" > +BOOT_MNT="/boot_part" > +TPM_PRIMARY_CTX="/tmp/tpm_primary.ctx" > +TPM_KEY_PRIV="/tmp/tpm_key.priv" > +TPM_KEY_PUB="/tmp/tpm_key.pub" > +TPM_KEY_CTX="/tmp/tpm_key.ctx" > +TPM2_HANDLE="0x81080001" # TPM persistent handle for LUKS key > +ENCRYPTION_MARKER="${BOOT_MNT}/.encryption_in_progress" > + > +# Wait for MMC device to appear (up to 10 seconds) > +/usr/bin/busybox echo "Waiting for storage device..." > +for i in 1 2 3 4 5 6 7 8 9 10; do > + if [ -b "${ROOT_DEV}" ]; then > + break > + fi > + /usr/bin/busybox sleep 1 > +done > + > +# Check if root device exists > +if [ ! -b "${ROOT_DEV}" ]; then > + /usr/bin/busybox echo "ERROR: Storage device not found!" > + /usr/bin/busybox sh > +fi > + > +# Mount boot partition > +/usr/bin/busybox echo "Mounting boot partition..." > +/usr/bin/busybox mkdir -p "${BOOT_MNT}" > +if ! /usr/bin/busybox mount "${BOOT_DEV}" "${BOOT_MNT}"; then > + /usr/bin/busybox echo "ERROR: Failed to mount boot partition!" > + /usr/bin/busybox echo "Attempting standard boot..." > + /usr/bin/busybox mkdir -p /newroot > + /usr/bin/busybox mount "${ROOT_DEV}" /newroot > + exec /usr/sbin/switch_root /newroot /sbin/init > +fi > + > +# Initialize fTPM in OP-TEE > +/usr/bin/busybox echo "Initializing secure hardware(fTPM)..." > + > +# Start TEE supplicant (required for fTPM TA to work) > +if [ -x /usr/sbin/tee-supplicant ]; then > + /usr/sbin/tee-supplicant -d & > + TEE_SUPPLICANT_PID=$! > + /usr/bin/busybox sleep 5 > +else > + /usr/bin/busybox echo "Warning: Trusted execution environment not available" > +fi > + > +# Load fTPM kernel module > +if ! /sbin/modprobe tpm_ftpm_tee; then > + /usr/bin/busybox echo "Warning: TPM module failed to load" > +fi > + > +# Wait for TPM device (up to 10 seconds) > +for i in 1 2 3 4 5 6 7 8 9 10; do > + if [ -c /dev/tpmrm0 ]; then > + break > + fi > + /usr/bin/busybox sleep 1 > +done > + > +# Check if TPM is available > +TPM_AVAILABLE=0 > +if [ -c /dev/tpmrm0 ]; then > + TPM_AVAILABLE=1 > + export TPM2TOOLS_TCTI="device:/dev/tpmrm0" > +else > + /usr/bin/busybox echo "Warning: fTPM not available - encryption will be skipped" > + if [ -n "${TEE_SUPPLICANT_PID}" ]; then > + /usr/bin/busybox kill "${TEE_SUPPLICANT_PID}" 2>/dev/null > + fi > +fi > + > +# Function: Generate 32-byte random key using TPM RNG > +generate_random_key() { > + if [ $TPM_AVAILABLE -eq 1 ]; then > + /usr/bin/tpm2_getrandom --hex 32 > + else > + /usr/bin/busybox echo "ERROR: TPM not available for key generation" > + return 1 > + fi > +} > + > +# Function: Seal data with TPM and store in persistent handle > +tpm_seal_key() { > + local KEY_DATA="$1" > + > + if [ $TPM_AVAILABLE -eq 0 ]; then > + /usr/bin/busybox echo "ERROR: TPM not available for sealing" > + return 1 > + fi > + > + # Create primary key in owner hierarchy > + /usr/bin/tpm2_createprimary -C o -c "${TPM_PRIMARY_CTX}" -Q || return 1 > + > + # Create sealed object > + /usr/bin/busybox echo -n "${KEY_DATA}" | \ > + /usr/bin/tpm2_create -C "${TPM_PRIMARY_CTX}" \ > + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ > + -i- -Q || return 1 > + > + # Load sealed object into TPM > + /usr/bin/tpm2_load -C "${TPM_PRIMARY_CTX}" \ > + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ > + -c "${TPM_KEY_CTX}" -Q || return 1 > + > + # Make key persistent at handle (stored in TPM NV RAM - RPMB) > + /usr/bin/tpm2_evictcontrol -C o -c "${TPM_KEY_CTX}" "${TPM2_HANDLE}" || return 1 > + > + return 0 > +} > + > +# Function: Unseal data from TPM persistent handle > +tpm_unseal_key() { > + if [ $TPM_AVAILABLE -eq 0 ]; then > + /usr/bin/busybox echo "ERROR: TPM not available for unsealing" >&2 > + return 1 > + fi > + > + # Check if persistent handle exists > + if ! /usr/bin/tpm2_getcap handles-persistent | grep -q "${TPM2_HANDLE}"; then > + /usr/bin/busybox echo "ERROR: TPM persistent handle not found" >&2 > + return 1 > + fi > + > + # Unseal key directly from persistent handle > + /usr/bin/tpm2_unseal -c "${TPM2_HANDLE}" || return 1 > + > + return 0 > +} > + > +# Function: Perform in-place LUKS encryption (first boot) > +encrypt_root_filesystem() { > + /usr/bin/busybox echo "==========================================" > + /usr/bin/busybox echo "First boot: Encrypting root filesystem" > + /usr/bin/busybox echo "==========================================" > + > + # Set marker to track encryption progress > + /usr/bin/busybox touch "${ENCRYPTION_MARKER}" > + /usr/bin/busybox sync > + > + # Generate random encryption key using TPM RNG > + /usr/bin/busybox echo "Generating encryption key..." > + LUKS_KEY=$(generate_random_key) > + > + if [ -z "${LUKS_KEY}" ]; then > + /usr/bin/busybox echo "ERROR: Failed to generate encryption key" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + fi > + > + # Seal key with TPM before encryption starts > + /usr/bin/busybox echo "Securing key with TPM..." > + if ! tpm_seal_key "${LUKS_KEY}"; then > + /usr/bin/busybox echo "ERROR: Failed to secure key" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + fi > + > + # Filesystem check before encryption > + /usr/bin/busybox echo "Checking filesystem integrity..." > + /usr/sbin/e2fsck -f -y "${ROOT_DEV}" > + E2FSCK_RET=$? > + if [ ${E2FSCK_RET} -ge 4 ]; then > + /usr/bin/busybox echo "ERROR: Filesystem check failed" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + fi > + > + # Shrink filesystem before encryption to leave room for LUKS header > + /usr/bin/busybox echo "Preparing filesystem for encryption..." > + /usr/sbin/resize2fs "${ROOT_DEV}" 368M || { > + /usr/bin/busybox echo "ERROR: Failed to prepare filesystem" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + } > + > + # Perform in-place encryption > + /usr/bin/busybox echo "==========================================" > + /usr/bin/busybox echo "Encrypting filesystem..." > + /usr/bin/busybox echo "This will take several minutes." > + /usr/bin/busybox echo "DO NOT POWER OFF THE DEVICE!" > + /usr/bin/busybox echo "==========================================" > + > + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ > + /usr/sbin/cryptsetup reencrypt --encrypt \ > + --type luks2 \ > + --cipher aes-xts-plain64 \ > + --key-size 256 \ > + --hash sha256 \ > + --reduce-device-size 32M \ > + --key-file - \ > + "${ROOT_DEV}" || { > + /usr/bin/busybox echo "ERROR: Encryption failed" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + } > + > + /usr/bin/busybox echo "==========================================" > + /usr/bin/busybox echo "Encryption completed successfully!" > + /usr/bin/busybox echo "==========================================" > + > + # Remove encryption marker > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + /usr/bin/busybox sync > + > + # Unlock the newly encrypted device > + /usr/bin/busybox echo "Activating encrypted filesystem..." > + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ > + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { > + /usr/bin/busybox echo "ERROR: Failed to activate encrypted filesystem" > + return 1 > + } > + > + # Resize filesystem to fit the encrypted device > + /usr/bin/busybox echo "Optimizing filesystem..." > + /usr/sbin/resize2fs -f "${CRYPT_DEV}" || { > + /usr/bin/busybox echo "ERROR: Failed to optimize filesystem" > + return 1 > + } > + > + # Verify filesystem after resize > + /usr/sbin/e2fsck -f -y "${CRYPT_DEV}" || { > + /usr/bin/busybox echo "WARNING: Filesystem verification had issues, but continuing" > + } > + return 0 > +} > + > +# Function: Unlock encrypted root filesystem (subsequent boots) > +unlock_encrypted_root() { > + /usr/bin/busybox echo "Unlocking encrypted filesystem..." > + > + # Unseal key from TPM persistent handle > + LUKS_KEY=$(tpm_unseal_key) > + > + if [ -z "${LUKS_KEY}" ]; then > + /usr/bin/busybox echo "ERROR: Failed to retrieve encryption key from TPM" > + /usr/bin/busybox echo "Attempting passphrase fallback..." > + > + # Try to unlock with passphrase (interactive) > + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" || { > + /usr/bin/busybox echo "ERROR: Failed to unlock encrypted filesystem" > + /usr/bin/busybox sh > + } > + else > + # Unlock with unsealed key > + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ > + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { > + /usr/bin/busybox echo "ERROR: Failed to unlock with TPM key" > + /usr/bin/busybox sh > + } > + fi > + > + /usr/bin/busybox echo "Encrypted filesystem unlocked" > +} > + > +# Main boot logic > +/usr/bin/busybox echo "Checking filesystem encryption status..." > + > +# Check if device is LUKS encrypted > +if /usr/sbin/cryptsetup isLuks "${ROOT_DEV}"; then > + /usr/bin/busybox echo "Filesystem is encrypted" > + unlock_encrypted_root > + MOUNT_DEV="${CRYPT_DEV}" > +else > + /usr/bin/busybox echo "Filesystem is not encrypted" > + > + # Check if encryption is enabled and TPM is available > + if [ $TPM_AVAILABLE -eq 1 ]; then > + # Check for encryption marker (resume interrupted encryption) > + if [ -f "${ENCRYPTION_MARKER}" ]; then > + /usr/bin/busybox echo "Resuming interrupted encryption..." > + if ! encrypt_root_filesystem; then > + /usr/bin/busybox echo "ERROR: Failed to resume encryption" > + /usr/bin/busybox echo "Booting without encryption..." > + MOUNT_DEV="${ROOT_DEV}" > + else > + MOUNT_DEV="${CRYPT_DEV}" > + fi > + else > + # First boot - perform encryption > + if encrypt_root_filesystem; then > + MOUNT_DEV="${CRYPT_DEV}" > + else > + /usr/bin/busybox echo "ERROR: Encryption failed - booting without encryption" > + MOUNT_DEV="${ROOT_DEV}" > + fi > + fi > + else > + /usr/bin/busybox echo "TPM not available - skipping encryption" > + MOUNT_DEV="${ROOT_DEV}" > + fi > +fi > + > +# Unmount boot partition before switching root > +/usr/bin/busybox umount "${BOOT_MNT}" > + > +# Mount root filesystem (encrypted or unencrypted) > +/usr/bin/busybox echo "Mounting root filesystem..." > +/usr/bin/busybox mkdir -p /newroot > +/usr/bin/busybox mount "${MOUNT_DEV}" /newroot || { > + /usr/bin/busybox echo "ERROR: Failed to mount root filesystem!" > + /usr/bin/busybox sh > +} > + > +/usr/bin/busybox echo "Boot complete" > + > +# Clean up tmpfs > +/usr/bin/busybox rm -f "${TPM_PRIMARY_CTX}" "${TPM_KEY_PUB}" "${TPM_KEY_PRIV}" "${TPM_KEY_CTX}" > + > +# Switch to real root > +exec /usr/sbin/switch_root /newroot /sbin/init > diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb > new file mode 100644 > index 00000000..7da878f7 > --- /dev/null > +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb > @@ -0,0 +1,30 @@ > +SUMMARY = "TI encrypted boot initramfs init script" > +DESCRIPTION = "Custom /init script for encrypted boot with fTPM + LUKS support" > + > +LICENSE = "MIT" > +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" > + > +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}/files:" > +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" > + > +SRC_URI = "file://init" > + > +S = "${WORKDIR}/sources" > +UNPACKDIR = "${WORKDIR}" > + > +# This recipe must run in the initramfs context > +inherit allarch > + > +do_install() { > + # Install /init script to root of initramfs > + install -m 0755 ${UNPACKDIR}/init ${D}/init > +} > + > +# Package the /init file > +FILES:${PN} = "/init" > + > +# Runtime dependencies > +RDEPENDS:${PN} = "busybox cryptsetup tpm2-tools tpm2-tss optee-client e2fsprogs-e2fsck e2fsprogs-resize2fs util-linux-blkid" > + > +# This package must be included in initramfs > +PACKAGE_ARCH = "${MACHINE_ARCH}" > diff --git a/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb > new file mode 100644 > index 00000000..314499db > --- /dev/null > +++ b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb > @@ -0,0 +1,50 @@ > +SUMMARY = "TI encrypted boot initramfs image" > + > +DESCRIPTION = "Minimal initramfs image with dm-crypt/fTPM support for encrypted root filesystem. \ > +This initramfs provides LUKS encryption with TPM-sealed keys stored in RPMB." > + > +LICENSE = "MIT" > + > +# Only build this when luks-encryption feature is enabled > +COMPATIBLE_MACHINE = "null" > +COMPATIBLE_MACHINE:k3 = "${@bb.utils.contains('MACHINE_FEATURES', 'luks-encryption', '.*', 'null', d)}" > + > +INITRAMFS_FSTYPES = "cpio.gz" > + > +IMAGE_NAME = "ti-encrypted-boot-initramfs" > + > +export IMAGE_BASENAME = "${IMAGE_NAME}" > + > +# Install our custom init script and dependencies > +PACKAGE_INSTALL = "\ > + initramfs-ti-encrypted-init \ > + busybox \ > + base-passwd \ > + kmod \ > + cryptsetup \ > + tpm2-tools \ > + tpm2-tss \ > + libtss2-tcti-device \ > + optee-client \ > + util-linux-blkid \ > + e2fsprogs-e2fsck \ > + e2fsprogs-resize2fs \ > + kernel-module-tpm-ftpm-tee \ > + ${ROOTFS_BOOTSTRAP_INSTALL} \ > +" > + > +# Ensure the initramfs only contains the bare minimum > +IMAGE_FEATURES = "" > +IMAGE_LINGUAS = "" > + > +# Exclude kernel image from initramfs > +PACKAGE_EXCLUDE = "kernel-image-*" > + > +IMAGE_FSTYPES = "${INITRAMFS_FSTYPES}" > +IMAGE_NAME_SUFFIX ?= "" > +IMAGE_ROOTFS_SIZE = "16384" > +IMAGE_ROOTFS_EXTRA_SPACE = "0" > + > +BAD_RECOMMENDATIONS += "busybox-syslog" > + > +inherit image
Is there some odd initramfs limitation that requires explicitly calling out /usr/bin/busybox throughout the whole script? Surely echo atleast can be relied on to be built into the shell or PATH. On Mon, Mar 2, 2026 at 12:07 PM Shiva Tripathi via lists.yoctoproject.org <s-tripathi1=ti.com@lists.yoctoproject.org> wrote: > > Add ti-encrypted-boot-initramfs for LUKS encryption with TPM-sealed > keys. This provides full disk encryption using dm-crypt with keys > sealed by firmware TPM (fTPM) running in OP-TEE and stored in eMMC RPMB. > > The initramfs includes: > - Custom init script for in-place LUKS encryption on first boot > - TPM key sealing/unsealing using persistent handle 0x81080001 > - Support for cryptsetup, tpm2-tools, and OP-TEE client > - Automatic filesystem resize after encryption > > ti-encrypted-boot-initramfs builds when MACHINE_FEATURES contains > 'luks-encryption'. > > Signed-off-by: Shiva Tripathi <s-tripathi1@ti.com> > --- > .../initramfs-ti-encrypted-init/files/init | 324 ++++++++++++++++++ > .../initramfs-ti-encrypted-init_1.0.bb | 30 ++ > .../initramfs/ti-encrypted-boot-initramfs.bb | 50 +++ > 3 files changed, 404 insertions(+) > create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init > create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb > create mode 100644 meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb > > diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init > new file mode 100644 > index 00000000..6675b6ed > --- /dev/null > +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init > @@ -0,0 +1,324 @@ > +#!/usr/bin/busybox sh > +# TI SDK initramfs init script with LUKS2 + fTPM encryption support > + > +# Mount essential filesystems > +/usr/bin/busybox echo "Initializing system..." > +/usr/bin/busybox mount -t proc proc /proc > +/usr/bin/busybox mount -t sysfs sysfs /sys > +/usr/bin/busybox mount -t devtmpfs devtmpfs /dev > + > +# Configuration > +BOOT_DEV="/dev/mmcblk1p1" # Boot partition (FAT, unencrypted) > +ROOT_DEV="/dev/mmcblk1p2" # Root partition (will be encrypted) > +CRYPT_NAME="root_crypt" > +CRYPT_DEV="/dev/mapper/${CRYPT_NAME}" > +BOOT_MNT="/boot_part" > +TPM_PRIMARY_CTX="/tmp/tpm_primary.ctx" > +TPM_KEY_PRIV="/tmp/tpm_key.priv" > +TPM_KEY_PUB="/tmp/tpm_key.pub" > +TPM_KEY_CTX="/tmp/tpm_key.ctx" > +TPM2_HANDLE="0x81080001" # TPM persistent handle for LUKS key > +ENCRYPTION_MARKER="${BOOT_MNT}/.encryption_in_progress" > + > +# Wait for MMC device to appear (up to 10 seconds) > +/usr/bin/busybox echo "Waiting for storage device..." > +for i in 1 2 3 4 5 6 7 8 9 10; do > + if [ -b "${ROOT_DEV}" ]; then > + break > + fi > + /usr/bin/busybox sleep 1 > +done > + > +# Check if root device exists > +if [ ! -b "${ROOT_DEV}" ]; then > + /usr/bin/busybox echo "ERROR: Storage device not found!" > + /usr/bin/busybox sh > +fi > + > +# Mount boot partition > +/usr/bin/busybox echo "Mounting boot partition..." > +/usr/bin/busybox mkdir -p "${BOOT_MNT}" > +if ! /usr/bin/busybox mount "${BOOT_DEV}" "${BOOT_MNT}"; then > + /usr/bin/busybox echo "ERROR: Failed to mount boot partition!" > + /usr/bin/busybox echo "Attempting standard boot..." > + /usr/bin/busybox mkdir -p /newroot > + /usr/bin/busybox mount "${ROOT_DEV}" /newroot > + exec /usr/sbin/switch_root /newroot /sbin/init > +fi > + > +# Initialize fTPM in OP-TEE > +/usr/bin/busybox echo "Initializing secure hardware(fTPM)..." > + > +# Start TEE supplicant (required for fTPM TA to work) > +if [ -x /usr/sbin/tee-supplicant ]; then > + /usr/sbin/tee-supplicant -d & > + TEE_SUPPLICANT_PID=$! > + /usr/bin/busybox sleep 5 > +else > + /usr/bin/busybox echo "Warning: Trusted execution environment not available" > +fi > + > +# Load fTPM kernel module > +if ! /sbin/modprobe tpm_ftpm_tee; then > + /usr/bin/busybox echo "Warning: TPM module failed to load" > +fi > + > +# Wait for TPM device (up to 10 seconds) > +for i in 1 2 3 4 5 6 7 8 9 10; do > + if [ -c /dev/tpmrm0 ]; then > + break > + fi > + /usr/bin/busybox sleep 1 > +done > + > +# Check if TPM is available > +TPM_AVAILABLE=0 > +if [ -c /dev/tpmrm0 ]; then > + TPM_AVAILABLE=1 > + export TPM2TOOLS_TCTI="device:/dev/tpmrm0" > +else > + /usr/bin/busybox echo "Warning: fTPM not available - encryption will be skipped" > + if [ -n "${TEE_SUPPLICANT_PID}" ]; then > + /usr/bin/busybox kill "${TEE_SUPPLICANT_PID}" 2>/dev/null > + fi > +fi > + > +# Function: Generate 32-byte random key using TPM RNG > +generate_random_key() { > + if [ $TPM_AVAILABLE -eq 1 ]; then > + /usr/bin/tpm2_getrandom --hex 32 > + else > + /usr/bin/busybox echo "ERROR: TPM not available for key generation" > + return 1 > + fi > +} > + > +# Function: Seal data with TPM and store in persistent handle > +tpm_seal_key() { > + local KEY_DATA="$1" > + > + if [ $TPM_AVAILABLE -eq 0 ]; then > + /usr/bin/busybox echo "ERROR: TPM not available for sealing" > + return 1 > + fi > + > + # Create primary key in owner hierarchy > + /usr/bin/tpm2_createprimary -C o -c "${TPM_PRIMARY_CTX}" -Q || return 1 > + > + # Create sealed object > + /usr/bin/busybox echo -n "${KEY_DATA}" | \ > + /usr/bin/tpm2_create -C "${TPM_PRIMARY_CTX}" \ > + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ > + -i- -Q || return 1 > + > + # Load sealed object into TPM > + /usr/bin/tpm2_load -C "${TPM_PRIMARY_CTX}" \ > + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ > + -c "${TPM_KEY_CTX}" -Q || return 1 > + > + # Make key persistent at handle (stored in TPM NV RAM - RPMB) > + /usr/bin/tpm2_evictcontrol -C o -c "${TPM_KEY_CTX}" "${TPM2_HANDLE}" || return 1 > + > + return 0 > +} > + > +# Function: Unseal data from TPM persistent handle > +tpm_unseal_key() { > + if [ $TPM_AVAILABLE -eq 0 ]; then > + /usr/bin/busybox echo "ERROR: TPM not available for unsealing" >&2 > + return 1 > + fi > + > + # Check if persistent handle exists > + if ! /usr/bin/tpm2_getcap handles-persistent | grep -q "${TPM2_HANDLE}"; then > + /usr/bin/busybox echo "ERROR: TPM persistent handle not found" >&2 > + return 1 > + fi > + > + # Unseal key directly from persistent handle > + /usr/bin/tpm2_unseal -c "${TPM2_HANDLE}" || return 1 > + > + return 0 > +} > + > +# Function: Perform in-place LUKS encryption (first boot) > +encrypt_root_filesystem() { > + /usr/bin/busybox echo "==========================================" > + /usr/bin/busybox echo "First boot: Encrypting root filesystem" > + /usr/bin/busybox echo "==========================================" > + > + # Set marker to track encryption progress > + /usr/bin/busybox touch "${ENCRYPTION_MARKER}" > + /usr/bin/busybox sync > + > + # Generate random encryption key using TPM RNG > + /usr/bin/busybox echo "Generating encryption key..." > + LUKS_KEY=$(generate_random_key) > + > + if [ -z "${LUKS_KEY}" ]; then > + /usr/bin/busybox echo "ERROR: Failed to generate encryption key" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + fi > + > + # Seal key with TPM before encryption starts > + /usr/bin/busybox echo "Securing key with TPM..." > + if ! tpm_seal_key "${LUKS_KEY}"; then > + /usr/bin/busybox echo "ERROR: Failed to secure key" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + fi > + > + # Filesystem check before encryption > + /usr/bin/busybox echo "Checking filesystem integrity..." > + /usr/sbin/e2fsck -f -y "${ROOT_DEV}" > + E2FSCK_RET=$? > + if [ ${E2FSCK_RET} -ge 4 ]; then > + /usr/bin/busybox echo "ERROR: Filesystem check failed" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + fi > + > + # Shrink filesystem before encryption to leave room for LUKS header > + /usr/bin/busybox echo "Preparing filesystem for encryption..." > + /usr/sbin/resize2fs "${ROOT_DEV}" 368M || { > + /usr/bin/busybox echo "ERROR: Failed to prepare filesystem" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + } > + > + # Perform in-place encryption > + /usr/bin/busybox echo "==========================================" > + /usr/bin/busybox echo "Encrypting filesystem..." > + /usr/bin/busybox echo "This will take several minutes." > + /usr/bin/busybox echo "DO NOT POWER OFF THE DEVICE!" > + /usr/bin/busybox echo "==========================================" > + > + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ > + /usr/sbin/cryptsetup reencrypt --encrypt \ > + --type luks2 \ > + --cipher aes-xts-plain64 \ > + --key-size 256 \ > + --hash sha256 \ > + --reduce-device-size 32M \ > + --key-file - \ > + "${ROOT_DEV}" || { > + /usr/bin/busybox echo "ERROR: Encryption failed" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + } > + > + /usr/bin/busybox echo "==========================================" > + /usr/bin/busybox echo "Encryption completed successfully!" > + /usr/bin/busybox echo "==========================================" > + > + # Remove encryption marker > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + /usr/bin/busybox sync > + > + # Unlock the newly encrypted device > + /usr/bin/busybox echo "Activating encrypted filesystem..." > + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ > + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { > + /usr/bin/busybox echo "ERROR: Failed to activate encrypted filesystem" > + return 1 > + } > + > + # Resize filesystem to fit the encrypted device > + /usr/bin/busybox echo "Optimizing filesystem..." > + /usr/sbin/resize2fs -f "${CRYPT_DEV}" || { > + /usr/bin/busybox echo "ERROR: Failed to optimize filesystem" > + return 1 > + } > + > + # Verify filesystem after resize > + /usr/sbin/e2fsck -f -y "${CRYPT_DEV}" || { > + /usr/bin/busybox echo "WARNING: Filesystem verification had issues, but continuing" > + } > + return 0 > +} > + > +# Function: Unlock encrypted root filesystem (subsequent boots) > +unlock_encrypted_root() { > + /usr/bin/busybox echo "Unlocking encrypted filesystem..." > + > + # Unseal key from TPM persistent handle > + LUKS_KEY=$(tpm_unseal_key) > + > + if [ -z "${LUKS_KEY}" ]; then > + /usr/bin/busybox echo "ERROR: Failed to retrieve encryption key from TPM" > + /usr/bin/busybox echo "Attempting passphrase fallback..." > + > + # Try to unlock with passphrase (interactive) > + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" || { > + /usr/bin/busybox echo "ERROR: Failed to unlock encrypted filesystem" > + /usr/bin/busybox sh > + } > + else > + # Unlock with unsealed key > + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ > + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { > + /usr/bin/busybox echo "ERROR: Failed to unlock with TPM key" > + /usr/bin/busybox sh > + } > + fi > + > + /usr/bin/busybox echo "Encrypted filesystem unlocked" > +} > + > +# Main boot logic > +/usr/bin/busybox echo "Checking filesystem encryption status..." > + > +# Check if device is LUKS encrypted > +if /usr/sbin/cryptsetup isLuks "${ROOT_DEV}"; then > + /usr/bin/busybox echo "Filesystem is encrypted" > + unlock_encrypted_root > + MOUNT_DEV="${CRYPT_DEV}" > +else > + /usr/bin/busybox echo "Filesystem is not encrypted" > + > + # Check if encryption is enabled and TPM is available > + if [ $TPM_AVAILABLE -eq 1 ]; then > + # Check for encryption marker (resume interrupted encryption) > + if [ -f "${ENCRYPTION_MARKER}" ]; then > + /usr/bin/busybox echo "Resuming interrupted encryption..." > + if ! encrypt_root_filesystem; then > + /usr/bin/busybox echo "ERROR: Failed to resume encryption" > + /usr/bin/busybox echo "Booting without encryption..." > + MOUNT_DEV="${ROOT_DEV}" > + else > + MOUNT_DEV="${CRYPT_DEV}" > + fi > + else > + # First boot - perform encryption > + if encrypt_root_filesystem; then > + MOUNT_DEV="${CRYPT_DEV}" > + else > + /usr/bin/busybox echo "ERROR: Encryption failed - booting without encryption" > + MOUNT_DEV="${ROOT_DEV}" > + fi > + fi > + else > + /usr/bin/busybox echo "TPM not available - skipping encryption" > + MOUNT_DEV="${ROOT_DEV}" > + fi > +fi > + > +# Unmount boot partition before switching root > +/usr/bin/busybox umount "${BOOT_MNT}" > + > +# Mount root filesystem (encrypted or unencrypted) > +/usr/bin/busybox echo "Mounting root filesystem..." > +/usr/bin/busybox mkdir -p /newroot > +/usr/bin/busybox mount "${MOUNT_DEV}" /newroot || { > + /usr/bin/busybox echo "ERROR: Failed to mount root filesystem!" > + /usr/bin/busybox sh > +} > + > +/usr/bin/busybox echo "Boot complete" > + > +# Clean up tmpfs > +/usr/bin/busybox rm -f "${TPM_PRIMARY_CTX}" "${TPM_KEY_PUB}" "${TPM_KEY_PRIV}" "${TPM_KEY_CTX}" > + > +# Switch to real root > +exec /usr/sbin/switch_root /newroot /sbin/init > diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb > new file mode 100644 > index 00000000..7da878f7 > --- /dev/null > +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb > @@ -0,0 +1,30 @@ > +SUMMARY = "TI encrypted boot initramfs init script" > +DESCRIPTION = "Custom /init script for encrypted boot with fTPM + LUKS support" > + > +LICENSE = "MIT" > +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" > + > +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}/files:" > +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" > + > +SRC_URI = "file://init" > + > +S = "${WORKDIR}/sources" > +UNPACKDIR = "${WORKDIR}" > + > +# This recipe must run in the initramfs context > +inherit allarch > + > +do_install() { > + # Install /init script to root of initramfs > + install -m 0755 ${UNPACKDIR}/init ${D}/init > +} > + > +# Package the /init file > +FILES:${PN} = "/init" > + > +# Runtime dependencies > +RDEPENDS:${PN} = "busybox cryptsetup tpm2-tools tpm2-tss optee-client e2fsprogs-e2fsck e2fsprogs-resize2fs util-linux-blkid" > + > +# This package must be included in initramfs > +PACKAGE_ARCH = "${MACHINE_ARCH}" > diff --git a/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb > new file mode 100644 > index 00000000..314499db > --- /dev/null > +++ b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb > @@ -0,0 +1,50 @@ > +SUMMARY = "TI encrypted boot initramfs image" > + > +DESCRIPTION = "Minimal initramfs image with dm-crypt/fTPM support for encrypted root filesystem. \ > +This initramfs provides LUKS encryption with TPM-sealed keys stored in RPMB." > + > +LICENSE = "MIT" > + > +# Only build this when luks-encryption feature is enabled > +COMPATIBLE_MACHINE = "null" > +COMPATIBLE_MACHINE:k3 = "${@bb.utils.contains('MACHINE_FEATURES', 'luks-encryption', '.*', 'null', d)}" > + > +INITRAMFS_FSTYPES = "cpio.gz" > + > +IMAGE_NAME = "ti-encrypted-boot-initramfs" > + > +export IMAGE_BASENAME = "${IMAGE_NAME}" > + > +# Install our custom init script and dependencies > +PACKAGE_INSTALL = "\ > + initramfs-ti-encrypted-init \ > + busybox \ > + base-passwd \ > + kmod \ > + cryptsetup \ > + tpm2-tools \ > + tpm2-tss \ > + libtss2-tcti-device \ > + optee-client \ > + util-linux-blkid \ > + e2fsprogs-e2fsck \ > + e2fsprogs-resize2fs \ > + kernel-module-tpm-ftpm-tee \ > + ${ROOTFS_BOOTSTRAP_INSTALL} \ > +" > + > +# Ensure the initramfs only contains the bare minimum > +IMAGE_FEATURES = "" > +IMAGE_LINGUAS = "" > + > +# Exclude kernel image from initramfs > +PACKAGE_EXCLUDE = "kernel-image-*" > + > +IMAGE_FSTYPES = "${INITRAMFS_FSTYPES}" > +IMAGE_NAME_SUFFIX ?= "" > +IMAGE_ROOTFS_SIZE = "16384" > +IMAGE_ROOTFS_EXTRA_SPACE = "0" > + > +BAD_RECOMMENDATIONS += "busybox-syslog" > + > +inherit image > -- > 2.34.1 > > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#19628): https://lists.yoctoproject.org/g/meta-ti/message/19628 > Mute This Topic: https://lists.yoctoproject.org/mt/118097473/7902621 > Group Owner: meta-ti+owner@lists.yoctoproject.org > Unsubscribe: https://lists.yoctoproject.org/g/meta-ti/unsub [jcormier@criticallink.com] > -=-=-=-=-=-=-=-=-=-=-=- >
On Mon Mar 2, 2026 at 8:46 AM CST, Shiva Tripathi via lists.yoctoproject.org wrote: > Add ti-encrypted-boot-initramfs for LUKS encryption with TPM-sealed > keys. This provides full disk encryption using dm-crypt with keys > sealed by firmware TPM (fTPM) running in OP-TEE and stored in eMMC RPMB. > > The initramfs includes: > - Custom init script for in-place LUKS encryption on first boot > - TPM key sealing/unsealing using persistent handle 0x81080001 > - Support for cryptsetup, tpm2-tools, and OP-TEE client > - Automatic filesystem resize after encryption > > ti-encrypted-boot-initramfs builds when MACHINE_FEATURES contains > 'luks-encryption'. > > Signed-off-by: Shiva Tripathi <s-tripathi1@ti.com> > --- > .../initramfs-ti-encrypted-init/files/init | 324 ++++++++++++++++++ > .../initramfs-ti-encrypted-init_1.0.bb | 30 ++ > .../initramfs/ti-encrypted-boot-initramfs.bb | 50 +++ > 3 files changed, 404 insertions(+) > create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init > create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb > create mode 100644 meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb > > diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init > new file mode 100644 > index 00000000..6675b6ed > --- /dev/null > +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init > @@ -0,0 +1,324 @@ > +#!/usr/bin/busybox sh > +# TI SDK initramfs init script with LUKS2 + fTPM encryption support > + > +# Mount essential filesystems > +/usr/bin/busybox echo "Initializing system..." > +/usr/bin/busybox mount -t proc proc /proc > +/usr/bin/busybox mount -t sysfs sysfs /sys > +/usr/bin/busybox mount -t devtmpfs devtmpfs /dev > + > +# Configuration > +BOOT_DEV="/dev/mmcblk1p1" # Boot partition (FAT, unencrypted) > +ROOT_DEV="/dev/mmcblk1p2" # Root partition (will be encrypted) > +CRYPT_NAME="root_crypt" > +CRYPT_DEV="/dev/mapper/${CRYPT_NAME}" > +BOOT_MNT="/boot_part" > +TPM_PRIMARY_CTX="/tmp/tpm_primary.ctx" > +TPM_KEY_PRIV="/tmp/tpm_key.priv" > +TPM_KEY_PUB="/tmp/tpm_key.pub" > +TPM_KEY_CTX="/tmp/tpm_key.ctx" > +TPM2_HANDLE="0x81080001" # TPM persistent handle for LUKS key > +ENCRYPTION_MARKER="${BOOT_MNT}/.encryption_in_progress" > + > +# Wait for MMC device to appear (up to 10 seconds) > +/usr/bin/busybox echo "Waiting for storage device..." > +for i in 1 2 3 4 5 6 7 8 9 10; do > + if [ -b "${ROOT_DEV}" ]; then > + break > + fi > + /usr/bin/busybox sleep 1 > +done > + > +# Check if root device exists > +if [ ! -b "${ROOT_DEV}" ]; then > + /usr/bin/busybox echo "ERROR: Storage device not found!" > + /usr/bin/busybox sh > +fi > + > +# Mount boot partition > +/usr/bin/busybox echo "Mounting boot partition..." > +/usr/bin/busybox mkdir -p "${BOOT_MNT}" > +if ! /usr/bin/busybox mount "${BOOT_DEV}" "${BOOT_MNT}"; then > + /usr/bin/busybox echo "ERROR: Failed to mount boot partition!" > + /usr/bin/busybox echo "Attempting standard boot..." > + /usr/bin/busybox mkdir -p /newroot > + /usr/bin/busybox mount "${ROOT_DEV}" /newroot > + exec /usr/sbin/switch_root /newroot /sbin/init > +fi The main boot path should be the error path here, not an arbitrary duplication of logic. > + > +# Initialize fTPM in OP-TEE > +/usr/bin/busybox echo "Initializing secure hardware(fTPM)..." > + > +# Start TEE supplicant (required for fTPM TA to work) > +if [ -x /usr/sbin/tee-supplicant ]; then > + /usr/sbin/tee-supplicant -d & > + TEE_SUPPLICANT_PID=$! > + /usr/bin/busybox sleep 5 > +else > + /usr/bin/busybox echo "Warning: Trusted execution environment not available" > +fi > + > +# Load fTPM kernel module > +if ! /sbin/modprobe tpm_ftpm_tee; then > + /usr/bin/busybox echo "Warning: TPM module failed to load" > +fi > + > +# Wait for TPM device (up to 10 seconds) > +for i in 1 2 3 4 5 6 7 8 9 10; do > + if [ -c /dev/tpmrm0 ]; then > + break > + fi > + /usr/bin/busybox sleep 1 > +done This should be a function who's exit code is use in the below script directly instead of rechecking if the device is present. > + > +# Check if TPM is available > +TPM_AVAILABLE=0 > +if [ -c /dev/tpmrm0 ]; then > + TPM_AVAILABLE=1 > + export TPM2TOOLS_TCTI="device:/dev/tpmrm0" > +else > + /usr/bin/busybox echo "Warning: fTPM not available - encryption will be skipped" > + if [ -n "${TEE_SUPPLICANT_PID}" ]; then > + /usr/bin/busybox kill "${TEE_SUPPLICANT_PID}" 2>/dev/null > + fi > +fi > + > +# Function: Generate 32-byte random key using TPM RNG > +generate_random_key() { > + if [ $TPM_AVAILABLE -eq 1 ]; then > + /usr/bin/tpm2_getrandom --hex 32 > + else > + /usr/bin/busybox echo "ERROR: TPM not available for key generation" > + return 1 > + fi > +} This should probably be reported to the user, or at least they should be told how to access it during runtime. > + > +# Function: Seal data with TPM and store in persistent handle > +tpm_seal_key() { > + local KEY_DATA="$1" > + > + if [ $TPM_AVAILABLE -eq 0 ]; then > + /usr/bin/busybox echo "ERROR: TPM not available for sealing" > + return 1 > + fi > + > + # Create primary key in owner hierarchy > + /usr/bin/tpm2_createprimary -C o -c "${TPM_PRIMARY_CTX}" -Q || return 1 > + > + # Create sealed object > + /usr/bin/busybox echo -n "${KEY_DATA}" | \ > + /usr/bin/tpm2_create -C "${TPM_PRIMARY_CTX}" \ > + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ > + -i- -Q || return 1 > + > + # Load sealed object into TPM > + /usr/bin/tpm2_load -C "${TPM_PRIMARY_CTX}" \ > + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ > + -c "${TPM_KEY_CTX}" -Q || return 1 > + > + # Make key persistent at handle (stored in TPM NV RAM - RPMB) > + /usr/bin/tpm2_evictcontrol -C o -c "${TPM_KEY_CTX}" "${TPM2_HANDLE}" || return 1 > + > + return 0 > +} > + > +# Function: Unseal data from TPM persistent handle > +tpm_unseal_key() { > + if [ $TPM_AVAILABLE -eq 0 ]; then > + /usr/bin/busybox echo "ERROR: TPM not available for unsealing" >&2 > + return 1 > + fi > + > + # Check if persistent handle exists > + if ! /usr/bin/tpm2_getcap handles-persistent | grep -q "${TPM2_HANDLE}"; then > + /usr/bin/busybox echo "ERROR: TPM persistent handle not found" >&2 > + return 1 > + fi > + > + # Unseal key directly from persistent handle > + /usr/bin/tpm2_unseal -c "${TPM2_HANDLE}" || return 1 > + > + return 0 > +} > + > +# Function: Perform in-place LUKS encryption (first boot) > +encrypt_root_filesystem() { > + /usr/bin/busybox echo "==========================================" > + /usr/bin/busybox echo "First boot: Encrypting root filesystem" > + /usr/bin/busybox echo "==========================================" > + > + # Set marker to track encryption progress > + /usr/bin/busybox touch "${ENCRYPTION_MARKER}" > + /usr/bin/busybox sync > + > + # Generate random encryption key using TPM RNG > + /usr/bin/busybox echo "Generating encryption key..." > + LUKS_KEY=$(generate_random_key) > + > + if [ -z "${LUKS_KEY}" ]; then > + /usr/bin/busybox echo "ERROR: Failed to generate encryption key" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + fi > + > + # Seal key with TPM before encryption starts > + /usr/bin/busybox echo "Securing key with TPM..." > + if ! tpm_seal_key "${LUKS_KEY}"; then > + /usr/bin/busybox echo "ERROR: Failed to secure key" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + fi > + > + # Filesystem check before encryption > + /usr/bin/busybox echo "Checking filesystem integrity..." > + /usr/sbin/e2fsck -f -y "${ROOT_DEV}" > + E2FSCK_RET=$? > + if [ ${E2FSCK_RET} -ge 4 ]; then > + /usr/bin/busybox echo "ERROR: Filesystem check failed" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + fi > + > + # Shrink filesystem before encryption to leave room for LUKS header > + /usr/bin/busybox echo "Preparing filesystem for encryption..." > + /usr/sbin/resize2fs "${ROOT_DEV}" 368M || { Arbitrary size here, prone to failure in the future. Look into the "-M" option instead. > + /usr/bin/busybox echo "ERROR: Failed to prepare filesystem" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + } > + > + # Perform in-place encryption > + /usr/bin/busybox echo "==========================================" > + /usr/bin/busybox echo "Encrypting filesystem..." > + /usr/bin/busybox echo "This will take several minutes." > + /usr/bin/busybox echo "DO NOT POWER OFF THE DEVICE!" > + /usr/bin/busybox echo "==========================================" > + > + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ > + /usr/sbin/cryptsetup reencrypt --encrypt \ > + --type luks2 \ > + --cipher aes-xts-plain64 \ > + --key-size 256 \ > + --hash sha256 \ > + --reduce-device-size 32M \ > + --key-file - \ > + "${ROOT_DEV}" || { > + /usr/bin/busybox echo "ERROR: Encryption failed" > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + return 1 > + } This should only work on partitions that already contain a LUKS header. The LUKS header is placed in sector 0 of the block device. resize2fs doesn't support changing the starting position of the filesystem so you will always corrupt the existing filesystem. It may still be recoverable, but that's not the point. This is a bad idea. Additionally, the partition should be overwritten with randomized data before use to make sure unused blocks look indistinguishable from later encrypted data. This is not something that can be done using an initramfs without external storage. > + > + /usr/bin/busybox echo "==========================================" > + /usr/bin/busybox echo "Encryption completed successfully!" > + /usr/bin/busybox echo "==========================================" > + > + # Remove encryption marker > + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" > + /usr/bin/busybox sync > + > + # Unlock the newly encrypted device > + /usr/bin/busybox echo "Activating encrypted filesystem..." > + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ > + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { > + /usr/bin/busybox echo "ERROR: Failed to activate encrypted filesystem" > + return 1 > + } > + > + # Resize filesystem to fit the encrypted device > + /usr/bin/busybox echo "Optimizing filesystem..." > + /usr/sbin/resize2fs -f "${CRYPT_DEV}" || { > + /usr/bin/busybox echo "ERROR: Failed to optimize filesystem" > + return 1 > + } > + > + # Verify filesystem after resize > + /usr/sbin/e2fsck -f -y "${CRYPT_DEV}" || { > + /usr/bin/busybox echo "WARNING: Filesystem verification had issues, but continuing" > + } > + return 0 > +} > + > +# Function: Unlock encrypted root filesystem (subsequent boots) > +unlock_encrypted_root() { > + /usr/bin/busybox echo "Unlocking encrypted filesystem..." > + > + # Unseal key from TPM persistent handle > + LUKS_KEY=$(tpm_unseal_key) > + > + if [ -z "${LUKS_KEY}" ]; then > + /usr/bin/busybox echo "ERROR: Failed to retrieve encryption key from TPM" > + /usr/bin/busybox echo "Attempting passphrase fallback..." > + > + # Try to unlock with passphrase (interactive) > + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" || { > + /usr/bin/busybox echo "ERROR: Failed to unlock encrypted filesystem" > + /usr/bin/busybox sh > + } > + else > + # Unlock with unsealed key > + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ > + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { > + /usr/bin/busybox echo "ERROR: Failed to unlock with TPM key" > + /usr/bin/busybox sh > + } > + fi > + > + /usr/bin/busybox echo "Encrypted filesystem unlocked" > +} > + > +# Main boot logic > +/usr/bin/busybox echo "Checking filesystem encryption status..." > + > +# Check if device is LUKS encrypted > +if /usr/sbin/cryptsetup isLuks "${ROOT_DEV}"; then > + /usr/bin/busybox echo "Filesystem is encrypted" > + unlock_encrypted_root > + MOUNT_DEV="${CRYPT_DEV}" > +else > + /usr/bin/busybox echo "Filesystem is not encrypted" > + > + # Check if encryption is enabled and TPM is available > + if [ $TPM_AVAILABLE -eq 1 ]; then > + # Check for encryption marker (resume interrupted encryption) > + if [ -f "${ENCRYPTION_MARKER}" ]; then > + /usr/bin/busybox echo "Resuming interrupted encryption..." > + if ! encrypt_root_filesystem; then > + /usr/bin/busybox echo "ERROR: Failed to resume encryption" > + /usr/bin/busybox echo "Booting without encryption..." > + MOUNT_DEV="${ROOT_DEV}" > + else > + MOUNT_DEV="${CRYPT_DEV}" > + fi > + else > + # First boot - perform encryption > + if encrypt_root_filesystem; then > + MOUNT_DEV="${CRYPT_DEV}" > + else > + /usr/bin/busybox echo "ERROR: Encryption failed - booting without encryption" > + MOUNT_DEV="${ROOT_DEV}" > + fi > + fi > + else > + /usr/bin/busybox echo "TPM not available - skipping encryption" > + MOUNT_DEV="${ROOT_DEV}" > + fi > +fi > + > +# Unmount boot partition before switching root > +/usr/bin/busybox umount "${BOOT_MNT}" > + > +# Mount root filesystem (encrypted or unencrypted) > +/usr/bin/busybox echo "Mounting root filesystem..." > +/usr/bin/busybox mkdir -p /newroot > +/usr/bin/busybox mount "${MOUNT_DEV}" /newroot || { > + /usr/bin/busybox echo "ERROR: Failed to mount root filesystem!" > + /usr/bin/busybox sh > +} > + > +/usr/bin/busybox echo "Boot complete" > + > +# Clean up tmpfs > +/usr/bin/busybox rm -f "${TPM_PRIMARY_CTX}" "${TPM_KEY_PUB}" "${TPM_KEY_PRIV}" "${TPM_KEY_CTX}" > + > +# Switch to real root > +exec /usr/sbin/switch_root /newroot /sbin/init In general I think this effort is misguided. An initrd is not a replacement for live image install. We should not be dramatically changing the running system as part of the first boot. > diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb > new file mode 100644 > index 00000000..7da878f7 > --- /dev/null > +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb > @@ -0,0 +1,30 @@ > +SUMMARY = "TI encrypted boot initramfs init script" > +DESCRIPTION = "Custom /init script for encrypted boot with fTPM + LUKS support" > + > +LICENSE = "MIT" > +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" > + > +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}/files:" > +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" > + > +SRC_URI = "file://init" > + > +S = "${WORKDIR}/sources" > +UNPACKDIR = "${WORKDIR}" > + > +# This recipe must run in the initramfs context > +inherit allarch > + > +do_install() { > + # Install /init script to root of initramfs > + install -m 0755 ${UNPACKDIR}/init ${D}/init > +} > + > +# Package the /init file > +FILES:${PN} = "/init" > + > +# Runtime dependencies > +RDEPENDS:${PN} = "busybox cryptsetup tpm2-tools tpm2-tss optee-client e2fsprogs-e2fsck e2fsprogs-resize2fs util-linux-blkid" > + > +# This package must be included in initramfs > +PACKAGE_ARCH = "${MACHINE_ARCH}" > diff --git a/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb > new file mode 100644 > index 00000000..314499db > --- /dev/null > +++ b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb > @@ -0,0 +1,50 @@ > +SUMMARY = "TI encrypted boot initramfs image" > + > +DESCRIPTION = "Minimal initramfs image with dm-crypt/fTPM support for encrypted root filesystem. \ > +This initramfs provides LUKS encryption with TPM-sealed keys stored in RPMB." > + > +LICENSE = "MIT" > + > +# Only build this when luks-encryption feature is enabled > +COMPATIBLE_MACHINE = "null" > +COMPATIBLE_MACHINE:k3 = "${@bb.utils.contains('MACHINE_FEATURES', 'luks-encryption', '.*', 'null', d)}" > + > +INITRAMFS_FSTYPES = "cpio.gz" > + > +IMAGE_NAME = "ti-encrypted-boot-initramfs" > + > +export IMAGE_BASENAME = "${IMAGE_NAME}" > + > +# Install our custom init script and dependencies > +PACKAGE_INSTALL = "\ > + initramfs-ti-encrypted-init \ > + busybox \ > + base-passwd \ > + kmod \ > + cryptsetup \ > + tpm2-tools \ > + tpm2-tss \ > + libtss2-tcti-device \ > + optee-client \ > + util-linux-blkid \ > + e2fsprogs-e2fsck \ > + e2fsprogs-resize2fs \ > + kernel-module-tpm-ftpm-tee \ > + ${ROOTFS_BOOTSTRAP_INSTALL} \ > +" > + > +# Ensure the initramfs only contains the bare minimum > +IMAGE_FEATURES = "" > +IMAGE_LINGUAS = "" > + > +# Exclude kernel image from initramfs > +PACKAGE_EXCLUDE = "kernel-image-*" > + > +IMAGE_FSTYPES = "${INITRAMFS_FSTYPES}" > +IMAGE_NAME_SUFFIX ?= "" > +IMAGE_ROOTFS_SIZE = "16384" > +IMAGE_ROOTFS_EXTRA_SPACE = "0" > + > +BAD_RECOMMENDATIONS += "busybox-syslog" > + > +inherit image
On 3/2/2026 4:36 PM, Randolph Sapp wrote: > On Mon Mar 2, 2026 at 8:46 AM CST, Shiva Tripathi via lists.yoctoproject.org wrote: >> Add ti-encrypted-boot-initramfs for LUKS encryption with TPM-sealed >> keys. This provides full disk encryption using dm-crypt with keys >> sealed by firmware TPM (fTPM) running in OP-TEE and stored in eMMC RPMB. >> >> The initramfs includes: >> - Custom init script for in-place LUKS encryption on first boot >> - TPM key sealing/unsealing using persistent handle 0x81080001 >> - Support for cryptsetup, tpm2-tools, and OP-TEE client >> - Automatic filesystem resize after encryption >> >> ti-encrypted-boot-initramfs builds when MACHINE_FEATURES contains >> 'luks-encryption'. >> >> Signed-off-by: Shiva Tripathi <s-tripathi1@ti.com> >> --- >> .../initramfs-ti-encrypted-init/files/init | 324 ++++++++++++++++++ >> .../initramfs-ti-encrypted-init_1.0.bb | 30 ++ >> .../initramfs/ti-encrypted-boot-initramfs.bb | 50 +++ >> 3 files changed, 404 insertions(+) >> create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init >> create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb >> create mode 100644 meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb >> >> diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init >> new file mode 100644 >> index 00000000..6675b6ed >> --- /dev/null >> +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init >> @@ -0,0 +1,324 @@ >> +#!/usr/bin/busybox sh >> +# TI SDK initramfs init script with LUKS2 + fTPM encryption support >> + >> +# Mount essential filesystems >> +/usr/bin/busybox echo "Initializing system..." >> +/usr/bin/busybox mount -t proc proc /proc >> +/usr/bin/busybox mount -t sysfs sysfs /sys >> +/usr/bin/busybox mount -t devtmpfs devtmpfs /dev >> + >> +# Configuration >> +BOOT_DEV="/dev/mmcblk1p1" # Boot partition (FAT, unencrypted) >> +ROOT_DEV="/dev/mmcblk1p2" # Root partition (will be encrypted) >> +CRYPT_NAME="root_crypt" >> +CRYPT_DEV="/dev/mapper/${CRYPT_NAME}" >> +BOOT_MNT="/boot_part" >> +TPM_PRIMARY_CTX="/tmp/tpm_primary.ctx" >> +TPM_KEY_PRIV="/tmp/tpm_key.priv" >> +TPM_KEY_PUB="/tmp/tpm_key.pub" >> +TPM_KEY_CTX="/tmp/tpm_key.ctx" >> +TPM2_HANDLE="0x81080001" # TPM persistent handle for LUKS key >> +ENCRYPTION_MARKER="${BOOT_MNT}/.encryption_in_progress" >> + >> +# Wait for MMC device to appear (up to 10 seconds) >> +/usr/bin/busybox echo "Waiting for storage device..." >> +for i in 1 2 3 4 5 6 7 8 9 10; do >> + if [ -b "${ROOT_DEV}" ]; then >> + break >> + fi >> + /usr/bin/busybox sleep 1 >> +done >> + >> +# Check if root device exists >> +if [ ! -b "${ROOT_DEV}" ]; then >> + /usr/bin/busybox echo "ERROR: Storage device not found!" >> + /usr/bin/busybox sh >> +fi >> + >> +# Mount boot partition >> +/usr/bin/busybox echo "Mounting boot partition..." >> +/usr/bin/busybox mkdir -p "${BOOT_MNT}" >> +if ! /usr/bin/busybox mount "${BOOT_DEV}" "${BOOT_MNT}"; then >> + /usr/bin/busybox echo "ERROR: Failed to mount boot partition!" >> + /usr/bin/busybox echo "Attempting standard boot..." >> + /usr/bin/busybox mkdir -p /newroot >> + /usr/bin/busybox mount "${ROOT_DEV}" /newroot >> + exec /usr/sbin/switch_root /newroot /sbin/init >> +fi > > The main boot path should be the error path here, not an arbitrary duplication > of logic. > >> + >> +# Initialize fTPM in OP-TEE >> +/usr/bin/busybox echo "Initializing secure hardware(fTPM)..." >> + >> +# Start TEE supplicant (required for fTPM TA to work) >> +if [ -x /usr/sbin/tee-supplicant ]; then >> + /usr/sbin/tee-supplicant -d & >> + TEE_SUPPLICANT_PID=$! >> + /usr/bin/busybox sleep 5 >> +else >> + /usr/bin/busybox echo "Warning: Trusted execution environment not available" >> +fi >> + >> +# Load fTPM kernel module >> +if ! /sbin/modprobe tpm_ftpm_tee; then >> + /usr/bin/busybox echo "Warning: TPM module failed to load" >> +fi >> + >> +# Wait for TPM device (up to 10 seconds) >> +for i in 1 2 3 4 5 6 7 8 9 10; do >> + if [ -c /dev/tpmrm0 ]; then >> + break >> + fi >> + /usr/bin/busybox sleep 1 >> +done > > This should be a function who's exit code is use in the below script directly > instead of rechecking if the device is present. > >> + >> +# Check if TPM is available >> +TPM_AVAILABLE=0 >> +if [ -c /dev/tpmrm0 ]; then >> + TPM_AVAILABLE=1 >> + export TPM2TOOLS_TCTI="device:/dev/tpmrm0" >> +else >> + /usr/bin/busybox echo "Warning: fTPM not available - encryption will be skipped" >> + if [ -n "${TEE_SUPPLICANT_PID}" ]; then >> + /usr/bin/busybox kill "${TEE_SUPPLICANT_PID}" 2>/dev/null >> + fi >> +fi >> + >> +# Function: Generate 32-byte random key using TPM RNG >> +generate_random_key() { >> + if [ $TPM_AVAILABLE -eq 1 ]; then >> + /usr/bin/tpm2_getrandom --hex 32 >> + else >> + /usr/bin/busybox echo "ERROR: TPM not available for key generation" >> + return 1 >> + fi >> +} > > This should probably be reported to the user, or at least they should be told > how to access it during runtime. > >> + >> +# Function: Seal data with TPM and store in persistent handle >> +tpm_seal_key() { >> + local KEY_DATA="$1" >> + >> + if [ $TPM_AVAILABLE -eq 0 ]; then >> + /usr/bin/busybox echo "ERROR: TPM not available for sealing" >> + return 1 >> + fi >> + >> + # Create primary key in owner hierarchy >> + /usr/bin/tpm2_createprimary -C o -c "${TPM_PRIMARY_CTX}" -Q || return 1 >> + >> + # Create sealed object >> + /usr/bin/busybox echo -n "${KEY_DATA}" | \ >> + /usr/bin/tpm2_create -C "${TPM_PRIMARY_CTX}" \ >> + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ >> + -i- -Q || return 1 >> + >> + # Load sealed object into TPM >> + /usr/bin/tpm2_load -C "${TPM_PRIMARY_CTX}" \ >> + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ >> + -c "${TPM_KEY_CTX}" -Q || return 1 >> + >> + # Make key persistent at handle (stored in TPM NV RAM - RPMB) >> + /usr/bin/tpm2_evictcontrol -C o -c "${TPM_KEY_CTX}" "${TPM2_HANDLE}" || return 1 >> + >> + return 0 >> +} >> + >> +# Function: Unseal data from TPM persistent handle >> +tpm_unseal_key() { >> + if [ $TPM_AVAILABLE -eq 0 ]; then >> + /usr/bin/busybox echo "ERROR: TPM not available for unsealing" >&2 >> + return 1 >> + fi >> + >> + # Check if persistent handle exists >> + if ! /usr/bin/tpm2_getcap handles-persistent | grep -q "${TPM2_HANDLE}"; then >> + /usr/bin/busybox echo "ERROR: TPM persistent handle not found" >&2 >> + return 1 >> + fi >> + >> + # Unseal key directly from persistent handle >> + /usr/bin/tpm2_unseal -c "${TPM2_HANDLE}" || return 1 >> + >> + return 0 >> +} >> + >> +# Function: Perform in-place LUKS encryption (first boot) >> +encrypt_root_filesystem() { >> + /usr/bin/busybox echo "==========================================" >> + /usr/bin/busybox echo "First boot: Encrypting root filesystem" >> + /usr/bin/busybox echo "==========================================" >> + >> + # Set marker to track encryption progress >> + /usr/bin/busybox touch "${ENCRYPTION_MARKER}" >> + /usr/bin/busybox sync >> + >> + # Generate random encryption key using TPM RNG >> + /usr/bin/busybox echo "Generating encryption key..." >> + LUKS_KEY=$(generate_random_key) >> + >> + if [ -z "${LUKS_KEY}" ]; then >> + /usr/bin/busybox echo "ERROR: Failed to generate encryption key" >> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >> + return 1 >> + fi >> + >> + # Seal key with TPM before encryption starts >> + /usr/bin/busybox echo "Securing key with TPM..." >> + if ! tpm_seal_key "${LUKS_KEY}"; then >> + /usr/bin/busybox echo "ERROR: Failed to secure key" >> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >> + return 1 >> + fi >> + >> + # Filesystem check before encryption >> + /usr/bin/busybox echo "Checking filesystem integrity..." >> + /usr/sbin/e2fsck -f -y "${ROOT_DEV}" >> + E2FSCK_RET=$? >> + if [ ${E2FSCK_RET} -ge 4 ]; then >> + /usr/bin/busybox echo "ERROR: Filesystem check failed" >> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >> + return 1 >> + fi >> + >> + # Shrink filesystem before encryption to leave room for LUKS header >> + /usr/bin/busybox echo "Preparing filesystem for encryption..." >> + /usr/sbin/resize2fs "${ROOT_DEV}" 368M || { > > Arbitrary size here, prone to failure in the future. Look into the "-M" option > instead. > >> + /usr/bin/busybox echo "ERROR: Failed to prepare filesystem" >> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >> + return 1 >> + } >> + >> + # Perform in-place encryption >> + /usr/bin/busybox echo "==========================================" >> + /usr/bin/busybox echo "Encrypting filesystem..." >> + /usr/bin/busybox echo "This will take several minutes." >> + /usr/bin/busybox echo "DO NOT POWER OFF THE DEVICE!" >> + /usr/bin/busybox echo "==========================================" >> + >> + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ >> + /usr/sbin/cryptsetup reencrypt --encrypt \ >> + --type luks2 \ >> + --cipher aes-xts-plain64 \ >> + --key-size 256 \ >> + --hash sha256 \ >> + --reduce-device-size 32M \ >> + --key-file - \ >> + "${ROOT_DEV}" || { >> + /usr/bin/busybox echo "ERROR: Encryption failed" >> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >> + return 1 >> + } > > This should only work on partitions that already contain a LUKS header. The LUKS > header is placed in sector 0 of the block device. resize2fs doesn't support > changing the starting position of the filesystem so you will always corrupt the > existing filesystem. It may still be recoverable, but that's not the point. This > is a bad idea. > > Additionally, the partition should be overwritten with randomized data before > use to make sure unused blocks look indistinguishable from later encrypted data. > This is not something that can be done using an initramfs without external > storage. > >> + >> + /usr/bin/busybox echo "==========================================" >> + /usr/bin/busybox echo "Encryption completed successfully!" >> + /usr/bin/busybox echo "==========================================" >> + >> + # Remove encryption marker >> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >> + /usr/bin/busybox sync >> + >> + # Unlock the newly encrypted device >> + /usr/bin/busybox echo "Activating encrypted filesystem..." >> + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ >> + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { >> + /usr/bin/busybox echo "ERROR: Failed to activate encrypted filesystem" >> + return 1 >> + } >> + >> + # Resize filesystem to fit the encrypted device >> + /usr/bin/busybox echo "Optimizing filesystem..." >> + /usr/sbin/resize2fs -f "${CRYPT_DEV}" || { >> + /usr/bin/busybox echo "ERROR: Failed to optimize filesystem" >> + return 1 >> + } >> + >> + # Verify filesystem after resize >> + /usr/sbin/e2fsck -f -y "${CRYPT_DEV}" || { >> + /usr/bin/busybox echo "WARNING: Filesystem verification had issues, but continuing" >> + } >> + return 0 >> +} >> + >> +# Function: Unlock encrypted root filesystem (subsequent boots) >> +unlock_encrypted_root() { >> + /usr/bin/busybox echo "Unlocking encrypted filesystem..." >> + >> + # Unseal key from TPM persistent handle >> + LUKS_KEY=$(tpm_unseal_key) >> + >> + if [ -z "${LUKS_KEY}" ]; then >> + /usr/bin/busybox echo "ERROR: Failed to retrieve encryption key from TPM" >> + /usr/bin/busybox echo "Attempting passphrase fallback..." >> + >> + # Try to unlock with passphrase (interactive) >> + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" || { >> + /usr/bin/busybox echo "ERROR: Failed to unlock encrypted filesystem" >> + /usr/bin/busybox sh >> + } >> + else >> + # Unlock with unsealed key >> + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ >> + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { >> + /usr/bin/busybox echo "ERROR: Failed to unlock with TPM key" >> + /usr/bin/busybox sh >> + } >> + fi >> + >> + /usr/bin/busybox echo "Encrypted filesystem unlocked" >> +} >> + >> +# Main boot logic >> +/usr/bin/busybox echo "Checking filesystem encryption status..." >> + >> +# Check if device is LUKS encrypted >> +if /usr/sbin/cryptsetup isLuks "${ROOT_DEV}"; then >> + /usr/bin/busybox echo "Filesystem is encrypted" >> + unlock_encrypted_root >> + MOUNT_DEV="${CRYPT_DEV}" >> +else >> + /usr/bin/busybox echo "Filesystem is not encrypted" >> + >> + # Check if encryption is enabled and TPM is available >> + if [ $TPM_AVAILABLE -eq 1 ]; then >> + # Check for encryption marker (resume interrupted encryption) >> + if [ -f "${ENCRYPTION_MARKER}" ]; then >> + /usr/bin/busybox echo "Resuming interrupted encryption..." >> + if ! encrypt_root_filesystem; then >> + /usr/bin/busybox echo "ERROR: Failed to resume encryption" >> + /usr/bin/busybox echo "Booting without encryption..." >> + MOUNT_DEV="${ROOT_DEV}" >> + else >> + MOUNT_DEV="${CRYPT_DEV}" >> + fi >> + else >> + # First boot - perform encryption >> + if encrypt_root_filesystem; then >> + MOUNT_DEV="${CRYPT_DEV}" >> + else >> + /usr/bin/busybox echo "ERROR: Encryption failed - booting without encryption" >> + MOUNT_DEV="${ROOT_DEV}" >> + fi >> + fi >> + else >> + /usr/bin/busybox echo "TPM not available - skipping encryption" >> + MOUNT_DEV="${ROOT_DEV}" >> + fi >> +fi >> + >> +# Unmount boot partition before switching root >> +/usr/bin/busybox umount "${BOOT_MNT}" >> + >> +# Mount root filesystem (encrypted or unencrypted) >> +/usr/bin/busybox echo "Mounting root filesystem..." >> +/usr/bin/busybox mkdir -p /newroot >> +/usr/bin/busybox mount "${MOUNT_DEV}" /newroot || { >> + /usr/bin/busybox echo "ERROR: Failed to mount root filesystem!" >> + /usr/bin/busybox sh >> +} >> + >> +/usr/bin/busybox echo "Boot complete" >> + >> +# Clean up tmpfs >> +/usr/bin/busybox rm -f "${TPM_PRIMARY_CTX}" "${TPM_KEY_PUB}" "${TPM_KEY_PRIV}" "${TPM_KEY_CTX}" >> + >> +# Switch to real root >> +exec /usr/sbin/switch_root /newroot /sbin/init > > In general I think this effort is misguided. An initrd is not a replacement for > live image install. We should not be dramatically changing the running system as > part of the first boot. 100% agree. This is something that should be done at build time as part of the image creation. >> diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb >> new file mode 100644 >> index 00000000..7da878f7 >> --- /dev/null >> +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb >> @@ -0,0 +1,30 @@ >> +SUMMARY = "TI encrypted boot initramfs init script" >> +DESCRIPTION = "Custom /init script for encrypted boot with fTPM + LUKS support" >> + >> +LICENSE = "MIT" >> +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" >> + >> +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}/files:" >> +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" >> + >> +SRC_URI = "file://init" >> + >> +S = "${WORKDIR}/sources" >> +UNPACKDIR = "${WORKDIR}" >> + >> +# This recipe must run in the initramfs context >> +inherit allarch >> + >> +do_install() { >> + # Install /init script to root of initramfs >> + install -m 0755 ${UNPACKDIR}/init ${D}/init >> +} >> + >> +# Package the /init file >> +FILES:${PN} = "/init" >> + >> +# Runtime dependencies >> +RDEPENDS:${PN} = "busybox cryptsetup tpm2-tools tpm2-tss optee-client e2fsprogs-e2fsck e2fsprogs-resize2fs util-linux-blkid" >> + >> +# This package must be included in initramfs >> +PACKAGE_ARCH = "${MACHINE_ARCH}" >> diff --git a/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb >> new file mode 100644 >> index 00000000..314499db >> --- /dev/null >> +++ b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb >> @@ -0,0 +1,50 @@ >> +SUMMARY = "TI encrypted boot initramfs image" >> + >> +DESCRIPTION = "Minimal initramfs image with dm-crypt/fTPM support for encrypted root filesystem. \ >> +This initramfs provides LUKS encryption with TPM-sealed keys stored in RPMB." >> + >> +LICENSE = "MIT" >> + >> +# Only build this when luks-encryption feature is enabled >> +COMPATIBLE_MACHINE = "null" >> +COMPATIBLE_MACHINE:k3 = "${@bb.utils.contains('MACHINE_FEATURES', 'luks-encryption', '.*', 'null', d)}" >> + >> +INITRAMFS_FSTYPES = "cpio.gz" >> + >> +IMAGE_NAME = "ti-encrypted-boot-initramfs" >> + >> +export IMAGE_BASENAME = "${IMAGE_NAME}" >> + >> +# Install our custom init script and dependencies >> +PACKAGE_INSTALL = "\ >> + initramfs-ti-encrypted-init \ >> + busybox \ >> + base-passwd \ >> + kmod \ >> + cryptsetup \ >> + tpm2-tools \ >> + tpm2-tss \ >> + libtss2-tcti-device \ >> + optee-client \ >> + util-linux-blkid \ >> + e2fsprogs-e2fsck \ >> + e2fsprogs-resize2fs \ >> + kernel-module-tpm-ftpm-tee \ >> + ${ROOTFS_BOOTSTRAP_INSTALL} \ >> +" >> + >> +# Ensure the initramfs only contains the bare minimum >> +IMAGE_FEATURES = "" >> +IMAGE_LINGUAS = "" >> + >> +# Exclude kernel image from initramfs >> +PACKAGE_EXCLUDE = "kernel-image-*" >> + >> +IMAGE_FSTYPES = "${INITRAMFS_FSTYPES}" >> +IMAGE_NAME_SUFFIX ?= "" >> +IMAGE_ROOTFS_SIZE = "16384" >> +IMAGE_ROOTFS_EXTRA_SPACE = "0" >> + >> +BAD_RECOMMENDATIONS += "busybox-syslog" >> + >> +inherit image >
On 3/3/26 04:10, Ryan Eatmon wrote: > > > On 3/2/2026 4:36 PM, Randolph Sapp wrote: >> On Mon Mar 2, 2026 at 8:46 AM CST, Shiva Tripathi via >> lists.yoctoproject.org wrote: >>> Add ti-encrypted-boot-initramfs for LUKS encryption with TPM-sealed >>> keys. This provides full disk encryption using dm-crypt with keys >>> sealed by firmware TPM (fTPM) running in OP-TEE and stored in eMMC RPMB. >>> >>> The initramfs includes: >>> - Custom init script for in-place LUKS encryption on first boot >>> - TPM key sealing/unsealing using persistent handle 0x81080001 >>> - Support for cryptsetup, tpm2-tools, and OP-TEE client >>> - Automatic filesystem resize after encryption >>> >>> ti-encrypted-boot-initramfs builds when MACHINE_FEATURES contains >>> 'luks-encryption'. >>> >>> Signed-off-by: Shiva Tripathi <s-tripathi1@ti.com> >>> --- >>> .../initramfs-ti-encrypted-init/files/init | 324 ++++++++++++++++++ >>> .../initramfs-ti-encrypted-init_1.0.bb | 30 ++ >>> .../initramfs/ti-encrypted-boot-initramfs.bb | 50 +++ >>> 3 files changed, 404 insertions(+) >>> create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti- >>> encrypted-init/files/init >>> create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti- >>> encrypted-init_1.0.bb >>> create mode 100644 meta-ti-bsp/recipes-ti/initramfs/ti-encrypted- >>> boot-initramfs.bb >>> >>> diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted- >>> init/files/init b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti- >>> encrypted-init/files/init >>> new file mode 100644 >>> index 00000000..6675b6ed >>> --- /dev/null >>> +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/ >>> files/init >>> @@ -0,0 +1,324 @@ >>> +#!/usr/bin/busybox sh >>> +# TI SDK initramfs init script with LUKS2 + fTPM encryption support >>> + >>> +# Mount essential filesystems >>> +/usr/bin/busybox echo "Initializing system..." >>> +/usr/bin/busybox mount -t proc proc /proc >>> +/usr/bin/busybox mount -t sysfs sysfs /sys >>> +/usr/bin/busybox mount -t devtmpfs devtmpfs /dev >>> + >>> +# Configuration >>> +BOOT_DEV="/dev/mmcblk1p1" # Boot partition (FAT, unencrypted) >>> +ROOT_DEV="/dev/mmcblk1p2" # Root partition (will be >>> encrypted) >>> +CRYPT_NAME="root_crypt" >>> +CRYPT_DEV="/dev/mapper/${CRYPT_NAME}" >>> +BOOT_MNT="/boot_part" >>> +TPM_PRIMARY_CTX="/tmp/tpm_primary.ctx" >>> +TPM_KEY_PRIV="/tmp/tpm_key.priv" >>> +TPM_KEY_PUB="/tmp/tpm_key.pub" >>> +TPM_KEY_CTX="/tmp/tpm_key.ctx" >>> +TPM2_HANDLE="0x81080001" # TPM persistent handle for LUKS >>> key >>> +ENCRYPTION_MARKER="${BOOT_MNT}/.encryption_in_progress" >>> + >>> +# Wait for MMC device to appear (up to 10 seconds) >>> +/usr/bin/busybox echo "Waiting for storage device..." >>> +for i in 1 2 3 4 5 6 7 8 9 10; do >>> + if [ -b "${ROOT_DEV}" ]; then >>> + break >>> + fi >>> + /usr/bin/busybox sleep 1 >>> +done >>> + >>> +# Check if root device exists >>> +if [ ! -b "${ROOT_DEV}" ]; then >>> + /usr/bin/busybox echo "ERROR: Storage device not found!" >>> + /usr/bin/busybox sh >>> +fi >>> + >>> +# Mount boot partition >>> +/usr/bin/busybox echo "Mounting boot partition..." >>> +/usr/bin/busybox mkdir -p "${BOOT_MNT}" >>> +if ! /usr/bin/busybox mount "${BOOT_DEV}" "${BOOT_MNT}"; then >>> + /usr/bin/busybox echo "ERROR: Failed to mount boot partition!" >>> + /usr/bin/busybox echo "Attempting standard boot..." >>> + /usr/bin/busybox mkdir -p /newroot >>> + /usr/bin/busybox mount "${ROOT_DEV}" /newroot >>> + exec /usr/sbin/switch_root /newroot /sbin/init >>> +fi >> >> The main boot path should be the error path here, not an arbitrary >> duplication >> of logic. >> >>> + >>> +# Initialize fTPM in OP-TEE >>> +/usr/bin/busybox echo "Initializing secure hardware(fTPM)..." >>> + >>> +# Start TEE supplicant (required for fTPM TA to work) >>> +if [ -x /usr/sbin/tee-supplicant ]; then >>> + /usr/sbin/tee-supplicant -d & >>> + TEE_SUPPLICANT_PID=$! >>> + /usr/bin/busybox sleep 5 >>> +else >>> + /usr/bin/busybox echo "Warning: Trusted execution environment >>> not available" >>> +fi >>> + >>> +# Load fTPM kernel module >>> +if ! /sbin/modprobe tpm_ftpm_tee; then >>> + /usr/bin/busybox echo "Warning: TPM module failed to load" >>> +fi >>> + >>> +# Wait for TPM device (up to 10 seconds) >>> +for i in 1 2 3 4 5 6 7 8 9 10; do >>> + if [ -c /dev/tpmrm0 ]; then >>> + break >>> + fi >>> + /usr/bin/busybox sleep 1 >>> +done >> >> This should be a function who's exit code is use in the below script >> directly >> instead of rechecking if the device is present. >> >>> + >>> +# Check if TPM is available >>> +TPM_AVAILABLE=0 >>> +if [ -c /dev/tpmrm0 ]; then >>> + TPM_AVAILABLE=1 >>> + export TPM2TOOLS_TCTI="device:/dev/tpmrm0" >>> +else >>> + /usr/bin/busybox echo "Warning: fTPM not available - encryption >>> will be skipped" >>> + if [ -n "${TEE_SUPPLICANT_PID}" ]; then >>> + /usr/bin/busybox kill "${TEE_SUPPLICANT_PID}" 2>/dev/null >>> + fi >>> +fi >>> + >>> +# Function: Generate 32-byte random key using TPM RNG >>> +generate_random_key() { >>> + if [ $TPM_AVAILABLE -eq 1 ]; then >>> + /usr/bin/tpm2_getrandom --hex 32 >>> + else >>> + /usr/bin/busybox echo "ERROR: TPM not available for key >>> generation" >>> + return 1 >>> + fi >>> +} >> >> This should probably be reported to the user, or at least they should >> be told >> how to access it during runtime. >> >>> + >>> +# Function: Seal data with TPM and store in persistent handle >>> +tpm_seal_key() { >>> + local KEY_DATA="$1" >>> + >>> + if [ $TPM_AVAILABLE -eq 0 ]; then >>> + /usr/bin/busybox echo "ERROR: TPM not available for sealing" >>> + return 1 >>> + fi >>> + >>> + # Create primary key in owner hierarchy >>> + /usr/bin/tpm2_createprimary -C o -c "${TPM_PRIMARY_CTX}" -Q || >>> return 1 >>> + >>> + # Create sealed object >>> + /usr/bin/busybox echo -n "${KEY_DATA}" | \ >>> + /usr/bin/tpm2_create -C "${TPM_PRIMARY_CTX}" \ >>> + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ >>> + -i- -Q || return 1 >>> + >>> + # Load sealed object into TPM >>> + /usr/bin/tpm2_load -C "${TPM_PRIMARY_CTX}" \ >>> + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ >>> + -c "${TPM_KEY_CTX}" -Q || return 1 >>> + >>> + # Make key persistent at handle (stored in TPM NV RAM - RPMB) >>> + /usr/bin/tpm2_evictcontrol -C o -c "${TPM_KEY_CTX}" >>> "${TPM2_HANDLE}" || return 1 >>> + >>> + return 0 >>> +} >>> + >>> +# Function: Unseal data from TPM persistent handle >>> +tpm_unseal_key() { >>> + if [ $TPM_AVAILABLE -eq 0 ]; then >>> + /usr/bin/busybox echo "ERROR: TPM not available for >>> unsealing" >&2 >>> + return 1 >>> + fi >>> + >>> + # Check if persistent handle exists >>> + if ! /usr/bin/tpm2_getcap handles-persistent | grep -q >>> "${TPM2_HANDLE}"; then >>> + /usr/bin/busybox echo "ERROR: TPM persistent handle not >>> found" >&2 >>> + return 1 >>> + fi >>> + >>> + # Unseal key directly from persistent handle >>> + /usr/bin/tpm2_unseal -c "${TPM2_HANDLE}" || return 1 >>> + >>> + return 0 >>> +} >>> + >>> +# Function: Perform in-place LUKS encryption (first boot) >>> +encrypt_root_filesystem() { >>> + /usr/bin/busybox echo "==========================================" >>> + /usr/bin/busybox echo "First boot: Encrypting root filesystem" >>> + /usr/bin/busybox echo "==========================================" >>> + >>> + # Set marker to track encryption progress >>> + /usr/bin/busybox touch "${ENCRYPTION_MARKER}" >>> + /usr/bin/busybox sync >>> + >>> + # Generate random encryption key using TPM RNG >>> + /usr/bin/busybox echo "Generating encryption key..." >>> + LUKS_KEY=$(generate_random_key) >>> + >>> + if [ -z "${LUKS_KEY}" ]; then >>> + /usr/bin/busybox echo "ERROR: Failed to generate encryption >>> key" >>> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >>> + return 1 >>> + fi >>> + >>> + # Seal key with TPM before encryption starts >>> + /usr/bin/busybox echo "Securing key with TPM..." >>> + if ! tpm_seal_key "${LUKS_KEY}"; then >>> + /usr/bin/busybox echo "ERROR: Failed to secure key" >>> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >>> + return 1 >>> + fi >>> + >>> + # Filesystem check before encryption >>> + /usr/bin/busybox echo "Checking filesystem integrity..." >>> + /usr/sbin/e2fsck -f -y "${ROOT_DEV}" >>> + E2FSCK_RET=$? >>> + if [ ${E2FSCK_RET} -ge 4 ]; then >>> + /usr/bin/busybox echo "ERROR: Filesystem check failed" >>> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >>> + return 1 >>> + fi >>> + >>> + # Shrink filesystem before encryption to leave room for LUKS header >>> + /usr/bin/busybox echo "Preparing filesystem for encryption..." >>> + /usr/sbin/resize2fs "${ROOT_DEV}" 368M || { >> >> Arbitrary size here, prone to failure in the future. Look into the "- >> M" option >> instead. >> >>> + /usr/bin/busybox echo "ERROR: Failed to prepare filesystem" >>> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >>> + return 1 >>> + } >>> + >>> + # Perform in-place encryption >>> + /usr/bin/busybox echo "==========================================" >>> + /usr/bin/busybox echo "Encrypting filesystem..." >>> + /usr/bin/busybox echo "This will take several minutes." >>> + /usr/bin/busybox echo "DO NOT POWER OFF THE DEVICE!" >>> + /usr/bin/busybox echo "==========================================" >>> + >>> + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ >>> + /usr/sbin/cryptsetup reencrypt --encrypt \ >>> + --type luks2 \ >>> + --cipher aes-xts-plain64 \ >>> + --key-size 256 \ >>> + --hash sha256 \ >>> + --reduce-device-size 32M \ >>> + --key-file - \ >>> + "${ROOT_DEV}" || { >>> + /usr/bin/busybox echo "ERROR: Encryption failed" >>> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >>> + return 1 >>> + } >> >> This should only work on partitions that already contain a LUKS >> header. The LUKS >> header is placed in sector 0 of the block device. resize2fs doesn't >> support >> changing the starting position of the filesystem so you will always >> corrupt the >> existing filesystem. It may still be recoverable, but that's not the >> point. This >> is a bad idea. >> >> Additionally, the partition should be overwritten with randomized data >> before >> use to make sure unused blocks look indistinguishable from later >> encrypted data. >> This is not something that can be done using an initramfs without >> external >> storage. >> >>> + >>> + /usr/bin/busybox echo "==========================================" >>> + /usr/bin/busybox echo "Encryption completed successfully!" >>> + /usr/bin/busybox echo "==========================================" >>> + >>> + # Remove encryption marker >>> + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" >>> + /usr/bin/busybox sync >>> + >>> + # Unlock the newly encrypted device >>> + /usr/bin/busybox echo "Activating encrypted filesystem..." >>> + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ >>> + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" >>> --key-file - || { >>> + /usr/bin/busybox echo "ERROR: Failed to activate encrypted >>> filesystem" >>> + return 1 >>> + } >>> + >>> + # Resize filesystem to fit the encrypted device >>> + /usr/bin/busybox echo "Optimizing filesystem..." >>> + /usr/sbin/resize2fs -f "${CRYPT_DEV}" || { >>> + /usr/bin/busybox echo "ERROR: Failed to optimize filesystem" >>> + return 1 >>> + } >>> + >>> + # Verify filesystem after resize >>> + /usr/sbin/e2fsck -f -y "${CRYPT_DEV}" || { >>> + /usr/bin/busybox echo "WARNING: Filesystem verification had >>> issues, but continuing" >>> + } >>> + return 0 >>> +} >>> + >>> +# Function: Unlock encrypted root filesystem (subsequent boots) >>> +unlock_encrypted_root() { >>> + /usr/bin/busybox echo "Unlocking encrypted filesystem..." >>> + >>> + # Unseal key from TPM persistent handle >>> + LUKS_KEY=$(tpm_unseal_key) >>> + >>> + if [ -z "${LUKS_KEY}" ]; then >>> + /usr/bin/busybox echo "ERROR: Failed to retrieve encryption >>> key from TPM" >>> + /usr/bin/busybox echo "Attempting passphrase fallback..." >>> + >>> + # Try to unlock with passphrase (interactive) >>> + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" >>> || { >>> + /usr/bin/busybox echo "ERROR: Failed to unlock encrypted >>> filesystem" >>> + /usr/bin/busybox sh >>> + } >>> + else >>> + # Unlock with unsealed key >>> + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ >>> + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" >>> "${CRYPT_NAME}" --key-file - || { >>> + /usr/bin/busybox echo "ERROR: Failed to unlock with TPM >>> key" >>> + /usr/bin/busybox sh >>> + } >>> + fi >>> + >>> + /usr/bin/busybox echo "Encrypted filesystem unlocked" >>> +} >>> + >>> +# Main boot logic >>> +/usr/bin/busybox echo "Checking filesystem encryption status..." >>> + >>> +# Check if device is LUKS encrypted >>> +if /usr/sbin/cryptsetup isLuks "${ROOT_DEV}"; then >>> + /usr/bin/busybox echo "Filesystem is encrypted" >>> + unlock_encrypted_root >>> + MOUNT_DEV="${CRYPT_DEV}" >>> +else >>> + /usr/bin/busybox echo "Filesystem is not encrypted" >>> + >>> + # Check if encryption is enabled and TPM is available >>> + if [ $TPM_AVAILABLE -eq 1 ]; then >>> + # Check for encryption marker (resume interrupted encryption) >>> + if [ -f "${ENCRYPTION_MARKER}" ]; then >>> + /usr/bin/busybox echo "Resuming interrupted encryption..." >>> + if ! encrypt_root_filesystem; then >>> + /usr/bin/busybox echo "ERROR: Failed to resume >>> encryption" >>> + /usr/bin/busybox echo "Booting without encryption..." >>> + MOUNT_DEV="${ROOT_DEV}" >>> + else >>> + MOUNT_DEV="${CRYPT_DEV}" >>> + fi >>> + else >>> + # First boot - perform encryption >>> + if encrypt_root_filesystem; then >>> + MOUNT_DEV="${CRYPT_DEV}" >>> + else >>> + /usr/bin/busybox echo "ERROR: Encryption failed - >>> booting without encryption" >>> + MOUNT_DEV="${ROOT_DEV}" >>> + fi >>> + fi >>> + else >>> + /usr/bin/busybox echo "TPM not available - skipping encryption" >>> + MOUNT_DEV="${ROOT_DEV}" >>> + fi >>> +fi >>> + >>> +# Unmount boot partition before switching root >>> +/usr/bin/busybox umount "${BOOT_MNT}" >>> + >>> +# Mount root filesystem (encrypted or unencrypted) >>> +/usr/bin/busybox echo "Mounting root filesystem..." >>> +/usr/bin/busybox mkdir -p /newroot >>> +/usr/bin/busybox mount "${MOUNT_DEV}" /newroot || { >>> + /usr/bin/busybox echo "ERROR: Failed to mount root filesystem!" >>> + /usr/bin/busybox sh >>> +} >>> + >>> +/usr/bin/busybox echo "Boot complete" >>> + >>> +# Clean up tmpfs >>> +/usr/bin/busybox rm -f "${TPM_PRIMARY_CTX}" "${TPM_KEY_PUB}" >>> "${TPM_KEY_PRIV}" "${TPM_KEY_CTX}" >>> + >>> +# Switch to real root >>> +exec /usr/sbin/switch_root /newroot /sbin/init >> >> In general I think this effort is misguided. An initrd is not a >> replacement for >> live image install. We should not be dramatically changing the running >> system as >> part of the first boot. > > 100% agree. This is something that should be done at build time as part > of the image creation. > Thanks for the review comments. I'll work on the changes. The current implementation focuses on first boot encryption because that way it's possible to seal encryption keys to TPM persistent handle 0x81080001 via tpm2_evictcontrol. The key becomes device-bound through TPM's internal sealing keys (unique per device) and is stored in the device's RPMB (not on the filesystem). Build-time encryption with TPM-sealed keys is not possible because: - TPM hardware is not available during image build - Each target device has a unique TPM with device-specific sealing keys - RPMB authentication is device-specific The key must be sealed on the actual target device where the TPM exists. CIP Core's initramfs-crypt-hook uses the same approach [1]- first-boot in-place encryption with TPM sealing [1] https://gitlab.com/cip-project/cip-core/isar-cip-core/-/blob/master/doc/README.tpm2.encryption.md#encrypted-partitions Regards, Shiva > >>> diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted- >>> init_1.0.bb b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti- >>> encrypted-init_1.0.bb >>> new file mode 100644 >>> index 00000000..7da878f7 >>> --- /dev/null >>> +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted- >>> init_1.0.bb >>> @@ -0,0 +1,30 @@ >>> +SUMMARY = "TI encrypted boot initramfs init script" >>> +DESCRIPTION = "Custom /init script for encrypted boot with fTPM + >>> LUKS support" >>> + >>> +LICENSE = "MIT" >>> +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/ >>> COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" >>> + >>> +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}/files:" >>> +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" >>> + >>> +SRC_URI = "file://init" >>> + >>> +S = "${WORKDIR}/sources" >>> +UNPACKDIR = "${WORKDIR}" >>> + >>> +# This recipe must run in the initramfs context >>> +inherit allarch >>> + >>> +do_install() { >>> + # Install /init script to root of initramfs >>> + install -m 0755 ${UNPACKDIR}/init ${D}/init >>> +} >>> + >>> +# Package the /init file >>> +FILES:${PN} = "/init" >>> + >>> +# Runtime dependencies >>> +RDEPENDS:${PN} = "busybox cryptsetup tpm2-tools tpm2-tss optee- >>> client e2fsprogs-e2fsck e2fsprogs-resize2fs util-linux-blkid" >>> + >>> +# This package must be included in initramfs >>> +PACKAGE_ARCH = "${MACHINE_ARCH}" >>> diff --git a/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot- >>> initramfs.bb b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot- >>> initramfs.bb >>> new file mode 100644 >>> index 00000000..314499db >>> --- /dev/null >>> +++ b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb >>> @@ -0,0 +1,50 @@ >>> +SUMMARY = "TI encrypted boot initramfs image" >>> + >>> +DESCRIPTION = "Minimal initramfs image with dm-crypt/fTPM support >>> for encrypted root filesystem. \ >>> +This initramfs provides LUKS encryption with TPM-sealed keys stored >>> in RPMB." >>> + >>> +LICENSE = "MIT" >>> + >>> +# Only build this when luks-encryption feature is enabled >>> +COMPATIBLE_MACHINE = "null" >>> +COMPATIBLE_MACHINE:k3 = "${@bb.utils.contains('MACHINE_FEATURES', >>> 'luks-encryption', '.*', 'null', d)}" >>> + >>> +INITRAMFS_FSTYPES = "cpio.gz" >>> + >>> +IMAGE_NAME = "ti-encrypted-boot-initramfs" >>> + >>> +export IMAGE_BASENAME = "${IMAGE_NAME}" >>> + >>> +# Install our custom init script and dependencies >>> +PACKAGE_INSTALL = "\ >>> + initramfs-ti-encrypted-init \ >>> + busybox \ >>> + base-passwd \ >>> + kmod \ >>> + cryptsetup \ >>> + tpm2-tools \ >>> + tpm2-tss \ >>> + libtss2-tcti-device \ >>> + optee-client \ >>> + util-linux-blkid \ >>> + e2fsprogs-e2fsck \ >>> + e2fsprogs-resize2fs \ >>> + kernel-module-tpm-ftpm-tee \ >>> + ${ROOTFS_BOOTSTRAP_INSTALL} \ >>> +" >>> + >>> +# Ensure the initramfs only contains the bare minimum >>> +IMAGE_FEATURES = "" >>> +IMAGE_LINGUAS = "" >>> + >>> +# Exclude kernel image from initramfs >>> +PACKAGE_EXCLUDE = "kernel-image-*" >>> + >>> +IMAGE_FSTYPES = "${INITRAMFS_FSTYPES}" >>> +IMAGE_NAME_SUFFIX ?= "" >>> +IMAGE_ROOTFS_SIZE = "16384" >>> +IMAGE_ROOTFS_EXTRA_SPACE = "0" >>> + >>> +BAD_RECOMMENDATIONS += "busybox-syslog" >>> + >>> +inherit image >> >
diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init new file mode 100644 index 00000000..6675b6ed --- /dev/null +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init @@ -0,0 +1,324 @@ +#!/usr/bin/busybox sh +# TI SDK initramfs init script with LUKS2 + fTPM encryption support + +# Mount essential filesystems +/usr/bin/busybox echo "Initializing system..." +/usr/bin/busybox mount -t proc proc /proc +/usr/bin/busybox mount -t sysfs sysfs /sys +/usr/bin/busybox mount -t devtmpfs devtmpfs /dev + +# Configuration +BOOT_DEV="/dev/mmcblk1p1" # Boot partition (FAT, unencrypted) +ROOT_DEV="/dev/mmcblk1p2" # Root partition (will be encrypted) +CRYPT_NAME="root_crypt" +CRYPT_DEV="/dev/mapper/${CRYPT_NAME}" +BOOT_MNT="/boot_part" +TPM_PRIMARY_CTX="/tmp/tpm_primary.ctx" +TPM_KEY_PRIV="/tmp/tpm_key.priv" +TPM_KEY_PUB="/tmp/tpm_key.pub" +TPM_KEY_CTX="/tmp/tpm_key.ctx" +TPM2_HANDLE="0x81080001" # TPM persistent handle for LUKS key +ENCRYPTION_MARKER="${BOOT_MNT}/.encryption_in_progress" + +# Wait for MMC device to appear (up to 10 seconds) +/usr/bin/busybox echo "Waiting for storage device..." +for i in 1 2 3 4 5 6 7 8 9 10; do + if [ -b "${ROOT_DEV}" ]; then + break + fi + /usr/bin/busybox sleep 1 +done + +# Check if root device exists +if [ ! -b "${ROOT_DEV}" ]; then + /usr/bin/busybox echo "ERROR: Storage device not found!" + /usr/bin/busybox sh +fi + +# Mount boot partition +/usr/bin/busybox echo "Mounting boot partition..." +/usr/bin/busybox mkdir -p "${BOOT_MNT}" +if ! /usr/bin/busybox mount "${BOOT_DEV}" "${BOOT_MNT}"; then + /usr/bin/busybox echo "ERROR: Failed to mount boot partition!" + /usr/bin/busybox echo "Attempting standard boot..." + /usr/bin/busybox mkdir -p /newroot + /usr/bin/busybox mount "${ROOT_DEV}" /newroot + exec /usr/sbin/switch_root /newroot /sbin/init +fi + +# Initialize fTPM in OP-TEE +/usr/bin/busybox echo "Initializing secure hardware(fTPM)..." + +# Start TEE supplicant (required for fTPM TA to work) +if [ -x /usr/sbin/tee-supplicant ]; then + /usr/sbin/tee-supplicant -d & + TEE_SUPPLICANT_PID=$! + /usr/bin/busybox sleep 5 +else + /usr/bin/busybox echo "Warning: Trusted execution environment not available" +fi + +# Load fTPM kernel module +if ! /sbin/modprobe tpm_ftpm_tee; then + /usr/bin/busybox echo "Warning: TPM module failed to load" +fi + +# Wait for TPM device (up to 10 seconds) +for i in 1 2 3 4 5 6 7 8 9 10; do + if [ -c /dev/tpmrm0 ]; then + break + fi + /usr/bin/busybox sleep 1 +done + +# Check if TPM is available +TPM_AVAILABLE=0 +if [ -c /dev/tpmrm0 ]; then + TPM_AVAILABLE=1 + export TPM2TOOLS_TCTI="device:/dev/tpmrm0" +else + /usr/bin/busybox echo "Warning: fTPM not available - encryption will be skipped" + if [ -n "${TEE_SUPPLICANT_PID}" ]; then + /usr/bin/busybox kill "${TEE_SUPPLICANT_PID}" 2>/dev/null + fi +fi + +# Function: Generate 32-byte random key using TPM RNG +generate_random_key() { + if [ $TPM_AVAILABLE -eq 1 ]; then + /usr/bin/tpm2_getrandom --hex 32 + else + /usr/bin/busybox echo "ERROR: TPM not available for key generation" + return 1 + fi +} + +# Function: Seal data with TPM and store in persistent handle +tpm_seal_key() { + local KEY_DATA="$1" + + if [ $TPM_AVAILABLE -eq 0 ]; then + /usr/bin/busybox echo "ERROR: TPM not available for sealing" + return 1 + fi + + # Create primary key in owner hierarchy + /usr/bin/tpm2_createprimary -C o -c "${TPM_PRIMARY_CTX}" -Q || return 1 + + # Create sealed object + /usr/bin/busybox echo -n "${KEY_DATA}" | \ + /usr/bin/tpm2_create -C "${TPM_PRIMARY_CTX}" \ + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ + -i- -Q || return 1 + + # Load sealed object into TPM + /usr/bin/tpm2_load -C "${TPM_PRIMARY_CTX}" \ + -u "${TPM_KEY_PUB}" -r "${TPM_KEY_PRIV}" \ + -c "${TPM_KEY_CTX}" -Q || return 1 + + # Make key persistent at handle (stored in TPM NV RAM - RPMB) + /usr/bin/tpm2_evictcontrol -C o -c "${TPM_KEY_CTX}" "${TPM2_HANDLE}" || return 1 + + return 0 +} + +# Function: Unseal data from TPM persistent handle +tpm_unseal_key() { + if [ $TPM_AVAILABLE -eq 0 ]; then + /usr/bin/busybox echo "ERROR: TPM not available for unsealing" >&2 + return 1 + fi + + # Check if persistent handle exists + if ! /usr/bin/tpm2_getcap handles-persistent | grep -q "${TPM2_HANDLE}"; then + /usr/bin/busybox echo "ERROR: TPM persistent handle not found" >&2 + return 1 + fi + + # Unseal key directly from persistent handle + /usr/bin/tpm2_unseal -c "${TPM2_HANDLE}" || return 1 + + return 0 +} + +# Function: Perform in-place LUKS encryption (first boot) +encrypt_root_filesystem() { + /usr/bin/busybox echo "==========================================" + /usr/bin/busybox echo "First boot: Encrypting root filesystem" + /usr/bin/busybox echo "==========================================" + + # Set marker to track encryption progress + /usr/bin/busybox touch "${ENCRYPTION_MARKER}" + /usr/bin/busybox sync + + # Generate random encryption key using TPM RNG + /usr/bin/busybox echo "Generating encryption key..." + LUKS_KEY=$(generate_random_key) + + if [ -z "${LUKS_KEY}" ]; then + /usr/bin/busybox echo "ERROR: Failed to generate encryption key" + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" + return 1 + fi + + # Seal key with TPM before encryption starts + /usr/bin/busybox echo "Securing key with TPM..." + if ! tpm_seal_key "${LUKS_KEY}"; then + /usr/bin/busybox echo "ERROR: Failed to secure key" + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" + return 1 + fi + + # Filesystem check before encryption + /usr/bin/busybox echo "Checking filesystem integrity..." + /usr/sbin/e2fsck -f -y "${ROOT_DEV}" + E2FSCK_RET=$? + if [ ${E2FSCK_RET} -ge 4 ]; then + /usr/bin/busybox echo "ERROR: Filesystem check failed" + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" + return 1 + fi + + # Shrink filesystem before encryption to leave room for LUKS header + /usr/bin/busybox echo "Preparing filesystem for encryption..." + /usr/sbin/resize2fs "${ROOT_DEV}" 368M || { + /usr/bin/busybox echo "ERROR: Failed to prepare filesystem" + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" + return 1 + } + + # Perform in-place encryption + /usr/bin/busybox echo "==========================================" + /usr/bin/busybox echo "Encrypting filesystem..." + /usr/bin/busybox echo "This will take several minutes." + /usr/bin/busybox echo "DO NOT POWER OFF THE DEVICE!" + /usr/bin/busybox echo "==========================================" + + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ + /usr/sbin/cryptsetup reencrypt --encrypt \ + --type luks2 \ + --cipher aes-xts-plain64 \ + --key-size 256 \ + --hash sha256 \ + --reduce-device-size 32M \ + --key-file - \ + "${ROOT_DEV}" || { + /usr/bin/busybox echo "ERROR: Encryption failed" + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" + return 1 + } + + /usr/bin/busybox echo "==========================================" + /usr/bin/busybox echo "Encryption completed successfully!" + /usr/bin/busybox echo "==========================================" + + # Remove encryption marker + /usr/bin/busybox rm -f "${ENCRYPTION_MARKER}" + /usr/bin/busybox sync + + # Unlock the newly encrypted device + /usr/bin/busybox echo "Activating encrypted filesystem..." + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { + /usr/bin/busybox echo "ERROR: Failed to activate encrypted filesystem" + return 1 + } + + # Resize filesystem to fit the encrypted device + /usr/bin/busybox echo "Optimizing filesystem..." + /usr/sbin/resize2fs -f "${CRYPT_DEV}" || { + /usr/bin/busybox echo "ERROR: Failed to optimize filesystem" + return 1 + } + + # Verify filesystem after resize + /usr/sbin/e2fsck -f -y "${CRYPT_DEV}" || { + /usr/bin/busybox echo "WARNING: Filesystem verification had issues, but continuing" + } + return 0 +} + +# Function: Unlock encrypted root filesystem (subsequent boots) +unlock_encrypted_root() { + /usr/bin/busybox echo "Unlocking encrypted filesystem..." + + # Unseal key from TPM persistent handle + LUKS_KEY=$(tpm_unseal_key) + + if [ -z "${LUKS_KEY}" ]; then + /usr/bin/busybox echo "ERROR: Failed to retrieve encryption key from TPM" + /usr/bin/busybox echo "Attempting passphrase fallback..." + + # Try to unlock with passphrase (interactive) + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" || { + /usr/bin/busybox echo "ERROR: Failed to unlock encrypted filesystem" + /usr/bin/busybox sh + } + else + # Unlock with unsealed key + /usr/bin/busybox echo -n "${LUKS_KEY}" | \ + /usr/sbin/cryptsetup luksOpen "${ROOT_DEV}" "${CRYPT_NAME}" --key-file - || { + /usr/bin/busybox echo "ERROR: Failed to unlock with TPM key" + /usr/bin/busybox sh + } + fi + + /usr/bin/busybox echo "Encrypted filesystem unlocked" +} + +# Main boot logic +/usr/bin/busybox echo "Checking filesystem encryption status..." + +# Check if device is LUKS encrypted +if /usr/sbin/cryptsetup isLuks "${ROOT_DEV}"; then + /usr/bin/busybox echo "Filesystem is encrypted" + unlock_encrypted_root + MOUNT_DEV="${CRYPT_DEV}" +else + /usr/bin/busybox echo "Filesystem is not encrypted" + + # Check if encryption is enabled and TPM is available + if [ $TPM_AVAILABLE -eq 1 ]; then + # Check for encryption marker (resume interrupted encryption) + if [ -f "${ENCRYPTION_MARKER}" ]; then + /usr/bin/busybox echo "Resuming interrupted encryption..." + if ! encrypt_root_filesystem; then + /usr/bin/busybox echo "ERROR: Failed to resume encryption" + /usr/bin/busybox echo "Booting without encryption..." + MOUNT_DEV="${ROOT_DEV}" + else + MOUNT_DEV="${CRYPT_DEV}" + fi + else + # First boot - perform encryption + if encrypt_root_filesystem; then + MOUNT_DEV="${CRYPT_DEV}" + else + /usr/bin/busybox echo "ERROR: Encryption failed - booting without encryption" + MOUNT_DEV="${ROOT_DEV}" + fi + fi + else + /usr/bin/busybox echo "TPM not available - skipping encryption" + MOUNT_DEV="${ROOT_DEV}" + fi +fi + +# Unmount boot partition before switching root +/usr/bin/busybox umount "${BOOT_MNT}" + +# Mount root filesystem (encrypted or unencrypted) +/usr/bin/busybox echo "Mounting root filesystem..." +/usr/bin/busybox mkdir -p /newroot +/usr/bin/busybox mount "${MOUNT_DEV}" /newroot || { + /usr/bin/busybox echo "ERROR: Failed to mount root filesystem!" + /usr/bin/busybox sh +} + +/usr/bin/busybox echo "Boot complete" + +# Clean up tmpfs +/usr/bin/busybox rm -f "${TPM_PRIMARY_CTX}" "${TPM_KEY_PUB}" "${TPM_KEY_PRIV}" "${TPM_KEY_CTX}" + +# Switch to real root +exec /usr/sbin/switch_root /newroot /sbin/init diff --git a/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb new file mode 100644 index 00000000..7da878f7 --- /dev/null +++ b/meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb @@ -0,0 +1,30 @@ +SUMMARY = "TI encrypted boot initramfs init script" +DESCRIPTION = "Custom /init script for encrypted boot with fTPM + LUKS support" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}/files:" +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" + +SRC_URI = "file://init" + +S = "${WORKDIR}/sources" +UNPACKDIR = "${WORKDIR}" + +# This recipe must run in the initramfs context +inherit allarch + +do_install() { + # Install /init script to root of initramfs + install -m 0755 ${UNPACKDIR}/init ${D}/init +} + +# Package the /init file +FILES:${PN} = "/init" + +# Runtime dependencies +RDEPENDS:${PN} = "busybox cryptsetup tpm2-tools tpm2-tss optee-client e2fsprogs-e2fsck e2fsprogs-resize2fs util-linux-blkid" + +# This package must be included in initramfs +PACKAGE_ARCH = "${MACHINE_ARCH}" diff --git a/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb new file mode 100644 index 00000000..314499db --- /dev/null +++ b/meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb @@ -0,0 +1,50 @@ +SUMMARY = "TI encrypted boot initramfs image" + +DESCRIPTION = "Minimal initramfs image with dm-crypt/fTPM support for encrypted root filesystem. \ +This initramfs provides LUKS encryption with TPM-sealed keys stored in RPMB." + +LICENSE = "MIT" + +# Only build this when luks-encryption feature is enabled +COMPATIBLE_MACHINE = "null" +COMPATIBLE_MACHINE:k3 = "${@bb.utils.contains('MACHINE_FEATURES', 'luks-encryption', '.*', 'null', d)}" + +INITRAMFS_FSTYPES = "cpio.gz" + +IMAGE_NAME = "ti-encrypted-boot-initramfs" + +export IMAGE_BASENAME = "${IMAGE_NAME}" + +# Install our custom init script and dependencies +PACKAGE_INSTALL = "\ + initramfs-ti-encrypted-init \ + busybox \ + base-passwd \ + kmod \ + cryptsetup \ + tpm2-tools \ + tpm2-tss \ + libtss2-tcti-device \ + optee-client \ + util-linux-blkid \ + e2fsprogs-e2fsck \ + e2fsprogs-resize2fs \ + kernel-module-tpm-ftpm-tee \ + ${ROOTFS_BOOTSTRAP_INSTALL} \ +" + +# Ensure the initramfs only contains the bare minimum +IMAGE_FEATURES = "" +IMAGE_LINGUAS = "" + +# Exclude kernel image from initramfs +PACKAGE_EXCLUDE = "kernel-image-*" + +IMAGE_FSTYPES = "${INITRAMFS_FSTYPES}" +IMAGE_NAME_SUFFIX ?= "" +IMAGE_ROOTFS_SIZE = "16384" +IMAGE_ROOTFS_EXTRA_SPACE = "0" + +BAD_RECOMMENDATIONS += "busybox-syslog" + +inherit image
Add ti-encrypted-boot-initramfs for LUKS encryption with TPM-sealed keys. This provides full disk encryption using dm-crypt with keys sealed by firmware TPM (fTPM) running in OP-TEE and stored in eMMC RPMB. The initramfs includes: - Custom init script for in-place LUKS encryption on first boot - TPM key sealing/unsealing using persistent handle 0x81080001 - Support for cryptsetup, tpm2-tools, and OP-TEE client - Automatic filesystem resize after encryption ti-encrypted-boot-initramfs builds when MACHINE_FEATURES contains 'luks-encryption'. Signed-off-by: Shiva Tripathi <s-tripathi1@ti.com> --- .../initramfs-ti-encrypted-init/files/init | 324 ++++++++++++++++++ .../initramfs-ti-encrypted-init_1.0.bb | 30 ++ .../initramfs/ti-encrypted-boot-initramfs.bb | 50 +++ 3 files changed, 404 insertions(+) create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init/files/init create mode 100644 meta-ti-bsp/recipes-ti/initramfs/initramfs-ti-encrypted-init_1.0.bb create mode 100644 meta-ti-bsp/recipes-ti/initramfs/ti-encrypted-boot-initramfs.bb