Manual Signature User Guide¶
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 1.0 | 01/31/2024 | |
| 1.1 | 06/05/2024 |
1. Overview¶
This article will introduce the boot image of each stage of manual security boot signing, and let users understand the meaning of each step of signing. For the complete Security boot principle and usage process, as well as the debugging process and formal process, please refer to the document "Security Boot User Guide".
To create a signature system image, it is recommended that customers use security_boot_tools to automatically process the SDK image package. The advantage is that it is simple and fast, but it requires compiling the SDK image package in advance. For customers with special requirements who do not want to use security_boot_tools to automatically sign, you can refer to this document and manually use the py tool to manually sign the system image created by the customer.
During the development stage, it is usually recommended that customers first use the debug mode to sign the image. The purpose is to first confirm that the OTP key content is burned correctly, and then use the OTP official mode to sign the image.
Making RSA key and aes Key has been described in details in the document"Security Boot User Guide".
1.1 Signing Tool¶
The manual signing tools are placed at:
-
project/image/security_boot_tools/tools/add_ipl_header.py
- This py is to perform aes encryption, append, sign and other operations on the image.
-
project/image/security_boot_tools/tools/key_proc.py
- This py performs aes encryption, append, sign and other operations on the image. It references deal_image.sh, sign_img.sh and pend.bin.
-
project/image/security_boot_tools/tools/mkimage
-
This tool is an sz-compressed image with header data added to the header.
-
project/image/security_boot_tools/tools/sz/sstar_sz.sh
-
This script performs sz compression on the image, which calls the sz, szdec, and szsplit tools.
-
project/image/security_boot_tools/tools/unsz/szdec and szrestore
-
Used to decompress the image to sz
2. IPL Signature¶
2.1. OTP official mode¶
-
Insert the public key into IPL.bin (if you only signature without encryption, use this command)
./key_proc.py --insert --rsa=./public-cust.pem -f ./IPL.bin (generates IPL.cipher.bin)
or
Insert the public key and IV value into IPL.bin (if signing + encryption, use this command)
./key_proc.py --insert --rsa=./public-cust.pem --IV=IV.bin -f ./IPL.bin (generates IPL.cipher.bin)
-
Change the IPL header to non-debug mode, and set the anti-rollback image version to 0.
./add_ipl_header.py ./IPL.cipher.bin ./IPL.cipher2.bin 0 0 0 0 (generates IPL.cipher2.bin)
-
Use the output file from the previous step to perform AES-CBC encryption (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=./IV.bin --aes=./aesKey128_1.bin -f ./IPL.cipher.bin (generates IPL.cipher.aes.bin)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-otp.pem -f ./IPL.cipher.aes.bin (generates IPL.cipher.aes.sig.bin)
or
./key_proc.py --sign --rsa=./private-otp.pem -f ./IPL.cipher.bin (generates IPL.cipher.sig.bin)
2.2. Debug mode¶
-
Insert the public key into IPL.bin (if you only sign without encryption, use this command)
./key_proc.py --insert --rsa=./public-cust.pem -f ./IPL.bin (generates IPL.cipher.bin)
or
Insert the public key and IV value into IPL.bin (if signing + encryption, use this command)
./key_proc.py --insert --rsa=./public-cust.pem --IV=IV.bin -f ./IPL.bin (generates IPL.cipher.bin)
-
Change the IPL header to debug mode, and set the anti-rollback image version to 0.
./add_ipl_header.py ./IPL.cipher.bin ./IPL.cipher2.bin 0 1 0 0 (generates IPL.cipher2.bin)
-
Use the output file from the previous step to perform AES-CBC encryption (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=./IV.bin --aes=./aesKey128_1.bin -f ./IPL.cipher2.bin (generates IPL.cipher2.aes.bin)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-otp.pem -f ./IPL.cipher2.aes.bin (generates IPL.cipher2.aes.sig.bin)
or
./key_proc.py --sign --rsa=./private-otp.pem -f ./IPL.cipher2.bin (generates IPL.cipher2.sig.bin)
3. IPL_CUST Signature¶
IPL_CUST only supports signatures and does not support encryption.
-
Insert the public key into IPL_CUST.bin
./key_proc.py --insert --rsa=./public-image.pem -f ./IPL_CUST.bin (generates IPL_CUST.cipher.bin)
-
Change the IPL_CUST header to debug mode (In OTP official mode, you can set to an arbitrary value), set the anti-rollback image version to 0 and set AES_KEY_NUMBE=0.
./add_ipl_header.py IPL_CUST.cipher.bin IPL_CUST.cipher2.bin 0 1 0 1 (generates IPL_CUST.cipher2.bin)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-cust.pem -f ./IPL_CUST.cipher2.bin (generates IPL_CUST.cipher2.sig.bin)
4. OPTEE Signature¶
OPTEE images are divided into two types: non-compressed and sz-compressed. The signing steps are determined based on the actual use of the customer.
4.1 tee.bin Signature¶
-
aes encrypt tee.bin (if only signature is not encrypted, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=./IV.bin --aes=./aesKey128_1.bin -f tee.bin (generate tee.aes.bin)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./tee.aes.bin (generate tee.aes.append.bin)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 --mode=cbc --IV=./IV.bin -f ./tee.bin (generate tee.append.bin)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-cust.pem -f tee.aes.append.bin (generates tee.aes.append.sig.bin)
or
./key_proc.py --sign --rsa=./private-cust.pem -f tee.append.bin (generates tee.append.sig.bin)
-
Join the input file from previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d tee.append.sig.bin tee.append.sig.bin.sbot (generates tee.append.sig.bin.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d tee.append.sig.bin tee.append.sig.bin.sbot (generates tee.append.sig.bin.sbot)
4.2 Signed tee.sz¶
-
First divide tee.sz into two pieces of data, tee.sz_text.sz is data data, and tee.sz_header is header data. After decompressing the data data sz, perform encryption and signature verification, and finally perform sz compression and put the header data.
dd if=tee.sz of=tee.sz_text.sz bs=1 skip=64
dd if=tee.sz of=tee.sz_header bs=64 count=1
./unsz/szrestore tee.sz_text.sz tee.sz.xz
./unsz/szdec tee.sz.xz tee.sz_payload
-
Use the output file from the previous step to perform AES encryption (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f tee.sz_payload (generate tee.aes.sz_payload)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f tee.aes.sz_payload (generate tee.aes. append.sz_payload)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f tee.sz_payload (generate tee.append.sz_payload)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-cust.pem -f tee.aes.append.sz_payload (generates tee.aes.append.sig.sz_payload)
or
./key_proc.py --sign --rsa=./private-cust.pem -f tee.append.sz_payload (generates tee.append.sig.sz_payload)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d tee.aes.append.sig.sz_payload tee.aes.append.sig.sz_payload.sbot (generates tee.aes.append.sig.sz_payload.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d tee.append.sig.sz_payload tee.append.sig.sz_payload.sbot (generates tee.append.sig.sz_payload.sbot)
-
Use the output file from the previous step to perform sz compression and header data, and finally generate tee.sz
./sz/sstar_sz.sh -d tee.aes.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 tee.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 tee.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 tee.sz_header)
version="${result%%.*}"
./mkimage -A arm -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d tee.aes.append.sig.sz_payload.sbot.sz tee.sz
or
./sz/sstar_sz.sh -d tee.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 tee.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 tee.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 tee.sz_header)
version="${result%%.*}"
./mkimage -A arm -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d tee.append.sig.sz_payload.sbot.sz tee.sz
5. TF_A Signature¶
TF-A images generally only come in uncompressed form. Taking u-bl31.bin as an example, which TF-A image is actually used depends on the actual situation of the customer.
-
aes encrypt u-bl31.bin (if only signature is not encrypted, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f u-bl31.bin (generate u-bl31.aes.bin)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./u-bl31.aes.bin (encrypted +Signature, generate u-bl31.aes.append.bin)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./u-bl31.bin (only signature, no encryption, generates u-bl31.append.bin)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-cust.pem -f u-bl31.aes.append.bin (encryption + signature, generates u-bl31.aes.append.sig.bin)
or
./key_proc.py --sign --rsa=./private-cust.pem -f u-bl31.append.bin (only signature, no encryption, generates u-bl31.append.sig.bin)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-bl31.aes.append.sig.bin u-bl31.aes.append.sig.bin.sbot (generates u-bl31.aes.append.sig.bin.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-bl31.append.sig.bin u-bl31.append.sig.bin.sbot (generates u-bl31.append.sig.bin.sbot)
6. VMM Signature¶
VMM images are divided into two types: non-compressed and sz-compressed. The signing steps are determined based on the actual use of the customer. Taking signed vmm32_ssc029a_512.bin and signed vmm32_ssc029a_512.sz as examples, which VMM image is actually used depends on the actual situation of the customer.
6.1 vmm32_ssc029a_512.bin Signature< span>¶
-
aes encrypt vmm32_ssc029a_512.bin (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f vmm32_ssc029a_512.bin ( generate vmm32_ssc029a_512.aes.bin)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./vmm32_ssc029a_512.aes.bin (generates vmm32_ssc029a_512. aes.append.bin)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./vmm32_ssc029a_512.bin (generate vmm32_ssc029a_512.append.bin)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-cust.pem -f vmm32_ssc029a_512.aes.append.bin (generates vmm32_ssc029a_512.aes.append.sig.bin)
or
./key_proc.py --sign --rsa=./private-cust.pem -f vmm32_ssc029a_512.append.bin (generates vmm32_ssc029a_512.append.sig.bin)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d vmm32_ssc029a_512.aes.append.sig.bin vmm32_ssc029a_512.aes.append.sig.bin.sbot (generates vmm32_ssc029a_512.aes.append.sig.bin.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d vmm32_ssc029a_512.append.sig vmm32_ssc029a_512.append.sig.sbot (generates vmm32_ssc029a_512.append.sig.sbot)
6.2 Signature vmm32_ssc029a_512.sz¶
-
vmm32_ssc029a_512.sz is divided into two parts, vmm32_ssc029a_512.sz_text.sz is the data data, and vmm32_ssc029a_512.sz_header is the header data. After decompressing the data data sz, perform encryption and signature verification, and finally sz compress and put the header data.
dd if=vmm32_ssc029a_512.sz of=vmm32_ssc029a_512.sz_text.sz bs=1 skip=64
dd if=vmm32_ssc029a_512.sz of=vmm32_ssc029a_512.sz_header bs=64 count=1
./unsz/szrestore vmm32_ssc029a_512.sz_text.sz vmm32_ssc029a_512.sz.xz
./unsz/szdec vmm32_ssc029a_512.sz.xz vmm32_ssc029a_512.sz_payload
-
Use the output file from the previous step to perform AES encryption (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f vmm32_ssc029a_512.sz_payload (generate vmm32_ssc029a_512.aes.sz_payload)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc -- IV=./IV.bin -f ./vmm32_ssc029a_512.aes.sz_payload ( generates vmm32_ssc029a_512. aes.append.sz_payload)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f vmm32_ssc029a_512.sz_payload (generate vmm32_ssc029a_512.append.sz_payload)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f vmm32_ssc029a_512.aes.append.sz_payload (generates vmm32_ssc029a_512.aes.append.sig.sz_payload)
or
./key_proc.py --sign --rsa=./private-image.pem -f vmm32_ssc029a_512.append.sz_payload (generates vmm32_ssc029a_512.append.sig.sz_payload)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d vmm32_ssc029a_512.aes.append.sig.sz_payload vmm32_ssc029a_512.aes.append.sig.sz_payload.sbot (generates vmm32_ssc029a_512.aes.append.sig.sz_payload.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d vmm32_ssc029a_512.append.sig.sz_payload vmm32_ssc029a_512.append.sig.sz_payload.sbot (generates vmm32_ssc029a_512.append.sig.sz_payload.sbot)
-
Use the output file from the previous step to perform sz compression and header data, and finally generate vmm32_ssc029a_512.sz
./sstar_sz.sh -d vmm32_ssc029a_512.aes.append.sig.sz_payload -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 vmm32_ssc029a_512.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 vmm32_ssc029a_512.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 vmm32_ssc029a_512.sz_header)
version="${result%%.*}"
./mkimage -A arm -O sigmastar-hyp -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d vmm32_ssc029a_512.aes.append.sig.sz_payload.sbot.sz vmm32_ssc029a_512.sz
or
./sstar_sz.sh -d vmm32_ssc029a_512.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 vmm32_ssc029a_512.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 vmm32_ssc029a_512.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 vmm32_ssc029a_512.sz_header)
version="${result%%.*}"
./mkimage -A arm -O sigmastar-hyp -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d vmm32_ssc029a_512.append.sig.sz_payload.sbot.sz vmm32_ssc029a_512.sz
7. UBOOT Signature¶
UBOOT images are divided into two types: uncompressed and sz compressed. The signing steps are determined based on the actual use of the customer. Taking signed u-boot_spinand.xz.img.bin and signed u-boot_spinand.sz.img.bin as an example, which UBOOT image is actually used depends on the actual situation of the customer.
7.1 u-boot_spinand.xz.img.bin Signature¶
-
AES encrypt u-boot_spinand.xz.img.bin (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f u-boot_spinand.xz.img.bin (generates u-boot_spinand.xz.img. aes.bin)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./u-boot_spinand.xz.img.aes .bin ( generate u-boot_spinand.xz.img.aes.append.bin)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./u-boot_spinand.xz.img.bin (generate u-boot_spinand.xz.img.append.bin)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f u-boot_spinand.xz.img.aes.append.bin (generates u-boot_spinand.xz.img.aes.append.sig.bin)
or
./key_proc.py --sign --rsa=./private-image.pem -f u-boot_spinand.xz.img.append.bin (generates u-boot_spinand.xz.img.append.sig.bin)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-boot_spinand.xz.img.append.sig.bin u-boot_spinand.xz.img.append.sig.bin.sbot (generates u-boot_spinand.xz.img.append.sig.bin.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-boot_spinand.xz.img.append.sig.bin u-boot_spinand.xz.img.append.sig.bin.sbot (generates u-boot_spinand.xz.img.append.sig.bin.sbot)
7.2 Sign u-boot_spinand.sz.img.bin¶
-
u-boot_spinand.sz.img.bin is divided into two parts, u-boot_spinand.sz.img.bin_text.sz is data data, and u-boot_spinand.sz.img.bin_header is header data. After decompressing the data data sz, perform encryption and signature verification, and finally sz compress and put the header data.
dd if=u-boot_spinand.sz.img.bin of=u-boot_spinand.sz.img.bin_text.sz bs=1 skip=64
dd if=u-boot_spinand.sz.img.bin of=u-boot_spinand.sz.img.bin_header bs=64 count=1
./unsz/szrestore u-boot_spinand.sz.img.bin_text.sz u-boot_spinand.sz.img.bin.xz
./unsz/szdec u-boot_spinand.sz.img.bin.xz u-boot_spinand.sz.img.bin_payload
-
Use the output file from the previous step to perform AES encryption (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f u-boot_spinand.sz.img.bin_payload (generates u-boot_spinand.sz.img. aes.bin_payload)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./u-boot_spinand.sz.img.aes .bin_payload (generates u-boot_spinand.sz.img.aes.append.bin_payload)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f u-boot_spinand.sz.img.bin_payload (generate u-boot_spinand.sz.img.append.bin_payload)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f u-boot_spinand.sz.img.aes.append.bin_payload (generates u-boot_spinand.sz.img.aes.append.sig. bin_payload)
or
./key_proc.py --sign --rsa=./private-image.pem -f u-boot_spinand.sz.img.append.bin_payload (generate u-boot_spinand.sz.img.append.sig.bin_payload)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-boot_spinand.sz.img.aes.append.sig.bin_payload u-boot_spinand.sz.img.aes.append.sig.bin_payload.sbot (generates u-boot_spinand.sz.img.aes.append.sig.bin_payload.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-boot_spinand.sz.img.append.bin_payload u-boot_spinand.sz.img.append.bin_payload.sbot (generates u-boot_spinand.sz.img.append.bin_payload.sbot)
-
Use the output file of the previous step to perform sz compression and header data, and finally generate u-boot_spinand.sz.img.bin
./sstar_sz.sh -d u-boot_spinand.sz.img.aes.append.sig.bin_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 u-boot_spinand.sz.img.bin_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 u-boot_spinand.sz.img.bin_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 u-boot_spinand.sz.img.bin_header)
version="${result%%.*}"
./mkimage -A arm -O u-boot -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d u-boot_spinand.sz.img.aes.append.sig. bin_payload.sbot.sz u-boot_spinand.sz.img.bin
or
./sstar_sz.sh -d u-boot_spinand.sz.img.append.sig.bin_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 u-boot_spinand.sz.img.bin_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 u-boot_spinand.sz.img.bin_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 u-boot_spinand.sz.img.bin_header)
version="${result%%.*}"
./mkimage -A arm -O u-boot -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d u-boot_spinand.sz.img.append.sig.bin_payload.sbot.sz u-boot_spinand.sz.img.bin
8. KERNEL Signature¶
KERNEL images are divided into two types: non-compressed and sz-compressed. The signing steps are determined based on the actual use of the customer. Taking signed uImage.xz and signed uImage.sz as an example, which KERNEL image is actually used depends on the actual situation of the customer.
8.1 Sign uImage.xz¶
-
aes encrypt uImage.xz (if only signature is not encrypted, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f uImage.xz (generate uImage.aes.xz)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./uImage.aes.xz (Generate uImage. aes.append.xz)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./uImage.xz (generate uImage.append.xz)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f uImage.aes.append.xz (generate uImage.aes.append.sig.xz)
or
./key_proc.py --sign --rsa=./private-image.pem -f uImage.append.xz (generate uImage.append.sig.xz)
8.2 uImage.sz Signature¶
-
uImage.sz is divided into two parts, uImage.sz_text.sz is data data, and uImage.sz_header is header data. After decompressing the data data sz, perform encryption and signature verification, and finally sz compress and put the header data.
dd if=uImage.sz of=uImage.sz_text.sz bs=1 skip=64
dd if=uImage.sz of=uImage.sz_header bs=64 count=1
./unsz/szrestore uImage.sz_text.sz uImage.sz.xz
./unsz/szdec uImage.sz.xz uImage.sz_payload
-
Use the output file from the previous step to perform AES encryption (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f uImage.sz_payload (generate uImage.aes.sz_payload)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./uImage.aes.sz_payload ( generate uImage. aes.append.sz_payload)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f uImage.sz_payload (generate uImage.append.sz_payload)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f uImage.aes.append.sz_payload (generates uImage.aes.append.sig.sz_payload)
or
./key_proc.py --sign --rsa=./private-image.pem -f uImage.append.sz_payload (generates uImage.append.sig.sz_payload)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d uImage.aes.append.sig.sz_payload uImage.aes.append.sig.sz_payload.sbot (generates uImage.aes.append.sig.sz_payload.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d uImage.append.sig.sz_payload uImage.append.sig.sz_payload.sbot (generates uImage.append.sig.sz_payload.sbot)
-
Use the output file from the previous step to perform sz compression and header data, and finally generate uImage.sz
./sstar_sz.sh -d uImage.aes.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 uImage.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 uImage.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 uImage.sz_header)
version="${result%%.*}"
./mkimage -A arm -O linux-C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d uImage.aes.append.sig.sz_payload.sbot.sz uImage.sz
or
./sstar_sz.sh -d uImage.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 uImage.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 uImage.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 uImage.sz_header)
version="${result%%.*}"
./mkimage -A arm -O linux -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d uImage.append.sig.sz_payload.sbot.sz uImage.sz
9. RTOS Signature¶
RTOS images are divided into two types: uncompressed and sz compressed. The signing steps are determined based on the actual use of the customer. Taking signed rtos.bin and signed rtos.sz as examples, which RTOS image is actually used depends on the actual situation of the customer.
9.1 rtos.bin Signature¶
-
aes encrypt rtos.bin (if only signature is not encrypted, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f rtos.bin (generate rtos.aes.bin)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./rtos.aes.bin (generate rtos. aes.append.bin)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./rtos.bin (generate rtos.append.bin)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f rtos.aes.append.bin (generates rtos.aes.append.sig.bin)
or
./key_proc.py --sign --rsa=./private-image.pem -f rtos.append.bin (generates rtos.append.sig.bin)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d rtos.aes.append.bin rtos.aes.append.bin.sbot (generates rtos.aes.append.bin.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d rtos.append.sig.bin rtos.append.sig.bin.sbot (generates rtos.append.sig.bin.sbot)
9.2 sign rtos.sz¶
-
rtos.sz is divided into two parts, rtos.sz_text.sz is data data, and rtos.sz_header is header data. After decompressing the data data sz, perform encryption and signature verification, and finally sz compress and put the header data.
dd if=rtos.sz of=rtos.sz_text.sz bs=1 skip=64
dd if=rtos.sz of=rtos.sz_header bs=64 count=1
./unsz/szrestore rtos.sz_text.sz rtos.sz.xz
./unsz/szdec rtos.sz.xz rtos.sz_payload
-
Use the output file from the previous step to perform AES encryption (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f rtos.sz_payload (generate rtos.aes.sz_payload)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc -- IV=./IV.bin -f ./rtos.aes.sz_payload ( generate rtos.aes.append.sz_payload)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f rtos.sz_payload (generate rtos.append.sz_payload)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f rtos.aes.append.sz_payload (generates rtos.aes.append.sig.sz_payload)
or
./key_proc.py --sign --rsa=./private-image.pem -f rtos.append.sz_payload (generates rtos.append.sig.sz_payload)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d rtos.aes.append.sig.sz_payload rtos.aes.append.sig.sz_payload.sbot (generates rtos.aes.append.sig.sz_payload.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d rtos.append.sig.sz_payload rtos.append.sig.sz_payload.sbot (generates rtos.append.sig.sz_payload.sbot)
-
Use the output file from the previous step to perform sz compression and header data, and finally generate rtos.sz
./sstar_sz.sh -d rtos.aes.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 rtos.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 rtos.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 rtos.sz_header)
version="${result%%.*}"
./mkimage -A arm -O sigmastar-rtos -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d rtos.aes.append.sig.sz_payload.sbot.sz rtos.sz
or
./sstar_sz.sh -d rtos.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 rtos.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 rtos.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 rtos.sz_header)
version="${result%%.*}"
./mkimage -A arm -O sigmastar-rtos -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d rtos.append.sig.sz_payload.sbot.sz rtos.sz
10. PM_RTOS Signature¶
PM_RTOS images generally only have uncompressed ones. Taking pm_rtos as an example, which PM_RTOS image is actually used depends on the actual situation of the customer.
-
aes encrypted PM_RTOS (if only signature is not encrypted, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=./IV.bin --aes=./aesKey128_1.bin -f pm_rtos (generate pm_rtos.aes)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./pm_rtos.aes(generate pm_rtos.aes.append)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./pm_rtos (generate pm_rtos.append)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f pm_rtos.aes.append (generates pm_rtos.aes.append.sig)
or
./key_proc.py --sign --rsa=./private-image.pem -f pm_rtos.append (generates pm_rtos.append.sig)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d pm_rtos.aes.append.sig pm_rtos.aes.append.sig.sbot (generates pm_rtos.aes.append.sig.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d pm_rtos.append.sig pm_rtos.append.sig.sbot (generates pm_rtos.append.sig.sbot)
11. File System Signature¶
Note: If the file system type is readable and writable or changes dynamically, such as FWFS, no signature will be performed. The following focuses on the signature of the root file system.
A signed image can be created only if the root file system has a read-only attribute and is small enough to be completely loaded into memory. If the root file system is readable and writable, or is too large to be loaded into the memory at once for signature verification, the signed image cannot be created. Take initfamfs as an example:
INITRAMFS images are divided into two types: non-compressed and sz-compressed. The signing steps are determined based on the actual use of the customer. Taking signed initramfs.gz.bin and signed initramfs.gz.sz as an example, which INITRAMFS image is actually used depends on the actual situation of the customer.
11.1 signed initramfs.gz¶
-
aes encrypt initramfs.gz.bin (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f initramfs.gz.bin (generates initramfs.gz.aes.bin)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./initramfs.gz.aes.bin (generates initramfs.gz.aes.append.bin)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./initramfs.gz.bin (generates initramfs.gz.append.bin)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f initramfs.gz.aes.append.bin (generates initramfs.gz.aes.append.sig.bin)
or
./key_proc.py --sign --rsa=./private-image.pem -f initramfs.gz.append.bin (generates initramfs.gz.append.sig.bin)
-
Append the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d initramfs.gz.aes.append.sig.bin initramfs.gz.aes.append.sig.bin.sbot (generates initramfs.gz.aes.append.sig.bin.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d initramfs.gz.append.sig.bin initramfs.gz.append.sig.bin.sbot (generates initramfs.gz.append.sig.bin.sbot)
11.2 Sign initramfs.gz.sz¶
-
initramfs.gz.sz is divided into two parts, initramfs.gz.sz_text.sz is data data, initramfs.gz.sz_header is header data. After decompressing the data data sz, perform encryption and signature verification, and finally sz compress and put the header data.
dd if=initramfs.gz.sz of=initramfs.gz.sz_text.sz bs=1 skip=64
dd if=initramfs.gz.sz of=initramfs.gz.sz_header bs=64 count=1
./unsz/szrestore initramfs.gz.sz_text.sz initramfs.gz.sz.xz
./unsz/szdec initramfs.gz.sz.xz initramfs.gz.sz_payload
-
Use the output file from the previous step to perform AES encryption (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f initramfs.gz.sz_payload (generate initramfs.gz.aes.sz_payload)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./initramfs.gz.aes.sz_payload (generated initramfs.gz.aes.append.sz_payload)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f initramfs.gz.sz_payload (generate initramfs.gz.append.sz_payload)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f initramfs.gz.aes.append.sz_payload (generates initramfs.gz.aes.append.sig.sz_payload)
or
./key_proc.py --sign --rsa=./private-image.pem -f initramfs.gz.append.sz_payload (generates initramfs.gz.append.sig.sz_payload)
-
Join the input file from the previous step to the header of Security_Boot
mkimage -A arm -C none -a 0 -e 0 -n sbot -d initramfs.gz.aes.append.sig.sz_payload initramfs.gz.aes.append.sig.sz_payload.sbot (generates initramfs.gz.aes.append.sig.sz_payload.sbot)
or
mkimage -A arm -C none -a 0 -e 0 -n sbot -d initramfs.gz.append.sz_payload initramfs.gz.append.sz_payload.sbot (generates initramfs.gz.append.sz_payload.sbot)
-
Use the output file of the previous step to perform sz compression and header data, and finally generate initramfs.gz.sz
./sstar_sz.sh -d initramfs.gz.aes.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 initramfs.gz.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 initramfs.gz.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 initramfs.gz.sz_header)
version="${result%%.*}"
./mkimage -A arm -O linux -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d initramfs.gz.aes.append.sig.sz_payload.sbot.sz initramfs.gz .sz
or
./sstar_sz.sh -d initramfs.gz.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 initramfs.gz.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 initramfs.gz.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 initramfs.gz.sz_header)
version="${result%%.*}"
./mkimage -A arm -O linux -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d initramfs.gz.append.sig.sz_payload.sbot.sz initramfs.gz.sz
Note: After initramfs is signed, uboot bootcmd needs to be set up to verify the signature, and the signature can be verified through the sigauth command. For example:
loados nand by_header RAMDISK by_header;sigauth ${loados_addr} 0x21000000;bootm start ${loados_addr};bootm loados;bootm prep;
11.3 Sign rootfs.sqfs¶
-
Encrypt rootfs.sqfs with AES (if you only sign but not encrypt, this step is omitted)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f rootfs.sqfs (generate rootfs.sqfs.aes.bin)
-
Use the output file from the previous step and append 32 bytes of data to the end.
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./rootfs.sqfs.aes.bin (generate rootfs.sqfs.aes.append.bin)
or
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./rootfs.sqfs (generate rootfs.sqfs)
-
Use the output file from the previous step to sign
./key_proc.py --sign --rsa=./private-image.pem -f rootfs.sqfs.aes.append.bin (generate rootfs.sqfs.aes.append.sig.bin)
or
./key_proc.py --sign --rsa=./private-image.pem -f rootfs.sqfs.append.bin (generate rootfs.sqfs.append.sig.bin )
Note: After initramfs is signed, uboot bootcmd needs to be set up to verify the signature, and the signature can be verified through the sigauth command. For example:
setenv bootcmd ' dcache off; loados nand 0x22000000 roofs 0x600000; sigauth 22000000 0x21000000 ; loados nand 0x23000000 KERNEL ${kernel_file_size};sigauth 23000000 0x21000000; dcache on; bootm 0x23000000; loados nand 0x23000000 RECOVERY ${recovery_file_size}; bootm 0x23000000;