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 <arturo.buzarra@digi.com>
This commit is contained in:
Arturo Buzarra 2025-10-01 12:50:15 +02:00
parent f1307670df
commit 3e5cf0c6e6
4 changed files with 65 additions and 4 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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