MCUXpresso SDK API Reference Manual  Rev. 0
NXP Semiconductors
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
CAAM: Cryptographic Acceleration and Assurance Module

Overview

The MCUXpresso SDK provides the Peripheral driver for the Cryptographic Acceleration and Assurance Module (CAAM) module. CAAM is an multi-function accelerator that supports the cryptographic functions common in many security protocols. This includes AES128, AES256, DES, 3DES, SHA1, SHA224, SHA256, RSA-4096 and a random number generator with a true entropic seed. CAAM includes a DMA engine that is descriptor based to reduce processor-accelerator interaction.

The driver comprises two sets of API functions.

In the first set, blocking APIs are provided, for selected subset of operations supported by CAAM hardware. The CAAM operations are complete (and results are made availabe for further usage) when a function returns. When called, these functions don't return until a CAAM operation is complete. These functions use main CPU for simple polling loops to determine operation complete or error status.

The CAAM job descriptor is placed on the system stack during the blocking API calls. The driver uses global variable to manage the input and output job rings. The driver uses critical section (implemented as global interrupt enable/disable) for a short time, whenever it needs to access these global variables. Therefore, the driver functions are designed to be re-entrant and as a consequence, one CPU thread can call one blocking API, such as AES Encrypt, while other CPU thread can call another blocking API, such as SHA-256 Update. The blocking functions provide typical interface to upper layer or application software.

In the second set, non-blocking variants of the first set APIs are provided. Internally, the blocking APIs are implemented as a non-blocking operation start, followed by a blocking wait (CPU polling CAAM output job ring). for an operation completion. The non-blocking functions allow upper layer to inject an application specific operation after the CAAM job start and CAAM job complete events. RTOS event wait and RTOS event set can be an example of such an operation.

CAAM Driver Initialization and Configuration

The CAAM Job Ring interface is a software job programming interface. CAAM implements 2 Job Ring interfaces. The CAAM driver uses caam_job_ring_interface_t data type as the Job Ring interface. Job Ring interface 0 is mandatory to be configured for the CAAM driver, Job Ring interface 1 is optional.

Initialize CAAM after Power On Reset or reset cycle

static caam_job_ring_interface_t s_jr0; /* Job Ring interface 0 */
static caam_job_ring_interface_t s_jr1; /* Job Ring interface 1 */
caam_config_t caamConfig;
CAAM_GetDefaultConfig(&caamConfig);
/* setup memory for job ring interface. Can be in system memory or CAAM's secure memory. */
caamConfig.jobRingInterface[0] = &s_jr0;
caamConfig.jobRingInterface[1] = &s_jr1;
CAAM_Init(base, &caamConfig);

CAAM Driver is initialized by calling the CAAM_Init() function. It enables the CAAM module clock, it configures the Job Ring interface(s) and it instantiates the CAAM RNG module in normal (non-deterministic) mode. Then, it calls CAAM_RNG_GenerateSecureKey() to load the JDKEK, TDKEK and TDSK registers and finally it configures the CAAM SCFGR register.

Comments about API usage in RTOS

CAAM operations provided by this driver are re-entrant by protecting global variables (Job Ring interface) in critical section (global interrupt enable/disable by EnableGlobalIRQ() and DisableGlobalIRQ() MCUXpresso SDK APIs). Different RTOS threads can call CAAM driver APIs simultaneously, if they need to, given that EnableGlobalIRQ() and DisableGlobalIRQ() can create critical section.

Comments about API usage in interrupt handler

All APIs can be used from interrupt handler although execution time shall be considered (interrupt latency of equal and lower priority interrupts increases).

CAAM Driver Examples

Simple examples

Encrypt plaintext by DES engine

