[U-Boot] [PATCH 0/3] arm: k3: Update build support

This series updates the build support for k3 devices to use rsa degenerate key. This significantly improves the boot time. While at it update the timeout for initializing system controller which cover a valid boot scenario.
Lokesh Vutla (3): tools: k3_get_x509 cert: Add a script to generate x509 certificate for K3 devices arm: k3: config.mk: Use k3_gen_x509_cert.sh to generate boot images remoteproc: k3_system_controller: Increase rx timeout
arch/arm/mach-k3/config.mk | 33 +-- drivers/remoteproc/k3_system_controller.c | 2 +- tools/k3_gen_x509_cert.sh | 244 ++++++++++++++++++++++ tools/k3_x509template.txt | 48 ----- 4 files changed, 249 insertions(+), 78 deletions(-) create mode 100755 tools/k3_gen_x509_cert.sh delete mode 100644 tools/k3_x509template.txt

TI's K3 boot architecture mandates a x509 certificate for every boot image. While signing the image K3 ROM allows for two types of keys based on which the boot image gets loaded in different ways: - Degenerate RSA keys: This generates a signature which is equal to the digest. When ROM sees this, it does a DMA for copying the images, which significantly improves the boot time. - Any other key: Does a memcpy to load the image. This is introduced as a fallback for DMA copy.
Add a script for generating boot images with the above options. Default generates image using rsa degenerate key in order to improve boot time.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com Signed-off-by: Dave Gerlach d-gerlach@ti.com Signed-off-by: Andreas Dannenberg dannenberg@ti.com --- tools/k3_gen_x509_cert.sh | 244 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100755 tools/k3_gen_x509_cert.sh
diff --git a/tools/k3_gen_x509_cert.sh b/tools/k3_gen_x509_cert.sh new file mode 100755 index 0000000000..b6d055f6f5 --- /dev/null +++ b/tools/k3_gen_x509_cert.sh @@ -0,0 +1,244 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +# +# Script to add K3 specific x509 cetificate to a binary. +# + +# Variables +OUTPUT=tiboot3.bin +TEMP_X509=x509-temp.cert +CERT=certificate.bin +RAND_KEY=eckey.pem +LOADADDR=0x41c00000 +BOOTCORE_OPTS=0 +BOOTCORE=16 + +gen_degen_template() { +cat << 'EOF' > degen-template.txt + +asn1=SEQUENCE:rsa_key + +[rsa_key] +version=INTEGER:0 +modulus=INTEGER:0xDEGEN_MODULUS +pubExp=INTEGER:1 +privExp=INTEGER:1 +p=INTEGER:0xDEGEN_P +q=INTEGER:0xDEGEN_Q +e1=INTEGER:1 +e2=INTEGER:1 +coeff=INTEGER:0xDEGEN_COEFF +EOF +} + +# Generate x509 Template +gen_template() { +cat << 'EOF' > x509-template.txt + [ req ] + distinguished_name = req_distinguished_name + x509_extensions = v3_ca + prompt = no + dirstring_type = nobmp + + [ req_distinguished_name ] + C = US + ST = TX + L = Dallas + O = Texas Instruments Incorporated + OU = Processors + CN = TI support + emailAddress = support@ti.com + + [ v3_ca ] + basicConstraints = CA:true + 1.3.6.1.4.1.294.1.1 = ASN1:SEQUENCE:boot_seq + 1.3.6.1.4.1.294.1.2 = ASN1:SEQUENCE:image_integrity + 1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv +# 1.3.6.1.4.1.294.1.4 = ASN1:SEQUENCE:encryption + 1.3.6.1.4.1.294.1.8 = ASN1:SEQUENCE:debug + + [ boot_seq ] + certType = INTEGER:TEST_CERT_TYPE + bootCore = INTEGER:TEST_BOOT_CORE + bootCoreOpts = INTEGER:TEST_BOOT_CORE_OPTS + destAddr = FORMAT:HEX,OCT:TEST_BOOT_ADDR + imageSize = INTEGER:TEST_IMAGE_LENGTH + + [ image_integrity ] + shaType = OID:2.16.840.1.101.3.4.2.3 + shaValue = FORMAT:HEX,OCT:TEST_IMAGE_SHA_VAL + + [ swrv ] + swrv = INTEGER:0 + +# [ encryption ] +# initalVector = FORMAT:HEX,OCT:TEST_IMAGE_ENC_IV +# randomString = FORMAT:HEX,OCT:TEST_IMAGE_ENC_RS +# iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX +# salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT + + [ debug ] + debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000 + debugType = INTEGER:4 + coreDbgEn = INTEGER:0 + coreDbgSecEn = INTEGER:0 +EOF +} + +parse_key() { + sed '/\ \ \ \ /s/://g' key.txt | awk '!/\ \ \ \ / {printf("\n%s\n", $0)}; /\ \ \ \ / {printf("%s", $0)}' | sed 's/\ \ \ \ //g' | awk "/$1:/{getline; print}" +} + +gen_degen_key() { +# Generate a 4096 bit RSA Key + openssl genrsa -out key.pem 1024 >>/dev/null 2>&1 + openssl rsa -in key.pem -text -out key.txt >>/dev/null 2>&1 + DEGEN_MODULUS=$( parse_key 'modulus' ) + DEGEN_P=$( parse_key 'prime1' ) + DEGEN_Q=$( parse_key 'prime2' ) + DEGEN_COEFF=$( parse_key 'coefficient' ) + gen_degen_template + + sed -e "s/DEGEN_MODULUS/$DEGEN_MODULUS/"\ + -e "s/DEGEN_P/$DEGEN_P/" \ + -e "s/DEGEN_Q/$DEGEN_Q/" \ + -e "s/DEGEN_COEFF/$DEGEN_COEFF/" \ + degen-template.txt > degenerateKey.txt + + openssl asn1parse -genconf degenerateKey.txt -out degenerateKey.der >>/dev/null 2>&1 + openssl rsa -in degenerateKey.der -inform DER -outform PEM -out $RAND_KEY >>/dev/null 2>&1 + KEY=$RAND_KEY + rm key.pem key.txt degen-template.txt degenerateKey.txt degenerateKey.der +} + +declare -A options_help +usage() { + if [ -n "$*" ]; then + echo "ERROR: $*" + fi + echo -n "Usage: $0 " + for option in "${!options_help[@]}" + do + arg=`echo ${options_help[$option]}|cut -d ':' -f1` + if [ -n "$arg" ]; then + arg=" $arg" + fi + echo -n "[-$option$arg] " + done + echo + echo -e "\nWhere:" + for option in "${!options_help[@]}" + do + arg=`echo ${options_help[$option]}|cut -d ':' -f1` + txt=`echo ${options_help[$option]}|cut -d ':' -f2` + tb="\t\t\t" + if [ -n "$arg" ]; then + arg=" $arg" + tb="\t" + fi + echo -e " -$option$arg:$tb$txt" + done + echo + echo "Examples of usage:-" + echo "# Example of signing the SYSFW binary with rsa degenerate key" + echo " $0 -c 0 -b ti-sci-firmware-am6x.bin -o sysfw.bin -l 0x40000" + echo "# Example of signing the SPL binary with rsa degenerate key" + echo " $0 -c 16 -b spl/u-boot-spl.bin -o tiboot3.bin -l 0x41c00000" +} + +options_help[b]="bin_file:Bin file that needs to be signed" +options_help[k]="key_file:file with key inside it. If not provided script generates a rsa degenerate key." +options_help[o]="output_file:Name of the final output file. default to $OUTPUT" +options_help[c]="core_id:target core id on which the image would be running. Default to $BOOTCORE" +options_help[l]="loadaddr: Target load address of the binary in hex. Default to $LOADADDR" + +while getopts "b:k:o:c:l:h" opt +do + case $opt in + b) + BIN=$OPTARG + ;; + k) + KEY=$OPTARG + ;; + o) + OUTPUT=$OPTARG + ;; + l) + LOADADDR=$OPTARG + ;; + c) + BOOTCORE=$OPTARG + ;; + h) + usage + exit 0 + ;; + ?) + usage "Invalid Option '-$OPTARG'" + exit 1 + ;; + :) + usage "Option '-$OPTARG' Needs an argument." + exit 1 + ;; + esac +done + +if [ "$#" -eq 0 ]; then + usage "Arguments missing" + exit 1 +fi + +if [ -z "$BIN" ]; then + usage "Bin file missing in arguments" + exit 1 +fi + +# Generate rsa degenerate key if user doesn't provide a key +if [ -z "$KEY" ]; then + gen_degen_key +fi + +if [ $BOOTCORE == 0 ]; then # BOOTCORE M3, loaded by ROM + CERTTYPE=2 +elif [ $BOOTCORE == 16 ]; then # BOOTCORE R5, loaded by ROM + CERTTYPE=1 +else # Non BOOTCORE, loaded by SYSFW + BOOTCORE_OPTS_VER=$(printf "%01x" 1) + # Add input args option for SET and CLR flags. + BOOTCORE_OPTS_SETFLAG=$(printf "%08x" 0) + BOOTCORE_OPTS_CLRFLAG=$(printf "%08x" 0x100) # Clear FLAG_ARMV8_AARCH32 + BOOTCORE_OPTS="0x$BOOTCORE_OPTS_VER$BOOTCORE_OPTS_SETFLAG$BOOTCORE_OPTS_CLRFLAG" + # Set the cert type to zero. + # We are not using public/private key store now + CERTTYPE=$(printf "0x%08x" 0) +fi + +SHA_VAL=`openssl dgst -sha512 -hex $BIN | sed -e "s/^.*= //g"` +BIN_SIZE=`cat $BIN | wc -c` +ADDR=`printf "%08x" $LOADADDR` + +gen_cert() { + #echo "Certificate being generated :" + #echo " LOADADDR = 0x$ADDR" + #echo " IMAGE_SIZE = $BIN_SIZE" + #echo " CERT_TYPE = $CERTTYPE" + sed -e "s/TEST_IMAGE_LENGTH/$BIN_SIZE/" \ + -e "s/TEST_IMAGE_SHA_VAL/$SHA_VAL/" \ + -e "s/TEST_CERT_TYPE/$CERTTYPE/" \ + -e "s/TEST_BOOT_CORE_OPTS/$BOOTCORE_OPTS/" \ + -e "s/TEST_BOOT_CORE/$BOOTCORE/" \ + -e "s/TEST_BOOT_ADDR/$ADDR/" x509-template.txt > $TEMP_X509 + openssl req -new -x509 -key $KEY -nodes -outform DER -out $CERT -config $TEMP_X509 -sha512 +} + +gen_template +gen_cert +cat $CERT $BIN > $OUTPUT + +# Remove all intermediate files +rm $TEMP_X509 $CERT x509-template.txt +if [ "$KEY" == "$RAND_KEY" ]; then + rm $RAND_KEY +fi

