From 661f59967c73572659d48cd609b458f4b1ef85ba Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Wed, 15 Mar 2023 17:17:11 +0100 Subject: [PATCH] trustfence: add function to generate a PKI tree if it doesn't exist The stand-alone signing script 'trustfence-sign-artifact.sh' checks if a valid PKI tree exists (by checking the existance of four SRK files) and if they don't, it calls trustfence-gen-pki.sh (which is a wrapper over different generators (for HAB or AHAB) to create one. Recipes such as 'dualboot' or 'recovery-initramfs' may need to call openssl functions over the PKI tree. These recipes do not currently generate the PKI tree; they expect it to be already in place. This might not be the case if the trustfence-sign-artifact.sh script has not been called yet. Originally, a fake dependency on virtual/kernel recipe was made to force it, but it doesn't quite work since the calling only happens on deploy() while regular DEPENDS doesn't wait for this task. If the PKI does not exist, a recipe that requires the PKI tree will fail. The solution is to create a function on the trustfence.bbclass that allows any recipe to check for the existance of a PKI tree and generate it if it doesn't exist. This is repeated inside the trustfence-sign-artifact.sh, but it needs to be in both places because this script must work stand-alone. The generation of the PKI tree takes some seconds so this commit adds a lock dir to prevent race conditions when called from different recipes. It also removes the fake dependency on virtual/kernel and adds a dependency on trustfence-cst-native (which is the recipe that provides the PKI generation tool). Signed-off-by: Hector Palacios https://onedigi.atlassian.net/browse/DEL-8430 (cherry picked from commit 6a8bf7affffc4cb38b55070f4b6aa8adfeda297a) --- .../trustfence-sign-artifact.sh | 16 ++++++++++++-- meta-digi-dey/classes/trustfence.bbclass | 22 +++++++++++++++++++ .../recovery/recovery-initramfs.bb | 8 +++---- .../recipes-digi/dualboot/dualboot.bb | 9 +++----- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact.sh b/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact.sh index 8c57ff03a..ba916eafa 100755 --- a/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact.sh +++ b/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact.sh @@ -152,6 +152,18 @@ if [ "${CONFIG_SIGN_MODE}" = "HAB" ]; then DEK_BLOB_OFFSET="0x100" fi +# Function to generate a PKI tree (with lock dir protection) +GENPKI_LOCK_DIR="${CONFIG_SIGN_KEYS_PATH}/.genpki.lock" +gen_pki_tree() { + if mkdir -p ${GENPKI_LOCK_DIR}; then + trustfence-gen-pki.sh ${CONFIG_SIGN_KEYS_PATH} + rm -rf ${GENPKI_LOCK_DIR} + else + echo "Could not get lock to generate PKI tree" + exit 1 + fi +} + # Default values [ -z "${CONFIG_KEY_INDEX}" ] && CONFIG_KEY_INDEX="0" CONFIG_KEY_INDEX_1="$((CONFIG_KEY_INDEX + 1))" @@ -170,7 +182,7 @@ if [ "${CONFIG_SIGN_MODE}" = "HAB" ]; then echo "Using existing PKI tree" elif [ "${n_commas}" -eq 0 ] || [ ! -f "${CERT_CSF}" ] || [ ! -f "${CERT_IMG}" ]; then # Generate PKI - trustfence-gen-pki.sh "${CONFIG_SIGN_KEYS_PATH}" + gen_pki_tree SRK_KEYS="$(echo ${CONFIG_SIGN_KEYS_PATH}/crts/SRK*crt.pem | sed s/\ /\,/g)" CERT_CSF="$(echo ${CONFIG_SIGN_KEYS_PATH}/crts/CSF${CONFIG_KEY_INDEX_1}*crt.pem)" @@ -185,7 +197,7 @@ elif [ "${CONFIG_SIGN_MODE}" = "AHAB" ]; then echo "Using existing PKI tree" elif [ "${n_commas}" -eq 0 ] && [ "${CONFIG_SIGN_MODE}" = "AHAB" ]; then # Generate PKI - trustfence-gen-pki.sh "${CONFIG_SIGN_KEYS_PATH}" + gen_pki_tree SRK_KEYS="$(echo ${CONFIG_SIGN_KEYS_PATH}/crts/SRK*crt.pem | sed s/\ /\,/g)" else diff --git a/meta-digi-dey/classes/trustfence.bbclass b/meta-digi-dey/classes/trustfence.bbclass index 663204290..0e430cf94 100644 --- a/meta-digi-dey/classes/trustfence.bbclass +++ b/meta-digi-dey/classes/trustfence.bbclass @@ -110,3 +110,25 @@ python () { else: d.setVar("TRUSTFENCE_INITRAMFS_IMAGE", ""); } + +# Function to generate a PKI tree (with lock dir protection) +GENPKI_LOCK_DIR = "${TRUSTFENCE_SIGN_KEYS_PATH}/.genpki.lock" +gen_pki_tree() { + if mkdir -p ${GENPKI_LOCK_DIR}; then + trustfence-gen-pki.sh ${TRUSTFENCE_SIGN_KEYS_PATH} + rm -rf ${GENPKI_LOCK_DIR} + else + bbfatal "Could not get lock to generate PKI tree" + fi +} + +# Function that generates a PKI tree if there isn't one +check_gen_pki_tree() { + SRK_KEYS="$(echo ${TRUSTFENCE_SIGN_KEYS_PATH}/crts/SRK*crt.pem | sed s/\ /\,/g)" + n_commas="$(echo ${SRK_KEYS} | grep -o "," | wc -l)" + if [ "${n_commas}" -eq 0 ]; then + gen_pki_tree + elif [ "${n_commas}" -ne 3 ]; then + bbfatal "Inconsistent PKI tree" + fi +} diff --git a/meta-digi-dey/recipes-core/recovery/recovery-initramfs.bb b/meta-digi-dey/recipes-core/recovery/recovery-initramfs.bb index b10bc069e..03e121515 100644 --- a/meta-digi-dey/recipes-core/recovery/recovery-initramfs.bb +++ b/meta-digi-dey/recipes-core/recovery/recovery-initramfs.bb @@ -4,11 +4,7 @@ SUMMARY = "Recovery initramfs files" LICENSE = "GPL-2.0-only" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6" -# When building a TrustFence enabled recovery initramfs, we need the TrustFence PKI tree to -# be already generated in order to copy the public key. Forcing a dependence against -# 'virtual/kernel' ensures that the keys are already generated as they are needed to sign the -# kernel artifacts. -DEPENDS += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'virtual/kernel openssl-native', '', d)}" +DEPENDS += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'openssl-native trustfence-cst-native', '', d)}" SRC_URI = " \ file://recovery-initramfs-init \ @@ -38,6 +34,8 @@ do_install() { # If Trustfence is enabled, copy the public key that is going to be used into the # initramfs '/etc/ssl/certs' folder in order to verify swupdate packages. if [ "${TRUSTFENCE_SIGN}" = "1" ]; then + # Check and generate a PKI tree if there isn't one + check_gen_pki_tree # Retrieve the key index to use. KEY_INDEX="0" if [ -n "${TRUSTFENCE_KEY_INDEX}" ]; then diff --git a/meta-digi-dey/recipes-digi/dualboot/dualboot.bb b/meta-digi-dey/recipes-digi/dualboot/dualboot.bb index 1876504a6..374a532c7 100644 --- a/meta-digi-dey/recipes-digi/dualboot/dualboot.bb +++ b/meta-digi-dey/recipes-digi/dualboot/dualboot.bb @@ -5,12 +5,7 @@ SECTION = "base" LICENSE = "GPL-2.0-only" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6" - -# When building a TrustFence enabled rootfs, we need the TrustFence PKI tree to -# be already generated in order to copy the public key. Forcing a dependency with -# 'virtual/kernel' ensures that the keys are already generated as they are needed to sign the -# kernel artifacts. -DEPENDS += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'virtual/kernel openssl-native', '', d)}" +DEPENDS += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'openssl-native trustfence-cst-native', '', d)}" SRC_URI = " \ file://dualboot-init \ @@ -41,6 +36,8 @@ do_install() { # If Trustfence is enabled, copy the public key that is going to be used into the # initramfs '/etc/ssl/certs' folder in order to verify swupdate packages. if [ "${TRUSTFENCE_SIGN}" = "1" ]; then + # Check and generate a PKI tree if there isn't one + check_gen_pki_tree # Retrieve the key index to use. KEY_INDEX="0" if [ -n "${TRUSTFENCE_KEY_INDEX}" ]; then