From 3e5cf0c6e6288ac2194c6c468de3db04ee198578 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Wed, 1 Oct 2025 12:50:15 +0200 Subject: [PATCH] trustfence: add signed and encrypted firmware support for Cortex-M on STM platforms Adds support for signing and encrypting Cortex-M firmware on STM platforms, following the STM32 MPU Ecosystem v6.1.0. This update enables secure boot of co-processor binaries on ConnectCore MP2, enhancing firmware protection. Signed-off-by: Arturo Buzarra --- meta-digi-arm/conf/machine/include/ccmp2.inc | 4 -- .../m33projects-stm32mp2.bbappend | 12 ++++++ .../trustfence-gen-pki-stm.sh | 43 +++++++++++++++++++ meta-digi-dey/classes/trustfence.bbclass | 10 +++++ 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/meta-digi-arm/conf/machine/include/ccmp2.inc b/meta-digi-arm/conf/machine/include/ccmp2.inc index 74bffae44..2b3a582db 100644 --- a/meta-digi-arm/conf/machine/include/ccmp2.inc +++ b/meta-digi-arm/conf/machine/include/ccmp2.inc @@ -108,10 +108,6 @@ ENCRYPT_SUFFIX ?= "_Encrypted" SIGN_ENABLE ?= "0" SIGN_SUFFIX ?= "_Signed" -# Disable signature of coprocessor firmware -SIGN_COPRO_ENABLE = "0" -# Disable encryption of coprocessor firmware -ENCRYPT_COPRO_ENABLE = "0" # ========================================================================= # Debug trace diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-extended/stm32mp2projects/m33projects-stm32mp2.bbappend b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-extended/stm32mp2projects/m33projects-stm32mp2.bbappend index 192656b73..ad26a9273 100644 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-extended/stm32mp2projects/m33projects-stm32mp2.bbappend +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-extended/stm32mp2projects/m33projects-stm32mp2.bbappend @@ -4,3 +4,15 @@ # Inherit custom DIGI sign class to skip signing tool and key parsing restrictions inherit sign-stm32mp-digi + +# Obtain password to use in m33 generation +# Get password from file using the given key index +do_compile[prefuncs] += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'set_m33_sign_key', '', d)}" +python set_m33_sign_key() { + passfile = d.getVar('TRUSTFENCE_COPRO_PASSWORD_FILE') + if (os.path.isfile(passfile)): + with open(passfile, "r") as file: + p = file.read().strip() + if (p): + d.setVar('SIGN_COPRO_ECC_PASS_%s' % (d.getVar('STM32MP_SOC_NAME').strip()), p); +} 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 0bb1d716e..65c734ed0 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 @@ -102,6 +102,41 @@ else fi fi +# Default values +RPROC_KEY_PASS_FILE="${CONFIG_SIGN_KEYS_PATH}/rproc-keys/key_pass.txt" + +# Generate random keys for Cortex-M coprocessor if they don't exist +if [ "${PLATFORM}" = "ccmp25" ]; then + N_PUBK="$(ls -l ${CONFIG_SIGN_KEYS_PATH}/rproc-keys/publicKey*.pem 2>/dev/null | wc -l)" + N_PRVK="$(ls -l ${CONFIG_SIGN_KEYS_PATH}/rproc-keys/privateKey*.pem 2>/dev/null | wc -l)" + N_DERK="$(ls -l ${CONFIG_SIGN_KEYS_PATH}/rproc-keys/publicKey*.der 2>/dev/null | wc -l)" + install -d "${CONFIG_SIGN_KEYS_PATH}/rproc-keys/" + if [ "${N_PUBK}" = "1" ] && [ "${N_PRVK}" = "1" ] && [ "${N_DERK}" = "1" ] && [ -f "${RPROC_KEY_PASS_FILE}" ]; then + # PKI tree already exists. + echo "Using existing PKI tree for Cortex-M coprocessor" + elif [ "${N_PUBK}" != "1" ] && [ "${N_PRVK}" != 1 ] && [ "${N_DERK}" != "1" ] && [ ! -f "${RPROC_KEY_PASS_FILE}" ]; then + # Random password + password="$(openssl rand -base64 32)" + echo "Generating random key" + if ! STM32MP_KeyGen_CLI -abs "${CONFIG_SIGN_KEYS_PATH}/rproc-keys/" -pwd ${password}; then + echo "[ERROR] Could not generate PKI tree for Cortex-M coprocessor" + exit 1 + fi + echo "${password}" > "${RPROC_KEY_PASS_FILE}" + chmod 400 "${RPROC_KEY_PASS_FILE}" + # Generate DER version of public key + if ! openssl ec -pubin -in ${CONFIG_SIGN_KEYS_PATH}/rproc-keys/publicKey.pem \ + -outform DER -pubout \ + -out ${CONFIG_SIGN_KEYS_PATH}/rproc-keys/publicKey.der; then + echo "[ERROR] Could not generate DER public key for Cortex-M coprocessor" + exit 1 + fi + else + echo "[ERROR] Could not generate PKI tree for Cortex-M coprocessor. An incomplete PKI tree may already exist." + exit 1 + fi +fi + if [ -n "${CONFIG_DEK_PATH}" ]; then [ -d "${CONFIG_DEK_PATH}" ] || mkdir "${CONFIG_DEK_PATH}" # Generate random keys if they don't exist @@ -122,6 +157,14 @@ if [ -n "${CONFIG_DEK_PATH}" ]; then fi chmod 444 "${CONFIG_DEK_PATH}/encryption_key_fip.bin" fi + if [ ! -f "${CONFIG_DEK_PATH}/encryption_key_rproc.bin" ]; then + echo "Generating random encryption keys for Cortex-M coprocessor" + if ! STM32MP_KeyGen_CLI -rand 32 "${CONFIG_DEK_PATH}/encryption_key_rproc.bin"; then + echo "[ERROR] Failed to generate 32-byte Cortex-M encryption key" + exit 1 + fi + chmod 444 "${CONFIG_DEK_PATH}/encryption_key_rproc.bin" + fi else echo "[ERROR] Could not generate encryption keys. Platform not supported." exit 1 diff --git a/meta-digi-dey/classes/trustfence.bbclass b/meta-digi-dey/classes/trustfence.bbclass index 2a57d7772..7ce380ef3 100644 --- a/meta-digi-dey/classes/trustfence.bbclass +++ b/meta-digi-dey/classes/trustfence.bbclass @@ -192,6 +192,13 @@ python () { 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")) + if (d.getVar("SIGN_COPRO_ENABLE") == "1" ): + d.setVar("SIGN_COPRO_ECC_PRIVKEY", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "/rproc-keys/privateKey.pem") + d.setVar("SIGN_COPRO_ECC_PRIVKEY_%s" % (d.getVar("STM32MP_SOC_NAME").strip()), d.getVar("SIGN_COPRO_ECC_PRIVKEY")) + d.setVar("SIGN_COPRO_ECC_INFOKEY", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "/rproc-keys/publicKey.der") + d.setVar("SIGN_COPRO_ECC_INFOKEY_%s" % (d.getVar("STM32MP_SOC_NAME").strip()), d.getVar("SIGN_COPRO_ECC_INFOKEY")) + d.setVar("TRUSTFENCE_COPRO_PASSWORD_FILE", d.getVar("TRUSTFENCE_SIGN_KEYS_PATH") + "rproc-keys/key_pass.txt") + d.setVar("SIGN_COPRO_ECC_PASS_%s" % (d.getVar("STM32MP_SOC_NAME").strip()), "UNDEFINED"); d.setVar("SIGN_KEY_%s" % (d.getVar("STM32MP_SOC_NAME").strip()), d.getVar("SIGN_KEY")); d.appendVar("UBOOT_TF_CONF", "CONFIG_SIGN_IMAGE=y ") @@ -220,6 +227,9 @@ python () { d.setVar("ENCRYPT_FSBL_KEY_%s" % (d.getVar("STM32MP_SOC_NAME").strip()), d.getVar("ENCRYPT_FSBL_KEY")) d.setVar("ENCRYPT_FIP_KEY", '%s/encryption_key_fip.bin' % d.getVar("TRUSTFENCE_DEK_PATH")) d.setVar("ENCRYPT_FIP_KEY_%s" % (d.getVar("STM32MP_SOC_NAME").strip()), d.getVar("ENCRYPT_FIP_KEY")) + if (d.getVar("ENCRYPT_COPRO_ENABLE") == "1"): + d.setVar("ENCRYPT_COPRO_KEY", '%s/encryption_key_rproc.bin' % d.getVar("TRUSTFENCE_DEK_PATH")) + d.setVar("ENCRYPT_COPRO_KEY_%s" % (d.getVar("STM32MP_SOC_NAME").strip()), d.getVar("ENCRYPT_COPRO_KEY")) if (d.getVar("TRUSTFENCE_SIGN_FIT_STM") == "1"): # FIT-related variables