CC26xx Driver Library
[aes.h] Advanced Encryption Standard

Functions

void AESStartDMAOperation (const uint8_t *channel0Addr, uint32_t channel0Length, uint8_t *channel1Addr, uint32_t channel1Length)
 Start a crypto DMA operation. More...
 
void AESSetInitializationVector (const uint32_t *initializationVector)
 Write the initialization vector (IV) to the crypto module. More...
 
void AESWriteCCMInitializationVector (const uint8_t *nonce, uint32_t nonceLength)
 Generate and load the initialization vector for a CCM operation. More...
 
uint32_t AESReadTag (uint8_t *tag, uint32_t tagLength)
 Read the tag out from the crypto module. More...
 
uint32_t AESVerifyTag (const uint8_t *tag, uint32_t tagLength)
 Verifies the provided tag against calculated one. More...
 
uint32_t AESWriteToKeyStore (const uint8_t *aesKey, uint32_t aesKeyLength, uint32_t keyStoreArea)
 Transfer a key from main memory to a key area within the key store. More...
 
uint32_t AESReadFromKeyStore (uint32_t keyStoreArea)
 Transfer a key from key store area to the internal buffers within the hardware module. More...
 
uint32_t AESWaitForIRQFlags (uint32_t irqFlags)
 Poll the interrupt status register and clear when done. More...
 
void AESConfigureCCMCtrl (uint32_t nonceLength, uint32_t macLength, bool encrypt)
 Configure AES engine for CCM operation. More...
 
static void AESInvalidateKey (uint32_t keyStoreArea)
 Invalidate a key in the key store. More...
 
static void AESSelectAlgorithm (uint32_t algorithm)
 Select type of operation. More...
 
static void AESSetCtrl (uint32_t ctrlMask)
 Set up the next crypto module operation. More...
 
static void AESSetDataLength (uint32_t length)
 Specify length of the crypto operation. More...
 
static void AESSetAuthLength (uint32_t length)
 Specify the length of the additional authentication data (AAD). More...
 
static void AESIntEnable (uint32_t intFlags)
 Enable individual crypto interrupt sources. More...
 
static void AESIntDisable (uint32_t intFlags)
 Disable individual crypto interrupt sources. More...
 
static uint32_t AESIntStatusMasked (void)
 Get the current masked interrupt status. More...
 
static uint32_t AESIntStatusRaw (void)
 Get the current raw interrupt status. More...
 
static void AESIntClear (uint32_t intFlags)
 Clear crypto interrupt sources. More...
 
static void AESIntRegister (void(*handlerFxn)(void))
 Register an interrupt handler for a crypto interrupt. More...
 
static void AESIntUnregister (void)
 Unregister an interrupt handler for a crypto interrupt. More...
 

Detailed Description

Introduction

The AES (advanced encryption standard) API provides access to the AES and key store functionality of the crypto core. The SHA2 accelerator is also contained within the crypto core. Hence, only one of SHA2 and AES may be used at the same time. This module offers hardware acceleration for several protocols using the AES block cypher. The protocols below are supported by the hardware. The driverlib documentation only explicitly references the most commonly used ones.

The key store is a section of crypto memory that is only accessible to the crypto module and may be written to by the application via the crypto DMA. It is not possible to read from the key store to main memory. Thereby, it is not possible to compromise the key should the application be hacked if the original key in main memory was overwritten already.

The crypto core does not have retention and all configuration settings and keys in the keystore are lost when going into standby or shutdown. The typical security advantages a key store offers are not available in these low power modes as the key must be saved in regular memory to reload it after going into standby or shutdown. Consequently, the keystore primarily serves as an interface to the AES accelerator.

Function Documentation

void AESConfigureCCMCtrl ( uint32_t  nonceLength,
uint32_t  macLength,
bool  encrypt 
)

Configure AES engine for CCM operation.

Parameters
[in]nonceLengthLength of the nonce. Must be <= 14.
[in]macLengthLength of the MAC. Must be <= 16.
[in]encryptWhether to set up an encrypt or decrypt operation.
  • true: encrypt
  • false: decrypt
