trustfence: stm: move generation of PKI out of sign script

Create a new script for the generation of PKI tree for STM platforms
and leave the trustfence-sign-artifact script exclusively for signing.
The new gen-pki script only requires the platform as an argument and the
path to where to save the tree (if it doesn't exist) in
CONFIG_SIGN_KEYS_PATH.

This commit also reverts commit 13c136dbc5 by getting rid of the
trustfence-genpki-native.bb recipe and moving back the PKI generation
functions into trustfence.bbclass. This recipe didn't quite guarantee
that the PKI was generated on time for the recipes that required the
keys to exist, anyway.
Instead, the PKI generation function must be called right after
do_compile() of recipe tf-a-stm32mp to be ready for do_deploy() where
the key is used.

Signed-off-by: Hector Palacios <hector.palacios@digi.com>
This commit is contained in:
Hector Palacios 2023-07-11 06:50:26 +02:00
parent fad45f44d7
commit ae327e8dae
6 changed files with 144 additions and 100 deletions

View File

@ -18,7 +18,7 @@ TF_A_CONFIG = "${DEY_TF_A_CONFIG}"
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[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"
DEPENDS += " \ DEPENDS += " \
${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'trustfence-sign-tools-native trustfence-genpki-native', '', d)} \ ${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'trustfence-sign-tools-native', '', d)} \
" "
# This dependency is required so that the PKI generation completes before # This dependency is required so that the PKI generation completes before
@ -29,6 +29,15 @@ do_install[depends] = " \
openssl-native:do_populate_sysroot \ openssl-native:do_populate_sysroot \
" "
# 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() {
if ${@oe.utils.conditional('TRUSTFENCE_SIGN','1','true','false',d)}; then
check_gen_pki_tree
fi
}
# Obtain password to use in FIP generation # Obtain password to use in FIP generation
# Get password from file using the given key index # Get password from file using the given key index
do_deploy[prefuncs] += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'set_fip_sign_key', '', d)}" do_deploy[prefuncs] += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'set_fip_sign_key', '', d)}"

View File

@ -1,62 +0,0 @@
# Copyright (C) 2023, Digi International Inc.
SUMMARY = "TrustFence generation of Public Key Infrastructure (PKI)"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6"
inherit native
RDEPENDS:${PN} = " \
trustfence-sign-tools-native \
openssl-native \
"
S = "${WORKDIR}"
do_fetch[noexec] = "1"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
# 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
if [ "${DEY_SOC_VENDOR}" = "NXP" ]; then
trustfence-gen-pki.sh ${TRUSTFENCE_SIGN_KEYS_PATH}
elif [ "${DEY_SOC_VENDOR}" = "STM" ]; then
# Call sign script with no artifact arguments to just
# generate the keys
export CONFIG_SIGN_KEYS_PATH="${TRUSTFENCE_SIGN_KEYS_PATH}"
export CONFIG_KEY_INDEX="${TRUSTFENCE_KEY_INDEX}"
trustfence-sign-artifact.sh -p ${DIGI_SOM}
fi
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() {
if [ "${DEY_SOC_VENDOR}" = "NXP" ]; then
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
elif [ "${DEY_SOC_VENDOR}" = "STM" ]; then
# The script that generates the PKI tree already checks if
# there isn't one, so there's nothing to do here but calling it.
gen_pki_tree
fi
}
do_install[depends] = "trustfence-sign-tools-native:do_populate_sysroot \
openssl-native:do_populate_sysroot"
do_install() {
check_gen_pki_tree
}
FILES:${PN} = "${bindir}"

View File

@ -18,6 +18,7 @@ SRC_URI = " \
${UBOOT_GIT_URI};branch=${SRCBRANCH} \ ${UBOOT_GIT_URI};branch=${SRCBRANCH} \
file://trustfence-sign-artifact-nxp.sh \ file://trustfence-sign-artifact-nxp.sh \
file://trustfence-sign-artifact-stm.sh \ file://trustfence-sign-artifact-stm.sh \
file://trustfence-gen-pki-stm.sh \
file://sign_hab;name=artifact-hab-sign \ file://sign_hab;name=artifact-hab-sign \
file://encrypt_hab;name=artifact-hab-encrypt \ file://encrypt_hab;name=artifact-hab-encrypt \
file://sign_ahab;name=artifact-ahab-sign \ file://sign_ahab;name=artifact-ahab-sign \
@ -57,6 +58,7 @@ do_install() {
elif [ "${DEY_SOC_VENDOR}" = "STM" ]; then elif [ "${DEY_SOC_VENDOR}" = "STM" ]; then
install -d ${D}${bindir} install -d ${D}${bindir}
install -m 0755 trustfence-sign-artifact-stm.sh ${D}${bindir}/trustfence-sign-artifact.sh install -m 0755 trustfence-sign-artifact-stm.sh ${D}${bindir}/trustfence-sign-artifact.sh
install -m 0755 trustfence-gen-pki-stm.sh ${D}${bindir}/trustfence-gen-pki.sh
fi fi
} }

