# Copyright (c) 2023-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause

**********************************************************************
                           Linux for Tegra
                          Tool: gen_ekb.py
                                README
**********************************************************************

This README provides an overview of the "gen_ekb.py" tool to generate
an EKS image file "eks.img". It has a predefined layout of EKB as shown
in the EKB layout section. The Jetson user key PTA in OP-TEE extracts
the EKB that generated by this script.

----------------------------------------------------------------------
Dependency
----------------------------------------------------------------------
- Python version 3.6 or above
- Python cryptography modules pyca/cryptography and pycrypto. You can
install that via "apt" or "pip" command on your Linux host machine.

$> apt-get install python3-cryptography
or
$> pip install cryptography

and

$> pip install pycrypto

----------------------------------------------------------------------
EKB layout
----------------------------------------------------------------------

Note that you can define a specific mechanism to encapsulate the EKB
contents depending on the requirement. Shown here is a reference
implementation.

EKB version 2.0 for T234:

-----------------------------------------------------------
|    EKB_size   |      Magic    |    Major   |   Minor    |
|    (4 bytes)  |    (8 bytes)  |  (2 bytes) | (2 bytes)  |
-----------------------------------------------------------
|                         FV (16 bytes)                   |
-----------------------------------------------------------
|                         MAC (16 bytes)                  |
-----------------------------------------------------------
|  Content_size | Content_magic |        Reserved         |
|   (4 bytes)   |   (4 bytes)   |        (8 bytes)        |
-----------------------------------------------------------
|                         IV (16 bytes)                   |
-----------------------------------------------------------
|    Key1_tag   |   Key1_len    |         Key1            |
|   (4 bytes)   |   (4 bytes)   |       (Key1_len)        |
-----------------------------------------------------------
|    Key2_tag   |   Key2_len    |         Key2            |
|   (4 bytes)   |   (4 bytes)   |       (Key2_len)        |
-----------------------------------------------------------
|                               ...                       |
-----------------------------------------------------------
|   End_tag1(\0\0\0\0)          |    End_tag2 (\0\0\0\0)  |
-----------------------------------------------------------

EKB version 2.1 for T264:

-----------------------------------------------------------
|    EKB_size   |      Magic    |    Major   |   Minor    |
|    (4 bytes)  |    (8 bytes)  |  (2 bytes) | (2 bytes)  |
-----------------------------------------------------------
|		      Reserved (16 bytes)                 |
-----------------------------------------------------------
|                       MAC (16 bytes)                    |
-----------------------------------------------------------
|  Content_size | Content_magic |        Reserved         |
|   (4 bytes)   |   (4 bytes)   |        (8 bytes)        |
-----------------------------------------------------------
|                       IV (16 bytes)                     |
-----------------------------------------------------------
|    Key1_tag   |   Key1_len    |         Key1            |
|   (4 bytes)   |   (4 bytes)   |       (Key1_len)        |
-----------------------------------------------------------
|    Key2_tag   |   Key2_len    |         Key2            |
|   (4 bytes)   |   (4 bytes)   |       (Key2_len)        |
-----------------------------------------------------------
|                               ...                       |
-----------------------------------------------------------
|   End_tag1(\0\0\0\0)          |    End_tag2 (\0\0\0\0)  |
-----------------------------------------------------------

* Each row in the first five fows occupies 16 bytes
* Each row aftet "IV" is not fixed legnth
* The key tag, key length and key data are encrypted and saved after "IV"
* The zeroes at the end of the EKB image indicate the end of user data
* Normally EKB saves user keys so the term "key" is used in above diagram
* Technically any user data can be saved in EKB

----------------------------------------------------------------------
The steps of EKB generation
----------------------------------------------------------------------

For T234:
* Derive EKB root key(EKB_RK)
  * Generate a random fixed vector (FV), and also save it to FV field
    of EKB header.
  * Deriving EBK_RK from fuse key(OEM_K1)
    * EKB_RK = AES-128-ECB(fuse_key, FV)