status_t status;
caam_handle_t caamHandle;
char plain[16];
char cipher[16];
char key1[CAAM_DES_KEY_SIZE];
char key2[CAAM_DES_KEY_SIZE];
char key3[CAAM_DES_KEY_SIZE];
memcpy(plain, "Hello World!", 12);
memcpy(iv, "initvect", CAAM_DES_IV_SIZE);
memcpy(key1, "mykey1aa", CAAM_DES_KEY_SIZE);
memcpy(key2, "mykey2bb", CAAM_DES_KEY_SIZE);
memcpy(key3, "mykey3cc", CAAM_DES_KEY_SIZE);
caamHandle.jobRing = kCAAM_JobRing0;
status = CAAM_DES3_EncryptCbc(CAAM, &caamHandle, plain, cipher, 16, iv, key1, key2, key3);

Encrypt plaintext by AES engine

status_t status;
caam_handle_t caamHandle;
char plain[16] = {0};
char cipher[16];
char iv[16] = {0};
char key[16] = {0};
memcpy(plain, "Hello World!", 12);
memcpy(iv, "initvectorinitve", 16);
memcpy(key, "__mykey1aa__^^..", 16);
caamHandle.jobRing = kCAAM_JobRing0;
status = CAAM_AES_EncryptCbc(CAAM, &caamHandle, plain, cipher, 16, iv, key, 16);

Compute keyed hash by AES engine (CMAC)

status_t status;
caam_handle_t caamHandle;
char message[] = "Hello World!";
char key[16] = {0};
char output[16];
size_t szOutput = 16u;
memcpy(key, "__mykey1aa__^^..", 16);
caamHandle.jobRing = kCAAM_JobRing0;
status = CAAM_HASH(CAAM, &caamHandle, kCAAM_Cmac, message, sizeof(message), key, 16, output, &szOutput);

Compute hash by MDHA engine (SHA-256)

status_t status;
caam_handle_t caamHandle;
char message[] = "Hello World!";
char output[32];
size_t szOutput = 32u;
caamHandle.jobRing = kCAAM_JobRing0;
status = CAAM_HASH(CAAM, &caamHandle, kCAAM_Sha256, message, sizeof(message), NULL, 0, output, &szOutput);

Compute modular integer exponentiation

