This guide describes the procedure and format to be followed to populate customer keys in eFuses of the SoC.
This document must be read along side OTP Keywriter TISCI Description
High Security (HS) Device Sub-types¶
HS-FS (High Security - Field Securable): Device type before customer keys are programmed (the state in which the device leaves TI factory). In this state, device protects the ROM code, TI keys and certain security peripherals. HS-FS devices do not enforce secure boot process.
- M3 JTAG port is closed, R5 JTAG port is open
- DMSC Firewalls are closed, SOC Firewalls are open
- Board configuration need not be signed
- ROM Boot expects a TI signed binary (encryption is optional)
- System Firmware binary is signed by the TI Private key (TI MPK). (Refer Signing an unencrypted binary for secure boot for more details)
HS-SE (High Security – Security Enforced): Device type after customer keys are programmed. HS-SE devices enforce secure boot.
- M3, R5 JTAG ports are both closed
- DMSC, SOC Firewalls are both closed
- Board configuration needs to be signed with active customer private key (SMPK/BMPK)
- ROM Boot expects a dual signed, encrypted system firmware binary
- System Firmware binary is encrypted by the TI Encryption key (TI MEK), and signed by the TI Private key (TI MPK). Customer has to dual sign it with their private key (SMPK/BMPK). (Refer Signing an encrypted binary for secure boot)
HS-FS to HS-SE Conversion¶
In order to convert a HS-FS device to HS-SE device, one has to program the customer root key set (optionally backup key set) on the target device, using OTP Keywriter.
Customer key information is encrypted into x509 certificate extension fields. A list of fields that OTP keywriter supports, can be found here.
The following figure illustrates the procedure to be followed to generate the required x509 certifcate for key writing.
- OEM generates a random 256-bit number to be used as an AES encryption key for protecting the OTP extension data.
- The AES-256 key from step 1 is used to encrypt all X509 extension fields, which require encryption protection.
- The following X509 extensions are created, using the AES key encrypted with the TI FEK (public key):
- Encrypting the AES-256 key with TI FEK
- Signing the AES-256 key with the SMPK, and encrypting that with the TI FEK
- (optionally, refer step 6) signing the AES-256 key with the BMPK, and encrypting that with the TI FEK
- All of the extensions from steps 1-3 are combined into a X.509 configuration which is used to generate and sign a certificate with the SMPK.
The SMPK Hash and the BMPK Hash are computed using SHA-512 Algorithm to hash the corresponding Public keys in DER format.
- This X509 config is sigend using SMPK (private).
- (Optional) If the OEM chooses to write BMPK/BMEK fields, the X509 config from step 5 needs to be signed using BMPK (private).
Following fields are supported by the Key writer.
|BMEK||Backup Manufacturer Encryption Key||256-bit Customer encryption key for encrypted boot|
|BMPKH||Backup Manufacturer Public Key Hash||BMPK is 4096-bit customer RSA signing key|
|EXTENDED OTP||Extended OTP array||1024 bit extended otp array|
|KEYCNT||Key count||2 if BMPK, SMPK are used, 1 if SMPK is used, 0 if none|
|KEYREV||Key revision||Can have a maximum value = key count|
|MEK Options||SMEK/BMEK options||(Reserved for future use) 5 bit value|
|MPK Options||SMPK/BMPK options||(Reserved for future use) 10 bit value (split into 2 parts)|
|MSV||Model specific value||20 bit value with 12 bit BCH code|
|SMEK||Secondary Manufacturer Encryption Key||256-bit Customer encryption key for encrypted boot|
|SMPKH||Secondary Manufacturer Public Key Hash||SMPK is 4096-bit customer RSA signing key|
|SWREV-BOARDCONFIG||Secure Board Configuration software revision||128 bit value (64 without double redundancy)|
|SWREV-SBL||SBL software revision||96 bit value (48 without double redundancy)|
|SWREV-SYSFW||Firmware software revision||96 bit value (48 without double redundancy)|
The current version of the OTP Keywriter only supports 4096 bit RSA format for SMPK and BMPK. Support for ECDSA and different key lengths will be available in subsequent versions.
These are currently not supported, and reserved for future use.
MPK (SMPKH/BMPKH) options is a 10 bit value, split into two 5 bit values, to be programmed contiguous to MPK part 1 and part 2. MEK options is a 5 bit value, programmed contiguous to MEK.
Secure ROM uses MPK options bit index 0 for RMA process.
On a HS-SE device, if this bit is set,
tiMpk will be used as root of trust
instead of SMPKH/BMPKH.
Model Specific Value is a 20 bit value.
BCH code is used for error correction.
BCH algorithm (288, 261, 7) is used for SMPKH(BMPKH), SMEK(BMEK).
Out of 261 bits, 256 correspond to SMPKH(BMPKH) part1/2 or SMEK(BMEK) and the remaining 5 bits are the MPK/MEK options. If no options are specified, they are set to 0.
BCH algorithm (32, 20, 5) is used for MSV (20 bit value, and 12 bit BCH code).
BCH codes are computed at time of fuse programming by OTP Keywriter firmware based on plaintext key values.
eFuse values of SWREV-SBL, SWREV-SYSFW, SWREV-BOARDCONFIG, use double redundancy to reduce the chance of data corruption. Refer SWREV decode logic for more details.
Use of SWREV is optional. However, if SWREV is used, an initial non-zero value is required to enforce revision checks. Thus, SWREV values are programmed to an initial value of ‘1’ for all fields at TI factory. Thus, individual SWREV fields typically are not required to be programmed.
The index and size of ext_otp in the x509 certificate extension Keywriter: AES Encrypted extended OTP should be multiples of 8
1024 bits are provided as input, out of which
size number of bits starting from
index are programmed into efuses. Following figure illustrates the bit mapping
from byte array (input) to efuse array (efuse rows).
If only byte array indexes 2 and 3 were to be programmed (0xCC, 0xDD respectively) from the above figure, we can see that efuse rows 0 and 1 would be programmed as (0x01CC0000) and (0x0000006E) with masks (0x01FF0000) and (0x0000007F) respectively.
If they were to be write protected, we have to write protect both row 0 and row 1.
So, we need to set
The MSB 16 octets are for wp, LSB 16 octets are for rp.
bits 0 and 1 are set in wp, to write protect efuse row 0 and row 1.
Please note that this would cause the remaining bits of row 0 and row 1 also to be write protected.
X509 Configuration Template¶
[ req ] distinguished_name = req_distinguished_name x509_extensions = v3_ca prompt = no dirstring_type = nobmp # This information will be filled by the end user. # The current data is only a place holder. # System firmware does not make decisions based # on the contents of this distinguished name block. [ req_distinguished_name ] C = oR ST = rx L = gQE843yQV0sag O = dqhGYAQ2Y4gFfCq0t1yABCYxex9eAxt71f OU = a87RB35W CN = x0FSqGTPWbGpuiV emailAddress = kFp5uGcgWXxcfxi@vsHs9C9qQWGrBs.com [ v3_ca ] basicConstraints = CA:true 22.214.171.124.4.1.294.1.64 = ASN1:SEQUENCE:enc_aes_key 126.96.36.199.4.1.294.1.65 = ASN1:SEQUENCE:enc_smpk_signed_aes_key 188.8.131.52.4.1.294.1.66 = ASN1:SEQUENCE:enc_bmpk_signed_aes_key 184.108.40.206.4.1.294.1.67 = ASN1:SEQUENCE:aesenc_smpkh 220.127.116.11.4.1.294.1.68 = ASN1:SEQUENCE:aesenc_smek 18.104.22.168.4.1.294.1.69 = ASN1:SEQUENCE:plain_mpk_options 22.214.171.124.4.1.294.1.70 = ASN1:SEQUENCE:aesenc_bmpkh 126.96.36.199.4.1.294.1.71 = ASN1:SEQUENCE:aesenc_bmek 188.8.131.52.4.1.294.1.72 = ASN1:SEQUENCE:plain_mek_options 184.108.40.206.4.1.294.1.73 = ASN1:SEQUENCE:aesenc_ext_otp 220.127.116.11.4.1.294.1.74 = ASN1:SEQUENCE:plain_key_rev 18.104.22.168.4.1.294.1.76 = ASN1:SEQUENCE:plain_msv 22.214.171.124.4.1.294.1.77 = ASN1:SEQUENCE:plain_key_cnt 126.96.36.199.4.1.294.1.78 = ASN1:SEQUENCE:plain_swrev_sysfw 188.8.131.52.4.1.294.1.79 = ASN1:SEQUENCE:plain_swrev_sbl 184.108.40.206.4.1.294.1.80 = ASN1:SEQUENCE:plain_swrev_sec_brdcfg 220.127.116.11.4.1.294.1.81 = ASN1:SEQUENCE:plain_keywr_min_version [ enc_aes_key ] # Replace PUT-ENC-AES-KEY with acutal Encrypted AES Key val = FORMAT:HEX,OCT:PUT_ENC_AES_KEY size = INTEGER:PUT_SIZE_ENC_AES [ enc_bmpk_signed_aes_key ] # Replace PUT-ENC-BMPK-SIGNED-AES-KEY with acutal Encrypted BMPK signed AES Key val = FORMAT:HEX,OCT:PUT_ENC_BMPK_SIGNED_AES_KEY size = INTEGER:PUT_SIZE_ENC_BMPK_SIGNED_AES [ enc_smpk_signed_aes_key ] # Replace PUT-ENC-SMPK-SIGNED-AES-KEY with acutal Encrypted SMPK signed AES Key val = FORMAT:HEX,OCT:PUT_ENC_SMPK_SIGNED_AES_KEY size = INTEGER:PUT_SIZE_ENC_SMPK_SIGNED_AES [ aesenc_smpkh ] # Replace PUT-AESENC-SPMKH with acutal Encrypted AES Key val = FORMAT:HEX,OCT:PUT_AESENC_SMPKH iv = FORMAT:HEX,OCT:PUT_IV_AESENC_SMPKH rs = FORMAT:HEX,OCT:PUT_RS_AESENC_SMPKH size = INTEGER:PUT_SIZE_AESENC_SMPKH action_flags = INTEGER:PUT_ACTFLAG_AESENC_SMPKH [ aesenc_smek ] # Replace PUT-AESENC-SMEK with acutal Encrypted AES Key val = FORMAT:HEX,OCT:PUT_AESENC_SMEK iv = FORMAT:HEX,OCT:PUT_IV_AESENC_SMEK rs = FORMAT:HEX,OCT:PUT_RS_AESENC_SMEK size = INTEGER:PUT_SIZE_AESENC_SMEK action_flags = INTEGER:PUT_ACTFLAG_AESENC_SMEK [ aesenc_bmpkh ] # Replace PUT-AESENC-BMPKH with acutal Encrypted BMPKH val = FORMAT:HEX,OCT:PUT_AESENC_BMPKH iv = FORMAT:HEX,OCT:PUT_IV_AESENC_BMPKH rs = FORMAT:HEX,OCT:PUT_RS_AESENC_BMPKH size = INTEGER:PUT_SIZE_AESENC_BMPKH action_flags = INTEGER:PUT_ACTFLAG_AESENC_BMPKH [ aesenc_bmek ] # Replace PUT-AESENC-BMEK with acutal Encrypted BMEK val = FORMAT:HEX,OCT:PUT_AESENC_BMEK iv = FORMAT:HEX,OCT:PUT_IV_AESENC_BMEK rs = FORMAT:HEX,OCT:PUT_RS_AESENC_BMEK size = INTEGER:PUT_SIZE_AESENC_BMEK action_flags = INTEGER:PUT_ACTFLAG_AESENC_BMEK [ plain_msv ] # Replace PUT-PLAIN-MSV with actual MSV value val = FORMAT:HEX,OCT:PUT_PLAIN_MSV action_flags = INTEGER:PUT_ACTFLAG_PLAIN_MSV [ plain_mpk_options ] # Replace PUT-PLAIN-MPK-OPT with actual MPK OPT value val = FORMAT:HEX,OCT:PUT_PLAIN_MPK_OPT action_flags = INTEGER:PUT_ACTFLAG_PLAIN_MPK_OPT [ plain_mek_options ] # Replace PUT-PLAIN-MEK-OPT with actual MEK OPT value val = FORMAT:HEX,OCT:PUT_PLAIN_MEK_OPT action_flags = INTEGER:PUT_ACTFLAG_PLAIN_MEK_OPT [ plain_key_rev ] # Replace PUT-PLAIN-KEY-REV with actual Key Rev value val = FORMAT:HEX,OCT:PUT_PLAIN_KEY_REV action_flags = INTEGER:PUT_ACTFLAG_PLAIN_KEY_REV [ plain_key_cnt ] # Replace PUT-PLAIN-KEY-CNT with actual Key Count value val = FORMAT:HEX,OCT:PUT_PLAIN_KEY_CNT action_flags = INTEGER:PUT_ACTFLAG_PLAIN_KEY_CNT [ plain_swrev_sysfw ] # Replace PUT-PLAIN-SWREV-SYSFW with actual SWREV SYSFW value val = FORMAT:HEX,OCT:PUT_PLAIN_SWREV_SYSFW action_flags = INTEGER:PUT_ACTFLAG_PLAIN_SWREV_SYSFW [ plain_swrev_sbl ] # Replace PUT-PLAIN-SWREV-SBL with actual SWREV SBL value val = FORMAT:HEX,OCT:PUT_PLAIN_SWREV_SBL action_flags = INTEGER:PUT_ACTFLAG_PLAIN_SWREV_SBL [ plain_swrev_sec_brdcfg ] # Replace PUT-PLAIN-SWREV-SEC-BRDCFG with actual SWREV SEC BRDCFG value val = FORMAT:HEX,OCT:PUT_PLAIN_SWREV_SEC_BRDCFG action_flags = INTEGER:PUT_ACTFLAG_PLAIN_SWREV_SEC_BRDCFG [plain_keywr_min_version ] # Replace PUT-PLAIN-KEYWR-MIN-VER with actual KEYWR-MIN-VER value val = FORMAT:HEX,OCT:PUT_PLAIN_KEYWR_MIN_VER [ aesenc_ext_otp ] # Replace PUT-AESENC-EXT-OTP with actual Encrypted OTP val = FORMAT:HEX,OCT:PUT_AESENC_EXT_OTP iv = FORMAT:HEX,OCT:PUT_IV_AESENC_EXT_OTP rs = FORMAT:HEX,OCT:PUT_RS_AESENC_EXT_OTP wprp = FORMAT:HEX,OCT:PUT_WPRP_AESENC_EXT_OTP index = INTEGER:PUT_INDX_AESENC_EXT_OTP size = INTEGER:PUT_SIZE_AESENC_EXT_OTP action_flags = INTEGER:PUT_ACTFLAG_AESENC_EXT_OTP