1# Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. 2# 3# This program is free software; you can redistribute it and/or 4# modify it under the terms of the GNU General Public License 5# as published by the Free Software Foundation; either version 2 6# of the License, or (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software 15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 17#! /bin/sh 18 19#If want to decrypt ddr_init.bin,u-boot.bin and their signatures, 20#you must to set the KEY and IV for aes, and IV can't be zero; 21#otherwise, ddr_init.bin, u-boot.bin and their signatures would 22#not be decrypted. 23 24#The IV and KEY must be used at the same time. 25 26#The length of IV should be 16 Byte. 27IV= 28 29#The length of KEY should be 32 Byte. 30KEY= 31 32#please set ddr_file uboot_file 33ddr_init_file=ddr_init_reg_info.bin 34uboot_file=u-boot-original.bin 35 36if [ ! -e $uboot_file ] || [ ! -e $ddr_init_file ];then 37echo ================================================================================== 38echo " please set ddr_init_file/uboot_file !!! " 39echo ================================================================================== 40exit 1 ; 41fi 42echo ""; 43echo "usage:"; 44echo " ddr_init_file = $ddr_init_file"; 45echo "" 46echo " uboot_file = $uboot_file"; 47echo ""; 48echo " IV = $IV"; 49echo ""; 50echo " KEY = $KEY"; 51echo ""; 52 53 54dec2hex(){ 55 printf "0x%08x" $1 56} 57 58function H_TO_NL { 59 local tmp1=$[$1 & 0xff] 60 local tmp2=$[$[$1 & 0xff00] >> 8] 61 local tmp3=$[$[$1 & 0xff0000] >> 16] 62 local tmp4=$[$[$1 & 0xff000000] >> 24] 63 local val=$[$[$tmp1 << 24] | $[$tmp2 << 16] | $[$tmp3 << 8] | $tmp4] 64 65 echo $val 66} 67 68function HASH_OTP_TABLE { 69 Str=`cat $1` 70 echo $Str > $2 71 echo ================================================================================== >> $2 72 echo "input_file: $1" >> $2 73 echo ================================================================================== >> $2 74 for((i=0; i<64; i=i+8)) 75 do 76 word=${Str:i:8}; 77 word=$(printf "0x%s" $word) 78 word=$(H_TO_NL $word) 79 word=$(printf "0x%08x" $word) 80 reg=$[0x100b000c + $(($i/2))] # OTP reg 81 reg=$(printf "%08x" $reg) 82 echo rootkey_hash[$(($i/8))]=mw 0x$reg $word >> $2 83 done 84} 85 86function AES_OTP_TABLE { 87 Str=$1 88 echo "AES KEY FILE" > $2 89 echo ================================================================================== >> $2 90 echo "AES KEY:: $1" >> $2 91 echo ================================================================================== >> $2 92 for((i=0; i<64; i=i+8)) 93 do 94 word=${Str:i:8}; 95 word=$(printf "0x%s" $word) 96 word=$(H_TO_NL $word) 97 word=$(printf "0x%08x" $word) 98 reg=$[0x100b000c + $(($i/2))] # OTP reg 99 reg=$(printf "%08x" $reg) 100 echo aes_key_val[$(($i/8))]=mw 0x$reg $word >> $2 101 done 102} 103 104##################2048############################ 105if [ $1 = "rsa2048pem_gen" ];then 106if [ -f rsa2048pem/rsa_pub_2048.pem ]; then 107echo "....................rsa_2048........................." 108#4:RSA_pub N+E 109openssl base64 -d -in rsa2048pem/rsa_pub_2048.pem -out private.bin 110dd if=./private.bin of=./fb1 bs=1 skip=33 count=256 111for((i=1;i<=253;i++)) 112do 113 echo 0x00 | xxd -r >> fb2 114done 115dd if=./private.bin of=./fb3 bs=1 skip=291 count=3 116cat fb1 fb2 fb3 > all.bin 117cp all.bin rsa2048pem/rsa_pub_2048.bin 118filesize=`wc -c < all.bin` 119if [ $filesize == 512 ];then 120echo "" 121echo 0:RSA_PUB creat OK! 122echo RSA_PUB file_size = $filesize 123echo "" 124else 125echo 0:RSA_PUB creat error! 126echo RSA_PUB file_size = $filesize 127echo "" 128fi 129rm -f fb1 fb2 fb3 private.bin 130 131#5:IV 132if [ $IV ];then 133echo 0x$IV | xxd -r >> all.bin 134else 135echo 0x00000000000000000000000000000000 | xxd -r >> all.bin 136fi 137 138#6:DDR_len 139#1)The ddr image must be filled with 16 bytes. 140filesize=`wc -c < $ddr_init_file` 141echo "1:The ddr image must be 16-byte aligned!" 142echo $ddr_init_file dec_size = $filesize 143a=$(($filesize % 16)) 144if [ $a == 0 ];then 145b=0 146else 147b=$((16-$a)) 148fi 149cp $ddr_init_file ddr_16byte_alig.bin 150for((i=1;i<=$b;i++)) 151do 152 echo 0x00 | xxd -r >> ddr_16byte_alig.bin 153done 154filesize=`wc -c < ddr_16byte_alig.bin` 155echo ddr_16byte_alig.bin dec_size = $filesize 156echo "" 157#2)fill iamge len 158a=$(dec2hex $filesize) 159a=$(H_TO_NL $a) 160a=$(dec2hex $a) 161echo $a | xxd -r > ddr_len.txt 162#big_lit ddr_len.txt 163cat ddr_len.txt >> all.bin 164 165#7:DDR.BIN 166cat ddr_16byte_alig.bin >> all.bin 167 168#8:ddr_sig 169openssl dgst -sha256 -sign rsa2048pem/rsa_priv_2048.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out ddr_sig.bin ddr_16byte_alig.bin 170if [ -f ddr_sig.bin ]; then 171echo 2:creat ddr_sig.bin ok! 172echo "" 173fi 174 175cat ddr_sig.bin >> all.bin 176 177#9:u-boot_len 178#1)The boot image must be filled with 16 bytes. 179filesize=`wc -c < $uboot_file` 180echo "3:The boot image must be 16-byte aligned!" 181echo $uboot_file dec_size = $filesize 182a=$(($filesize % 16)) 183if [ $a == 0 ];then 184b=0 185else 186b=$((16-$a)) 187fi 188cp $uboot_file uboot_16byte_alig.bin 189for((i=1;i<=$b;i++)) 190do 191 echo 0x00 | xxd -r >> uboot_16byte_alig.bin 192done 193#2)fill iamge len 194filesize=`wc -c < uboot_16byte_alig.bin` 195filesize=$[filesize] 196echo uboot_16byte_alig.bin dec_size = $filesize 197echo "" 198a=$(dec2hex $filesize) 199a=$(H_TO_NL $a) 200a=$(dec2hex $a) 201echo $a | xxd -r > uboot_len.txt 202#big_lit uboot_len.txt 203cat uboot_len.txt >> all.bin 204 205#10:u-boot.bin + uboot_sing.bin 206if [ $KEY ]; then 207#IV and KEY have set, 208#1) Obtain a new KEY by decrypting the ECB mode. 209echo 0x50db86c592c52f0c436cca6f2ffecaf5 | xxd -r > seed_1.bin 210echo 0x4a96ae013fc60e205e9da4c9d5ad9b99 | xxd -r > seed_2.bin 211openssl enc -nopad -d -nosalt -aes-256-ecb -K "$KEY" -in seed_1.bin -out out_1.bin 212openssl enc -nopad -d -nosalt -aes-256-ecb -K "$KEY" -in seed_2.bin -out out_2.bin 213cat out_2.bin >> out_1.bin 214KEY_ecb=$(xxd -ps out_1.bin | sed 'N;s/\n//g') 215rm out_*.bin seed_*.bin 216echo 4:Obtain a new KEY by decrypting the ECB mode! 217echo new_KEY = $KEY_ecb 218echo "" 219#boot_sig+boot ---->> openssl_cbc ------>> cbc mode boot 220#2)boot_sig+boot 221openssl dgst -sha256 -sign rsa2048pem/rsa_priv_2048.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out uboot_sig.bin uboot_16byte_alig.bin 222if [ -f uboot_sig.bin ];then 223echo 5:AES:creat uboot_sig.bin OK! 224echo "" 225else 226echo 5:AES:creat uboot_sig.bin error! 227echo "" 228fi 229cp uboot_16byte_alig.bin u-cbc.bin 230cat uboot_sig.bin >> u-cbc.bin 231#3) Use the new KEY and IV to encrypt the image in CBC mode. 232if [ $IV ];then 233openssl enc -aes-256-cbc -nopad -K "$KEY_ecb" -iv "$IV" -in u-cbc.bin -out cbc_boot.bin 234else 235echo error: please set IV! 236fi 237cat cbc_boot.bin >> all.bin 238rm u-cbc.bin cbc_boot.bin 239 240else 241#If the IV and KEY are not set, use the default image. 242#1)boot_bin 243cat uboot_16byte_alig.bin >> all.bin 244#2):boot_sig 245openssl dgst -sha256 -sign rsa2048pem/rsa_priv_2048.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out uboot_sig.bin uboot_16byte_alig.bin 246if [ -f uboot_sig.bin ];then 247echo 4:RSA:creat uboot_sig.bin OK! 248echo "" 249else 250echo 4:RSA:creat uboot_sig.bin error! 251fi 252cat uboot_sig.bin >> all.bin 253fi 254 255#1:MAGIC 256touch head.txt 257val=0x4253424d 258val=$(H_TO_NL $val) 259val=$(dec2hex $val) 260echo $val | xxd -r > head.txt 261 262#2:TOTAL_LEN 263filesize=`wc -c < all.bin` 264filesize=$[$filesize+16] 265echo all.bin dec_size = $filesize 266a=$(dec2hex $filesize) 267a=$(H_TO_NL $a) 268a=$(dec2hex $a) 269echo $a | xxd -r >> head.txt 270 271#3:RSA2048 272a=0x00000100 273a=$(H_TO_NL $a) 274a=$(dec2hex $a) 275echo $a | xxd -r >> head.txt 276echo $a | xxd -r >> head.txt 277 278#######big->lit########## 279#touch head_e.txt 280#Fill in the first 16 bytes of the image. 281cat all.bin >> head.txt 282cat head.txt > u-boot-rsa2048.bin 283 284#Gets the hash value of the public KEY 285echo Gets the hash value of the public KEY! 286dd if=./u-boot-rsa2048.bin of=rsa2048pem/rsa_pub_2048.bin bs=1 skip=16 count=512 287openssl dgst -sha256 -r -hex rsa2048pem/rsa_pub_2048.bin >rsa2048pem/rsa_pub_2048_sha256.txt 288 289 290HASH_OTP_TABLE rsa2048pem/rsa_pub_2048_sha256.txt rsa2048pem/rsa2048_pem_hash_val.txt 291cat rsa2048pem/rsa2048_pem_hash_val.txt 292 293#clean 294rm ddr_16byte_alig.bin uboot_16byte_alig.bin all.bin 295rm *.txt *_sig.bin 296echo "....................................................." 297echo 298echo 299fi 300fi 301 302################################################## 303####################4096########################## 304################################################# 305if [ $1 = "rsa4096pem_gen" ];then 306if [ -f rsa4096pem/rsa_pub_4096.pem ]; then 307echo "....................rsa_4096........................." 308#4:RSA_pub 309openssl base64 -d -in rsa4096pem/rsa_pub_4096.pem -out private_4096.bin 310dd if=./private_4096.bin of=./fb1 bs=1 skip=33 count=512 311for((i=1;i<=509;i++)) 312do 313 echo 0x00 | xxd -r >> fb2 314done 315dd if=./private_4096.bin of=./fb3 bs=1 skip=547 count=3 316cat fb1 fb2 fb3 > all.bin 317 318filesize=`wc -c < all.bin` 319if [ $filesize == 1024 ];then 320 echo "" 321 echo 0:RSA_PUB creat OK! 322 echo RSA_PUB file_size = $filesize 323 echo "" 324else 325 echo 0:RSA_PUB creat error! 326 echo RSA_PUB file_size = $filesize 327 echo "" 328fi 329rm -f fb1 fb2 fb3 private.bin 330 331#5:IV 332if [ $IV ];then 333echo 0x$IV | xxd -r >> all.bin 334else 335echo 0x00000000000000000000000000000000 | xxd -r >> all.bin 336fi 337 338#6:DDR_len 339#1)The ddr image must be filled with 16 bytes. 340filesize=`wc -c < $ddr_init_file` 341echo "1:The ddr image must be 16-byte aligned!" 342echo $ddr_init_file dec_size = $filesize 343a=$(($filesize % 16)) 344if [ $a == 0 ];then 345b=0 346else 347b=$((16-$a)) 348fi 349cp $ddr_init_file ddr_16byte_alig.bin 350for((i=1;i<=$b;i++)) 351do 352 echo 0x00 | xxd -r >> ddr_16byte_alig.bin 353done 354filesize=`wc -c < ddr_16byte_alig.bin` 355echo ddr_16byte_alig.bin dec_size = $filesize 356echo "" 357#2)fill iamge len 358a=$(dec2hex $filesize) 359a=$(H_TO_NL $a) 360a=$(dec2hex $a) 361echo $a | xxd -r > ddr_len.txt 362#big_lit ddr_len.txt 363cat ddr_len.txt >> all.bin 364 365#7:DDR.BIN 366openssl dgst -sha256 -sign rsa4096pem/rsa_priv_4096.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out ddr_sig.bin ddr_16byte_alig.bin 367cat ddr_16byte_alig.bin >> all.bin 368 369#8:ddr_sig 370cat ddr_sig.bin >> all.bin 371if [ -f ddr_sig.bin ]; then 372echo 2:creat ddr_sig.bin ok! 373echo "" 374fi 375 376#9:u-boot_len 377#1)The boot image must be filled with 16 bytes. 378filesize=`wc -c < $uboot_file` 379echo "3:The boot image must be 16-byte aligned!" 380echo $uboot_file dec_size = $filesize 381a=$(($filesize % 16)) 382if [ $a == 0 ];then 383b=0 384else 385b=$((16-$a)) 386fi 387cp $uboot_file uboot_16byte_alig.bin 388for((i=1;i<=$b;i++)) 389do 390 echo 0x00 | xxd -r >> uboot_16byte_alig.bin 391done 392#2)fill iamge len 393filesize=`wc -c < uboot_16byte_alig.bin` 394filesize=$[filesize] 395echo uboot_16byte_alig.bin dec_size = $filesize 396echo "" 397a=$(dec2hex $filesize) 398a=$(H_TO_NL $a) 399a=$(dec2hex $a) 400echo $a | xxd -r > uboot_len.txt 401#big_lit uboot_len.txt 402cat uboot_len.txt >> all.bin 403 404#10:u-boot.bin + uboot_sing.bin 405if [ $KEY ]; then 406#IV and KEY have set, 407#1) Obtain a new KEY by decrypting the ECB mode. 408echo 0x50db86c592c52f0c436cca6f2ffecaf5 | xxd -r > seed_1.bin 409echo 0x4a96ae013fc60e205e9da4c9d5ad9b99 | xxd -r > seed_2.bin 410openssl enc -nopad -d -nosalt -aes-256-ecb -K "$KEY" -in seed_1.bin -out out_1.bin 411openssl enc -nopad -d -nosalt -aes-256-ecb -K "$KEY" -in seed_2.bin -out out_2.bin 412cat out_2.bin >> out_1.bin 413KEY_ecb=$(xxd -ps out_1.bin | sed 'N;s/\n//g') 414rm out_*.bin seed_*.bin 415echo 4:Obtain a new KEY by decrypting the ECB mode! 416echo new_KEY = $KEY_ecb 417echo "" 418#boot_sig+boot ---->> openssl_cbc ------>> cbc mode boot 419#2)boot_sig+boot 420openssl dgst -sha256 -sign rsa4096pem/rsa_priv_4096.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out uboot_sig.bin uboot_16byte_alig.bin 421if [ -f uboot_sig.bin ];then 422echo 5:AES:creat uboot_sig.bin OK! 423echo "" 424else 425echo 5:AES:creat uboot_sig.bin error! 426echo "" 427fi 428 429cp uboot_16byte_alig.bin u-cbc.bin 430cat uboot_sig.bin >> u-cbc.bin 431#3) Use the new KEY and IV to encrypt the image in CBC mode. 432if [ $IV ];then 433openssl enc -aes-256-cbc -nopad -K "$KEY_ecb" -iv "$IV" -in u-cbc.bin -out cbc_boot.bin 434fi 435cat cbc_boot.bin >> all.bin 436rm u-cbc.bin cbc_boot.bin 437 438else 439#If the IV and KEY are not set, use the default image. 440#1)boot_bin 441cat uboot_16byte_alig.bin >> all.bin 442#2):boot_sig 443openssl dgst -sha256 -sign rsa4096pem/rsa_priv_4096.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out uboot_sig.bin uboot_16byte_alig.bin 444if [ -f uboot_sig.bin ];then 445echo 4:RSA:creat uboot_sig.bin OK! 446echo "" 447else 448echo 4:RSA:creat uboot_sig.bin error! 449echo "" 450fi 451cat uboot_sig.bin >> all.bin 452fi 453 454#1:MAGIC 455touch head.txt 456val=0x4253424D 457val=$(H_TO_NL $val) 458val=$(dec2hex $val) 459echo $val | xxd -r > head.txt 460 461#2:TOTAL_LEN 462filesize=`wc -c < all.bin` 463filesize=$[$filesize+16] 464echo all.bin dec_size = $filesize 465a=$(dec2hex $filesize) 466a=$(H_TO_NL $a) 467a=$(dec2hex $a) 468echo $a | xxd -r >> head.txt 469 470#3:RSA4096 471a=0x00000200 472a=$(H_TO_NL $a) 473a=$(dec2hex $a) 474echo $a | xxd -r >> head.txt 475echo $a | xxd -r >> head.txt 476 477#######big->lit########## 478#touch head_e.txt 479#Fill in the first 16 bytes of the image. 480cat all.bin >> head.txt 481cat head.txt > u-boot-rsa4096.bin 482 483#Gets the hash value of the public KEY 484echo Gets the hash value of the public KEY! 485dd if=./u-boot-rsa4096.bin of=rsa4096pem/rsa_pub_4096.bin bs=1 skip=16 count=1024 486openssl dgst -sha256 -r -hex rsa4096pem/rsa_pub_4096.bin >rsa4096pem/rsa_pub_4096_sha256.txt 487 488HASH_OTP_TABLE rsa4096pem/rsa_pub_4096_sha256.txt rsa4096pem/rsa4096_pem_hash_val.txt 489cat rsa4096pem/rsa4096_pem_hash_val.txt 490 491#clean 492rm ddr_16byte_alig.bin uboot_16byte_alig.bin all.bin 493rm *.txt *_sig.bin 494echo "....................................................." 495fi 496fi 497 498if [ $KEY ]; then 499AES_OTP_TABLE $KEY aes_otp_cfg.txt 500echo create aes_otp_cfg.txt over! 501fi 502