* Generate EKB_EK and EKB_AK that follows NIST-SP-800-108 KDF scheme
  * EKB_EK = NIST-SP-800-108(EKB_RK, ...)
  * EKB_AK = NIST-SP-800-108(EKB_RK, ...)
* Acquire EKB content
  * Generate a random initial vector (IV), and also save it to IV field
    of EKB content header
  * Content_ciphertext = AES-128-CBC(EKB_EK, IV, Content_plaintext)
  * EKB_content = EKB_content_header + Content_ciphertext
* Acquire message authentication code (MAC)
  * MAC = AES-CMAC(EKB_AK, EKB_content)
  * Save MAC to MAC field of EKB header
* Generate EKB blob (eks.img)
  * EKB = EKB_header + EKB_content

For T264:
* Derive EKB root key(EKB_RK)
  * Deriving EBK_RK from fuse key(OEM_KDK1)
    * STATIC_RT_KDK = HMAC-SHA256-KDF(fuse_key, label, context)
    * STATIC_RT_TZ_KDK = HMAC-SHA256-KDF(STATIC_RT_KDK, label, context)
    * EKB_RK = HMAC-SHA256-KDF(STATIC_RT_TZ_KDK, label, context)
* Generate EKB_EK and EKB_AK that follows NIST-SP-800-108 KDF scheme
  * EKB_EK = HMAC-SHA256-KDF(EKB_RK, label, context)
  * EKB_AK = HMAC-SHA256-KDF(EKB_RK, label, context)
* Acquire EKB content
  * Generate a random initial vector (IV), and also save it to IV field
    of EKB content header
  * Content_ciphertext = AES-128-CBC(EKB_EK, IV, Content_plaintext)
  * EKB_content = EKB_content_header + Content_ciphertext
* Acquire message authentication code (MAC)
  * MAC = AES-CMAC(EKB_AK, EKB_content)
  * Save MAC to MAC field of EKB header
* Filled reserved field in the EKB header with zeros
* Generate EKB blob (eks.img)
  * EKB = EKB_header + EKB_content

----------------------------------------------------------------------
Default EKB Binary
----------------------------------------------------------------------

The default EKB binary is located at:
<Linux_for_Tegra>/bootloader/eks_t234.img
or
<Linux_for_Tegra>/bootloader/eks_t264.img

----------------------------------------------------------------------
How to use the gen_ekb.py
----------------------------------------------------------------------

This program is a sample program that generates the EKB that works with
TEE sample: sample/hwkey-agent

To generate the sample EKB for EKS partition yourself, run "example.sh".

To view usage:
$ python gen_ekb.py --help

The input options:
-chip: specify chip: t234 | t264
-oem_k1_key: 32-byte OEM key 1 file in hex format (t234 only)
-oem_kdk1_key: 32-byte OEM key 1 file in hex format (t264 only)
-in_sym_key: 32-byte UEFI payload encryption key file in hex format
-in_sym_key2: 16-byte disk encryption key file in hex format
-in_auth_key: 16-byte UEFI variable authentication key file in hex format
-in_ftpm_sn: 20 bytes fTPM serial number in hex string
-in_ftpm_eps_seed: fTPM EPS seed file in hex format
-in_ftpm_rsa_ek_cert: fTPM RSA EK cert in DER format
-in_ftpm_ec_ek_cert: fTPM EC EK cert in DER format
-in_sid_cert: the device silicon ID cert in DER format
-in_ftpm_rsa_ek_csr: fTPM RSA EK csr in DER format
-in_ftpm_ec_ek_csr: fTPM EC EK csr in DER format
-out: where the eks image file is stored

Following the command for example.

$ 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_ftpm_sn 00000000000000000000 \
	-in_ftpm_eps_seed ftpm_eps_seed_file \
	-in_ftpm_rsa_ek_cert ftpm_rsa_ek_cert.der \
	-in_ftpm_ec_ek_cert ftpm_ec_ek_cert.der \
	-in_sid_cert sid_cert.der \
	-in_ftpm_rsa_ek_csr ftpm_rsa_ek_csr.der \
	-in_ftpm_ec_ek_csr ftpm_ec_ek_csr.der \
	-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 \
	-out eks_t264.img