Returns
None
338 {
339  uint32_t ctrlVal = 0;
340 
341  ctrlVal = ((15 - nonceLength - 1) << CRYPTO_AESCTL_CCM_L_S);
342  if ( macLength >= 2 ) {
343  ctrlVal |= ((( macLength - 2 ) >> 1 ) << CRYPTO_AESCTL_CCM_M_S );
344  }
345  ctrlVal |= CRYPTO_AESCTL_CCM |
349  ctrlVal |= encrypt ? CRYPTO_AESCTL_DIR : 0;
350 
351  AESSetCtrl(ctrlVal);
352 }
static void AESSetCtrl(uint32_t ctrlMask)
Set up the next crypto module operation.
Definition: aes.h:527

Here is the call graph for this function:

static void AESIntClear ( uint32_t  intFlags)
inlinestatic

Clear crypto interrupt sources.

The specified crypto interrupt sources are cleared, so that they no longer assert. This function must be called in the interrupt handler to keep the interrupt from being recognized again immediately upon exit.

Note
Due to write buffers and synchronizers in the system it may take several clock cycles from a register write clearing an event in the module until the event is actually cleared in the NVIC of the system CPU. It is recommended to clear the event source early in the interrupt service routine (ISR) to allow the event clear to propagate to the NVIC before returning from the ISR.
Parameters
[in]intFlagsis a bit mask of the interrupt sources to be cleared.
Returns
None
703 {
704  // Check the arguments.
705  ASSERT((intFlags & AES_DMA_IN_DONE) ||
706  (intFlags & AES_RESULT_RDY));
707 
708  // Clear the requested interrupt sources,
709  HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = intFlags;
710 }
#define ASSERT(expr)
Definition: debug.h:73
#define AES_RESULT_RDY
Definition: aes.h:108
#define AES_DMA_IN_DONE
Definition: aes.h:107
static void AESIntDisable ( uint32_t  intFlags)
inlinestatic

Disable individual crypto interrupt sources.

This function disables the indicated crypto interrupt sources. Only the sources that are enabled can be reflected to the processor interrupt. Disabled sources have no effect on the processor.

Parameters
[in]intFlagsis the bitwise OR of the interrupt sources to be enabled.
Returns
None
630 {
631  // Check the arguments.
632  ASSERT((intFlags & AES_DMA_IN_DONE) ||
633  (intFlags & AES_RESULT_RDY));
634 
635  // Disable the specified interrupts.
636  HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN) &= ~intFlags;
637 }
#define ASSERT(expr)
Definition: debug.h:73
#define AES_RESULT_RDY
Definition: aes.h:108
#define AES_DMA_IN_DONE
Definition: aes.h:107
static void AESIntEnable ( uint32_t  intFlags)
inlinestatic

Enable individual crypto interrupt sources.

This function enables the indicated crypto interrupt sources. Only the sources that are enabled can be reflected to the processor interrupt. Disabled sources have no effect on the processor.

Parameters
[in]intFlagsis the bitwise OR of the interrupt sources to be enabled.
Returns
None
602 {
603  // Check the arguments.
604  ASSERT((intFlags & AES_DMA_IN_DONE) ||
605  (intFlags & AES_RESULT_RDY));
606 
607  // Using level interrupt.
609 
610  // Enable the specified interrupts.
611  HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN) |= intFlags;
612 }
#define ASSERT(expr)
Definition: debug.h:73
#define AES_RESULT_RDY
Definition: aes.h:108
#define AES_DMA_IN_DONE
Definition: aes.h:107
static void AESIntRegister ( void(*)(void)  handlerFxn)
inlinestatic

Register an interrupt handler for a crypto interrupt.

This function does the actual registering of the interrupt handler. This function enables the global interrupt in the interrupt controller; specific crypto interrupts must be enabled via AESIntEnable(). It is the interrupt handler's responsibility to clear the interrupt source.

Parameters
handlerFxnis a pointer to the function to be called when the crypto interrupt occurs.
Returns
None
See also
IntRegister() for important information about registering interrupt handlers.
731 {
732  // Register the interrupt handler.
733  IntRegister(INT_CRYPTO_RESULT_AVAIL_IRQ, handlerFxn);
734 
735  // Enable the crypto interrupt.
736  IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
737 }
void IntRegister(uint32_t ui32Interrupt, void(*pfnHandler)(void))
Registers a function as an interrupt handler in the dynamic vector table.
Definition: interrupt.c:153
void IntEnable(uint32_t ui32Interrupt)
Enables an interrupt or system exception.
Definition: interrupt.c:283

Here is the call graph for this function:

static uint32_t AESIntStatusMasked ( void  )
inlinestatic

Get the current masked interrupt status.

This function returns the masked interrupt status of the crypto module.

