Jetson Linux API Reference

32.6.1 Release

 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Hardware-Based AES-CMAC Functions

Detailed Description

Specifies an implementation of the hardware-based AES-CMAC function, very similar to the OpenSSL CMAC implementation, and based on the same concepts.

If you are not familiar with the OpenSSL implementation of CMAC, the reference above will help you understand it. Each AES-CMAC function corresponds to an OpenSSL CMAC function with a similar name and usage. To use AES-CMAC, follow the same sequence of operations as for OpenSSL CMAC, using the AES-CMAC functions instead of the OpenSSL CMAC ones.key definition functions.

OpenSSL CMAC function Corresponding hardware-based
AES-CMAC function
CMAC_CTX_new() tegra_se_cmac_new()
CMAC_Init() tegra_se_cmac_init()
CMAC_Update() tegra_se_cmac_update()
CMAC_Final() tegra_se_cmac_final()
CMAC_CTX_free() tegra_se_cmac_free()
Note
To prevent security issues, the SE keyslots must be cleared after the hardware-based KDF process has finished. Then the untrusted rich OS (Jetson Linux) cannot use these keyslots in the non-secure world.

The hardware-based KDF may only be used at boot time to avoid a runtime conflict with SE hardware usage by the SE driver in the Linux kernel. A run time, use the software-based KDF instead.

Example

The following code shows examples of how the API functions can be used.

se_cmac_ctx *se_cmac = NULL;
uint8_t test_key_256[] = {
.0x72, 0xd1, 0x1f, 0x8b, 0x1c, 0x01, 0xe1, 0x5c,
.0x49, 0x86, 0x07, 0x2a, 0xe5, 0x63, 0x42, 0x21,
.0x65, 0x3f, 0x2e, 0x7f, 0x22, 0xfd, 0x05, 0x4c,
.0x60, 0xc9, 0x76, 0xa6, 0xf4, 0x3a, 0x93, 0xfe,
};
char test_msg[] = "SE_aes_cmac_test_string";
uint8_t openssl_cmac_digest[AES_BLOCK_SIZE] = { 0 };
uint8_t se_cmac_digest[AES_BLOCK_SIZE] = {0};
size_t cmac_len;
// OpenSSL AES-CMAC
CMAC_CTX *cmac = NULL;
cmac = CMAC_CTX_new();
CMAC_Init(cmac, test_key_256, AES_KEY_256_SIZE, EVP_aes_256_cbc(), NULL);
CMAC_Update(cmac, test_msg, sizeof(test_msg));
CMAC_Final(cmac, openssl_cmac_digest, &cmac_len);
CMAC_CTX_free(cmac);
// Write key into keyslot
se_write_keyslot(test_key_256, AES_KEY_256_SIZE, AES_QUAD_KEYS_256,
SE_AES_KEYSLOT_KEK256);
// SE AES-CMAC
se_cmac = tegra_se_cmac_new();
if (se_cmac == NULL)
return;
tegra_se_cmac_init(se_cmac, SE_AES_KEYSLOT_KEK256, AES_KEY_256_SIZE);
tegra_se_cmac_update(se_cmac, test_msg, sizeof(test_msg));
tegra_se_cmac_final(se_cmac, se_cmac_digest, &cmac_len);
// Verify the result
if (memcmp(openssl_cmac_digest, se_cmac_digest, cmac_len))
TLOGE("%s: Tegra SE AES-CMAC verification is not match.\n", __func__);

Typedefs

typedef struct
tegra_se_cmac_context 
se_cmac_ctx
 

Functions

uint32_t se_acquire (void)
 
void se_release (void)
 
uint32_t se_derive_root_key (uint8_t *root_key, size_t root_key_len, uint8_t *fv, size_t fv_len, uint32_t keyslot)
 
int se_write_keyslot (uint8_t *key_in, uint32_t keylen, uint32_t key_quad_sel, uint32_t keyslot)
 
uint32_t se_clear_aes_keyslots (void)
 
se_cmac_ctxtegra_se_cmac_new (void)
 Creates an SE CMAC context. More...
 
void tegra_se_cmac_free (se_cmac_ctx *se_cmac)
 Frees an SE CMAC context. More...
 
int tegra_se_cmac_init (se_cmac_ctx *se_cmac, se_aes_keyslot_t keyslot, uint32_t keylen)
 Initialize the SE CMAC from a user-provided key. More...
 
int tegra_se_cmac_update (se_cmac_ctx *se_cmac, void *data, uint32_t dlen)
 Caches input data in an SE CMAC. More...
 
int tegra_se_cmac_final (se_cmac_ctx *se_cmac, uint8_t *out, uint32_t *poutlen)
 Finalizes a SE CMAC. More...
 

Typedef Documentation

typedef struct tegra_se_cmac_context se_cmac_ctx

Definition at line 199 of file tegra_se.h.

Function Documentation

uint32_t se_acquire ( void  )
uint32_t se_clear_aes_keyslots ( void  )
uint32_t se_derive_root_key ( uint8_t *  root_key,
size_t  root_key_len,
uint8_t *  fv,
size_t  fv_len,
uint32_t  keyslot 
)
void se_release ( void  )
int se_write_keyslot ( uint8_t *  key_in,
uint32_t  keylen,
uint32_t  key_quad_sel,
uint32_t  keyslot 
)
int tegra_se_cmac_final ( se_cmac_ctx se_cmac,
uint8_t *  out,
uint32_t *  poutlen 
)

Finalizes a SE CMAC.

Call this function after the input has been processed and the output has been used.

Parameters
[in]*se_cmacA pointer to the SE CMAC context.
[out]*outA pointer to an output buffer. The function places the derived key here.
[out]*poutlenA pointer to the derived key length. The function places the length of the derived key here.
Returns
NO_ERROR if successful, or ERR_INVALID_ARGS if any of the arguments is invalid.

Referenced by tegra_se_cmac_self_test().

void tegra_se_cmac_free ( se_cmac_ctx se_cmac)

Frees an SE CMAC context.

Parameters
[in]*se_cmacA pointer to the SE CMAC context.

Referenced by tegra_se_cmac_self_test().

int tegra_se_cmac_init ( se_cmac_ctx se_cmac,
se_aes_keyslot_t  keyslot,
uint32_t  keylen 
)

Initialize the SE CMAC from a user-provided key.

Parameters
[in]*se_cmacA pointer to the SE CMAC context.
[in]*keyslotA pointer to an SE keyslot containing the user-provided key.
[in]*keylenLength of the user-provided key.
Return values
NO_ERRORif successful.
ERR_INVALID_ARGSif any of the arguments is invalid.
ERR_NO_MEMORYif no memory is available.

Referenced by tegra_se_cmac_self_test().

se_cmac_ctx* tegra_se_cmac_new ( void  )

Creates an SE CMAC context.

Returns
A pointer to the SE CMAC context if successful, or NULL otherwise.

Referenced by tegra_se_cmac_self_test().

int tegra_se_cmac_update ( se_cmac_ctx se_cmac,
void *  data,
uint32_t  dlen 
)

Caches input data in an SE CMAC.

This function may be called multiple times to cache additional data.

Parameters
[in]*se_cmacA pointer to the SE CMAC context.
[in]*dataA pointer to input data.
[in]dlenLength of the input data.
Return values
NO_ERRORif successful.
ERR_INVALID_ARGSif any of the arguments is invalid.
ERR_NO_MEMORYif no memory is available.

Referenced by tegra_se_cmac_self_test().