EKB Key Retrieval in OP-TEE TA on Jetson Xavier

HI,
I am attempting to retrieve information related to the EKB key within an OP-TEE Trusted Application (TA) on a Jetson Xavier. I am using the JETSON_USER_KEY_CMD_GET_EKB_KEY command, but I am encountering unexpected results.

My goal is to perform encryption and decryption with different keys (derived from KEK2). However, during my tests, all devices return “00000000000000000000000000000000” when attempting to retrieve the EKB key using JETSON_USER_KEY_CMD_GET_EKB_KEY.

This raises the following questions:

  • EKB Key Retrieval: Is this the correct approach for retrieving key material related to the EKB key within a custom OP-TEE TA on the Jetson Xavier? Are there specific NVIDIA-provided APIs or best practices that should be followed?
  • Zero-Value Output: Does the all-zero output indicate that the actual EKB-related key is indeed all zeros, or does it suggest that the key value is protected by hardware or software mechanisms, preventing direct access in this manner?
  • Alternative Methods: If direct retrieval of the EKB key (or a close derivative) is not the intended use case, what are the recommended alternative methods for securely obtaining a key suitable for encryption/decryption operations within a TA, while still leveraging the security provided by the AGX Xavier’s hardware security features

Specifically, I have added the following code to my custom TA (based on sample application)

static TEE_Result get_ekb_op(srv_sess_t *sess,
                    uint32_t param_types,
                    TEE_Param params[TEE_NUM_PARAMS])
 {
     TEE_Result rc = TEE_SUCCESS;
     uint32_t disk_key_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
                         TEE_PARAM_TYPE_MEMREF_OUTPUT,
                         TEE_PARAM_TYPE_NONE,
                         TEE_PARAM_TYPE_NONE);
     TEE_Param params_for_disk_key[TEE_NUM_PARAMS] = { };
     uint8_t disk_key[AES128_KEY_BYTE_SIZE] = { 0 };

     /* Get disk key from EKB. */
     params_for_disk_key[0].value.a = EKB_USER_KEY_DISK_ENCRYPTION; // Assuming this is the correct value
     params_for_disk_key[1].memref.buffer = disk_key;
     params_for_disk_key[1].memref.size = AES128_KEY_BYTE_SIZE;
     rc = invoke_jetson_user_key_pta(JETSON_USER_KEY_CMD_GET_EKB_KEY,
                     disk_key_pt, params_for_disk_key);
     if (rc)
         return rc;

     params[0].memref.buffer = disk_key;
     params[0].memref.size = params_for_disk_key[1].memref.size;

     return rc;
 }

And I am calling this TA function from my Client Application (CA) with the following code:

   TEEC_Operation op;
    TEEC_Result rc;
    uint32_t origin;
    uint8_t *buff = calloc(1, AES_BLOCK_SIZE);

    memset(&op, 0, sizeof(op));
    op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT,
                     TEEC_NONE,
                     TEEC_NONE,
                     TEEC_NONE);
    op.params[0].tmpref.buffer = buff;
    op.params[0].tmpref.size = AES_BLOCK_SIZE;

    printf("TEEC_InvokeCommand TA_CMD_GET_EKB_KEY\n");
    /* Send command to TA. */
    rc = TEEC_InvokeCommand(&ctx->sess, TA_CMD_GET_EKB_KEY,
        &op, &origin);

When I execute this, the disk_key buffer in my CA contains all zeros: “00000000000000000000000000000000”.

Any insights or recommended procedures would be greatly appreciated. Thanks in advance.

hello kyoungh,

may I know what’s the actual use-case to retrieval EKB key?
you may see-also Topic 288196 for reference.

Hello JerryChang,

I’m working on developing a Client Application (CA) and Trusted Application (TA) using OP-TEE on the AGX Xavier (JetPack 5.1.x) to encrypt and decrypt files. My goal is to ensure that encryption and decryption are only possible between AGX Xavier devices that have been fused with the same KEK2 key.

To achieve this, I’ve decided against using JETSON_USER_KEY_CMD_GEN_UNIQUE_KEY_BY_EKB (as seen in nvhwkey-app), as it generates a unique key per device. Instead, I’m exploring the approach used in nvluks-srv-app, which involves using JETSON_USER_KEY_CMD_GET_EKB_KEY to retrieve a key derived from KEK2 and then using JETSON_USER_KEY_CMD_GEN_KEY to potentially generate a symmetric key for file encryption/decryption.

However, I’ve encountered an issue during testing. Even when using two AGX Xavier devices that I believe have been fused and flashed with different KEK2 keys, I am observing the same encryption results. This leads me to suspect that the key I’m obtaining or generating is not unique to the KEK2 fuse as expected.

This brings me to a few questions:

  1. Is my understanding of how JETSON_USER_KEY_CMD_GET_EKB_KEY and JETSON_USER_KEY_CMD_GEN_KEY should behave in relation to the KEK2 fuse correct?
  2. What could be the reason that I am getting the same encryption results across devices with different KEK2 fuses? Could the KEK2 fuses not be programmed correctly, or is there something I’m misunderstanding in the key derivation process?

Any insights or guidance on how to properly implement this device-specific encryption/decryption functionality based on the KEK2 fuse would be greatly appreciated.

Thank you for your time and assistance.

is looks duplicated, let’s using single discussion thread for your inquiries.