diff options
author | Andreas Dannenberg | 2018-08-31 13:09:00 -0500 |
---|---|---|
committer | Andreas Dannenberg | 2018-09-13 13:43:39 -0500 |
commit | 00f62b3e8b3b02a17b8d08686f1a907d6a395ff9 (patch) | |
tree | 95775d7d1f7902a2e9a64d2a6039a46ceb1c3929 /gen_x509_cert.sh | |
download | k3-image-gen-00f62b3e8b3b02a17b8d08686f1a907d6a395ff9.tar.gz k3-image-gen-00f62b3e8b3b02a17b8d08686f1a907d6a395ff9.tar.xz k3-image-gen-00f62b3e8b3b02a17b8d08686f1a907d6a395ff9.zip |
Introduce framework to build SYSFW and config data into an ITB
In order to be able to consume system firmware (SYSFW) as well as the
associated configuration data from the boot media introduce a framework
that allows building the SYSFW image itself as well as the different
domain-specific configuration fragments (board, pm, rm, and sec) into an
image tree blob (ITB) file called sysfw.itb.
To establish a known-good starting point for development and testing use
U-Boot commit 7501705610 ("arm: K3: am654: Update board config for
v2018.07a enforcement in 2018.08 release of sysfw") as a baseline for the
AM654x board configuration data. Furthermore integrate SYSFW v2018.08b as
released on 09/12/2018 by way of download URL.
See included README.md for a more complete description.
Signed-off-by: Andreas Dannenberg <dannenberg@ti.com>
Diffstat (limited to 'gen_x509_cert.sh')
-rwxr-xr-x | gen_x509_cert.sh | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/gen_x509_cert.sh b/gen_x509_cert.sh new file mode 100755 index 000000000..e5ce09b84 --- /dev/null +++ b/gen_x509_cert.sh | |||
@@ -0,0 +1,341 @@ | |||
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 | # | ||
35 | |||
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" | ||
48 | |||
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 | ||
54 | |||
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 | ||
62 | |||
63 | gen_key() { | ||
64 | openssl ecparam -out $RAND_KEY -name prime256v1 -genkey | ||
65 | KEY=$RAND_KEY | ||
66 | } | ||
67 | |||
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" | ||
107 | } | ||
108 | |||
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" | ||
118 | |||
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 | ||
185 | |||
186 | if [ "$#" -eq 0 ] | ||
187 | then | ||
188 | usage "Arguments missing" | ||
189 | exit 1 | ||
190 | fi | ||
191 | |||
192 | if [ -z "$BIN" -a -z "$ELF" ]; then | ||
193 | usage "Either Input bin file or ELF file to sign" | ||
194 | exit 1 | ||
195 | fi | ||
196 | |||
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 | ||
204 | |||
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 | ||
217 | |||
218 | # Generate random key if user doesn't provide a key | ||
219 | if [ -z "$KEY" ]; then | ||
220 | gen_key | ||
221 | fi | ||
222 | |||
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 | ||
246 | |||
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 | ||
256 | |||
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` | ||
261 | |||
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 | ||
270 | |||
271 | [ req_distinguished_name ] | ||
272 | C = US | ||
273 | ST = SC | ||
274 | L = New York | ||
275 | O = Texas Instruments, Inc. | ||
276 | OU = DSP | ||
277 | CN = Albert | ||
278 | emailAddress = Albert@gt.ti.com | ||
279 | |||
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 | ||
287 | |||
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 | ||
294 | |||
295 | [ image_integrity ] | ||
296 | shaType = OID:TEST_IMAGE_SHA_OID | ||
297 | shaValue = FORMAT:HEX,OCT:TEST_IMAGE_SHA_VAL | ||
298 | |||
299 | [ swrv ] | ||
300 | swrv = INTEGER:0 | ||
301 | |||
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 | ||
307 | |||
308 | [ debug ] | ||
309 | debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000 | ||
310 | debugType = INTEGER:4 | ||
311 | coreDbgEn = INTEGER:0 | ||
312 | coreDbgSecEn = INTEGER:0 | ||
313 | EOF | ||
314 | } | ||
315 | |||
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 | ||
329 | } | ||
330 | |||
331 | gen_template | ||
332 | gen_cert | ||
333 | cat $CERT $BIN > $OUTPUT | ||
334 | |||
335 | echo "SUCCESS: Image $OUTPUT generated." | ||
336 | |||
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 | ||