include: Add AM65X specific headers corresponding to SYSFW
[processor-firmware/system-firmware-image-gen.git] / gen_x509_cert.sh
1 #!/bin/bash
2 #
3 # Script to add x509 certificate to binary/ELF
4 #
5 # Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
6 #
7 #  Redistribution and use in source and binary forms, with or without
8 #  modification, are permitted provided that the following conditions
9 #  are met:
10 #
11 #    Redistributions of source code must retain the above copyright
12 #    notice, this list of conditions and the following disclaimer.
13 #
14 #    Redistributions in binary form must reproduce the above copyright
15 #    notice, this list of conditions and the following disclaimer in the
16 #    documentation and/or other materials provided with the
17 #    distribution.
18 #
19 #    Neither the name of Texas Instruments Incorporated nor the names of
20 #    its contributors may be used to endorse or promote products derived
21 #    from this software without specific prior written permission.
22 #
23 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 #  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 #  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 #  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 #  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 #  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 #  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 #  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 #  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 #  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 #  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #
36 # Variables
37 VALID_SHAS="sha256 sha384 sha512 sha224"
38 OUTPUT=x509-firmware.bin
39 TEMP_X509=x509-temp.cert
40 CERT=certificate.bin
41 RAND_KEY=eckey.pem
42 VALID_ROM_CORES="r5 m3"
43 VALID_DMSC_CORES="r5-00 r5-01 a53-00 a53-01 a53-10 a53-11"
44 SHA=sha512
45 CORE=m3
46 LOADADDR=0x00040000
47 VALID_MASTERS="rom dmsc"
49 declare -A sha_oids
50 sha_oids["sha256"]=2.16.840.1.101.3.4.2.1
51 sha_oids["sha384"]=2.16.840.1.101.3.4.2.2
52 sha_oids["sha512"]=2.16.840.1.101.3.4.2.3
53 sha_oids["sha224"]=2.16.840.1.101.3.4.2.4
55 declare -A core_ids
56 core_ids["a53-00"]=0x20
57 core_ids["a53-01"]=0x21
58 core_ids["a53-10"]=0x22
59 core_ids["a53-11"]=0x23
60 core_ids["r5-00"]=0x01
61 core_ids["r5-01"]=0x02
63 gen_key() {
64         openssl ecparam -out $RAND_KEY -name prime256v1 -genkey
65         KEY=$RAND_KEY
66 }
68 declare -A options_help
69 usage() {
70         if [ -n "$*" ]; then
71                 echo "ERROR: $*"
72         fi
73         echo -n "Usage: $0 "
74         for option in "${!options_help[@]}"
75         do
76                 arg=`echo ${options_help[$option]}|cut -d ':' -f1`
77                 if [ -n "$arg" ]; then
78                         arg=" $arg"
79                 fi
80                 echo -n "[-$option$arg] "
81         done
82         echo
83         echo -e "\nWhere:"
84         for option in "${!options_help[@]}"
85         do
86                 arg=`echo ${options_help[$option]}|cut -d ':' -f1`
87                 txt=`echo ${options_help[$option]}|cut -d ':' -f2`
88                 tb="\t\t\t"
89                 if [ -n "$arg" ]; then
90                         arg=" $arg"
91                         tb="\t"
92                 fi
93                 echo -e "   -$option$arg:$tb$txt"
94         done
95         echo
96         echo "Examples of usage:-"
97         echo "# Generate x509 certificate with random key from elf"
98         echo "    CROSS_COMPILE=arm-linux-gnueabihf- $0 -b ti-sci-firmware-am6x.elf -o dmsc.bin -l 0x40000"
99         echo "# Generate x509 certificate with random key from bin"
100         echo "    $0 -b ti-sci-firmware-am6x.bin -o dmsc.bin -l 0x40000"
101         echo "# Example of signing the DMSC binary"
102         echo "    $0 -m rom -c m3 -b ti-sci-firmware-am6x.bin -o dmsc.bin -l 0x40000"
103         echo "# Example of signing the SPL binary"
104         echo "    $0 -m rom -c r5 -b spl/u-boot-spl.bin -o tiboot3.bin -l 0x41c00000"
105         echo "# Example of signing the ATF binary to run on A53"
106         echo "    $0 -m dmsc -c a53-00 -b bl31.bin -o atf.bin -l 0x70000000"
109 options_help[e]="elf_file:ELF file that needs to be signed"
110 options_help[b]="bin_file:Bin file that needs to be signed"
111 options_help[k]="key_file:file with key inside it. If not provided script generates a random key."
112 options_help[o]="output_file:Name of the final output file. default x509-firmware.bin"
113 options_help[c]="core:target core on which the image would be running. Default is m3. Valid option for rom are $VALID_ROM_CORES. Valid options for DMSC are $VALID_DMSC_CORES"
114 options_help[d]=":Countersign DMSC firmware image. This signs a previously signed image for a second time."
115 options_help[s]="sha_type:sha type to be used for certificate generation. Default is sha512. Valid option are $VALID_SHAS"
116 options_help[l]="loadaddr: Target load address of the binary in hex. Default to $LOADADDR"
117 options_help[m]="master: Master name for which the image is created. This master software parses the certificate and load the images accordingly. Default to rom. valid options are $VALID_MASTERS"
119 while getopts "e:b:k:o:c:ds:l:m:h" opt
120 do
121         case $opt in
122         e)
123                 ELF=$OPTARG
124         ;;
125         b)
126                 BIN=$OPTARG
127         ;;
128         k)
129                 KEY=$OPTARG
130         ;;
131         o)
132                 OUTPUT=$OPTARG
133         ;;
134         l)
135                 LOADADDR=$OPTARG
136         ;;
137         s)
138                 SHA=$OPTARG
139                 sha_valid=0
140                 for tsha in $VALID_SHAS
141                 do
142                         if [ "$tsha" == "$SHA" ]; then
143                                 sha_valid=1
144                         fi
145                 done
146                 if [ $sha_valid == 0 ]; then
147                         usage "Invalid sha input $SHA"
148                         exit 1
149                 fi
150         ;;
151         c)
152                 CORE=$OPTARG
153         ;;
154         d)
155                 CERTTYPE=3      # CERT_TYPE_FIRMWARE_COUNTERSIGN
156         ;;
157         m)
158                 MASTER=$OPTARG
159                 master_valid=0
160                 for vmaster in $VALID_MASTERS
161                 do
162                         if [ "$vmaster" == "$MASTER" ]; then
163                                 master_valid=1
164                         fi
165                 done
166                 if [ $master_valid == 0 ]; then
167                         usage "Invalid master input $MASTER"
168                         exit 1
169                 fi
170         ;;
171         h)
172                 usage
173                 exit 0
174         ;;
175         \?)
176                 usage "Invalid Option '-$OPTARG'"
177                 exit 1
178         ;;
179         :)
180                 usage "Option '-$OPTARG' Needs an argument."
181                 exit 1
182         ;;
183         esac
184 done
186 if [ "$#" -eq 0 ]
187 then
188         usage "Arguments missing"
189         exit 1
190 fi
192 if [ -z "$BIN" -a -z "$ELF" ]; then
193         usage "Either Input bin file or ELF file to sign"
194         exit 1
195 fi
197 if [ "$MASTER" == "dmsc" ]; then
198         VALID_CORES=$VALID_DMSC_CORES
199 else
200         # Defaut to ROM image
201         VALID_CORES=$VALID_ROM_CORES
202         MASTER="rom"
203 fi
205 # Verify for valid core inputs
206 core_valid=0
207 for tcore in $VALID_CORES
208 do
209         if [ "$tcore" == "$CORE" ]; then
210                 core_valid=1
211         fi
212 done
213 if [ $core_valid == 0 ]; then
214         usage "Invalid target core $CORE"
215         exit 1
216 fi
218 # Generate random key if user doesn't provide a key
219 if [ -z "$KEY" ]; then
220         gen_key
221 fi
223 if [ "$MASTER" == "dmsc" ]; then
224         BOOTCORE=${core_ids["$CORE"]}
225         BOOTCORE_OPTS_VER=$(printf "%01x" 1)
226         # Add input args option for SET and CLR flags.
227         BOOTCORE_OPTS_SETFLAG=$(printf "%08x" 0)
228         BOOTCORE_OPTS_CLRFLAG=$(printf "%08x" 0x100) # Clear FLAG_ARMV8_AARCH32
229         BOOTCORE_OPTS="0x$BOOTCORE_OPTS_VER$BOOTCORE_OPTS_SETFLAG$BOOTCORE_OPTS_CLRFLAG"
230         # Set the cert type to zero.
231         # We are not using public/private key store now
232         CERTTYPE=$(printf "0x%08x" 0)
233 else
234         if [ "$CORE" == "m3" ]; then
235                 if [ -z "$CERTTYPE" ]; then
236                         CERTTYPE=2      # CERT_TYPE_FIRMWARE_IMAGE_BIN
237                 fi
238                 BOOTCORE=0              # DMSC Controller (M3)
239                 BOOTCORE_OPTS=32
240         else
241                 CERTTYPE=1              # CERT_TYPE_PRIMARY_IMAGE_BIN
242                 BOOTCORE=16             # MCU (R5)
243                 BOOTCORE_OPTS=32
244         fi
245 fi
247 if [ -z "$BIN" ]; then
248         echo "Generating bin from elf $ELF"
249         BIN=firmware.bin
250         ${CROSS_COMPILE}objcopy -g -S --gap-fill 0x0 -O binary $ELF $BIN
251         if [ "$?" != "0" ]; then
252                 echo "ERROR: Generating bin from $ELF failed. CROSS_COMPILE?"
253                 exit 1
254         fi
255 fi
257 SHA_OID=${sha_oids["$SHA"]}
258 SHA_VAL=`openssl dgst -$SHA -hex $BIN | sed -e "s/^.*= //g"`
259 BIN_SIZE=`cat $BIN | wc -c`
260 ADDR=`printf "%08x" $LOADADDR`
262 # Generate x509 Template
263 gen_template() {
264 cat << 'EOF' > x509-template.txt
265  [ req ]
266  distinguished_name     = req_distinguished_name
267  x509_extensions        = v3_ca
268  prompt                 = no
269  dirstring_type         = nobmp
271  [ req_distinguished_name ]
272  C                      = US
273  ST                     = TX
274  L                      = Dallas
275  O                      = Texas Instruments Incorporated
276  OU                     = Processors
277  CN                     = TI Support
278  emailAddress           = support@ti.com
280  [ v3_ca ]
281  basicConstraints = CA:true
282  1.3.6.1.4.1.294.1.1 = ASN1:SEQUENCE:boot_seq
283  1.3.6.1.4.1.294.1.2 = ASN1:SEQUENCE:image_integrity
284  1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv
285 # 1.3.6.1.4.1.294.1.4 = ASN1:SEQUENCE:encryption
286  1.3.6.1.4.1.294.1.8 = ASN1:SEQUENCE:debug
288  [ boot_seq ]
289  certType = INTEGER:TEST_CERT_TYPE
290  bootCore = INTEGER:TEST_BOOT_CORE
291  bootCoreOpts = INTEGER:TEST_BOOT_CORE_OPTS
292  destAddr = FORMAT:HEX,OCT:TEST_BOOT_ADDR
293  imageSize = INTEGER:TEST_IMAGE_LENGTH
295  [ image_integrity ]
296  shaType = OID:TEST_IMAGE_SHA_OID
297  shaValue = FORMAT:HEX,OCT:TEST_IMAGE_SHA_VAL
299  [ swrv ]
300  swrv = INTEGER:0
302 # [ encryption ]
303 # initalVector = FORMAT:HEX,OCT:TEST_IMAGE_ENC_IV
304 # randomString = FORMAT:HEX,OCT:TEST_IMAGE_ENC_RS
305 # iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX
306 # salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT
308  [ debug ]
309  debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000
310  debugType = INTEGER:4
311  coreDbgEn = INTEGER:0
312  coreDbgSecEn = INTEGER:0
313 EOF
316 gen_cert() {
317         echo "Certificate being generated :"
318         echo "  LOADADDR = 0x$ADDR"
319         echo "  IMAGE_SIZE = $BIN_SIZE"
320         echo "  CERT_TYPE = $CERTTYPE"
321         sed -e "s/TEST_IMAGE_LENGTH/$BIN_SIZE/" \
322                 -e "s/TEST_IMAGE_SHA_OID/$SHA_OID/" \
323                 -e "s/TEST_IMAGE_SHA_VAL/$SHA_VAL/" \
324                 -e "s/TEST_CERT_TYPE/$CERTTYPE/" \
325                 -e "s/TEST_BOOT_CORE_OPTS/$BOOTCORE_OPTS/" \
326                 -e "s/TEST_BOOT_CORE/$BOOTCORE/" \
327                 -e "s/TEST_BOOT_ADDR/$ADDR/" x509-template.txt > $TEMP_X509
328         openssl req -new -x509 -key $KEY -nodes -outform DER -out $CERT -config $TEMP_X509 -$SHA
331 gen_template
332 gen_cert
333 cat $CERT $BIN > $OUTPUT
335 echo "SUCCESS: Image $OUTPUT generated."
337 # Remove all intermediate files
338 rm $TEMP_X509 $CERT x509-template.txt
339 if [ "$KEY" == "$RAND_KEY" ]; then
340         rm $RAND_KEY
341 fi