EKB: Encrypted Key Blob#
Different security functions often need different types of keys to encrypt, decrypt, authenticate, and verify data. These keys are usually confidential and sensitive, and compromising them would have serious consequences. As a complement to fuses, the Encrypted Key Blob (EKB) provides additional storage for security keys and data. Its usage is completely defined by the user, making it flexible and scalable.
The EKB is encrypted by the EKB Encryption Key (EKB_EK) and authenticated by the EKB Authentication Key (EKB_AK), both of which are derived from a hardware-backed key (EKB Fuse Key). The EKB content is visible in plaintext only to the secure world. Although the EKB is designed to store user keys, you can also use it to save any sensitive data.
Note
The EKB can be updated only through OTA, not at runtime.
An EKB binary is often named eks_<version>.img, which is the filename of the EKB binary flashed to the EKS partition by default. For example, the EKB binary for the Jetson Orin series is eks_t234.img and for the Jetson Thor series is eks_t264.img.
Note
Currently, the version of eks_t234.img is V2.0; the version of eks_t264.img is V2.1.
Terminology#
This section defines terms used throughout the EKB documentation. For the key derivation formulas that produce these keys, see Key Hierarchy and Derivation.
EKB Fuse Key#
An AES key that is burned into a fuse. This key is not visible to software.
For the Jetson Orin series, OP-TEE uses the EKB fuse key during boot through the SE to derive EKB_RK. The EKB fuse key has 256 bits and can be burned into the OEM_K1 fuse or the OEM_K2 fuse. We recommend that you use the OEM_K1 fuse as the EKB fuse key.
For the Jetson Thor series, PSC-BL1 uses the EKB fuse key during early boot through the PSC SE to derive TZ_RK. The EKB fuse key has 256 bits and is burned into the PSC_OEM_KDK1 fuse.
Key Distribution System (KDS)#
On the Jetson Thor series, KDS provides a secure and fast way to transfer keys across multiple endpoints in chip without exposing them to software.
During the early boot, PSC-BL1 derives the TZ root key from the EKB fuse key and moves it to KDS. OP-TEE or MB2 can then move the key from KDS to the SE keyslot to derive the usage root keys from the keyslots.
Keyslot#
A secure storage area in the Jetson Security Engine (SE) that protects secure keys from unauthorized reading and writing.
For the Jetson AGX Orin series, the Jetson Orin NX series, and the Jetson Orin Nano series, during the early boot PSC-BL1 loads the secure keys from fuse storage to the keyslots so that OP-TEE can later use the SE to derive the keys from the keyslots.
TZ Root Key (TZ_RK)#
The TZ root key is a 256-bit AES key that is derived from the PSC_OEM_KDK1 fuse (Jetson Thor series only).
Note
TZ_RK is the root key of many usage root keys, such as EKB_RK and HUK_RK. Do not use this key directly; use it to derive usage root keys, then use the derived usage root keys to derive usage keys to encrypt and authenticate data.
EKB Root Key (EKB_RK)#
The EKB root key is derived from the EKB fuse key.
For the Jetson Orin series,
EKB_RKis a 128-bit AES key derived fromOEM_K1orOEM_K2.For the Jetson Thor series,
EKB_RKis a 256-bit AES key derived fromTZ_RK.
Note
Do not use this key directly; use it to derive keys, then use the derived keys to encrypt and authenticate data.
EKB Encryption Key (EKB_EK)#
The EKB encryption key encrypts and decrypts the EKB. EKB_EK is a 128-bit (Jetson Orin series) or 256-bit (Jetson Thor series) AES key derived from EKB_RK.
EKB Authentication Key (EKB_AK)#
The EKB authentication key authenticates EKB content. EKB_AK is a 128-bit (Jetson Orin series) or 256-bit (Jetson Thor series) AES key derived from EKB_RK.
Note
We strongly recommend that you use the same KDF as OP-TEE to generate different keys for different purposes. For example, use EKB_EK to encrypt and decrypt EKB content and use EKB_AK to authenticate EKB content.
SE#
SE is an abbreviation of the Jetson Security Engine.
MB2#
MB2 is the bootloader stage that passes the EKB to OP-TEE. The boot flow executes MB2 before OP-TEE is initialized.
Key Hierarchy and Derivation#
This section defines the key derivation functions (KDFs) that produce EKB_EK and EKB_AK from the EKB fuse key. The procedures in EKB Generation and EKB Extraction both reference these formulas.
Jetson Orin Series#
Pseudocode for the NIST-SP-800-108 AES-CMAC algorithm:
NIST-SP-800-108(KI, KO, L, context_string, label_string) {
uint8_t count = 0x01;
for (count=0x01; count<=L/128; count++) {
AES-128-CMAC(key=KI, count || label_string || 0x00 || context_string || BE32(L), output=&KO[count*128]);
}
}
KIis a 128-bit input key.KOis an output key.Lis a multiple of 128, the bit length of KO.context_stringandlabel_stringhave the values shown in the next table.
The following are the derivation parameters required to derive EKB_EK and EKB_AK from EKB_RK:
Parent key |
Derived Key |
context_string |
label_string |
|---|---|---|---|
|
|
“ekb” |
“encryption” |
|
|
“ekb” |
“authentication” |
Jetson Thor Series#
Pseudocode for the NIST-SP-800-108 HMAC-SHA256 algorithm:
NIST-SP-800-108(KI, KO, L, context_string, label_string) {
uint32_t count = 0x00000001;
for (count=0x01; count<=L/256; count++) {
HMAC-SHA256(key=KI, BE32(count) || label_string || 0x00 || context_string || BE32(L), output=&KO[count*256]);
}
}
KIis a 256-bit input key.KOis an output key.Lis a multiple of 128, the bit length of KO.context_stringandlabel_stringhave the values shown in the next table.
The following are the derivation parameters required to derive STATIC_RT_KDK1, TZ_RK, EKB_RK, EKB_EK, and EKB_AK from PSC_OEM_KDK1:
Parent key |
Derived Key |
label_string |
context_string |
|---|---|---|---|
|
|
“STATIC_RT” |
0x00 |
|
|
“STATIC_RT_TZ” |
0x00 |
|
|
“ekb” |
“root” |
|
|
“ekb” |
“encryption” |
|
|
“ekb” |
“authentication” |
The following diagram illustrates the key hierarchy:
EKB Format#
The EKB format is designed to be as generic as possible, giving you full control of the actual key blob structure. The following is the EKB layout:
EKB Header#
The EKB header contains Header (which includes EKB_size, Magic, Major, and Minor), FV (Jetson Orin series only) or Reserved (Jetson Thor series only), and MAC. The EKB header is consumed and parsed by OP-TEE. It must match the following layout:
EKB_size is the length of the EKB binary starting from the Magic field. EKB_size is four bytes long, in little endian format. Its value must be 4 less than the length of the EKB binary in bytes.
Magic is eight bytes long, and must contain the exact string "NVEKBP\0\0".
Major is two bytes long and contains the current major version, which is 2.
Minor is two bytes long and contains the current minor version, which is 0 for the Jetson Orin series or 1 for the Jetson Thor series.
FV is a fixed vector that has a fixed 16-byte value. For the Jetson Orin series, it is also used for the EKB_RK key derivation. It can be generated with a random number generator. We recommend using /dev/random or /dev/urandom. The following command generates a 16-byte random number and saves it in hexadecimal form:
$ openssl rand -rand /dev/urandom -hex 16 > fv_hex_file
Reserved is a reserved field in EKB version 2.1 (Jetson Thor series only).
EKB version |
FV |
|---|---|
1.0 |
A hardcoded 16-byte value. |
2.0 |
A random generated 16-byte value. |
2.1 |
A reserved field. |
MAC is a message authentication code, used to authenticate the data from content header to the end. It is generated by the AES-CMAC algorithm using EKB_AK.
EKB Content Header#
The EKB content header contains Content_header (this data includes Content_size, Content_magic, and Reserved) and IV. The EKB content header information is parsed by OP-TEE. It must match the following layout:
Content_size is the length of the encrypted EKB key data starting after the IV field. Content_Size is four bytes long and is in little endian format.
Content_magic is four bytes long and must contain the exact string "EEKB".
Reserved is an 8-byte field reserved for future use. Its default value is zero.
IV is 16 bytes long and is used to encrypt and decrypt the EKB key data with EKB_EK. IV can be generated with a random number generator. We recommend using /dev/random or /dev/urandom. The following command generates a 16-byte random number and saves it in hexadecimal form:
$ openssl rand -rand /dev/urandom -hex 16 > iv_hex_file
EKB Key Format#
The EKB content can contain any number of keys or similar data and is ended by an End_tag1 (0000) and an End_tag2 (0000). The EKB content format is as follows:
Key_tag is the type of data stored in the EKB. Key_tag is four bytes long and is in little endian format.
Key_len is four bytes long and indicates the length of the data that follows.
Key is the data content of the tag. The data content length is indicated by Key_len.
You can add additional keys or data to the EKB by adding key or data that conform to the EKB key format (Key_tag, Key_len, Key) and extending the script (see Tool for EKB Generation) to support additional keys.
EKB Binary Size Restrictions#
For security reasons, an EKB binary must be at least 1024 bytes long, and it must not exceed the EKS partition size. If the size of an EKB binary is not in this range, flashing fails.
If you have very little EKB content, the EKB generation tool pads the EKB binary to a length of at least 1024 bytes. The jetson-user-key PTA in OP-TEE decrypts the entire binary and then discards the padding.
EKB Generation#
The sample EKB layout is intended to help you design a sufficiently secure mechanism to protect private data in the EKB. It stores user-defined keys in the EKB. As shown in EKB Format, you can extend EKB content, for example, by adding EKB keys in the EKB key format for multiple keys.
NVIDIA recommends that you use the EKB layout described in EKB Format. However, you can always replace it with a customized layout.
The EKB generation process is as follows:
Define a format for the EKB content and generate the EKB content in plaintext.
Generate a symmetric key as an EKB fuse key. For both the Jetson Orin series and the Jetson Thor series, the key size is 256 bits.
Burn the EKB fuse key into the device’s fuse.
For the Jetson Orin series, the fuse is
OEM_K1orOEM_K2. We recommend usingOEM_K1.For the Jetson Thor series, the fuse is
PSC_OEM_KDK1.
For more information about the fuses, see the Fuse Specification Application Note for your Jetson device.
Generate a random FV and save it to the
FVfield in the EKB header (Jetson Orin series only).Derive
EKB_EKandEKB_AK.For the Jetson Orin series, first compute
EKB_RKusing AES ECB encryption:EKB_RK= AES-128-ECB(FV, EKB fuse key)Then derive
EKB_EKandEKB_AKaccording to the formulas in Key Hierarchy and Derivation.
Generate a random IV and save it in the
IVfield of the EKB content header. EncryptContent (plaintext)withEKB_EKandIV:Content (ciphertext)= AES-CBC(IV,EKB_EK,Content (plaintext))Concatenate
Content_header,IV, andContent (ciphertext):EKB_content=Content_header+IV+Content (ciphertext)Calculate the MAC of
EKB_contentwithEKB_AKand save it to theMACfield ofEKB_header:MAC= AES-CMAC(key =EKB_AK,EKB_content)Concatenate
EKB_headerandEKB_contentas described in EKB Format. The resulting file is a fully generated EKB binary:EKB=EKB_header+EKB_contentFlash the EKB binary to the Jetson device’s EKS partition.
The following flow diagram illustrates the EKB generation process for the Jetson Orin series:
The following flow diagram illustrates the EKB generation process for the Jetson Thor series:
Tool for EKB Generation#
Before you generate the EKB with your own EKB fuse key, ensure that the key is burned into the corresponding fuse.
You can generate user-defined keys separately by running the openssl tool from the command line and store them in different files.
Note
The current JetPack release supports EKB version 2.0 for the Jetson Orin series and EKB version 2.1 for the Jetson Thor series. The extraction in the jetson-user-key PTA for the Jetson Orin series is backward compatible; it still supports EKB version 1. The extraction in the jetson-user-key PTA for the Jetson Thor series is not backward compatible because the EKB fuse key has changed.
The following example shows how to run the EKB generation tool for the Jetson Orin series and Jetson Thor series:
$ python3 gen_ekb.py -chip t234 \
-oem_k1_key <oem_k1.key> \
-in_sym_key <sym_t234.key> \
-in_sym_key2 <sym2_t234.key> \
-in_auth_key <auth_t234.key> \
-in_hw_key <hwkey_t234.key> \
-out <eks_t234.img>
$ python3 gen_ekb.py -chip t264 \
-oem_kdk1_key <oem_kdk1.key> \
-in_sym_key <sym_t264.key> \
-in_sym_key2 <sym2_t264.key> \
-in_auth_key <auth_t264.key> \
-in_hw_key <hwkey_t264.key> \
-out <eks_t264.img>
<oem_k1.key>is the key that is stored in theOEM_K1fuse (Jetson Orin series only).<oem_kdk1.key>is the key that is stored in thePSC_OEM_KDK1fuse (Jetson Thor series only).<sym_t234.key>and<sym_t264.key>are the UEFI payload encryption keys.In the current L4T reference implementation, this is the UEFI payload encryption key provided by the
--uefi-encoption in the flash command. (For more information, refer to Prepare the User Key in the topic Secure Boot.)Note
The UEFI payload encryption is currently not supported in the Jetson AGX Thor series.
<sym2_t234.key>and<sym2_t264.key>are the disk encryption keys.The disk encryption key is the source key for generation of the LUKS key in the disk-encryption reference implementation.
<auth_t234.key>and<auth_t264.key>are the UEFI variable authentication keys.In the current L4T reference implementation, this is the UEFI Variable Protection key. The authentication key is saved in the EKB and used by OP-TEE.
<hwkey_t234.key>and<hwkey_t264.key>are the sample keys forhwkey-agent.This example uses the key for data encryption and decryption.
<eks_t234.img>or<eks_t264.img>is the respective output image file, intended to be flashed into the EKS partition of the device.
Note
For both the Jetson Orin series and the Jetson Thor series, you can copy and substitute
<Linux_for_Tegra>/bootloader/eks_<version>.imgwith the EKS image you create. As described in EKB Generation, the EKS image is encrypted and signed by theEKB_EKandEKB_AKkeys derived from the EKB fuse key (OEM_K1for the Jetson Orin series andPSC_OEM_KDK1for the Jetson Thor series).To test the EKS feature on a board where the EKB fuse key has not been burned, OP-TEE uses a pre-defined hard-coded key instead of a fuse key. However, after the
OemKeyValidbit of theBootSecurityInfofuse or theSecurityModefuse is burned (ensure that the fuse key is burned before theSecurityModefuse is burned), the EKS image must be created withEKB_AKas the signing key andEKB_EKas the encryption key. Refer toexample.sh, which is the script in the OP-TEE source package that generates the default EKS image with the test key.To update the EKS image in the EKS partitions with Capsule update, refer to To Customize the BUP.
EKB Extraction#
EKB extraction is the reverse of EKB generation. During boot, the jetson-user-key PTA in OP-TEE (see Jetson User Key PTA) performs the following steps:
PSC prepares
TZ_RK(Jetson Thor series only) orOEM_K1(Jetson Orin series only) for OP-TEE.Derive
EKB_EKandEKB_AKaccording to the formulas in Key Hierarchy and Derivation.Authenticate
EKB_contentwithEKB_AKand theMACstored in the EKS image:MAC= AES-CMAC(EKB_AK,EKB_content)If authentication succeeds, decrypt
EKB_contentwithEKB_EKandIVfromEKB_content_headerto obtain plaintext:Content (plaintext)= AES-CBC(IV,EKB_EK,Content (ciphertext))Extract user keys in EKB key format from
Content (plaintext), store the keys in a linked list, and use them as needed within the PTA.
The following flow diagram illustrates the EKB extraction process for the Jetson Thor series:
The following flow diagram illustrates the EKB extraction process for the Jetson Orin series:
EKB Extraction Sample#
For an example of how to perform EKB extraction, see the source code of the jetson-user-key PTA in OP-TEE.
SE Keyslot Clearing#
The fuse keys are loaded into keyslots during an early boot stage before OP-TEE runs. Because software cannot read them back from the keyslots, a TA can only derive the keys from the keyslots through the SE. After the EKB fuse key in the keyslot has been used, it no longer needs to persist in the keyslot. To prevent a component from using this key after the device boots, we strongly recommend that you wipe the key from the keyslot.
The person who uses the EKB fuse key is responsible for clearing the key. You can clear the keyslot by calling the tegra_se_clear_aes_keyslots() function provided by the SE driver.