meta-digi-arm: add support for signed and encrypted uImages
https://jira.digi.com/browse/DUB-534 https://jira.digi.com/browse/DUB-602 Signed-off-by: Diaz de Grenu, Jose <Jose.DiazdeGrenu@digi.com>
This commit is contained in:
parent
f23d8c6abb
commit
d91661d7de
|
|
@ -25,7 +25,22 @@ S = "${WORKDIR}/git"
|
|||
# machine, with different entry points
|
||||
KERNEL_EXTRA_ARGS += "LOADADDR=${UBOOT_ENTRYPOINT}"
|
||||
|
||||
# In order to sign and encrypt the uImage, we need to know the address
|
||||
# in which U-Boot loads the uImage. This is CONFIG_LOADADDR in U-Boot
|
||||
# configuration file.
|
||||
UBOOT_CONFIG_LOADADDR = ""
|
||||
UBOOT_CONFIG_LOADADDR_ccimx6 = "0x12000000"
|
||||
UBOOT_CONFIG_LOADADDR_ccimx6ul = "0x80800000"
|
||||
|
||||
do_deploy_append() {
|
||||
if [ -n "${TRUSTFENCE_SIGN}" ]; then
|
||||
export CONFIG_SIGN_KEYS_PATH="${TRUSTFENCE_SIGN_KEYS_PATH}"
|
||||
export CONFIG_UIMAGE_LOADADDR="${UBOOT_CONFIG_LOADADDR}"
|
||||
[ -n "${TRUSTFENCE_KEY_INDEX}" ] && export CONFIG_KEY_INDEX="${TRUSTFENCE_KEY_INDEX}"
|
||||
[ -n "${TRUSTFENCE_DEK_PATH}" ] && [ "${TRUSTFENCE_DEK_PATH}" != "0" ] && export CONFIG_DEK_PATH="${TRUSTFENCE_DEK_PATH}"
|
||||
"${THISDIR}/../../scripts/trustfence-sign-uimage.sh" "${DEPLOYDIR}/${KERNEL_IMAGE_BASE_NAME}.bin" "${DEPLOYDIR}/${KERNEL_IMAGE_BASE_NAME}-signed.bin"
|
||||
mv "${DEPLOYDIR}/${KERNEL_IMAGE_BASE_NAME}-signed.bin" "${DEPLOYDIR}/${KERNEL_IMAGE_BASE_NAME}.bin"
|
||||
fi
|
||||
(cd ${DEPLOYDIR} && ln -sf ${KERNEL_IMAGE_BASE_NAME}.bin ${KERNEL_IMAGE_SYMLINK_NAME})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
# The syntax for this file is documented in the HAB Code-Signing Tool
|
||||
# User's Guide which is included in the CST package distributed by NXP
|
||||
[Header]
|
||||
Version = 4.1
|
||||
Hash Algorithm = sha256
|
||||
Engine Configuration = 0
|
||||
Certificate Format = X509
|
||||
Signature Format = CMS
|
||||
Engine = CAAM
|
||||
|
||||
[Install SRK]
|
||||
File = "%srk_table%"
|
||||
Source index = %key_index%
|
||||
|
||||
[Install CSFK]
|
||||
File = "%cert_csf%"
|
||||
|
||||
[Authenticate CSF]
|
||||
|
||||
[Install Key]
|
||||
Verification index = 0
|
||||
Target index = 2
|
||||
File = "%cert_img%"
|
||||
|
||||
[Authenticate Data]
|
||||
Verification index = 2
|
||||
Blocks = %ivt_ram_start% %ivt_uimage_start% %ivt_size% "%uimage_path%"
|
||||
|
||||
[Authenticate Data]
|
||||
Verification index = 2
|
||||
Blocks = %entrypoint_ram_start% %entrypoint_uimage_offset% %entrypoint_size% "%uimage_path%"
|
||||
|
||||
[Authenticate Data]
|
||||
Verification index = 2
|
||||
Blocks = %header_ram_start% %header_uimage_offset% %header_size% "%uimage_path%"
|
||||
|
||||
[Install Secret Key]
|
||||
Verification index = 0
|
||||
Target index = 0
|
||||
Key = "%dek_path%"
|
||||
Key Length = %dek_len%
|
||||
Blob address = %dek_offset%
|
||||
|
||||
[Decrypt Data]
|
||||
Verification index = 0
|
||||
Mac Bytes = 16
|
||||
Blocks = %r1_ram_start% %r1_uimage_offset% %r1_size% "%uimage_path%", \
|
||||
%r2_ram_start% %r2_uimage_offset% %r2_size% "%uimage_path%"
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# The syntax for this file is documented in the HAB Code Signing Tool
|
||||
# User's Guid which is included in the CST package distributed by NXP
|
||||
[Header]
|
||||
Version = 4.0
|
||||
Hash Algorithm = sha256
|
||||
Engine Configuration = 0
|
||||
Certificate Format = X509
|
||||
Signature Format = CMS
|
||||
|
||||
[Install SRK]
|
||||
File = "%srk_table%"
|
||||
Source index = %key_index%
|
||||
|
||||
|
||||
[Install CSFK]
|
||||
File = "%cert_csf%"
|
||||
|
||||
[Authenticate CSF]
|
||||
|
||||
[Unlock]
|
||||
Engine = CAAM
|
||||
Features = RNG
|
||||
|
||||
[Install Key]
|
||||
Verification index = 0
|
||||
Target index = 2
|
||||
File = "%cert_img%"
|
||||
|
||||
[Authenticate Data]
|
||||
Verification index = 2
|
||||
Blocks = %ram_start% %image_offset% %auth_len% "%uimage_path%"
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
#!/bin/bash
|
||||
#===============================================================================
|
||||
#
|
||||
# trustfence_sign_uimage.sh
|
||||
#
|
||||
# Copyright (C) 2016 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 building signed and encrypted kernel uImages using NXP CST.
|
||||
#
|
||||
# The following environment variables define the script behaviour:
|
||||
# CONFIG_SIGN_KEYS_PATH: (mandatory) path to the CST folder by NXP with keys generated.
|
||||
# CONFIG_UIMAGE_LOADADDR: (mandatory) memory address in which U-Boot loads the uImage
|
||||
# CONFIG_KEY_INDEX: (optional) key index to use for signing. Default is 0.
|
||||
# CONFIG_DEK_PATH: (optional) Path to keyfile. Define it to generate
|
||||
# encrypted images
|
||||
#
|
||||
#===============================================================================
|
||||
|
||||
# Negative offset with respect to CONFIG_UIMAGE_LOADADDR in which U-Boot
|
||||
# copies the DEK blob.
|
||||
DEK_BLOB_OFFSET="0x100"
|
||||
CONFIG_CSF_SIZE="0x4000"
|
||||
|
||||
UIMAGE_PATH="$(readlink -e ${1})"
|
||||
TARGET="$(readlink -m ${2})"
|
||||
SCRIPT_BASEDIR="$(cd $(dirname ${0}) && pwd)"
|
||||
|
||||
# Check arguments
|
||||
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}"
|
||||
|
||||
if [ -n "${CONFIG_DEK_PATH}" ]; then
|
||||
if [ ! -f "${CONFIG_DEK_PATH}" ]; then
|
||||
echo "DEK not found. Generating random 256 bit DEK."
|
||||
[ -d $(dirname ${CONFIG_DEK_PATH}) ] || mkdir -p $(dirname ${CONFIG_DEK_PATH})
|
||||
dd if=/dev/urandom of="${CONFIG_DEK_PATH}" bs=32 count=1
|
||||
fi
|
||||
dek_size="$((8 * $(stat -L -c %s ${CONFIG_DEK_PATH})))"
|
||||
if [ "${dek_size}" != "128" ] && [ "${dek_size}" != "192" ] && [ "${dek_size}" != "256" ]; then
|
||||
echo "Invalid DEK size: ${dek_size} bits. Valid sizes are 128, 192 and 256 bits"
|
||||
exit 1
|
||||
fi
|
||||
ENCRYPT="true"
|
||||
fi
|
||||
if [ -z "${CONFIG_UIMAGE_LOADADDR}" ]; then
|
||||
echo "Undefined CONFIG_UIMAGE_LOADADDR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Default values
|
||||
[ -z "${CONFIG_KEY_INDEX}" ] && CONFIG_KEY_INDEX="0"
|
||||
CONFIG_KEY_INDEX_1="$((CONFIG_KEY_INDEX + 1))"
|
||||
[ -z "${CONFIG_DEK_SIZE}" ] && CONFIG_DEK_SIZE="128"
|
||||
|
||||
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)"
|
||||
CERT_IMG="$(echo ${CONFIG_SIGN_KEYS_PATH}/crts/IMG${CONFIG_KEY_INDEX_1}*crt.pem)"
|
||||
|
||||
n_commas="$(echo ${SRK_KEYS} | grep -o "," | wc -l)"
|
||||
|
||||
if [ "${n_commas}" -eq 3 ] && [ -f "${CERT_CSF}" ] && [ -f "${CERT_IMG}" ]; then
|
||||
# PKI tree already exists.
|
||||
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}"
|
||||
|
||||
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)"
|
||||
CERT_IMG="$(echo ${CONFIG_SIGN_KEYS_PATH}/crts/IMG${CONFIG_KEY_INDEX_1}*crt.pem)"
|
||||
else
|
||||
echo "Inconsistent CST folder."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SRK_TABLE="$(pwd)/SRK_table.bin"
|
||||
|
||||
# Other constants
|
||||
GAP_FILLER="0x00"
|
||||
|
||||
# Compute dek blob size in bytes:
|
||||
# header (8) + 256-bit AES key (32) + MAC (16) + custom key size in bytes
|
||||
dek_blob_size="$((8 + 32 + 16 + CONFIG_DEK_SIZE/8))"
|
||||
dek_blob_offset="$((CONFIG_UIMAGE_LOADADDR - DEK_BLOB_OFFSET))"
|
||||
|
||||
# Compute the layout: sizes and offsets.
|
||||
uimage_size="$(stat -L -c %s ${UIMAGE_PATH})"
|
||||
uimage_offset="0x0"
|
||||
pad_len="$((uimage_size - uimage_size % 0x1000 + 0x1000))"
|
||||
auth_len="$((pad_len + 0x20))"
|
||||
sig_len="$((auth_len + CONFIG_CSF_SIZE))"
|
||||
|
||||
ivt_uimage_start="$((auth_len - 0x20))"
|
||||
ivt_ram_start="$((CONFIG_UIMAGE_LOADADDR + ivt_uimage_start))"
|
||||
ivt_size="0x20"
|
||||
csf_ram_start="$((ivt_ram_start + ivt_size))"
|
||||
entrypoint_uimage_offset="0x1000"
|
||||
entrypoint_ram_start="$((CONFIG_UIMAGE_LOADADDR + entrypoint_uimage_offset))"
|
||||
entrypoint_size="0x20"
|
||||
header_uimage_offset="0x0"
|
||||
header_ram_start="${CONFIG_UIMAGE_LOADADDR}"
|
||||
header_size="0x40"
|
||||
|
||||
r1_uimage_offset="${header_size}"
|
||||
r1_ram_start="$((CONFIG_UIMAGE_LOADADDR + r1_uimage_offset))"
|
||||
r1_size="$((entrypoint_uimage_offset - header_size ))"
|
||||
r2_uimage_offset="$((entrypoint_uimage_offset + entrypoint_size))"
|
||||
r2_ram_start="$((CONFIG_UIMAGE_LOADADDR + r2_uimage_offset))"
|
||||
r2_size="$((ivt_uimage_start - (entrypoint_uimage_offset + entrypoint_size)))"
|
||||
|
||||
# Generate actual CSF descriptor file from template
|
||||
if [ "${ENCRYPT}" = "true" ]; then
|
||||
sed -e "s,%ram_start%,${CONFIG_UIMAGE_LOADADDR},g" \
|
||||
-e "s,%srk_table%,${SRK_TABLE},g " \
|
||||
-e "s,%cert_csf%,${CERT_CSF},g" \
|
||||
-e "s,%cert_img%,${CERT_IMG},g" \
|
||||
-e "s,%uimage_path%,${TARGET},g" \
|
||||
-e "s,%key_index%,${CONFIG_KEY_INDEX},g" \
|
||||
-e "s,%dek_len%,${dek_size},g" \
|
||||
-e "s,%dek_path%,${CONFIG_DEK_PATH},g" \
|
||||
-e "s,%dek_offset%,${dek_blob_offset},g" \
|
||||
-e "s,%ivt_uimage_start%,${ivt_uimage_start},g" \
|
||||
-e "s,%ivt_ram_start%,${ivt_ram_start},g" \
|
||||
-e "s,%ivt_size%,${ivt_size},g" \
|
||||
-e "s,%entrypoint_uimage_offset%,${entrypoint_uimage_offset},g" \
|
||||
-e "s,%entrypoint_ram_start%,${entrypoint_ram_start},g" \
|
||||
-e "s,%entrypoint_size%,${entrypoint_size},g" \
|
||||
-e "s,%header_uimage_offset%,${header_uimage_offset},g" \
|
||||
-e "s,%header_ram_start%,${header_ram_start},g" \
|
||||
-e "s,%header_size%,${header_size},g" \
|
||||
-e "s,%r1_uimage_offset%,${r1_uimage_offset},g" \
|
||||
-e "s,%r1_ram_start%,${r1_ram_start},g" \
|
||||
-e "s,%r1_size%,${r1_size},g" \
|
||||
-e "s,%r2_uimage_offset%,${r2_uimage_offset},g" \
|
||||
-e "s,%r2_ram_start%,${r2_ram_start},g" \
|
||||
-e "s,%r2_size%,${r2_size},g" \
|
||||
"${SCRIPT_BASEDIR}/templates/encrypt_uimage" > csf_descriptor
|
||||
else
|
||||
sed -e "s,%ram_start%,${CONFIG_UIMAGE_LOADADDR},g" \
|
||||
-e "s,%srk_table%,${SRK_TABLE},g" \
|
||||
-e "s,%image_offset%,${uimage_offset},g" \
|
||||
-e "s,%auth_len%,${auth_len},g" \
|
||||
-e "s,%cert_csf%,${CERT_CSF},g" \
|
||||
-e "s,%cert_img%,${CERT_IMG},g" \
|
||||
-e "s,%uimage_path%,${TARGET},g" \
|
||||
-e "s,%key_index%,${CONFIG_KEY_INDEX},g" \
|
||||
"${SCRIPT_BASEDIR}/templates/sign_uimage" > csf_descriptor
|
||||
fi
|
||||
|
||||
# Generate SRK tables
|
||||
srktool --hab_ver 4 --certs "${SRK_KEYS}" --table "${SRK_TABLE}" --efuses /dev/null --digest sha256
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "[ERROR] Could not generate SRK tables"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Pad to IVT
|
||||
objcopy -I binary -O binary --pad-to "${pad_len}" --gap-fill="${GAP_FILLER}" "${UIMAGE_PATH}" "${TARGET}"
|
||||
|
||||
# Generate and attach IVT
|
||||
# Fields: header, jump location, reserved (0), DCD pointer (null)
|
||||
# boot data (null), self pointer, CSF pointer, reserved (0)
|
||||
IVT_HEADER="0x402000D1"
|
||||
printf "0: %.8x" ${IVT_HEADER} | sed -E 's/0: (..)(..)(..)(..)/0: \4\3\2\1/' | xxd -r -g0 > ivt
|
||||
printf "0: %.8x" "${entrypoint_ram_start}" | sed -E 's/0: (..)(..)(..)(..)/0: \4\3\2\1/' | xxd -r -g0 >> ivt
|
||||
printf "0: %.8x" 0 | sed -E 's/0: (..)(..)(..)(..)/0: \4\3\2\1/' | xxd -r -g0 >> ivt
|
||||
printf "0: %.8x" 0 | sed -E 's/0: (..)(..)(..)(..)/0: \4\3\2\1/' | xxd -r -g0 >> ivt
|
||||
printf "0: %.8x" 0 | sed -E 's/0: (..)(..)(..)(..)/0: \4\3\2\1/' | xxd -r -g0 >> ivt
|
||||
printf "0: %.8x" "${ivt_ram_start}" | sed -E 's/0: (..)(..)(..)(..)/0: \4\3\2\1/' | xxd -r -g0 >> ivt
|
||||
printf "0: %.8x" "${csf_ram_start}" | sed -E 's/0: (..)(..)(..)(..)/0: \4\3\2\1/' | xxd -r -g0 >> ivt
|
||||
printf "0: %.8x" 0 | sed -E 's/0: (..)(..)(..)(..)/0: \4\3\2\1/' | xxd -r -g0 >> ivt
|
||||
cat ivt >> "${TARGET}"
|
||||
|
||||
CURRENT_PATH="$(pwd)"
|
||||
cst -o "${CURRENT_PATH}/csf.bin" -i "${CURRENT_PATH}/csf_descriptor"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "[ERROR] Could not generate CSF"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat csf.bin >> "${TARGET}"
|
||||
|
||||
objcopy -I binary -O binary --pad-to "${sig_len}" --gap-fill="${GAP_FILLER}" "${TARGET}"
|
||||
echo "Signed uImage at ${TARGET}"
|
||||
rm -f "${SRK_TABLE}" csf_descriptor csf.bin ivt 2> /dev/null
|
||||
Loading…
Reference in New Issue