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 <[email protected]> --- .../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/21656 Group Owner: [email protected] Unsubscribe: https://lists.yoctoproject.org/g/meta-ti/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