Returns
Returns the status of the masked lines when enabled:
651 {
652  uint32_t mask;
653 
654  // Return the masked interrupt status
655  mask = HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN);
656  return(mask & HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT));
657 }
static uint32_t AESIntStatusRaw ( void  )
inlinestatic

Get the current raw interrupt status.

This function returns the raw interrupt status of the crypto module. It returns both the status of the lines routed to the NVIC as well as the error flags.

Returns
Returns the raw interrupt status:
676 {
677  // Return either the raw interrupt status
678  return(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT));
679 }
static void AESIntUnregister ( void  )
inlinestatic

Unregister an interrupt handler for a crypto interrupt.

This function does the actual unregistering of the interrupt handler. It clears the handler called when a crypto interrupt occurs. This function also masks off the interrupt in the interrupt controller so that the interrupt handler no longer is called.

Returns
None
See also
IntRegister() for important information about registering interrupt handlers.
755 {
756  //
757  // Disable the interrupt.
758  //
759  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
760 
761  //
762  // Unregister the interrupt handler.
763  //
764  IntUnregister(INT_CRYPTO_RESULT_AVAIL_IRQ);
765 }
void IntUnregister(uint32_t ui32Interrupt)
Unregisters an interrupt handler in the dynamic vector table.
Definition: interrupt.c:189
void IntDisable(uint32_t ui32Interrupt)
Disables an interrupt or system exception.
Definition: interrupt.c:327

Here is the call graph for this function:

static void AESInvalidateKey ( uint32_t  keyStoreArea)
inlinestatic

Invalidate a key in the key store.

Parameters
[in]keyStoreAreais the entry in the key store to invalidate. This permanently deletes the key from the key store.
Returns
None

Referenced by AESWriteToKeyStore().

477 {
478  ASSERT((keyStoreArea == AES_KEY_AREA_0) ||
479  (keyStoreArea == AES_KEY_AREA_1) ||
480  (keyStoreArea == AES_KEY_AREA_2) ||
481  (keyStoreArea == AES_KEY_AREA_3) ||
482  (keyStoreArea == AES_KEY_AREA_4) ||
483  (keyStoreArea == AES_KEY_AREA_5) ||
484  (keyStoreArea == AES_KEY_AREA_6) ||
485  (keyStoreArea == AES_KEY_AREA_7));
486 
487  // Clear any previously written key at the key location
488  HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITTENAREA) = (0x00000001 << keyStoreArea);
489 }
#define AES_KEY_AREA_7
Definition: aes.h:163
#define AES_KEY_AREA_5
Definition: aes.h:161
#define AES_KEY_AREA_6
Definition: aes.h:162
#define AES_KEY_AREA_4
Definition: aes.h:160
#define AES_KEY_AREA_0
Definition: aes.h:156
#define ASSERT(expr)
Definition: debug.h:73
#define AES_KEY_AREA_1
Definition: aes.h:157
#define AES_KEY_AREA_3
Definition: aes.h:159
#define AES_KEY_AREA_2
Definition: aes.h:158
uint32_t AESReadFromKeyStore ( uint32_t  keyStoreArea)

Transfer a key from key store area to the internal buffers within the hardware module.

The function polls until the transfer is complete.