On Thu, May 02, 2019 at 03:35:50PM +0530, Lokesh Vutla wrote:
TI's K3 boot architecture mandates a x509 certificate for every boot image. While signing the image K3 ROM allows for two types of keys based on which the boot image gets loaded in different ways:
- Degenerate RSA keys: This generates a signature which is equal to the digest. When ROM sees this, it does a DMA for copying the images, which significantly improves the boot time.
- Any other key: Does a memcpy to load the image. This is introduced as a fallback for DMA copy.
Add a script for generating boot images with the above options. Default generates image using rsa degenerate key in order to improve boot time.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com Signed-off-by: Dave Gerlach d-gerlach@ti.com Signed-off-by: Andreas Dannenberg dannenberg@ti.com
Applied to u-boot/master, thanks!

Instead of overlading makefile, use the k3_gen_x509_cert.sh script to generate boot images.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- arch/arm/mach-k3/config.mk | 33 ++++---------------------- tools/k3_x509template.txt | 48 -------------------------------------- 2 files changed, 4 insertions(+), 77 deletions(-) delete mode 100644 tools/k3_x509template.txt
diff --git a/arch/arm/mach-k3/config.mk b/arch/arm/mach-k3/config.mk index 2d8f61f9db..f6b63db349 100644 --- a/arch/arm/mach-k3/config.mk +++ b/arch/arm/mach-k3/config.mk @@ -11,31 +11,11 @@ ifeq ($(shell which openssl),) $(error "No openssl in $(PATH), consider installing openssl") endif
-SHA_VALUE= $(shell openssl dgst -sha512 -hex $(obj)/u-boot-spl.bin | sed -e "s/^.*= //g") IMAGE_SIZE= $(shell cat $(obj)/u-boot-spl.bin | wc -c) -LOADADDR= $(shell echo $(CONFIG_SPL_TEXT_BASE) | sed -e "s/^0x//g") MAX_SIZE= $(shell printf "%d" $(CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE))
-# Parameters to get populated into the x509 template -SED_OPTS= -e s/TEST_IMAGE_LENGTH/$(IMAGE_SIZE)/ -SED_OPTS+= -e s/TEST_IMAGE_SHA_VAL/$(SHA_VALUE)/ -SED_OPTS+= -e s/TEST_CERT_TYPE/1/ # CERT_TYPE_PRIMARY_IMAGE_BIN -SED_OPTS+= -e s/TEST_BOOT_CORE/$(CONFIG_SYS_K3_BOOT_CORE_ID)/ -SED_OPTS+= -e s/TEST_BOOT_ARCH_WIDTH/32/ -SED_OPTS+= -e s/TEST_BOOT_ADDR/$(LOADADDR)/ - -# Command to generate ecparam key -quiet_cmd_genkey = OPENSSL $@ -cmd_genkey = openssl ecparam -out $@ -name prime256v1 -genkey - -# Command to generate x509 certificate -quiet_cmd_gencert = OPENSSL $@ -cmd_gencert = cat $(srctree)/tools/k3_x509template.txt | sed $(SED_OPTS) > u-boot-spl-x509.txt; \ - openssl req -new -x509 -key $(KEY) -nodes -outform DER -out $@ -config u-boot-spl-x509.txt -sha512 - -# If external key is not provided, generate key using openssl. ifeq ($(CONFIG_SYS_K3_KEY), "") -KEY=u-boot-spl-eckey.pem +KEY="" # On HS use real key or warn if not available ifeq ($(CONFIG_TI_SECURE_DEVICE),y) ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/keys/custMpk.pem),) @@ -48,15 +28,9 @@ else KEY=$(patsubst "%",$(srctree)/%,$(CONFIG_SYS_K3_KEY)) endif
-u-boot-spl-eckey.pem: FORCE - $(call if_changed,genkey) - # tiboot3.bin is mandated by ROM and ROM only supports R5 boot. # So restrict tiboot3.bin creation for CPU_V7R. ifdef CONFIG_CPU_V7R -u-boot-spl-cert.bin: $(KEY) $(obj)/u-boot-spl.bin image_check FORCE - $(call if_changed,gencert) - image_check: $(obj)/u-boot-spl.bin FORCE @if [ $(IMAGE_SIZE) -gt $(MAX_SIZE) ]; then \ echo "===============================================" >&2; \ @@ -66,8 +40,9 @@ image_check: $(obj)/u-boot-spl.bin FORCE exit 1; \ fi
-tiboot3.bin: u-boot-spl-cert.bin $(obj)/u-boot-spl.bin FORCE - $(call if_changed,cat) +tiboot3.bin: image_check FORCE + $(srctree)/tools/k3_gen_x509_cert.sh -c 16 -b $(obj)/u-boot-spl.bin \ + -o $@ -l $(CONFIG_SPL_TEXT_BASE) -k $(KEY)
ALL-y += tiboot3.bin endif diff --git a/tools/k3_x509template.txt b/tools/k3_x509template.txt deleted file mode 100644 index f176ff3ad2..0000000000 --- a/tools/k3_x509template.txt +++ /dev/null @@ -1,48 +0,0 @@ - [ req ] - distinguished_name = req_distinguished_name - x509_extensions = v3_ca - prompt = no - dirstring_type = nobmp - - [ req_distinguished_name ] - C = US - ST = TX - L = Dallas - O = Texas Instruments Incorporated - OU = Processors - CN = TI Support - emailAddress = support@ti.com - - [ v3_ca ] - basicConstraints = CA:true - 1.3.6.1.4.1.294.1.1 = ASN1:SEQUENCE:boot_seq - 1.3.6.1.4.1.294.1.2 = ASN1:SEQUENCE:image_integrity - 1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv -# 1.3.6.1.4.1.294.1.4 = ASN1:SEQUENCE:encryption - 1.3.6.1.4.1.294.1.8 = ASN1:SEQUENCE:debug - - [ boot_seq ] - certType = INTEGER:TEST_CERT_TYPE - bootCore = INTEGER:TEST_BOOT_CORE - bootCoreOpts = INTEGER:TEST_BOOT_ARCH_WIDTH - destAddr = FORMAT:HEX,OCT:TEST_BOOT_ADDR - imageSize = INTEGER:TEST_IMAGE_LENGTH - - [ image_integrity ] - shaType = OID:2.16.840.1.101.3.4.2.3 - shaValue = FORMAT:HEX,OCT:TEST_IMAGE_SHA_VAL - - [ swrv ] - swrv = INTEGER:0 - -# [ encryption ] -# initalVector = FORMAT:HEX,OCT:TEST_IMAGE_ENC_IV -# randomString = FORMAT:HEX,OCT:TEST_IMAGE_ENC_RS -# iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX -# salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT - - [ debug ] - debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000 - debugType = INTEGER:4 - coreDbgEn = INTEGER:0 - coreDbgSecEn = INTEGER:0

