At the high-level, CCM operation is performed in the following sequence:
- Provide CCM context (key, IV including flags, lengths and mode)
- Provide hash only data
- Provide next hash only data
- Provide last hash only data
- Provide first crypto data
- Provide next crypto data
- Read result data and provide next crypto data
- ...
- Read result data and provide last crypto data
- Read result data
- Read result data
- Read authentication result (TAG)
The read/write of data can be managed via DMA or by CPU software.
To implement CCM encryption over N blocks of plaintext and M blocks of AAD, follow these steps:
- Configure Output DMA channel for saving ciphertext:
- Set DMA channel trigger selection to AES Trig1
- Set DMA channel source address to DATA_OUT
- Set DMA channel destination address to location where ciphertext is to be stored (for example, SRAM)
- Set DMA channel transfer size to N×4
- Set DMA channel mode to single transfer mode
- In the AES event registers, unmask Trig1 in the IMASK register of DMA_TRIG_DATAOUT
- Configure Input DMA channel for loading AAD and plaintext:
- Set DMA channel trigger selection to AES Trig0
- Set DMA channel source address to location where plaintext is stored (for example, SRAM)
- Set DMA channel destination address to DATA_IN
- Set DMA channel transfer size to (N+M)*4
- Set DMA channel mode to single transfer mode
- In the AES event registers, unmask Trig0 in the IMASK register of DMA_TRIG0
- Configure and enable the DMA interrupt for the Output DMA channel in the DMA controller
- Configure DMA_HS for DMA based handshake: set DMA_HS[DMA_DATA_ACK] = 1
- Load Encryption/Decryption key as described in Section 24.2.1
- Load Initialization vector (IV) by writing to IV0, IV1, IV2 and IV3 registers (must contain the flags for the cryptographic operation and the NONCE bytes, for both authentication and encryption)
- Configure the CTRL register for block cipher encryption mode for CCM
- Select key size via CTRL[KEY_SIZ]
- Select Direction for Encryption by CTRL[DIR] = 1
- Select CCM mode by setting CTRL[CCM] = 1
- Select CTR mode by setting CTRL[CTR] =
1
-
Enabke saving of TAG by setting CTRL[SAVE_CNTXT] = 1
- Configure CTRL[CCML] -- CCM-L can be set to any value, representing a crypto data length field of CCML plus one Bytes.
- Configure CTRL[CTR_WIDTH] -- Note: CCM-L sets the actual counter field width in the IV register for CCM operations, in the range from 2 (CCM-L = 1) up to and including 8 (CCM-L = 7) Bytes. The actual counter width chosen with the CTR_WIDTH must be long enough to cover this field. The counter field width must be chosen so that the counter cannot overflow.
- Configure CTRL[CCMM] -- CCM-M can be set to any value and has no effect on the actual processing (other than being present in the special ‘B0’ block that is encrypted at the start of the operation). The CPU must select the valid TAG bytes from the 128-bit TAG (which are in the least significant 2 * (CCMM + 1) Bytes).
- Write encryption/decryption byte count N×4 to AES C_LENGTH_0 and C_LENGTH_1 registers
- Write authentication data (AAD) byte count M*4 to AES AAD_LENGTH register
- Wait for the DMA output channel interrupt that indicates completion of the entire operation. The output is stored started at the location configured in step 1c.
- Read out the final TAG from the TAG0/1/2/3 registers
Note: The AAD and cryptographic data can end misaligned. The CPU must pad both to a 128-bit boundary with zeroes. More formally, the AAD and crypto data padding must satisfy the bit string: 0n, with 0<= n <= 127. This means that the AAD must be provided as separate blocks to the engine, such that the cryptographic data starts 128-bit aligned. If the AAD/cryptographic data stream is 128-bit aligned, no padding is required. Because the engine
only supports bytes, n must be such that (n MOD 8) = 0. Further, since a single DMA channel is used to supply both AAD and plaintext, the entire data must be organized contiguously in memory with the first M blocks of AAD followed by N blocks of plaintext. This memory contiguity restriction is not applicable when CPU software directly provides inputs via interrupt handling.
Do not write both length values with zeroes. If a data stream is done and the next data stream uses the same key and control, only the IV and length values need be re-loaded.