Parameters
[in]keyStoreAreaThe key store area to transfer the key from. When using 256-bit keys, either of the occupied key areas may be specified to load the key. There is no need to specify the length of the key here as the key store keeps track of how long a key associated with any valid key area is and where is starts.
Returns
Returns a status code depending on the result of the transfer. When specifying a keyStoreArea value without a valid key in it an error is returned. If there was an error in the read process itself, an error is returned. Otherwise, a success code is returned.
See also
AESWriteToKeyStore
235 {
236  // Check the arguments.
237  ASSERT((keyStoreArea == AES_KEY_AREA_0) ||
238  (keyStoreArea == AES_KEY_AREA_1) ||
239  (keyStoreArea == AES_KEY_AREA_2) ||
240  (keyStoreArea == AES_KEY_AREA_3) ||
241  (keyStoreArea == AES_KEY_AREA_4) ||
242  (keyStoreArea == AES_KEY_AREA_5) ||
243  (keyStoreArea == AES_KEY_AREA_6) ||
244  (keyStoreArea == AES_KEY_AREA_7));
245 
246  // Check if there is a valid key in the specified keyStoreArea
247  if (!(HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITTENAREA) & (1 << keyStoreArea))) {
249  }
250 
251  // Enable keys to read (e.g. Key 0).
252  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = keyStoreArea;
253 
254  // Wait until key is loaded to the AES module.
255  // We cannot simply poll the IRQ status as only an error is communicated through
256  // the IRQ status and not the completion of the transfer.
257  do {
258  CPUdelay(1);
259  }
261 
262  // Check for keyStore read error.
264  return AES_KEYSTORE_ERROR;
265  }
266  else {
267  return AES_SUCCESS;
268  }
269 }
#define AES_KEY_AREA_7
Definition: aes.h:163
#define AES_SUCCESS
Definition: aes.h:121
#define AES_KEYSTORE_AREA_INVALID
Definition: aes.h:123
#define AES_KEY_AREA_5
Definition: aes.h:161
#define AES_KEYSTORE_ERROR
Definition: aes.h:122
#define AES_KEY_AREA_6
Definition: aes.h:162
#define AES_KEY_AREA_4
Definition: aes.h:160
#define AES_KEY_AREA_0
Definition: aes.h:156
#define ASSERT(expr)
Definition: debug.h:73
#define AES_KEY_AREA_1
Definition: aes.h:157
#define AES_KEY_AREA_3
Definition: aes.h:159
void CPUdelay(uint32_t ui32Count)
Provide a small delay using a simple loop counter.
Definition: cpu.c:343
#define AES_KEY_AREA_2
Definition: aes.h:158

Here is the call graph for this function:

uint32_t AESReadTag ( uint8_t *  tag,
uint32_t  tagLength 
)

Read the tag out from the crypto module.

This function copies the tagLength bytes from the tag calculated by the crypto module in CCM, GCM, or CBC-MAC mode to tag.

Parameters
[out]tagPointer to an array of tagLength bytes.
[in]tagLengthNumber of bytes to copy to tag.
Returns
Returns a status code depending on the result of the transfer.

Referenced by AESVerifyTag().

277 {
278  // The intermediate array is used instead of a caller-provided one
279  // to enable a simple API with no unintuitive alignment or size requirements.
280  // This is a trade-off of stack-depth vs ease-of-use that came out on the
281  // ease-of-use side.
282  uint32_t computedTag[AES_BLOCK_SIZE / sizeof(uint32_t)];
283 
284  // Wait until the computed tag is ready.
286 
287  // Read computed tag out from the HW registers
288  // Need to read out all 128 bits in four reads to correctly clear CRYPTO_AESCTL_SAVED_CONTEXT_RDY flag
289  computedTag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
290  computedTag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
291  computedTag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
292  computedTag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
293 
294  memcpy(tag, computedTag, tagLength);
295 
296  return AES_SUCCESS;
297 }
#define AES_SUCCESS
Definition: aes.h:121
#define AES_BLOCK_SIZE
Definition: aes.h:136
static void AESSelectAlgorithm ( uint32_t  algorithm)
inlinestatic

Select type of operation.

Parameters
[in]algorithmFlags that specify which type of operation the crypto module shall perform. The flags are mutually exclusive.
Returns
None
506 {
507  ASSERT((algorithm == AES_ALGSEL_AES) ||
508  (algorithm == AES_ALGSEL_AES | AES_ALGSEL_TAG) ||
509  (algorithm == AES_ALGSEL_KEY_STORE));
510 
511  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = algorithm;
512 }
#define AES_ALGSEL_AES
Definition: aes.h:144
#define AES_ALGSEL_KEY_STORE
Definition: aes.h:145
#define ASSERT(expr)
Definition: debug.h:73
#define AES_ALGSEL_TAG
Definition: aes.h:146
static void AESSetAuthLength ( uint32_t  length)
inlinestatic

Specify the length of the additional authentication data (AAD).

Despite specifying it here, the crypto DMA must still be set up with the correct AAD length.

Parameters
[in]lengthSpecifies how long the AAD is in a CCM operation. In CCM mode, set this to 0 if no AAD is required. If set to 0, AESWriteDataLength() must be set to >0. Range depends on the mode:
  • ECB: Do not call.
  • CBC: [0]
  • CBC-MAC: [0]
  • CCM: [0, sizeof(RAM)]
Returns
None
See also
AESWriteDataLength
582 {
583  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = length;
584 }
static void AESSetCtrl ( uint32_t  ctrlMask)
inlinestatic

Set up the next crypto module operation.

