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 <hector.palacios@digi.com>

https://onedigi.atlassian.net/browse/DEL-8430
(cherry picked from commit 6a8bf7afff)
This commit is contained in:
Hector Palacios 2023-03-15 17:17:11 +01:00
parent 358dd2a815
commit 661f59967c
4 changed files with 42 additions and 13 deletions

View File

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

View File

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

View File

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

View File

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