The Code signing tool has been used to create signed images which contains the certificates and signatures. This information is captured by HAB to authenticate the image in the chip. HAB processes the set of commands from the CSF and authenticates the image serially. The process not only involves authenticating the boot image but also verification of various components like certificates, SRK fuses etc. Verification of all these components and finally authenticating the image is necessary to completely validate a signed image.
A typical CSF file is as follows:
[Header]
Version = 4.1
Hash Algorithm = sha256
Engine Configuration = 0
Certificate Format = X509
Signature Format = CMS
[Install SRK]
File = "../crts/SRK_1_2_3_4_table.bin"
Source index = 0
[Install CSFK]
File = "../crts/CSF1_1_sha256_2048_65537_v3_usr_crt.pem"
[Authenticate CSF]
[Install Key]
Verification index = 0
Target index = 2
File = "../crts/IMG1_1_sha256_2048_65537_v3_usr_crt.pem"
[Authenticate Data]
Verification index = 2
Blocks = 0x177FF400 0x000 0x93c00 "u-boot.bin"
CST tool interprets and converts this CSF file into a set of commands in binary format. These commands are then processed by HAB to verify each component.
[Header] - Header information is used by CST to validate certain necessary configuration needed by HAB to process.
[Install SRK] - HAB processes this command as follows (in no particular order):
1. Copy SRK table in persistent memory
2. Compare hash of SRK table (SHA256) with SRK fuses
3. Install the SRK1 key
[Install CSFK] - HAB processes this command as follows:
1. Install CSF key
2. Verify CSF certificate against SRK certificate.
[Authenticate CSF]
1. Authenticate CSF image using the CSF public key in CSF certificate
[Install Key]
1. Install IMG key
2. Verify IMG certificate against SRK certificate.
[Authenticate Data]
1. Authenticate boot image using the IMG public key in IMG certificate.
The Installation of keys cannot be performed offline but the verification and authentication steps can be performed using OpenSSL.
Before starting to authenticate the components of the CSF file, they need to be extracted first. The components that need to be extracted are SRK table, CSF and IMG certificates, CSF and Image signatures. Please use csf_parser tool to extract these components from your signed boot image or CSF binary.
csf_parser -d -c u-boot_csf.bin
This extracts the files as follows:
output/
├── cert0.der <-- CSF certificate
├── cert1.der <-- IMG certificate
├── debug_log.txt
├── parsed_output.txt
├── sig0.bin <-- CSF signature
├── sig1.bin <-- Boot image signature
└── SRKTable.bin
Compare SRK table with SRK hash:
1. #Create SRK fuses from SRK table and compare with SRK hash in the chip
./createSRKFuses <SRK table> <Number of SRKs> <SRK key length>
2. #Verify CSF certificate against SRK certificate. (Similarly IMG certificate against SRK certificate)
Using openssl command line the procedure to verify the certificate chain is as follows:
openssl verify -verbose -CAfile CA1_sha256_2048_65537_v3_ca_crt.pem -untrusted SRK1_sha256_2048_65537_v3_ca_crt.pem CSF1_1_sha256_2048_65537_v3_usr_crt.pem
Note: Pay attention to the color of the text for matching data
Signer: SRK1
Certificate : CSF1
1. # Extract encrypted signature from Certificate CSF1
openssl asn1parse -in CSF1_1_sha256_2048_65537_v3_usr_crt.der -inform der
570:d=1 hl=2 l= 13 cons: SEQUENCE
572:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption
583:d=2 hl=2 l= 0 prim: NULL
585:d=1 hl=4 l= 257 prim: BIT STRING
openssl asn1parse -inform DER -in CSF1_1_sha256_2048_65537_v3_usr_crt.der -out enc_sig_csf1.bin -noout -strparse 585
2. #Extract SRK1 public key from SRK1 certificate
openssl x509 -in SRK1_sha256_2048_65537_v3_ca_crt.pem -pubkey -noout > SRK1_pubkey.pem
3. # Decrypt the encrypted signature from CSF1 certificate with SRK1 public key
openssl rsautl -verify -inkey SRK1_pubkey.pem -in enc_sig_csf1.bin -pubin > sig_csf1.bin
4. # Get the Hash from the CSF1 signature
openssl asn1parse -in sig_csf1.bin -inform DER
....
0:d=0 hl=2 l= 49 cons: SEQUENCE
2:d=1 hl=2 l= 13 cons: SEQUENCE
4:d=2 hl=2 l= 9 prim: OBJECT :sha256
15:d=2 hl=2 l= 0 prim: NULL
17:d=1 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:8E8D56112C3CBDB00806407256BD0E68CDD707AEDFBC2FC3327E5D1B3544EBDF
5. # Get the Hash of CSF1 certificate body
openssl asn1parse -in CSF1_1_sha256_2048_65537_v3_usr_crt.der -inform DER -strparse 4 -out CSF1_body.der -noout
sha256sum CSF1_body.der
8e8d56112c3cbdb00806407256bd0e68cdd707aedfbc2fc3327e5d1b3544ebdf CSF1_body.der
6. #Compare the hashes. If hashes match, the CSF1 is verified against SRK1.
1. #Parse the CSF signature
openssl asn1parse -in sig0.bin -inform der
….
187:d=7 hl=2 l= 9 prim: OBJECT :messageDigest
198:d=7 hl=2 l= 34 cons: SET
200:d=8 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:09A369AD89EB5DAB81B9034B5E4CF698431318386201A2719FE1784B44AE0DC4
234:d=5 hl=2 l= 13 cons: SEQUENCE
236:d=6 hl=2 l= 9 prim: OBJECT :rsaEncryption
247:d=6 hl=2 l= 0 prim: NULL
249:d=5 hl=4 l= 256 prim: OCTET STRING [HEX DUMP]:389A07D62CEF65442BEA7AD9E64729DAB8255298CF5CCF0524AF16B07D89B128
CE955E9D15BCB3E11D956699A8413BECA9AE26E5ADA1D4EECDA71376F88ECBF3B59F15A8791FA12CECE1A9471C1153FAD3EE99B37708D7
67D62B1FC4DF932644E3FD679E55B650D4FDFBF8CD92710CE88C64480029E827CB9B67320B61B8E7E9C315A9CA5194BF45E42E7CD136AC5
2DAE58EDECBD387E0DA64F90A2B65C5AA6174436758C1E332369A74B9E726924E1E0A60EEDA4EA1F17E8E14785495F5A8207AA0F2E776F6
F810ED4781CB4B6E432B25C0E31F278FB96DCE567D4EC21FC4513DF5158828109FF9A600556146AEFC0F8B7D2EB296EAD2D4772C439117E4
EC31
2. #Compare hash of CSF binary image with hash in message-digest
a. #Determine the length of CSF commands from CSF binary
od -tx1 -N 4 u-boot_csf.bin
0000000 d4 00 50 41
b. #Extract CSF commands (as per CSF file) in binary
dd if=u-boot_csf.bin of=csf_commands.bin bs=1 count=80 && sync
c. #Hash the csf_commands output file
sha256sum csf_commands.bin
09a369ad89eb5dab81b9034b5e4cf698431318386201a2719fe1784b44ae0dc4 csf_commands.bin
d. #Compare the hash generated of csf_commands with that in the Signature file in #1
3. #Extract encrypted hash from the signature
openssl asn1parse -in sig0.bin -inform der -offset 249 -out enc_digest_csf.der -noout
dd if=enc_digest_csf.der of=enc_digest_csf.hex bs=1 skip="$(expr `stat --printf="%s" enc_digest_csf.der` - 256)"
4. #Get public CSF1 key from CSF1 certificate
openssl x509 -in CSF1_1_sha256_2048_65537_v3_usr_crt.pem -pubkey -noout > CSF1_pubkey.pem
5. #Decrypt the encrypted hash using CSF1 public key
openssl rsautl -verify -inkey CSF1_pubkey.pem -in enc_digest_csf.hex -pubin > digest_CSF1_signedAttr.der
6. #Extract CSF1 signed attribute’s digest from DER encoded digest file
openssl asn1parse -in digest_CSF1_signedAttr.der -inform der
0:d=0 hl=2 l= 49 cons: SEQUENCE
2:d=1 hl=2 l= 13 cons: SEQUENCE
4:d=2 hl=2 l= 9 prim: OBJECT :sha256
15:d=2 hl=2 l= 0 prim: NULL
17:d=1 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:132DC3E6E5CF08C20CD16A5888BFAABB9F1D0E3B298D7D6FDEC0F16D8346C89E
7. #Determine the Signed content to calculate the digest
openssl cms -in sig0.bin -inform DER -cmsout -noout -print
…..
signedAttrs:
object: contentType (1.2.840.113549.1.9.3)
value.set:
OBJECT:pkcs7-data (1.2.840.113549.1.7.1)object: signingTime (1.2.840.113549.1.9.5)
value.set:
UTCTIME:Sep 13 21:54:45 2018 GMTobject: messageDigest (1.2.840.113549.1.9.4)
value.set:
OCTET STRING:
0000 - 09 a3 69 ad 89 eb 5d ab-81 b9 03 4b 5e ..i...]....K^
000d - 4c f6 98 43 13 18 38 62-01 a2 71 9f e1 L..C..8b..q..
001a - 78 4b 44 ae 0d c4 xKD...
……
8. #Visualizing same content in ASN.1 format to extract it
openssl asn1parse -in sig0.bin -inform DER -i
…..
127:d=5 hl=2 l= 105 cons: cont [ 0 ]
129:d=6 hl=2 l= 24 cons: SEQUENCE
131:d=7 hl=2 l= 9 prim: OBJECT :contentType
142:d=7 hl=2 l= 11 cons: SET
144:d=8 hl=2 l= 9 prim: OBJECT :pkcs7-data
155:d=6 hl=2 l= 28 cons: SEQUENCE
157:d=7 hl=2 l= 9 prim: OBJECT :signingTime
168:d=7 hl=2 l= 15 cons: SET
170:d=8 hl=2 l= 13 prim: UTCTIME :180913215445Z
185:d=6 hl=2 l= 47 cons: SEQUENCE
187:d=7 hl=2 l= 9 prim: OBJECT :messageDigest
198:d=7 hl=2 l= 34 cons: SET
200:d=8 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:09A369AD89EB5DAB81B9034B5E4CF698431318386201A2719FE1784B44AE0DC4
……
9. #Extract the Signed Attributes using ASN.1
dd if=sig0.bin of=signedAttr_csf_sig.hex bs=1 skip=127 count=107 && sync
10. #Replace the First byte in signedAttr_uboot_sig.hex file 0xA0 with 0x31 as per RFC5652
11. #Determine SHA256 (Hashing algorithm mentioned in signature)
sha256sum signedAttr_csf_sig.hex
132dc3e6e5cf08c20cd16a5888bfaabb9f1d0e3b298d7d6fdec0f16d8346c89e signedAttr_csf_sig.hex
12. #Compare the digest of signed Attributes with the digest determined from encrypted hash in #6
1. #Parse the Image signature
openssl asn1parse -in sig1.bin -inform der
….
187:d=7 hl=2 l= 9 prim: OBJECT :messageDigest
198:d=7 hl=2 l= 34 cons: SET
200:d=8 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:44909B596C1FD47A11FF0B2D21E5A1466F3847CEE1494970DFAE815DBD72C463
234:d=5 hl=2 l= 13 cons: SEQUENCE
236:d=6 hl=2 l= 9 prim: OBJECT :rsaEncryption
247:d=6 hl=2 l= 0 prim: NULL
249:d=5 hl=4 l= 256 prim: OCTET STRING [HEX DUMP]:B16F157E7AD984BC42D18236304890AD78E67A230394ECD16E312B
6F6F3BA26A5BB891D3490219586C4D12D76A40B92D2A29346A5F86EFE39955F6958F3CF0CF4786B657E8B9312A7B65E4E3B99
7B4CBDFCB441B7F8BB13DF94593AE61BAA7AE21265FD4756417A7B83DCCC145A6B3B034A37098B74EFEA617B8990804501B0
F8FDB7E28723F53F9E910A67953C57C0B656890C75CDBDD80F85BB4B9AC7C0133A5F8B1D580A392A0D1B262EBA875FBEE523
F880C506941C7035E927931A9BBC0DD05877BADFE06BD4C87982B05463AD00BBA0EBDCEFC53DC9B8F24FB44A3A6C32249215
2DF2DF7098CF7A792BF62678429D42AE438F896A5A5ECE124F9755278
2. #Compare hash of image with hash in message-digest
sha256sum u-boot.imx
44909b596c1fd47a11ff0b2d21e5a1466f3847cee1494970dfae815dbd72c463 u-boot.imx
3. #Extract encrypted hash from the signature
openssl asn1parse -in sig1.bin -inform der -offset 249 -out enc_digest_uboot.der -noout
dd if=enc_digest_uboot.der of=enc_digest_uboot.hex bs=1 skip="$(expr `stat --printf="%s" enc_digest_uboot.der` - 256)"
4. #Get public IMG1 key from IMG1 certificate
openssl x509 -in IMG1_1_sha256_2048_65537_v3_usr_crt.pem -pubkey -noout > IMG1_pubkey.pem
5. #Decrypt the encrypted hash using IMG1 public key
openssl rsautl -verify -inkey IMG1_pubkey.pem -in enc_digest_uboot.hex -pubin > digest_IMG1_signedAttr.der
6. #Extract IMG1 signed attribute’s digest from DER encoded digest file
openssl asn1parse -in digest_IMG1_signedAttr.der -inform der
0:d=0 hl=2 l= 49 cons: SEQUENCE
2:d=1 hl=2 l= 13 cons: SEQUENCE
4:d=2 hl=2 l= 9 prim: OBJECT :sha256
15:d=2 hl=2 l= 0 prim: NULL
17:d=1 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:17440A2439C79DEC3DB298EFB8F477C9F41E8DE10CBC2620392EEE8EBD3B7F66
7. #Determine the Signed content to calculate the digest
openssl cms -in sig1.bin -inform DER -cmsout -noout -print
…..
signedAttrs:
object: contentType (1.2.840.113549.1.9.3)
value.set:
OBJECT:pkcs7-data (1.2.840.113549.1.7.1)object: signingTime (1.2.840.113549.1.9.5)
value.set:
UTCTIME:Sep 13 21:54:45 2018 GMTobject: messageDigest (1.2.840.113549.1.9.4)
value.set:
OCTET STRING:
0000 - 44 90 9b 59 6c 1f d4 7a-11 ff 0b 2d 21 D..Yl..z...-!
000d - e5 a1 46 6f 38 47 ce e1-49 49 70 df ae ..Fo8G..IIp..
001a - 81 5d bd 72 c4 63 .].r.c……
8. #Visualizing same content in ASN.1 format to extract it
openssl asn1parse -in sig1.bin -inform DER -i
…..
127:d=5 hl=2 l= 105 cons: cont [ 0 ]
129:d=6 hl=2 l= 24 cons: SEQUENCE
131:d=7 hl=2 l= 9 prim: OBJECT :contentType
142:d=7 hl=2 l= 11 cons: SET
144:d=8 hl=2 l= 9 prim: OBJECT :pkcs7-data
155:d=6 hl=2 l= 28 cons: SEQUENCE
157:d=7 hl=2 l= 9 prim: OBJECT :signingTime
168:d=7 hl=2 l= 15 cons: SET
170:d=8 hl=2 l= 13 prim: UTCTIME :180913215445Z
185:d=6 hl=2 l= 47 cons: SEQUENCE
187:d=7 hl=2 l= 9 prim: OBJECT :messageDigest
198:d=7 hl=2 l= 34 cons: SET
200:d=8 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:44909B596C1FD47A11FF0B2D21E5A1466F3847CEE1494970DFAE815DBD72C463
…….
9. #Extract the Signed Attributes using ASN.1
dd if=sig1.bin of=signedAttr_uboot_sig.hex bs=1 skip=127 count=107 && sync
10. #Replace the First byte in signedAttr_uboot_sig.hex file 0xA0 with 0x31 as per RFC5652
11. #Determine SHA256 (Hashing algorithm mentioned in signature)
sha256sum signedAttr_uboot_sig.hex
17440a2439c79dec3db298efb8f477c9f41e8de10cbc2620392eee8ebd3b7f66 signedAttr_uboot_sig.hex
12. #Compare the digest of signed Attributes with the digest determined from the encrypted hash in #6