The function uses a bitwise OR of the fields within the CRYPTO_O_AESCTL register. The relevant field names have the format:

  • CRYPTO_AESCTL_[field name]
Parameters
[in]ctrlMaskSpecifies which register fields shall be set.
Returns
None

Referenced by AESConfigureCCMCtrl().

528 {
529  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ctrlMask;
530 }
static void AESSetDataLength ( uint32_t  length)
inlinestatic

Specify length of the crypto operation.

Despite specifying it here, the crypto DMA must still be set up with the correct data length.

Parameters
[in]lengthData length in bytes. If this value is set to 0, only authentication of the AAD is performed in CCM-mode and AESWriteAuthLength() must be set to >0. Range depends on the mode:
  • ECB: [16]
  • CBC: [1, sizeof(RAM)]
  • CBC-MAC: [1, sizeof(RAM)]
  • CCM: [0, sizeof(RAM)]
Returns
None
See also
AESWriteAuthLength
555 {
556  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = length;
557  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
558 }
void AESSetInitializationVector ( const uint32_t *  initializationVector)

Write the initialization vector (IV) to the crypto module.

Depending on the mode of operation, the tag must be constructed differently:

  • CBC: No special care must be taken. Any 128-bit IV (initialization vector) will suffice.
  • CBC-MAC: IV's must be all 0's.
  • CCM: Only 12 and 13 byte IV's are permitted. See code below for formatting.
    1 uint8_t initVectorLength = 12; // Could also be 13
    2 
    3 union {
    4  uint32_t word[4];
    5  uint8_t byte[16];
    6 } initVector;
    7 
    8 uint8_t initVectorUnformatted[initVectorLength];
    9 
    10 // This is the same field length value that is written to the ctrl register
    11 initVector.byte[0] = L - 1;
    12 
    13 memcpy(&initVector.byte[1], initVectorUnformatted, initVectorLength);
    14 
    15 // Fill the remaining bytes with zeros
    16 for (initVectorLength++; initVectorLength < sizeof(initVector.byte); initVectorLength++) {
    17  initVector.byte[initVectorLength] = 0;
    18 }
Parameters
[in]initializationVectorPointer to an array with four 32-bit elements to be used as initialization vector. Elements of array must be word aligned in memory.
Returns
None

Referenced by AESWriteCCMInitializationVector().

76 {
77  // Write initialization vector to the aes registers
78  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = initializationVector[0];
79  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = initializationVector[1];
80  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = initializationVector[2];
81  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = initializationVector[3];
82 }
void AESStartDMAOperation ( const uint8_t *  channel0Addr,
uint32_t  channel0Length,
uint8_t *  channel1Addr,
uint32_t  channel1Length 
)

Start a crypto DMA operation.

Enable the crypto DMA channels, configure the channel addresses, and set the length of the data transfer. Setting the length of the data transfer automatically starts the transfer. It is also used by the hardware module as a signal to begin the encryption, decryption, or MAC operation.

Parameters
[in]channel0AddrA pointer to the address channel 0 shall use.
[in]channel0LengthLength of the data in bytes to be read from or written to at channel0Addr. Set to 0 to not set up this channel. Permitted ranges are mode dependent and displayed below.
  • ECB: [16]
  • CBC: [1, sizeof(RAM)]
  • CBC-MAC: [1, sizeof(RAM)]
  • CCM: [1, sizeof(RAM)]
[out]channel1AddrA pointer to the address channel 1 shall use.
[in]channel1LengthLength of the data in bytes to be read from or written to at channel1Addr. Set to 0 to not set up this channel.Permitted ranges are mode dependent and displayed below.
  • ECB: [16]
  • CBC: [1, sizeof(RAM)]
  • CBC-MAC: [1, sizeof(RAM)]
  • CCM: [1, sizeof(RAM)]
Returns
None

Referenced by AESWriteToKeyStore().

90 {
91  if (channel0Length && channel0Addr) {
92  // We actually want to perform an operation. Clear any outstanding events.
93  HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = CRYPTO_IRQCLR_RESULT_AVAIL_M | CRYPTO_IRQEN_DMA_IN_DONE_M; // This might need AES_IRQEN_DMA_IN_DONE as well
94 
96 
97  // Configure the DMA controller - enable both DMA channels.
99 
100  // Base address of the payload data in ext. memory.
101  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)channel0Addr;
102 
103  // Payload data length in bytes, equal to the cipher text length.
104  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = channel0Length;
105  }
106 
107  if (channel1Length && channel1Addr) {
108  // Enable DMA channel 1.
110 
111  // Base address of the output data buffer.
112  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1EXTADDR) = (uint32_t)channel1Addr;
113 
114  // Output data length in bytes, equal to the cipher text length.
115  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = channel1Length;
116  }
117 }
uint32_t AESVerifyTag ( const uint8_t *  tag,
uint32_t  tagLength 
)

