Key Writer

This guide describes the procedure and format to be followed to populate customer keys in eFuses of the SoC.

Note

This document must be read along side OTP Keywriter TISCI Description

High Security (HS) Device Sub-types

  1. 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)
  2. 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.

../_images/hsfs_to_hsse_conversion.png

Procedure

The following figure illustrates the procedure to be followed to generate the required x509 certifcate for key writing.

../_images/key_writer_procedure.png
  1. OEM generates a random 256-bit number to be used as an AES encryption key for protecting the OTP extension data.
  2. The AES-256 key from step 1 is used to encrypt all X509 extension fields, which require encryption protection.
  3. 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
  4. 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.

Note

The SMPK Hash and the BMPK Hash are computed using SHA-512 Algorithm to hash the corresponding Public keys in DER format.

  1. This X509 config is sigend using SMPK (private).
  2. (Optional) If the OEM chooses to write BMPK/BMEK fields, the X509 config from step 5 needs to be signed using BMPK (private).

Supported fields

Following fields are supported by the Key writer.

Table 5 Supported OTP keys
Key Description Notes
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)

Important

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.

MPK/MEK Options

Note

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.

MSV

Model Specific Value is a 20 bit value.

BCH code

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.

SWREV

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.

Extended OTP

Important

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).

../_images/efuse_32_to_25_example.png

Example

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 wprp to 0000000000000003 0000000000000000 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
1.3.6.1.4.1.294.1.64 = ASN1:SEQUENCE:enc_aes_key
1.3.6.1.4.1.294.1.65 = ASN1:SEQUENCE:enc_smpk_signed_aes_key
1.3.6.1.4.1.294.1.66 = ASN1:SEQUENCE:enc_bmpk_signed_aes_key
1.3.6.1.4.1.294.1.67 = ASN1:SEQUENCE:aesenc_smpkh
1.3.6.1.4.1.294.1.68 = ASN1:SEQUENCE:aesenc_smek
1.3.6.1.4.1.294.1.69 = ASN1:SEQUENCE:plain_mpk_options
1.3.6.1.4.1.294.1.70 = ASN1:SEQUENCE:aesenc_bmpkh
1.3.6.1.4.1.294.1.71 = ASN1:SEQUENCE:aesenc_bmek
1.3.6.1.4.1.294.1.72 = ASN1:SEQUENCE:plain_mek_options
1.3.6.1.4.1.294.1.73 = ASN1:SEQUENCE:aesenc_ext_otp
1.3.6.1.4.1.294.1.74 = ASN1:SEQUENCE:plain_key_rev
1.3.6.1.4.1.294.1.76 = ASN1:SEQUENCE:plain_msv
1.3.6.1.4.1.294.1.77 = ASN1:SEQUENCE:plain_key_cnt
1.3.6.1.4.1.294.1.78 = ASN1:SEQUENCE:plain_swrev_sysfw
1.3.6.1.4.1.294.1.79 = ASN1:SEQUENCE:plain_swrev_sbl
1.3.6.1.4.1.294.1.80 = ASN1:SEQUENCE:plain_swrev_sec_brdcfg
1.3.6.1.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