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