Verifies the provided tag against calculated one.

This function compares the provided tag against the tag calculated by the crypto module during the last CCM, GCM, or CBC-MAC

This function copies the tagLength bytes from the tag calculated by the crypto module in CCM, GCM, or CBC-MAC mode to tag.

Parameters
[in]tagPointer to an array of tagLength bytes.
[in]tagLengthNumber of bytes to compare.
Returns
Returns a status code depending on the result of the transfer.
306 {
307  uint32_t resultStatus;
308  // The intermediate array is allocated on the stack to ensure users do not
309  // point the tag they provide and the one computed at the same location.
310  // That would cause memcmp to compare an array against itself. We could add
311  // a check that verifies that the arrays are not the same. If we did that and
312  // modified AESReadTag to just copy all 128 bits into a provided array,
313  // we could save 16 bytes of stack space while making the API much more
314  // complicated.
315  uint8_t computedTag[AES_BLOCK_SIZE];
316 
317  resultStatus = AESReadTag(computedTag, tagLength);
318 
319  if (resultStatus != AES_SUCCESS) {
320  return resultStatus;
321  }
322 
323  resultStatus = memcmp(computedTag, tag, tagLength);
324 
325  if (resultStatus != 0) {
327  }
328 
329  return AES_SUCCESS;
330 }
#define AES_SUCCESS
Definition: aes.h:121
#define AES_TAG_VERIFICATION_FAILED
Definition: aes.h:127
uint32_t AESReadTag(uint8_t *tag, uint32_t tagLength)
Read the tag out from the crypto module.
Definition: aes.c:276
#define AES_BLOCK_SIZE
Definition: aes.h:136

Here is the call graph for this function:

uint32_t AESWaitForIRQFlags ( uint32_t  irqFlags)

Poll the interrupt status register and clear when done.

This function polls until one of the bits in the irqFlags is asserted. Only AES_DMA_IN_DONE and AES_RESULT_RDY can actually trigger the interrupt line. That means that one of those should always be included in irqFlags and will always be returned together with any error codes.

Parameters
[in]irqFlagsIRQ flags to poll and mask that the status register will be masked with. May consist of any bitwise OR of the flags below that includes at least one of AES_DMA_IN_DONE or AES_RESULT_RDY :
Returns
Returns the IRQ status register masked with irqFlags. May be any bitwise OR of the following masks:

Referenced by AESWriteToKeyStore().

