HAL AES How to Use ¶
- group AES_How_To_Use
-
How to use the AES HAL module driver ¶
The AES main features: ¶
This AES HAL driver is a generic driver that provides a set of APIs to configure the AES/SAES peripheral to an Advanced Encryption Standard compliant algorithm to perform data encryption or decryption.
The AES HAL driver can be used as follows: ¶
Initialization/De-initialization ¶
Declare a hal_aes_handle_t handle structure, for example: hal_aes_handle_t haes
Initialize the AES low-level resources:
Enable the AES/SAES peripheral clock:
Either at the application level by calling:
HAL_RCC_AES_EnableClock() API for AES instance
HAL_RCC_SAES_EnableClock() API for SAES instance
Or set the USE_HAL_AES_CLK_ENABLE_MODEL define to HAL_CLK_ENABLE_PERIPH_ONLY within the stm32c5xx_hal_conf.h file. In this case, the AES/SAES clock is enabled within the HAL_AES_Init() API.
NVIC configuration to use interrupt process APIs (HAL_AES_Encrypt_IT() and HAL_AES_Decrypt_IT()):
Configure the AES interrupt priority
Enable the NVIC AES IRQ Channel
DMA configuration to use DMA process APIs (HAL_AES_Encrypt_DMA() and HAL_AES_Decrypt_DMA()):
Declare a hal_dma_handle_t handle structure for the transfer input or transfer output channel
Enable the DMAx interface clock
Configure the DMA handle parameters
Configure the DMA Inx or Outx channel
Associate the initialized DMA handle with the haes DMA In or Out handle
Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA In or Out channel
Initialize the AES handle by calling the HAL_AES_Init() API, which performs these operations:
Associate the instance with the handle
Initialize the handle state to HAL_AES_STATE_INIT
De-initialize the AES handle by calling the HAL_AES_DeInit() API, which performs these operations:
Disable the AES/SAES peripheral
Abort the DMA input and output transfers
De-initialize the current handle object
Reset the handle state to HAL_AES_STATE_RESET
Configuration ¶
Configure the AES/SAES peripheral in three steps:
Step 1 (Chaining mode (algorithm) configuration according to the defined compilation algorithm flag):
By default, all compilation algorithm flags are defined. Undefine the unused ones to optimize code size and reduce footprint.
The AES compilation algorithm flags are:
USE_HAL_AES_ECB_CBC_ALGO flag: The AES/SAES peripheral can be configured with one of the following chaining modes:
Electronic Code Book algorithm (ECB) by using HAL_AES_ECB_SetConfig() API; no parameter is required
Cipher Block Chaining algorithm (CBC) by using HAL_AES_CBC_SetConfig() API and provide the initialization vector
USE_HAL_AES_CTR_ALGO flag: Configure the AES peripheral to Counter chaining mode (CTR) by using HAL_AES_CTR_SetConfig() API and provide the initialization vector
USE_HAL_AES_GCM_GMAC_ALGO flag: The AES peripheral is configured to Galois/counter chaining mode(GCM/GMAC) by using HAL_AES_GCM_GMAC_SetConfig() API and provide the header, its size, and the initialization vector
USE_HAL_AES_CCM_ALGO flag: The AES peripheral is configured to Counter with Cipher Block Chaining-Message(CCM) by using HAL_AES_CCM_SetConfig() API and provide the header, its size, and B0
Step2 (Key configuration according to one of the following use cases):
Use the application normal key:
Call HAL_AES_SetNormalKey() API and provide the key and its size
This API is available with AES/SAES peripheral
Use the SAES Hardware key:
Call HAL_AES_SetHWKey() API and set the SAES hardware key, its size, and the key mode:
Set the normal key mode to encrypt/decrypt application messages
Set the wrap key mode to wrap/unwrap the application key
Set the share key mode to share/unshare the application key
This API is only available with SAES peripheral
When the selected HW key is either the BHK or the DHUK_XOR_BHK, read it from TAMP backup registers before any encryption/decryption
Use the application key shared by SAES peripheral: This key mode lets the AES instance receive the key shared by SAES peripheral via secure hardware buses:
Call HAL_AES_SetSharedKey() API and set the key size
This API is only available with AES peripheral
Use the application wrapped key: This key mode lets the SAES instance secure an application key by encrypting it with the SAES hardware key (wrapper key). To use the key, decrypt it with the same wrapper key. This mode is ensured by applying the following sequence:
Call HAL_AES_SetHWKey() API and select the SAES hardware key, set its size (wrapper key), and set the key mode to wrapped mode
Call HAL_AES_WrapKey() API and provide the application key to encrypt with the configured wrapper key and an output key buffer to write the encrypted key
After the process ends, delete the original key to keep it secure
To use the original key, configure the same wrapper key by calling HAL_AES_SetHWKey() and unwrap the encrypted key by calling HAL_AES_UnwrapKey() API. After the process ends, the decrypted key cannot be read and is loaded automatically into the key registers for further encrypt/decrypt operations
This API is only available with SAES peripheral Provide the same key size for HAL_AES_SetHWKey() API and the key size provided for the HAL_AES_WrapKey() and HAL_AES_UnwrapKey() APIs When the selected wrapper key is either the BHK or the DHUK_XOR_BHK, read it from TAMP backup registers before calling both APIs HAL_AES_WrapKey() and HAL_AES_UnwrapKey()
Step3 (Configure the data swapping):
By default, the AES is configured to no swap. If swapped data is provided, configure the swap mode by using the HAL_AES_SetDataSwapping() API
Skipping configuration steps use cases:
Step 1 configuration is always required before each one-shot message encrypt or decrypt. When encrypting or decrypting a single message with consecutive calls of a processing API, apply the configuration only before processing the first piece of this message.
Step 2 configuration is not required as long as the configured key has not been changed. Redo step 2 after ECB or CBC decrypt because those algorithms derive the original key during decryption
Step 3 is always required before each one-shot message encrypt/decrypt when the provided data is swapped
Sharing SAES key ¶
The SAES peripheral can share application keys with the AES peripheral without being exposed in clear text. The key sharing sequence involves both sides (the SAES sharing-key peripheral and the AES target peripheral receiving the shared key):
SAES peripheral sharing key:
Call HAL_AES_SetHWKey() API and select the SAES hardware key, set its size (wrapper key), and set the key mode to shared mode
Call HAL_AES_EncryptSharedKey() API and provide the application key to encrypt with the configured wrapper key and an output key buffer to write the encrypted key in share mode. Specify the peripheral receiving the shared key by providing the target_id (target_id value is equal to 0 for c5 families)
After the process ends, delete the original key to keep it secure.
To share the original key with the AES peripheral, configure the same wrapper key by calling the HAL_AES_SetHWKey() API and decrypt the encrypted key in share mode using the HAL_AES_DecryptSharedKey() API. After decryption ends, the decrypted key cannot be read and is loaded automatically into hardware buses and shared with AES for further AES encrypt/decrypt operations.
AES peripheral target receiving the shared key:
On the other side, configure the receiver of the shared key via HAL_AES_SetSharedKey() API
Provide the same key size for HAL_AES_SetHWKey() API and the key size provided for the HAL_AES_EncryptSharedKey() and HAL_AES_DecryptSharedKey() APIs When the selected wrapper key is either the BHK or the DHUK_XOR_BHK, read it from TAMP backup registers before calling both APIs HAL_AES_EncryptSharedKey() and HAL_AES_DecryptSharedKey()
Polling mode IO operation ¶
Encrypt an amount of data in blocking mode using HAL_AES_Encrypt()
Decrypt an amount of data in blocking mode using HAL_AES_Decrypt()
The driver pads only the missing words within a block (one block is equal to four words). When the provided data size is not a multiple of words, pad the missing bytes within the last word with zeros for GCM and CCM algorithms.
TAG Generation ¶
Generate the tag after encryption or decryption by using either HAL_AES_GCM_GenerateAuthTAG() API for GCM algorithm or HAL_AES_CCM_GenerateAuthTAG() API for CCM algorithm
Interrupt mode IO operation ¶
Encrypt an amount of data in interrupt mode using HAL_AES_Encrypt_IT()
At the end of the transfer of data between the user buffer and the AES/SAES peripheral, HAL_AES_InCpltCallback() and HAL_AES_OutCpltCallback() are executed
Decrypt an amount of data in interrupt mode using HAL_AES_Decrypt_IT()
At the end of the transfer of data between the user buffer and the AES/SAES peripheral, HAL_AES_InCpltCallback() and HAL_AES_OutCpltCallback() are executed
The driver pads only the missing words within a block (one block is equal to four words). When the provided data size is not a multiple of words, pad the missing bytes within the last word with zeros for GCM and CCM algorithms.
DMA mode IO operation ¶
Encrypt/decrypt an amount of data after transfer from the input user buffer to the AES/SAES peripheral and get encrypted/decrypted data from AES/SAES peripheral via DMA using HAL_AES_Encrypt_DMA() or HAL_AES_Decrypt_DMA()
The minimum data amount transferred with DMA must be equal to one block (four complete words), as the DMA transfer does not support the padding (the driver handles the padding with a direct transfer of the incomplete data without using DMA)
At the end of a transfer of data from the user buffer to the AES/SAES peripheral, one of these callbacks is generated:
AES_ECB_CBC_CTR_DMAInCplt() which generates the HAL_AES_InCpltCallback() callback
AES_GCM_GMAC_CCM_DMAInCplt() is executed after the header phase blocks transfer to handle the padding if it exists and to initiate the payload phase when plaintext is not NULL. The HAL_AES_InCpltCallback() is then generated
At the end of a transfer of data from AES/SAES peripheral to the user buffer, one of these callbacks is generated:
AES_ECB_CBC_CTR_DMAOutCplt() where the operation is completed and the AES is disabled and which generates the HAL_AES_OutCpltCallback() callback
AES_GCM_GMAC_CCM_DMAOutCplt() is executed after the payload phase blocks transfer to handle the padding if it exists and to end the operation by generating the HAL_AES_OutCpltCallback()
If a hardware AES DMA error happens during DMA transfer, an AES_DMAError() callback is generated to end the operation and generate HAL_AES_ErrorCallback()
Suspend Resume management ¶
Use the suspend/resume feature for two purposes and under the following conditions:
The USE_HAL_AES_SUSPEND_RESUME compilation flag must be defined
Suspend conditions:
Only IT mode processes can be suspended
The suspension is only possible after the completion of processing an entire block
The suspension is not possible when only one block remains to be processed (it is too late to suspend the operation)
Purpose 1 (without context modification): Suspend a process due to time constraints and resume it later
Call HAL_AES_RequestSuspend() API to request suspension
When suspended, a HAL_AES_SuspendCallback callback is generated
Call HAL_AES_Resume() API to restore the suspended process from the suspended endpoint
Purpose 2 (with context modification): Suspend a low-priority message processing to process a high-priority message instead
Call HAL_AES_RequestSuspend() API to request suspension
When suspended, a HAL_AES_SuspendCallback callback is generated
Call HAL_AES_SaveContext() API and provide a structure to save all internal data needed to restart later. Then change the context to process the high-priority message (change the peripheral, the configuration, the AES operation…)
When the high priority message processing is over, call the HAL_AES_RestoreContext() API with the already filled structure to restore the low priority suspended context
Call HAL_AES_Resume() API to restore the suspended process from the suspended endpoint
Callback registration ¶
When the USE_HAL_AES_REGISTER_CALLBACKS compilation flag is set to 1, configure the driver callbacks dynamically:
HAL_AES_RegisterInTransferCpltCallback(): callback for end of transfer of data
HAL_AES_RegisterOutTransferCpltCallback(): callback for end of transfer of data
HAL_AES_RegisterErrorCallback(): callback for error.
HAL_AES_RegisterSuspendCallback(): callback for suspend. When the compilation flag is set to 0 or not defined, the callback registration feature is not available, and all callbacks are set to the corresponding weak functions.