View File

@ -0,0 +1,85 @@
#!/bin/sh
#===============================================================================
#
# trustfence-gen-pki-stm.sh
#
# Copyright (C) 2023 by Digi International Inc.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published by
# the Free Software Foundation.
#
#
# Description:
# Script for generating PKI tree using STM tools
#
#===============================================================================
# Avoid parallel execution of this script
SINGLE_PROCESS_LOCK="/tmp/gen_pki_script.lock.d"
trap 'rm -rf "${SINGLE_PROCESS_LOCK}"' INT TERM EXIT
while ! mkdir "${SINGLE_PROCESS_LOCK}" > /dev/null 2>&1; do
sleep 1
done
SCRIPT_NAME="$(basename "${0}")"
SUPPORTED_PLATFORMS="ccmp15, ccmp13"
while getopts "p:" c; do
case "${c}" in
p) PLATFORM="${OPTARG}";;
esac
done
shift "$((OPTIND - 1))"
usage() {
cat <<EOF
Usage: ${SCRIPT_NAME} <OPTIONS>
Options:
-p <platform> platform
Supported platforms: ${SUPPORTED_PLATFORMS}
EOF
}
if [ -z "${CONFIG_SIGN_KEYS_PATH}" ]; then
echo "Undefined CONFIG_SIGN_KEYS_PATH";
exit 1
fi
[ -d "${CONFIG_SIGN_KEYS_PATH}" ] || mkdir "${CONFIG_SIGN_KEYS_PATH}"
# Default values
KEY_PASS_FILE="${CONFIG_SIGN_KEYS_PATH}/keys/key_pass.txt"
# Generate random keys if they don't exist
N_PUBK="$(ls -l "${CONFIG_SIGN_KEYS_PATH}"/keys/publicKey0* 2>/dev/null | wc -l)"
N_PRVK="$(ls -l "${CONFIG_SIGN_KEYS_PATH}"/keys/privateKey0* 2>/dev/null | wc -l)"
if [ "${PLATFORM}" = "ccmp15" ]; then
if [ "${N_PUBK}" != "1" ] && [ "${N_PRVK}" != 1 ] && [ ! -f "${KEY_PASS_FILE}" ]; then
install -d "${CONFIG_SIGN_KEYS_PATH}/keys/"
# Random password
password="$(openssl rand -base64 32)"
echo "Generating random key"
STM32MP_KeyGen_CLI -abs "${CONFIG_SIGN_KEYS_PATH}/keys/" -pwd "${password}" -n 1
echo "${password}" > "${KEY_PASS_FILE}"
fi
elif [ "${PLATFORM}" = "ccmp13" ]; then
if [ "${N_PUBK}" != "8" ] && [ "${N_PRVK}" != 8 ] && [ ! -f "${KEY_PASS_FILE}" ]; then
install -d "${CONFIG_SIGN_KEYS_PATH}/keys/"
# 8 random passwords (separated by whitespaces)
passwords="$(openssl rand -base64 32)"
for i in $(seq 1 7); do
passwords="${passwords} $(openssl rand -base64 32)"
done
echo "Generating random keys"
STM32MP_KeyGen_CLI -abs "${CONFIG_SIGN_KEYS_PATH}/keys/" -pwd "${passwords}" -n 8
echo "${passwords}" > "${KEY_PASS_FILE}"
fi
else
echo "Undefined platform"
exit 1
fi

View File