125 {
126  uint32_t irqTrigger = 0;
127  // Wait for the DMA operation to complete. Add a delay to make sure we are
128  // not flooding the bus with requests too much.
129  do {
130  CPUdelay(1);
131  }
132  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & irqFlags & (CRYPTO_IRQSTAT_DMA_IN_DONE_M |
136 
137  // Save the IRQ trigger source
138  irqTrigger = HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & irqFlags;
139 
140  // Clear IRQ flags
141  HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = irqTrigger;
142 
143  return irqTrigger;
144 }
void CPUdelay(uint32_t ui32Count)
Provide a small delay using a simple loop counter.
Definition: cpu.c:343

Here is the call graph for this function:

void AESWriteCCMInitializationVector ( const uint8_t *  nonce,
uint32_t  nonceLength 
)

Generate and load the initialization vector for a CCM operation.

Parameters
[in]noncePointer to a nonce of length nonceLength.
[in]nonceLengthNumber of bytes to copy from nonce when creating the CCM IV. The L-value is also derived from it.
Returns
None
360 {
361  union {
362  uint32_t word[4];
363  uint8_t byte[16];
364  } initializationVector = {{0}};
365 
366  initializationVector.byte[0] = 15 - nonceLength - 1;
367 
368  memcpy(&(initializationVector.byte[1]), nonce, nonceLength);
369 
370  AESSetInitializationVector(initializationVector.word);
371 }
void AESSetInitializationVector(const uint32_t *initializationVector)
Write the initialization vector (IV) to the crypto module.
Definition: aes.c:75

Here is the call graph for this function:

uint32_t AESWriteToKeyStore ( const uint8_t *  aesKey,
uint32_t  aesKeyLength,
uint32_t  keyStoreArea 
)

Transfer a key from main memory to a key area within the key store.

The crypto DMA transfers the key and function does not return until the operation completes. The keyStore can only contain valid keys of one aesKeyLength at any one point in time. The keyStore cannot contain both 128-bit and 256-bit keys simultaneously. When a key of a different aesKeyLength from the previous aesKeyLength is loaded, all previous keys are invalidated.

Parameters
[in]aesKeyPointer to key. Does not need to be word-aligned.
[in]aesKeyLengthThe key size in bytes. Currently, 128-bit, 192-bit, and 256-bit keys are supported.
[in]keyStoreAreaThe key store area to transfer the key to. When using 128-bit keys, only the specified key store area will be occupied. When using 256-bit or 192-bit keys, two consecutive key areas are used to store the key.
Returns
Returns a status code depending on the result of the transfer. If there was an error in the read process itself, an error is returned. Otherwise, a success code is returned.
See also
AESReadFromKeyStore
152 {
153  // Check the arguments.
154  ASSERT((keyStoreArea == AES_KEY_AREA_0) ||
155  (keyStoreArea == AES_KEY_AREA_1) ||
156  (keyStoreArea == AES_KEY_AREA_2) ||
157  (keyStoreArea == AES_KEY_AREA_3) ||
158  (keyStoreArea == AES_KEY_AREA_4) ||
159  (keyStoreArea == AES_KEY_AREA_5) ||
160  (keyStoreArea == AES_KEY_AREA_6) ||
161  (keyStoreArea == AES_KEY_AREA_7));
162 
163  ASSERT((aesKeyLength == AES_128_KEY_LENGTH_BYTES) ||
164  (aesKeyLength == AES_192_KEY_LENGTH_BYTES) ||
165  (aesKeyLength == AES_256_KEY_LENGTH_BYTES));
166 
167  uint32_t keySize = 0;
168 
169  switch (aesKeyLength) {
171  keySize = CRYPTO_KEYSIZE_SIZE_128_BIT;
172  break;
174  keySize = CRYPTO_KEYSIZE_SIZE_192_BIT;
175  break;
177  keySize = CRYPTO_KEYSIZE_SIZE_256_BIT;
178  break;
179  }
180 
181  // Clear any previously written key at the keyLocation
182  AESInvalidateKey(keyStoreArea);
183 
184  // Disable the external interrupt to stop the interrupt form propagating
185  // from the module to the System CPU.
186  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
187 
188  // Enable internal interrupts.
191 
192  // Configure master control module.
194 
195  // Clear any outstanding events.
197 
198  // Configure the size of keys contained within the key store
199  // Do not write to the register if the correct key size is already set.
200  // Writing to this register causes all current keys to be invalidated.
201  uint32_t keyStoreKeySize = HWREG(CRYPTO_BASE + CRYPTO_O_KEYSIZE);
202  if (keySize != keyStoreKeySize) {
203  HWREG(CRYPTO_BASE + CRYPTO_O_KEYSIZE) = keySize;
204  }
205 
206  // Enable key to write (e.g. Key 0).
207  HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITEAREA) = 1 << keyStoreArea;
208 
209  // Total key length in bytes (16 for 1 x 128-bit key and 32 for 1 x 256-bit key).
210  AESStartDMAOperation(aesKey, aesKeyLength, 0, 0);
211 
212  // Wait for the DMA operation to complete.
214 
215  // Re-enable interrupts globally.
216  IntPendClear(INT_CRYPTO_RESULT_AVAIL_IRQ);
217  IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
218 
219  // If we had a bus error or the key is not in the CRYPTO_O_KEYWRITTENAREA, return an error.
220  if ((irqTrigger & (CRYPTO_IRQSTAT_DMA_BUS_ERR_M | CRYPTO_IRQSTAT_KEY_ST_WR_ERR_M)) || !(HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITTENAREA) & (1 << keyStoreArea))) {
221  // There was an error in writing to the keyStore.
222  return AES_KEYSTORE_ERROR;
223  }
224  else {
225  return AES_SUCCESS;
226  }
227 }
uint32_t AESWaitForIRQFlags(uint32_t irqFlags)
Poll the interrupt status register and clear when done.
Definition: aes.c:124
void IntPendClear(uint32_t ui32Interrupt)
Unpends an interrupt.
Definition: interrupt.c:443
#define AES_KEY_AREA_7
Definition: aes.h:163
#define AES_SUCCESS
Definition: aes.h:121
#define AES_KEY_AREA_5
Definition: aes.h:161
#define AES_KEYSTORE_ERROR
Definition: aes.h:122
#define AES_KEY_AREA_6
Definition: aes.h:162
#define AES_KEY_AREA_4
Definition: aes.h:160
#define AES_KEY_AREA_0
Definition: aes.h:156
#define ASSERT(expr)
Definition: debug.h:73
static void AESInvalidateKey(uint32_t keyStoreArea)
Invalidate a key in the key store.
Definition: aes.h:476
#define AES_KEY_AREA_1
Definition: aes.h:157
#define AES_128_KEY_LENGTH_BYTES
Definition: aes.h:132
#define AES_KEY_AREA_3
Definition: aes.h:159
#define AES_192_KEY_LENGTH_BYTES
Definition: aes.h:133
void AESStartDMAOperation(const uint8_t *channel0Addr, uint32_t channel0Length, uint8_t *channel1Addr, uint32_t channel1Length)
Start a crypto DMA operation.
Definition: aes.c:89
#define AES_256_KEY_LENGTH_BYTES
Definition: aes.h:134
#define AES_KEY_AREA_2
Definition: aes.h:158
void IntDisable(uint32_t ui32Interrupt)
Disables an interrupt or system exception.
Definition: interrupt.c:327
void IntEnable(uint32_t ui32Interrupt)
Enables an interrupt or system exception.
Definition: interrupt.c:283