On Thu, May 02, 2019 at 03:35:51PM +0530, Lokesh Vutla wrote:
Instead of overlading makefile, use the k3_gen_x509_cert.sh script to generate boot images.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!

There is one case where 400ms is not sufficient for loading the system firmware: - System firmware is not signed with rsa degenerate key. - ROM loading the sysfw directly from SPI flash which is in memory mapped mode.
The above scenario is definitely not desired in production use cases as it effects boot time. But still keeping this support as this is a valid boot scenario.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- drivers/remoteproc/k3_system_controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/remoteproc/k3_system_controller.c b/drivers/remoteproc/k3_system_controller.c index 214ea18d8a..44e56c759f 100644 --- a/drivers/remoteproc/k3_system_controller.c +++ b/drivers/remoteproc/k3_system_controller.c @@ -301,7 +301,7 @@ static int k3_sysctrler_probe(struct udevice *dev)
static const struct k3_sysctrler_desc k3_sysctrler_am654_desc = { .host_id = 4, /* HOST_ID_R5_1 */ - .max_rx_timeout_us = 400000, + .max_rx_timeout_us = 800000, .max_msg_size = 60, };

On Thu, May 02, 2019 at 03:35:52PM +0530, Lokesh Vutla wrote:
There is one case where 400ms is not sufficient for loading the system firmware:
- System firmware is not signed with rsa degenerate key.
- ROM loading the sysfw directly from SPI flash which is in memory mapped mode.
The above scenario is definitely not desired in production use cases as it effects boot time. But still keeping this support as this is a valid boot scenario.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!
participants (2)
-
Lokesh Vutla
-
Tom Rini