1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3#
4# Script to add K3 specific x509 cetificate to a binary.
5#
6
7# Variables
8OUTPUT=tiboot3.bin
9TEMP_X509=x509-temp.cert
10CERT=certificate.bin
11RAND_KEY=eckey.pem
12LOADADDR=0x41c00000
13BOOTCORE_OPTS=0
14BOOTCORE=16
15DEBUG_TYPE=0
16
17gen_degen_template() {
18cat << 'EOF' > degen-template.txt
19
20asn1=SEQUENCE:rsa_key
21
22[rsa_key]
23version=INTEGER:0
24modulus=INTEGER:0xDEGEN_MODULUS
25pubExp=INTEGER:1
26privExp=INTEGER:1
27p=INTEGER:0xDEGEN_P
28q=INTEGER:0xDEGEN_Q
29e1=INTEGER:1
30e2=INTEGER:1
31coeff=INTEGER:0xDEGEN_COEFF
32EOF
33}
34
35# Generate x509 Template
36gen_template() {
37cat << 'EOF' > x509-template.txt
38 [ req ]
39 distinguished_name     = req_distinguished_name
40 x509_extensions        = v3_ca
41 prompt                 = no
42 dirstring_type         = nobmp
43
44 [ req_distinguished_name ]
45 C                      = US
46 ST                     = TX
47 L                      = Dallas
48 O                      = Texas Instruments Incorporated
49 OU                     = Processors
50 CN                     = TI support
51 emailAddress           = support@ti.com
52
53 [ v3_ca ]
54 basicConstraints = CA:true
55 1.3.6.1.4.1.294.1.1 = ASN1:SEQUENCE:boot_seq
56 1.3.6.1.4.1.294.1.2 = ASN1:SEQUENCE:image_integrity
57 1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv
58# 1.3.6.1.4.1.294.1.4 = ASN1:SEQUENCE:encryption
59 1.3.6.1.4.1.294.1.8 = ASN1:SEQUENCE:debug
60
61 [ boot_seq ]
62 certType = INTEGER:TEST_CERT_TYPE
63 bootCore = INTEGER:TEST_BOOT_CORE
64 bootCoreOpts = INTEGER:TEST_BOOT_CORE_OPTS
65 destAddr = FORMAT:HEX,OCT:TEST_BOOT_ADDR
66 imageSize = INTEGER:TEST_IMAGE_LENGTH
67
68 [ image_integrity ]
69 shaType = OID:2.16.840.1.101.3.4.2.3
70 shaValue = FORMAT:HEX,OCT:TEST_IMAGE_SHA_VAL
71
72 [ swrv ]
73 swrv = INTEGER:0
74
75# [ encryption ]
76# initalVector = FORMAT:HEX,OCT:TEST_IMAGE_ENC_IV
77# randomString = FORMAT:HEX,OCT:TEST_IMAGE_ENC_RS
78# iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX
79# salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT
80
81 [ debug ]
82 debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000
83 debugType = INTEGER:TEST_DEBUG_TYPE
84 coreDbgEn = INTEGER:0
85 coreDbgSecEn = INTEGER:0
86EOF
87}
88
89parse_key() {
90	sed '/\ \ \ \ /s/://g' key.txt | awk  '!/\ \ \ \ / {printf("\n%s\n", $0)}; /\ \ \ \ / {printf("%s", $0)}' | sed 's/\ \ \ \ //g' | awk "/$1:/{getline; print}"
91}
92
93gen_degen_key() {
94# Generate a 4096 bit RSA Key
95	openssl genrsa -out key.pem 1024 >>/dev/null 2>&1
96	openssl rsa -in key.pem -text -out key.txt >>/dev/null 2>&1
97	DEGEN_MODULUS=$( parse_key 'modulus' )
98	DEGEN_P=$( parse_key 'prime1' )
99	DEGEN_Q=$( parse_key 'prime2' )
100	DEGEN_COEFF=$( parse_key 'coefficient' )
101	gen_degen_template
102
103	sed -e "s/DEGEN_MODULUS/$DEGEN_MODULUS/"\
104		-e "s/DEGEN_P/$DEGEN_P/" \
105		-e "s/DEGEN_Q/$DEGEN_Q/" \
106		-e "s/DEGEN_COEFF/$DEGEN_COEFF/" \
107		 degen-template.txt > degenerateKey.txt
108
109	openssl asn1parse -genconf degenerateKey.txt -out degenerateKey.der >>/dev/null 2>&1
110	openssl rsa -in degenerateKey.der -inform DER -outform PEM -out $RAND_KEY >>/dev/null 2>&1
111	KEY=$RAND_KEY
112	rm key.pem key.txt degen-template.txt degenerateKey.txt degenerateKey.der
113}
114
115declare -A options_help
116usage() {
117	if [ -n "$*" ]; then
118		echo "ERROR: $*"
119	fi
120	echo -n "Usage: $0 "
121	for option in "${!options_help[@]}"
122	do
123		arg=`echo ${options_help[$option]}|cut -d ':' -f1`
124		if [ -n "$arg" ]; then
125			arg=" $arg"
126		fi
127		echo -n "[-$option$arg] "
128	done
129	echo
130	echo -e "\nWhere:"
131	for option in "${!options_help[@]}"
132	do
133		arg=`echo ${options_help[$option]}|cut -d ':' -f1`
134		txt=`echo ${options_help[$option]}|cut -d ':' -f2`
135		tb="\t\t\t"
136		if [ -n "$arg" ]; then
137			arg=" $arg"
138			tb="\t"
139		fi
140		echo -e "   -$option$arg:$tb$txt"
141	done
142	echo
143	echo "Examples of usage:-"
144	echo "# Example of signing the SYSFW binary with rsa degenerate key"
145	echo "    $0 -c 0 -b ti-sci-firmware-am6x.bin -o sysfw.bin -l 0x40000"
146	echo "# Example of signing the SPL binary with rsa degenerate key"
147	echo "    $0 -c 16 -b spl/u-boot-spl.bin -o tiboot3.bin -l 0x41c00000"
148}
149
150options_help[b]="bin_file:Bin file that needs to be signed"
151options_help[k]="key_file:file with key inside it. If not provided script generates a rsa degenerate key."
152options_help[o]="output_file:Name of the final output file. default to $OUTPUT"
153options_help[c]="core_id:target core id on which the image would be running. Default to $BOOTCORE"
154options_help[l]="loadaddr: Target load address of the binary in hex. Default to $LOADADDR"
155options_help[d]="debug_type: Debug type, set to 4 to enable early JTAG. Default to $DEBUG_TYPE"
156
157while getopts "b:k:o:c:l:d:h" opt
158do
159	case $opt in
160	b)
161		BIN=$OPTARG
162	;;
163	k)
164		KEY=$OPTARG
165	;;
166	o)
167		OUTPUT=$OPTARG
168	;;
169	l)
170		LOADADDR=$OPTARG
171	;;
172	c)
173		BOOTCORE=$OPTARG
174	;;
175	d)
176		DEBUG_TYPE=$OPTARG
177	;;
178	h)
179		usage
180		exit 0
181	;;
182	\?)
183		usage "Invalid Option '-$OPTARG'"
184		exit 1
185	;;
186	:)
187		usage "Option '-$OPTARG' Needs an argument."
188		exit 1
189	;;
190	esac
191done
192
193if [ "$#" -eq 0 ]; then
194	usage "Arguments missing"
195	exit 1
196fi
197
198if [ -z "$BIN" ]; then
199	usage "Bin file missing in arguments"
200	exit 1
201fi
202
203# Generate rsa degenerate key if user doesn't provide a key
204if [ -z "$KEY" ]; then
205	gen_degen_key
206fi
207
208if [ $BOOTCORE == 0 ]; then	# BOOTCORE M3, loaded by ROM
209	CERTTYPE=2
210elif [ $BOOTCORE == 16 ]; then	# BOOTCORE R5, loaded by ROM
211	CERTTYPE=1
212else				# Non BOOTCORE, loaded by SYSFW
213	BOOTCORE_OPTS_VER=$(printf "%01x" 1)
214	# Add input args option for SET and CLR flags.
215	BOOTCORE_OPTS_SETFLAG=$(printf "%08x" 0)
216	BOOTCORE_OPTS_CLRFLAG=$(printf "%08x" 0x100) # Clear FLAG_ARMV8_AARCH32
217	BOOTCORE_OPTS="0x$BOOTCORE_OPTS_VER$BOOTCORE_OPTS_SETFLAG$BOOTCORE_OPTS_CLRFLAG"
218	# Set the cert type to zero.
219	# We are not using public/private key store now
220	CERTTYPE=$(printf "0x%08x" 0)
221fi
222
223SHA_VAL=`openssl dgst -sha512 -hex $BIN | sed -e "s/^.*= //g"`
224BIN_SIZE=`cat $BIN | wc -c`
225ADDR=`printf "%08x" $LOADADDR`
226
227gen_cert() {
228	#echo "Certificate being generated :"
229	#echo "	LOADADDR = 0x$ADDR"
230	#echo "	IMAGE_SIZE = $BIN_SIZE"
231	#echo "	CERT_TYPE = $CERTTYPE"
232	#echo "	DEBUG_TYPE = $DEBUG_TYPE"
233	sed -e "s/TEST_IMAGE_LENGTH/$BIN_SIZE/"	\
234		-e "s/TEST_IMAGE_SHA_VAL/$SHA_VAL/" \
235		-e "s/TEST_CERT_TYPE/$CERTTYPE/" \
236		-e "s/TEST_BOOT_CORE_OPTS/$BOOTCORE_OPTS/" \
237		-e "s/TEST_BOOT_CORE/$BOOTCORE/" \
238		-e "s/TEST_BOOT_ADDR/$ADDR/" \
239		-e "s/TEST_DEBUG_TYPE/$DEBUG_TYPE/" \
240		x509-template.txt > $TEMP_X509
241	openssl req -new -x509 -key $KEY -nodes -outform DER -out $CERT -config $TEMP_X509 -sha512
242}
243
244gen_template
245gen_cert
246cat $CERT $BIN > $OUTPUT
247
248# Remove all intermediate files
249rm $TEMP_X509 $CERT x509-template.txt
250if [ "$KEY" == "$RAND_KEY" ]; then
251	rm $RAND_KEY
252fi
253