| #!/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 |
| DEBUG_TYPE=0 |
| SWRV=1 |
| |
| 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:TEST_SWRV |
| |
| # [ 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:TEST_DEBUG_TYPE |
| 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" |
| options_help[d]="debug_type: Debug type, set to 4 to enable early JTAG. Default to $DEBUG_TYPE" |
| options_help[r]="SWRV: Software Rev for X509 certificate" |
| |
| while getopts "b:k:o:c:l:d:h:r:" opt |
| do |
| case $opt in |
| b) |
| BIN=$OPTARG |
| ;; |
| k) |
| KEY=$OPTARG |
| ;; |
| o) |
| OUTPUT=$OPTARG |
| ;; |
| l) |
| LOADADDR=$OPTARG |
| ;; |
| c) |
| BOOTCORE=$OPTARG |
| ;; |
| d) |
| DEBUG_TYPE=$OPTARG |
| ;; |
| r) |
| SWRV=$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" |
| #echo " DEBUG_TYPE = $DEBUG_TYPE" |
| echo " SWRV = $SWRV" |
| 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/" \ |
| -e "s/TEST_DEBUG_TYPE/$DEBUG_TYPE/" \ |
| -e "s/TEST_SWRV/$SWRV/" \ |
| 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 |