status_t status;
caam_handle_t caamHandle;
const char bigA[] = "112233445566778899aabbccddeeff";
const char bigN[] = "aabbaabbaabb112233445566778899aabbccddeefe";
const char bigE[] = "065537";
char A[256], E[256], N[256], res[256];
size_t sizeA, sizeE, sizeN, sizeRes;
/* Note CAAM PKHA integer format is most significant byte at lowest address (big endian).
* The _read_string() function converts the input string to CAAM PKHA integer format
* and writes sizeof() the integer to the size variable (sizeA, sizeE, sizeN).
*/
_read_string(A, &sizeA, bigA);
_read_string(E, &sizeE, bigN);
_read_string(N, &sizeN, bigE);
caamHandle.jobRing = kCAAM_JobRing0;
status = CAAM_PKHA_ModExp(CAAM, &caamHandle, A, sizeA, N, sizeN, E, sizeE, res, &sizeRes, kCAAM_PKHA_IntegerArith,

Compute elliptic curve point addition

crypto_pkha_ecc_point_t A0, B0, res0;
status_t status;
caam_handle_t caamHandle;
/* Test on P-256 curve */
uint8_t Gx[32] = {0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2,
0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96};
uint8_t Gy[32] = {0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16,
0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5};
uint8_t Qx[32] = {0xe7, 0x73, 0xae, 0x41, 0x95, 0xa8, 0xe6, 0x7b, 0xa1, 0xf3, 0x82, 0xdf, 0xfa, 0x6f, 0x4a, 0x3f,
0x94, 0x45, 0x88, 0x84, 0x9f, 0x62, 0xde, 0x91, 0x69, 0x93, 0xb3, 0xd6, 0xcc, 0xac, 0x68, 0x35};
uint8_t Qy[32] = {0x61, 0x9a, 0x6d, 0x18, 0xb2, 0x49, 0xb2, 0x13, 0xc6, 0xf1, 0x58, 0x58, 0xe0, 0xd3, 0x88, 0xb5,
0x64, 0x43, 0x3a, 0x54, 0xe6, 0x68, 0x12, 0x42, 0xbd, 0xf7, 0x7a, 0x79, 0x36, 0x03, 0x93, 0x63};
uint8_t GplusQ_x[32] = {0};
uint8_t GplusQ_y[32] = {0};
uint8_t secp256r1_a[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC};
uint8_t secp256r1_b[] = {0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD,
0x55, 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53,
0xB0, 0xF6, 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B};
uint8_t secp256r1_p[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
A0.X = Gx;
A0.Y = Gy;
B0.X = Qx;
B0.Y = Qy;
res0.X = GplusQ_x;
res0.Y = GplusQ_y;
caamHandle.jobRing = kCAAM_JobRing0;
status = CAAM_PKHA_ECC_PointAdd(CAAM, &caamHandle, &A0, &B0, secp256r1_p, NULL, secp256r1_a, secp256r1_b, 32,
kCRYPTO_PKHA_IntegerArith, &res0);

Modules

 CAAM Blocking APIs
 
 CAAM Non-blocking APIs
 

Data Structures

struct  caam_job_callback_t
 CAAM callback function. More...
 
struct  caam_handle_t
 CAAM handle Specifies jobRing and optionally the user callback function. More...
 
struct  caam_config_t
 CAAM configuration structure. More...
 

Typedefs

typedef uint32_t caam_desc_aes_ecb_t [64]
 Memory buffer to hold CAAM descriptor for AESA ECB job.
 
typedef uint32_t caam_desc_aes_cbc_t [64]
 Memory buffer to hold CAAM descriptor for AESA CBC job.
 
typedef uint32_t caam_desc_aes_ctr_t [64]
 Memory buffer to hold CAAM descriptor for AESA CTR job.
 
typedef uint32_t caam_desc_aes_ccm_t [64]
 Memory buffer to hold CAAM descriptor for AESA CCM job.
 
typedef uint32_t caam_desc_aes_gcm_t [64]
 Memory buffer to hold CAAM descriptor for AESA GCM job.
 
typedef uint32_t caam_desc_hash_t [64]
 Memory buffer to hold CAAM descriptor for MDHA job or AESA CMAC job.
 
typedef uint32_t caam_desc_rng_t [64]
 Memory buffer to hold CAAM descriptor for RNG jobs.
 
typedef uint32_t caam_desc_cipher_des_t [64]
 Memory buffer to hold CAAM descriptor for DESA jobs.
 
typedef uint32_t caam_desc_pkha_t [64]
 Memory buffer to hold CAAM descriptor for PKHA jobs.
 
typedef uint32_t caam_desc_pkha_ecc_t [64]
 Memory buffer to hold CAAM descriptor for PKHA ECC jobs.
 

Enumerations

enum  caam_job_ring_t {
  kCAAM_JobRing0 = 0u,
  kCAAM_JobRing1 = 1u
}
 CAAM job ring selection. More...
 
enum  caam_wait_mode_t {
  kCAAM_Blocking = 0u,
  kCAAM_Nonblocking = 1u
}
 CAAM driver wait mechanism. More...
 
enum  caam_rng_sample_mode_t {
  kCAAM_RNG_SampleModeVonNeumann = 0U,
  kCAAM_RNG_SampleModeRaw = 1U,
  kCAAM_RNG_SampleModeVonNeumannRaw
}
 CAAM RNG sample mode. More...
 
enum  caam_rng_ring_osc_div_t {
  kCAAM_RNG_RingOscDiv0 = 0U,
  kCAAM_RNG_RingOscDiv2 = 1U,
  kCAAM_RNG_RingOscDiv4 = 2U,
  kCAAM_RNG_RingOscDiv8 = 3U
}
 CAAM RNG ring oscillator divide. More...
 
enum  caam_priblob_t {
  kCAAM_PrivSecureBootBlobs = 0U,
  kCAAM_PrivProvisioningBlobsType1 = 1U,
  kCAAM_PrivProvisioningBlobsType2 = 2U,
  kCAAM_NormalOperationBlobs = 3U
}
 CAAM Private Blob. More...
 
enum  caam_ext_key_xfr_source_t {
  kCAAM_ExtKeyXfr_KeyRegisterClass1 = 1U,
  kCAAM_ExtKeyXfr_KeyRegisterClass2 = 2U,
  kCAAM_ExtKeyXfr_PkhaRamE = 3U
}
 CAAM External Key Transfer command SRC (The source from which the key will be obtained) More...
 

Functions

void CAAM_Init (CAAM_Type *base, const caam_config_t *config)
 Initializes the CAAM driver. More...
 
void CAAM_Deinit (CAAM_Type *base)
 Deinitializes the CAAM driver. More...
 
void CAAM_GetDefaultConfig (caam_config_t *config)
 Gets the default configuration structure. More...
 
status_t CAAM_Wait (CAAM_Type *base, caam_handle_t *handle, void *descriptor, caam_wait_mode_t mode)
 Wait for a CAAM job to complete. More...
 
status_t CAAM_ExternalKeyTransfer (CAAM_Type *base, caam_handle_t *handle, caam_ext_key_xfr_source_t keySource, size_t keySize)
 External Key Transfer. More...
 

Driver version

#define FSL_CAAM_DRIVER_VERSION   (MAKE_VERSION(2, 0, 1))
 CAAM driver version. More...
 

Data Structure Documentation

struct caam_job_callback_t

Data Fields

void(* JobCompleted )(void *userData)
 CAAM Job complete callback.
 
struct caam_handle_t

The user callback functions is invoked only if jobRing interrupt has been enabled by the user. By default the jobRing interrupt is disabled (default job complete test is polling CAAM output ring).

Data Fields

caam_job_callback_t callback
 Callback function.
 
void * userData
 Parameter for CAAM job complete callback.
 
struct caam_config_t

Data Fields

caam_rng_sample_mode_t rngSampleMode
 RTMCTL Sample Mode. More...
 
caam_rng_ring_osc_div_t rngRingOscDiv
 RTMCTL Oscillator Divide. More...
 
bool scfgrLockTrngProgramMode
 SCFGR Lock TRNG Program Mode. More...
 
bool scfgrRandomRngStateHandle0
 SCFGR Random Number Generator State Handle 0. More...
 
bool scfgrRandomDpaResistance
 SCFGR Random Differential Power Analysis Resistance. More...
 
caam_priblob_t scfgrPriblob
 SCFGR Private Blob. More...
 

Field Documentation

caam_rng_sample_mode_t caam_config_t::rngSampleMode
caam_rng_ring_osc_div_t caam_config_t::rngRingOscDiv
bool caam_config_t::scfgrLockTrngProgramMode
bool caam_config_t::scfgrRandomRngStateHandle0
bool caam_config_t::scfgrRandomDpaResistance
caam_priblob_t caam_config_t::scfgrPriblob

Macro Definition Documentation

#define FSL_CAAM_DRIVER_VERSION   (MAKE_VERSION(2, 0, 1))

Version 2.0.1.

Current version: 2.0.1

Change log:

  • Version 2.0.0
    • Initial version
  • Version 2.0.1
    • Removed CAAM_SCFGR_RDB

Enumeration Type Documentation

Enumerator
kCAAM_JobRing0 

CAAM Job ring 0.

kCAAM_JobRing1 

CAAM Job ring 1.

Enumerator
kCAAM_Blocking 

CAAM_Wait blocking mode.

kCAAM_Nonblocking 

CAAM Wait non-blocking mode.

Used by caam_config_t.

Enumerator
kCAAM_RNG_SampleModeVonNeumann 

Use von Neumann data in both Entropy shifter and Statistical Checker.

kCAAM_RNG_SampleModeRaw 

Use raw data into both Entropy shifter and Statistical Checker.

kCAAM_RNG_SampleModeVonNeumannRaw 

Use von Neumann data in Entropy shifter.

Use raw data into Statistical Checker.

Used by caam_config_t.

Enumerator
kCAAM_RNG_RingOscDiv0 

Ring oscillator with no divide.

kCAAM_RNG_RingOscDiv2 

Ring oscillator divided-by-2.

kCAAM_RNG_RingOscDiv4 

Ring oscillator divided-by-4.

kCAAM_RNG_RingOscDiv8 

Ring oscillator divided-by-8.

Used by caam_config_t.

Enumerator
kCAAM_PrivSecureBootBlobs 

Private secure boot software blobs.

kCAAM_PrivProvisioningBlobsType1 

Private Provisioning Type 1 blobs.

kCAAM_PrivProvisioningBlobsType2 

Private Provisioning Type 2 blobs.

kCAAM_NormalOperationBlobs 

Normal operation blobs.

Enumerator
kCAAM_ExtKeyXfr_KeyRegisterClass1 

The Class 1 Key Register is the source.

kCAAM_ExtKeyXfr_KeyRegisterClass2 

The Class 2 Key Register is the source.

kCAAM_ExtKeyXfr_PkhaRamE 

The PKHA E RAM is the source.

Function Documentation

void CAAM_Init ( CAAM_Type *  base,
const caam_config_t config 
)

This function initializes the CAAM driver, including CAAM's internal RNG.

Parameters
baseCAAM peripheral base address
configPointer to configuration structure.
void CAAM_Deinit ( CAAM_Type *  base)

This function deinitializes the CAAM driver.

Parameters
baseCAAM peripheral base address
void CAAM_GetDefaultConfig ( caam_config_t config)

This function initializes the CAAM configuration structure to a default value. The default values are as follows. caamConfig->rngSampleMode = kCAAM_RNG_SampleModeVonNeumann; caamConfig->rngRingOscDiv = kCAAM_RNG_RingOscDiv4;

Parameters
[out]configPointer to configuration structure.
status_t CAAM_Wait ( CAAM_Type *  base,
caam_handle_t handle,
void *  descriptor,
caam_wait_mode_t  mode 
)

This function polls CAAM output ring for a specific job.

The CAAM job ring is specified by the jobRing field in the caam_handle_t structure. The job to be waited is specified by it's descriptor address.

This function has two modes, determined by the mode argument. In blocking mode, the function polls the specified jobRing until the descriptor is available in the CAAM output job ring. In non-blocking mode, it polls the output ring once and returns status immediately.

The function can be called from multiple threads or interrupt service routines, as internally it uses global critical section (global interrupt disable enable) to protect it's operation against concurrent accesses. The global interrupt is disabled only when the descriptor is found in the output ring, for a very short time, to remove the descriptor from the output ring safely.

Parameters
baseCAAM peripheral base address
handleData structure with CAAM jobRing used for this request
descriptor
modeBlocking and non-blocking mode. Zero is blocking. Non-zero is non-blocking.
Returns
kStatus_Success the CAAM job has completed with zero job termination status word
kStatus_Fail the CAAM job has completed with non-zero job termination status word
kStatus_Again In non-blocking mode, the job is not ready in the CAAM Output Ring
status_t CAAM_ExternalKeyTransfer ( CAAM_Type *  base,
caam_handle_t handle,
caam_ext_key_xfr_source_t  keySource,
size_t  keySize 
)

This function loads the given key source to an CAAM external destination via a private interface, such as Inline Encryption Engine IEE Private Key bus.

The CAAM job ring is specified by the jobRing field in the caam_handle_t structure.

This function is blocking.

Parameters
baseCAAM peripheral base address
handleData structure with CAAM jobRing used for this request.
keySourceThe source from which the key will be obtained.
keySizeSize of the key in bytes.
Returns
kStatus_Success the CAAM job has completed with zero job termination status word
kStatus_Fail the CAAM job has completed with non-zero job termination status word