@ -47,59 +47,36 @@ Usage: ${SCRIPT_NAME} <OPTIONS> [<input-unsigned-image> <output-signed-image>]
Supported platforms: ${SUPPORTED_PLATFORMS} Supported platforms: ${SUPPORTED_PLATFORMS}
When called without filename parameters, it generates random keys if they
do not exist.
EOF EOF
} }
if [ "${#}" != "2" ]; then
usage
exit 1
fi
if [ -z "${CONFIG_SIGN_KEYS_PATH}" ]; then if [ -z "${CONFIG_SIGN_KEYS_PATH}" ]; then
echo "Undefined CONFIG_SIGN_KEYS_PATH"; echo "Undefined CONFIG_SIGN_KEYS_PATH";
exit 1 exit 1
fi fi
[ -d "${CONFIG_SIGN_KEYS_PATH}" ] || mkdir "${CONFIG_SIGN_KEYS_PATH}"
# Default values # Default values
[ -z "${CONFIG_KEY_INDEX}" ] && CONFIG_KEY_INDEX="0" [ -z "${CONFIG_KEY_INDEX}" ] && CONFIG_KEY_INDEX="0"
KEY_PASS_FILE="${CONFIG_SIGN_KEYS_PATH}/keys/key_pass.txt" KEY_PASS_FILE="${CONFIG_SIGN_KEYS_PATH}/keys/key_pass.txt"
# Generate random keys if they don't exist # Generate random keys if they don't exist
if [ "${PLATFORM}" = "ccmp15" ]; then if ! trustfence-gen-pki.sh -p ${PLATFORM}; then
PUBLIC_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/publicKey00.pem"
PRIVATE_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/privateKey00.pem"
if [ ! -f "${PRIVATE_KEY}" ] && [ ! -f "${PUBLIC_KEY}" ] && [ ! -f "${KEY_PASS_FILE}" ]; then
install -d "${CONFIG_SIGN_KEYS_PATH}/keys/"
# Random password
password="$(openssl rand -base64 32)"
echo "Generating random key"
STM32MP_KeyGen_CLI -abs "${CONFIG_SIGN_KEYS_PATH}/keys/" -pwd ${password} -n 1
echo "${password}" > "${KEY_PASS_FILE}"
fi
elif [ "${PLATFORM}" = "ccmp13" ]; then
N_PUBK="$(ls -l ${CONFIG_SIGN_KEYS_PATH}/keys/publicKey0* 2>/dev/null | wc -l)"
N_PRVK="$(ls -l ${CONFIG_SIGN_KEYS_PATH}/keys/privateKey0* 2>/dev/null | wc -l)"
PUBLIC_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/publicKey0*.pem"
PRIVATE_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/privateKey0${CONFIG_KEY_INDEX}.pem"
if [ "${N_PUBK}" != "8" ] && [ "${N_PRVK}" != 8 ] && [ ! -f "${KEY_PASS_FILE}" ]; then
install -d "${CONFIG_SIGN_KEYS_PATH}/keys/"
# 8 random passwords (separated by whitespaces)
passwords="$(openssl rand -base64 32)"
for i in $(seq 1 7); do
passwords="${passwords} $(openssl rand -base64 32)"
done
echo "Generating random keys"
STM32MP_KeyGen_CLI -abs "${CONFIG_SIGN_KEYS_PATH}/keys/" -pwd ${passwords} -n 8
echo "${passwords}" > "${KEY_PASS_FILE}"
fi
else
echo "Undefined platform"
exit 1 exit 1
fi fi
if [ "${#}" = "0" ]; then if [ "${PLATFORM}" = "ccmp15" ]; then
exit 0 PUBLIC_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/publicKey00.pem"
elif [ "${#}" != "2" ]; then PRIVATE_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/privateKey00.pem"
usage elif [ "${PLATFORM}" = "ccmp13" ]; then
PUBLIC_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/publicKey0*.pem"
PRIVATE_KEY="${CONFIG_SIGN_KEYS_PATH}/keys/privateKey0${CONFIG_KEY_INDEX}.pem"
else
echo "Undefined platform"
exit 1 exit 1
fi fi

View File

@ -36,6 +36,39 @@ TRUSTFENCE_READ_ONLY_ROOTFS ?= "${@bb.utils.contains("IMAGE_FEATURES", "read-onl
IMAGE_FEATURES += "dey-trustfence" IMAGE_FEATURES += "dey-trustfence"
# 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
if [ "${DEY_SOC_VENDOR}" = "NXP" ]; then
trustfence-gen-pki.sh ${TRUSTFENCE_SIGN_KEYS_PATH}
elif [ "${DEY_SOC_VENDOR}" = "STM" ]; then
export CONFIG_SIGN_KEYS_PATH="${TRUSTFENCE_SIGN_KEYS_PATH}"
trustfence-gen-pki.sh -p ${DIGI_SOM}
fi
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() {
if [ "${DEY_SOC_VENDOR}" = "NXP" ]; then
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
elif [ "${DEY_SOC_VENDOR}" = "STM" ]; then
# The script that generates the PKI tree already checks if
# there isn't one, so there's nothing to do here but calling it.
gen_pki_tree
fi
}
python () { python () {
import binascii import binascii
import hashlib import hashlib