Here is the call graph for this function:

Macro Definition Documentation

#define AES_128_KEY_LENGTH_BYTES   (128 / 8)

Referenced by AESWriteToKeyStore().

#define AES_192_KEY_LENGTH_BYTES   (192 / 8)

Referenced by AESWriteToKeyStore().

#define AES_256_KEY_LENGTH_BYTES   (256 / 8)

Referenced by AESWriteToKeyStore().

#define AES_ALGSEL_AES   CRYPTO_ALGSEL_AES_M

Referenced by AESSelectAlgorithm().

#define AES_ALGSEL_KEY_STORE   CRYPTO_ALGSEL_KEY_STORE_M

Referenced by AESSelectAlgorithm().

#define AES_ALGSEL_TAG   CRYPTO_ALGSEL_TAG_M

Referenced by AESSelectAlgorithm().

#define AES_BLOCK_SIZE   16

Referenced by AESReadTag(), and AESVerifyTag().

#define AES_CTR_WIDTH_128   0x3
#define AES_CTR_WIDTH_32   0x0
#define AES_CTR_WIDTH_64   0x1
#define AES_CTR_WIDTH_96   0x2
#define AES_DMA_BUS_ERR   CRYPTO_IRQCLR_DMA_BUS_ERR_M
#define AES_DMA_BUSY   3
#define AES_DMA_CHANNEL0_ACTIVE   CRYPTO_DMASTAT_CH0_ACT_M
#define AES_DMA_CHANNEL1_ACTIVE   CRYPTO_DMASTAT_CH1_ACT_M
#define AES_DMA_ERROR   4
#define AES_DMA_IN_DONE   CRYPTO_IRQEN_DMA_IN_DONE_M
#define AES_DMA_PORT_ERROR   CRYPTO_DMASTAT_PORT_ERR_M
#define AES_IV_LENGTH_BYTES   16
#define AES_KEY_AREA_0   0
#define AES_KEY_AREA_1   1
#define AES_KEY_AREA_2   2
#define AES_KEY_AREA_3   3
#define AES_KEY_AREA_4   4
#define AES_KEY_AREA_5   5
#define AES_KEY_AREA_6   6
#define AES_KEY_AREA_7   7
#define AES_KEY_ST_RD_ERR   CRYPTO_IRQCLR_KEY_ST_RD_ERR_M
#define AES_KEY_ST_WR_ERR   CRYPTO_IRQCLR_KEY_ST_WR_ERR_M
#define AES_KEYSTORE_AREA_INVALID   2

Referenced by AESReadFromKeyStore().

#define AES_KEYSTORE_ERROR   1
#define AES_RESULT_RDY   CRYPTO_IRQEN_RESULT_AVAIL_M
#define AES_TAG_LENGTH_BYTES   16
#define AES_TAG_NOT_READY   5
#define AES_TAG_VERIFICATION_FAILED   6

Referenced by AESVerifyTag().