From b1800736af5ad1ac24c70d6db144f9b176dbca29 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Thu, 13 Mar 2025 16:13:12 +0100 Subject: [PATCH] trustfence: update support to STM platforms and integrate CCMP2 This commit updates secure boot support based on the STM32 MPU Ecosystem v6.0 and integrates support for the ConnectCore MP2 platform. https://onedigi.atlassian.net/browse/DEL-9442 Signed-off-by: Arturo Buzarra --- .../fip-stm32mp/fip-stm32mp.bbappend | 11 ++++ .../tf-a-stm32mp_2.10.bbappend | 53 ++++++------------- .../trustfence-gen-pki-stm.sh | 11 ++-- .../trustfence-sign-artifact-stm.sh | 32 +++++++---- meta-digi-dey/classes/trustfence.bbclass | 31 ++++++----- .../trustfence/trustfence-initramfs.bb | 2 +- 6 files changed, 66 insertions(+), 74 deletions(-) diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/fip-stm32mp/fip-stm32mp.bbappend b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/fip-stm32mp/fip-stm32mp.bbappend index 8601ff512..6f9ccebd0 100644 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/fip-stm32mp/fip-stm32mp.bbappend +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/fip-stm32mp/fip-stm32mp.bbappend @@ -7,6 +7,17 @@ STM32MP_DEVICETREE_USB = " ${@' '.join('%s' % dt_file for dt_file in list(dict.f FIP_CONFIG[optee-usb] ?= "optee,${STM32MP_DEVICETREE_USB},default:optee,usb" FIP_CONFIG += "${@bb.utils.contains('BOOTSCHEME_LABELS', 'optee', bb.utils.contains('BOOTDEVICE_LABELS', 'usb', 'optee-usb', '', d), '', d)}" +# Obtain password to use in FIP generation +# Get password from file using the given key index +do_deploy[prefuncs] += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'set_fip_sign_key', '', d)}" +python set_fip_sign_key() { + passfile = d.getVar('TRUSTFENCE_PASSWORD_FILE') + if (os.path.isfile(passfile)): + with open(passfile, "r") as file: + p = file.read().strip() + if (p): + d.setVar('SIGN_KEY_PASS', p) +} # Addons parameters for FIP_WRAPPER FIP_SOC_SEARCH ?= "" FIP_SOC_SEARCH:ccmp2 ?= " stm32mp25 " diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.10.bbappend b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.10.bbappend index cb1c39ec7..f0d968c09 100644 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.10.bbappend +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.10.bbappend @@ -14,6 +14,13 @@ SRC_URI = " \ ${TFA_GIT_URI};branch=${SRCBRANCH} \ " +# stm32mp15 = header-version 1 +SIGN_TOOL_EXTRA_soc:ccmp15 = " ${@bb.utils.contains('ENCRYPT_ENABLE', '1', '-of ${TF_A_ENCRYPT_OF}', '', d)}" +# stm32mp13 = header-version 2 +SIGN_TOOL_EXTRA_soc:ccmp13 = " ${@bb.utils.contains('ENCRYPT_ENABLE', '1', '-of ${TF_A_ENCRYPT_OF}', '-of ${TF_A_SIGN_OF}', d)}" +# stm32mp2 = header-version 2.2 +SIGN_TOOL_EXTRA_soc:stm32mp2common = " --header-version 2.2 ${@bb.utils.contains('ENCRYPT_ENABLE', '1', '-of ${TF_A_ENCRYPT_OF}', '-of ${TF_A_SIGN_OF}', d)}" + TF_A_CONFIG[nand] = "${DEVICE_BOARD_ENABLE:NAND},STM32MP_RAW_NAND=1 ${@'STM32MP_FORCE_MTD_START_OFFSET=${TF_A_MTD_START_OFFSET_NAND}' if ${TF_A_MTD_START_OFFSET_NAND} else ''} STM32MP_USB_PROGRAMMER=1" # TF_A_CONFIG[uart] (same as 'optee-programmer-uart') TF_A_CONFIG[uart] ?= "\ @@ -43,24 +50,25 @@ do_install[depends] = " \ " # Generate PKI tree if it doesn't exist. -# This is an append to do_compile because in this recipe, the do_deploy -# task comes right after do_compile, and the keys must be ready before that. -do_compile:append() { +# This is an prepend to do_compile because in this recipe, the keys +# must be ready before that. +do_generate_pki_tree() { if ${@oe.utils.conditional('TRUSTFENCE_SIGN','1','true','false',d)}; then check_gen_pki_tree fi } +addtask generate_pki_tree before do_compile after do_configure -# Obtain password to use in FIP generation +# Obtain password to use in TF-A generation # Get password from file using the given key index -do_deploy[prefuncs] += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'set_fip_sign_key', '', d)}" -python set_fip_sign_key() { +do_compile[prefuncs] += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'set_tfa_sign_key', '', d)}" +python set_tfa_sign_key() { passfile = d.getVar('TRUSTFENCE_PASSWORD_FILE') if (os.path.isfile(passfile)): with open(passfile, "r") as file: p = file.read().strip() if (p): - d.setVar('FIP_SIGN_KEY_PASS', p) + d.setVar('SIGN_KEY_PASS', p) } # This runs after 'tf_a_sysroot_populate()' which populates all @@ -96,34 +104,3 @@ deploy_symlinks_atf() { fi } SYSROOT_PREPROCESS_FUNCS += "deploy_symlinks_atf" - -# Sign TF-A image -do_deploy[postfuncs] += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'tfa_sign', '', d)}" -tfa_sign() { - export CONFIG_SIGN_KEYS_PATH="${TRUSTFENCE_SIGN_KEYS_PATH}" - export CONFIG_KEY_INDEX="${TRUSTFENCE_KEY_INDEX}" - - unset i - for config in ${TF_A_CONFIG}; do - i=$(expr $i + 1) - # Initialize devicetree list and tf-a basename - dt_config=$(echo ${TF_A_DEVICETREE} | cut -d',' -f${i}) - tfa_basename=$(echo ${TF_A_BINARIES} | cut -d',' -f${i}) - tfa_file_type=$(echo ${TF_A_FILES} | cut -d',' -f${i}) - for dt in ${dt_config}; do - for file_type in ${tfa_file_type}; do - case "${file_type}" in - bl2) - TF_A_FILENAME="${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" - if [ -f "${DEPLOYDIR}/arm-trusted-firmware/${TF_A_FILENAME}" ]; then - trustfence-sign-artifact.sh -p "${DIGI_SOM}" -t "${DEPLOYDIR}/arm-trusted-firmware/${TF_A_FILENAME}" "${DEPLOYDIR}/arm-trusted-firmware/${TF_A_FILENAME}${TFA_SIGN_SUFFIX}" - # the generated artifact lacks 'w' permission which prevents deletion by the build system - chmod u+w "${DEPLOYDIR}/arm-trusted-firmware/${TF_A_FILENAME}${TFA_SIGN_SUFFIX}" - # symlink TF-A - ln -s "arm-trusted-firmware/${TF_A_FILENAME}${TFA_SIGN_SUFFIX}" "${DEPLOYDIR}/" - fi - esac - done # for file_type in ${tfa_file_type} - done # for dt in ${dt_config} - done # for config in ${TF_A_CONFIG} -} diff --git a/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-gen-pki-stm.sh b/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-gen-pki-stm.sh index 0fcb54aa5..7dcccee17 100755 --- a/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-gen-pki-stm.sh +++ b/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-gen-pki-stm.sh @@ -3,7 +3,7 @@ # # trustfence-gen-pki-stm.sh # -# Copyright (C) 2023 by Digi International Inc. +# Copyright (C) 2023,2025 by Digi International Inc. # All rights reserved. # # This program is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ while ! mkdir "${SINGLE_PROCESS_LOCK}" > /dev/null 2>&1; do done SCRIPT_NAME="$(basename "${0}")" -SUPPORTED_PLATFORMS="ccmp15, ccmp13" while getopts "p:" c; do case "${c}" in @@ -39,9 +38,8 @@ usage() { Usage: ${SCRIPT_NAME} Options: - -p platform + -p platform (such as ccmp15, ccmp13, ccmp25...) -Supported platforms: ${SUPPORTED_PLATFORMS} EOF } @@ -73,7 +71,7 @@ if [ "${PLATFORM}" = "ccmp15" ]; then echo "${password}" > "${KEY_PASS_FILE}" chmod 400 "${KEY_PASS_FILE}" fi -elif [ "${PLATFORM}" = "ccmp13" ]; then +else if [ "${N_PUBK}" = "8" ] && [ "${N_PRVK}" = "8" ] && [ "${N_PASS}" = "8" ]; then # PKI tree already exists. echo "Using existing PKI tree" @@ -102,7 +100,4 @@ elif [ "${PLATFORM}" = "ccmp13" ]; then echo "[ERROR] Could not generate PKI tree. An incomplete PKI tree may already exist." exit 1 fi -else - echo "Undefined platform" - exit 1 fi diff --git a/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact-stm.sh b/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact-stm.sh index 52f853c78..4868cb7bd 100755 --- a/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact-stm.sh +++ b/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact-stm.sh @@ -3,7 +3,7 @@ # # trustfence-sign-artifact.sh # -# Copyright (C) 2023 by Digi International Inc. +# Copyright (C) 2023,2025 by Digi International Inc. # All rights reserved. # # This program is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ while ! mkdir "${SINGLE_PROCESS_LOCK}" > /dev/null 2>&1; do done SCRIPT_NAME="$(basename "${0}")" -SUPPORTED_PLATFORMS="ccmp15, ccmp13" while getopts "p:t" c; do case "${c}" in @@ -42,11 +41,9 @@ usage() { Usage: ${SCRIPT_NAME} [ ] Options: - -p platform + -p platform (such as ccmp15, ccmp13, ccmp25...) -t sign/encrypt TF-A artifact -Supported platforms: ${SUPPORTED_PLATFORMS} - EOF } @@ -72,10 +69,11 @@ if [ "${PLATFORM}" = "ccmp15" ]; then KEY_PASS_FILE="${CONFIG_SIGN_KEYS_PATH}/keys/key_pass.txt" PUBLIC_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/publicKey.pem" PRIVATE_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/privateKey.pem" -elif [ "${PLATFORM}" = "ccmp13" ]; then +else KEY_PASS_FILE="${CONFIG_SIGN_KEYS_PATH}/keys/key_pass0${CONFIG_KEY_INDEX}.txt" PUBLIC_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/publicKey0*.pem" PRIVATE_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/privateKey0${CONFIG_KEY_INDEX}.pem" + TF_A_SIGN_OF="0x00000001" else echo "Undefined platform" exit 1 @@ -95,11 +93,23 @@ PASS=$(cat "${KEY_PASS_FILE}") # Sign TF-A artifact if [ "${ARTIFACT_TFA}" = "y" ]; then - if [ "${PLATFORM}" = "ccmp15" ]; then - SOC_OPTIONS="-hv 1" - elif [ "${PLATFORM}" = "ccmp13" ]; then - SOC_OPTIONS="-hv 2 -of 0x00000001" - fi + case "${PLATFORM}" in + ccmp15) + SOC_OPTIONS="-hv 1" + ;; + ccmp13) + SOC_OPTIONS="-hv 2 -of ${TF_A_SIGN_OF}" + ;; + ccmp2*) + SOC_OPTIONS="-hv 2.2 -of ${TF_A_SIGN_OF}" + ;; + *) + echo "Error: Undefined platform: ${PLATFORM}" + usage + exit 1 + ;; + esac + STM32MP_SigningTool_CLI -bin ${INPUT_FILE} \ --public-key ${PUBLIC_KEY} \ --private-key ${PRIVATE_KEY} \ diff --git a/meta-digi-dey/classes/trustfence.bbclass b/meta-digi-dey/classes/trustfence.bbclass index 109339e6b..b0761d066 100644 --- a/meta-digi-dey/classes/trustfence.bbclass +++ b/meta-digi-dey/classes/trustfence.bbclass @@ -23,15 +23,19 @@ TRUSTFENCE_SRK_REVOKE_MASK ?= "0x0" TRUSTFENCE_KEY_INDEX ?= "0" TRUSTFENCE_SIGN_ARTIFACTS = "1" TRUSTFENCE_SIGN_ARTIFACTS:ccmp1 = "0" +TRUSTFENCE_SIGN_ARTIFACTS:ccmp2 = "0" TRUSTFENCE_SIGN_FIT_STM:ccmp1 ?= "1" +TRUSTFENCE_SIGN_FIT_STM:ccmp2 ?= "1" # Partition encryption configuration TRUSTFENCE_ENCRYPT_PARTITIONS ?= "1" TRUSTFENCE_ENCRYPT_PARTITIONS:ccimx9 ?= "0" TRUSTFENCE_ENCRYPT_PARTITIONS:ccmp1 ?= "0" +TRUSTFENCE_ENCRYPT_PARTITIONS:ccmp2 ?= "0" TRUSTFENCE_ENCRYPT_ROOTFS ?= "${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", "0", "1", d)}" TRUSTFENCE_ENCRYPT_ROOTFS:ccimx9 ?= "0" TRUSTFENCE_ENCRYPT_ROOTFS:ccmp1 ?= "0" +TRUSTFENCE_ENCRYPT_ROOTFS:ccmp2 ?= "0" TRUSTFENCE_FILE_BASED_ENCRYPT ?= "${TF_FILE_BASED_ENCRYPT}" # Read-only rootfs @@ -45,9 +49,11 @@ TRUSTFENCE_READ_ONLY_ROOTFS ?= "${@bb.utils.contains("IMAGE_FEATURES", "read-onl TF_DEK_PATH = "default" TF_DEK_PATH:ccimx9 = "0" TF_DEK_PATH:ccmp1 = "0" +TF_DEK_PATH:ccmp2 = "0" TF_FILE_BASED_ENCRYPT = "0" TF_FILE_BASED_ENCRYPT:ccimx9 = "1" TF_FILE_BASED_ENCRYPT:ccmp1 = "1" +TF_FILE_BASED_ENCRYPT:ccmp2 = "1" # NXP-based sign a FIT-format boot artifact TRUSTFENCE_SIGN_FIT_NXP = "0" @@ -125,11 +131,8 @@ copy_public_key() { elif [ "${DEY_SOC_VENDOR}" = "STM" ]; then if [ "${DIGI_SOM}" = "ccmp15" ]; then PUBLIC_KEY="${TRUSTFENCE_SIGN_KEYS_PATH}/keys/publicKey.pem" - elif [ "${DIGI_SOM}" = "ccmp13" ]; then - PUBLIC_KEY="${TRUSTFENCE_SIGN_KEYS_PATH}/keys/publicKey0${TRUSTFENCE_KEY_INDEX}.pem" else - bberror "Unknown DIGI_SOM" - exit 1 + PUBLIC_KEY="${TRUSTFENCE_SIGN_KEYS_PATH}/keys/publicKey0${TRUSTFENCE_KEY_INDEX}.pem" fi else echo "ERROR: Cannot determine the public key" @@ -171,24 +174,20 @@ python () { if (d.getVar("DEY_SOC_VENDOR") == "NXP"): if (d.getVar("TRUSTFENCE_DEK_PATH") == "default"): d.setVar("TRUSTFENCE_DEK_PATH", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "/dek.bin"); - elif (d.getVar("DEY_SOC_VENDOR") == "STM"): - # Enable authentication capabilities on TF-A independently - # of whether the images are going to be signed by DEY or externally - d.setVar("TF_A_SIGN_ENABLE", "1") - if (d.getVar("TRUSTFENCE_SIGN") == "0"): - d.setVar("FIP_SIGN_ENABLE", "0") if (d.getVar("TRUSTFENCE_SIGN") == "1"): # Set STM-specific variables for signing images if (d.getVar("DEY_SOC_VENDOR") == "STM"): - d.setVar("FIP_SIGN_ENABLE", "1") - d.setVar("FIP_SIGN_KEY_EXTERNAL", "1") + d.setVar("SIGN_ENABLE", "1") + d.setVar("EXTERNAL_KEY_CONF", "1") + d.setVar("SIGN_TOOL", "STM32MP_SigningTool_CLI") if (d.getVar("DIGI_SOM") == "ccmp15" ): - d.setVar("FIP_SIGN_KEY", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "/keys/privateKey.pem"); + d.setVar("SIGN_KEY", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "/keys/privateKey.pem"); d.setVar("TRUSTFENCE_PASSWORD_FILE", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "/keys/key_pass.txt") - elif (d.getVar("DIGI_SOM") == "ccmp13" ): - d.setVar("FIP_SIGN_KEY", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "/keys/privateKey0%s.pem" % d.getVar("TRUSTFENCE_KEY_INDEX")); + else: + d.setVar("SIGN_KEY", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "/keys/privateKey0%s.pem" % d.getVar("TRUSTFENCE_KEY_INDEX")); d.setVar("TRUSTFENCE_PASSWORD_FILE", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "/keys/key_pass0%s.txt" % d.getVar("TRUSTFENCE_KEY_INDEX")) + d.setVar("SIGN_KEY_%s" % (d.getVar("STM32MP_SOC_NAME").strip()), d.getVar("SIGN_KEY")); d.appendVar("UBOOT_TF_CONF", "CONFIG_SIGN_IMAGE=y ") if (d.getVar("TRUSTFENCE_SIGN_ARTIFACTS") == "1"): @@ -265,7 +264,7 @@ python () { # Set the key password. if (d.getVar("DIGI_SOM") == "ccmp15"): d.setVar("SWUPDATE_PASSWORD_FILE", keys_path + "/keys/key_pass.txt") - elif (d.getVar("DIGI_SOM") == "ccmp13"): + else: d.setVar("SWUPDATE_PASSWORD_FILE", keys_path + "/keys/key_pass0" + str(key_index) + ".txt") # Enable partition encryption if rootfs encryption is enabled diff --git a/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs.bb b/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs.bb index 18526acf7..ff1c76cf9 100644 --- a/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs.bb +++ b/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs.bb @@ -26,4 +26,4 @@ RDEPENDS:${PN} = " \ " PACKAGE_ARCH = "${MACHINE_ARCH}" -COMPATIBLE_MACHINE = "(ccimx6|ccimx8m|ccimx8x|ccimx9)" +COMPATIBLE_MACHINE = "(ccimx6|ccimx8m|ccimx8x|ccimx9|ccmp25)"