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.