Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,732 @@
|
||||
/*!
|
||||
\file gd32h7xx_cau.c
|
||||
\brief CAU driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gd32h7xx_cau.h"
|
||||
#include "gd32h7xx_rcu.h"
|
||||
|
||||
#define STAT0_AESDES_MASK ((uint32_t)0x00000015U)
|
||||
#define STAT0_TDES_MASK ((uint32_t)0x00000014U)
|
||||
|
||||
/*!
|
||||
\brief reset the CAU peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_deinit(void)
|
||||
{
|
||||
/* enable CAU reset state */
|
||||
rcu_periph_reset_enable(RCU_CAURST);
|
||||
/* release CAU from reset state */
|
||||
rcu_periph_reset_disable(RCU_CAURST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the CAU encrypt and decrypt parameter struct with the default values
|
||||
\param[in] none
|
||||
\param[out] cau_parameter:
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key
|
||||
key_size: key size in bytes
|
||||
iv: initialization vector
|
||||
iv_size: iv size in bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes
|
||||
aad: additional authentication data
|
||||
aad_size: header size
|
||||
\retval none
|
||||
*/
|
||||
void cau_struct_para_init(cau_parameter_struct *cau_parameter)
|
||||
{
|
||||
/* set the CAU encrypt and decrypt parameters struct with the default values */
|
||||
cau_parameter->alg_dir = CAU_ENCRYPT;
|
||||
cau_parameter->key = 0U;
|
||||
cau_parameter->key_size = 0U;
|
||||
cau_parameter->iv = 0U;
|
||||
cau_parameter->iv_size = 0U;
|
||||
cau_parameter->input = 0U;
|
||||
cau_parameter->in_length = 0U;
|
||||
cau_parameter->aad = 0U;
|
||||
cau_parameter->aad_size = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the key parameter structure with the default values
|
||||
\param[in] none
|
||||
\param[out] key_initpara:
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
\retval none
|
||||
*/
|
||||
void cau_key_struct_para_init(cau_key_parameter_struct *key_initpara)
|
||||
{
|
||||
/* set the key parameters struct with the default values */
|
||||
key_initpara->key_0_high = 0U;
|
||||
key_initpara->key_0_low = 0U;
|
||||
key_initpara->key_1_high = 0U;
|
||||
key_initpara->key_1_low = 0U;
|
||||
key_initpara->key_2_high = 0U;
|
||||
key_initpara->key_2_low = 0U;
|
||||
key_initpara->key_3_high = 0U;
|
||||
key_initpara->key_3_low = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the vectors parameter struct with the default values
|
||||
\param[in] none
|
||||
\param[out] iv_initpara:
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
\retval none
|
||||
*/
|
||||
void cau_iv_struct_para_init(cau_iv_parameter_struct *iv_initpara)
|
||||
{
|
||||
/* set the vectors parameters struct with the default values */
|
||||
iv_initpara->iv_0_high = 0U;
|
||||
iv_initpara->iv_0_low = 0U;
|
||||
iv_initpara->iv_1_high = 0U;
|
||||
iv_initpara->iv_1_low = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the context parameter struct with the default values
|
||||
\param[in] none
|
||||
\param[out] cau_context:
|
||||
ctl_config: current configuration
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
gcmccmctxs[8]: GCM or CCM mode context switch
|
||||
gcmctxs[8]: GCM mode context switch
|
||||
\retval none
|
||||
*/
|
||||
void cau_context_struct_para_init(cau_context_parameter_struct *cau_context)
|
||||
{
|
||||
cau_context->ctl_config = 0U;
|
||||
|
||||
/* set the vectors parameters with the default values */
|
||||
cau_context->iv_0_high = 0U;
|
||||
cau_context->iv_0_low = 0U;
|
||||
cau_context->iv_1_high = 0U;
|
||||
cau_context->iv_1_low = 0U;
|
||||
|
||||
/* set the key parameters with the default values */
|
||||
cau_context->key_0_high = 0U;
|
||||
cau_context->key_0_low = 0U;
|
||||
cau_context->key_1_high = 0U;
|
||||
cau_context->key_1_low = 0U;
|
||||
cau_context->key_2_high = 0U;
|
||||
cau_context->key_2_low = 0U;
|
||||
cau_context->key_3_high = 0U;
|
||||
cau_context->key_3_low = 0U;
|
||||
|
||||
/* set the context switch with the default values */
|
||||
cau_context->gcmccmctxs[0] = 0U;
|
||||
cau_context->gcmccmctxs[1] = 0U;
|
||||
cau_context->gcmccmctxs[2] = 0U;
|
||||
cau_context->gcmccmctxs[3] = 0U;
|
||||
cau_context->gcmccmctxs[4] = 0U;
|
||||
cau_context->gcmccmctxs[5] = 0U;
|
||||
cau_context->gcmccmctxs[6] = 0U;
|
||||
cau_context->gcmccmctxs[7] = 0U;
|
||||
|
||||
cau_context->gcmctxs[0] = 0U;
|
||||
cau_context->gcmctxs[1] = 0U;
|
||||
cau_context->gcmctxs[2] = 0U;
|
||||
cau_context->gcmctxs[3] = 0U;
|
||||
cau_context->gcmctxs[4] = 0U;
|
||||
cau_context->gcmctxs[5] = 0U;
|
||||
cau_context->gcmctxs[6] = 0U;
|
||||
cau_context->gcmctxs[7] = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CAU peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_enable(void)
|
||||
{
|
||||
/* enable the CAU processor */
|
||||
CAU_CTL |= CAU_CTL_CAUEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CAU peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_disable(void)
|
||||
{
|
||||
/* disable the CAU processor */
|
||||
CAU_CTL &= ~CAU_CTL_CAUEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CAU DMA interface
|
||||
\param[in] dma_req: specify the CAU DMA transfer request to be enabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CAU_DMA_INFIFO: DMA for incoming(Rx) data transfer
|
||||
\arg CAU_DMA_OUTFIFO: DMA for outgoing(Tx) data transfer
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_dma_enable(uint32_t dma_req)
|
||||
{
|
||||
/* enable the selected CAU DMA request */
|
||||
CAU_DMAEN |= dma_req;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CAU DMA interface
|
||||
\param[in] dma_req: specify the CAU DMA transfer request to be disabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CAU_DMA_INFIFO: DMA for incoming(Rx) data transfer
|
||||
\arg CAU_DMA_OUTFIFO: DMA for outgoing(Tx) data transfer
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_dma_disable(uint32_t dma_req)
|
||||
{
|
||||
/* disable the selected CAU DMA request */
|
||||
CAU_DMAEN &= ~(dma_req);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the CAU peripheral
|
||||
\param[in] alg_dir: algorithm direction
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_ENCRYPT: encrypt
|
||||
\arg CAU_DECRYPT: decrypt
|
||||
\param[in] algo_mode: algorithm mode selection
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_MODE_TDES_ECB: TDES-ECB (3DES Electronic codebook)
|
||||
\arg CAU_MODE_TDES_CBC: TDES-CBC (3DES Cipher block chaining)
|
||||
\arg CAU_MODE_DES_ECB: DES-ECB (simple DES Electronic codebook)
|
||||
\arg CAU_MODE_DES_CBC: DES-CBC (simple DES Cipher block chaining)
|
||||
\arg CAU_MODE_AES_ECB: AES-ECB (AES Electronic codebook)
|
||||
\arg CAU_MODE_AES_CBC: AES-CBC (AES Cipher block chaining)
|
||||
\arg CAU_MODE_AES_CTR: AES-CTR (AES counter mode)
|
||||
\arg CAU_MODE_AES_KEY: AES decryption key preparation mode
|
||||
\arg CAU_MODE_AES_GCM: AES-GCM (AES Galois/counter mode)
|
||||
\arg CAU_MODE_AES_CCM: AES-CCM (AES combined cipher machine mode)
|
||||
\arg CAU_MODE_AES_CFB: AES-CFB (cipher feedback mode)
|
||||
\arg CAU_MODE_AES_OFB: AES-OFB (output feedback mode)
|
||||
\param[in] swapping: data swapping selection
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_SWAPPING_32BIT: no swapping
|
||||
\arg CAU_SWAPPING_16BIT: half-word swapping
|
||||
\arg CAU_SWAPPING_8BIT: bytes swapping
|
||||
\arg CAU_SWAPPING_1BIT: bit swapping
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_init(uint32_t alg_dir, uint32_t algo_mode, uint32_t swapping)
|
||||
{
|
||||
/* select algorithm mode */
|
||||
CAU_CTL &= ~CAU_CTL_ALGM;
|
||||
CAU_CTL |= algo_mode;
|
||||
|
||||
/* select data swapping */
|
||||
CAU_CTL &= ~CAU_CTL_DATAM;
|
||||
CAU_CTL |= swapping;
|
||||
|
||||
/* select algorithm direction */
|
||||
CAU_CTL &= ~CAU_CTL_CAUDIR;
|
||||
CAU_CTL |= alg_dir;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure key selection
|
||||
\param[in] key_selection: key source selection when aes mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_KEY: use the key from CAU register
|
||||
\arg CAU_EFUSE_KEY: use the key from EFUSE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_aes_key_select(uint32_t key_selection)
|
||||
{
|
||||
CAU_CTL &= ~CAU_CTL_KEY_SEL;
|
||||
CAU_CTL |= key_selection;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure key size if use AES algorithm
|
||||
\param[in] key_size: key length selection when aes mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_KEYSIZE_128BIT: 128 bit key length
|
||||
\arg CAU_KEYSIZE_192BIT: 192 bit key length
|
||||
\arg CAU_KEYSIZE_256BIT: 256 bit key length
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_aes_keysize_config(uint32_t key_size)
|
||||
{
|
||||
CAU_CTL &= ~CAU_CTL_KEYM;
|
||||
CAU_CTL |= key_size;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the key parameters
|
||||
\param[in] key_initpara: key init parameter struct
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_key_init(cau_key_parameter_struct *key_initpara)
|
||||
{
|
||||
CAU_KEY0H = key_initpara->key_0_high;
|
||||
CAU_KEY0L = key_initpara->key_0_low;
|
||||
CAU_KEY1H = key_initpara->key_1_high;
|
||||
CAU_KEY1L = key_initpara->key_1_low;
|
||||
CAU_KEY2H = key_initpara->key_2_high;
|
||||
CAU_KEY2L = key_initpara->key_2_low;
|
||||
CAU_KEY3H = key_initpara->key_3_high;
|
||||
CAU_KEY3L = key_initpara->key_3_low;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the vectors parameters
|
||||
\param[in] iv_initpara: vectors init parameter struct
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_iv_init(cau_iv_parameter_struct *iv_initpara)
|
||||
{
|
||||
CAU_IV0H = iv_initpara->iv_0_high;
|
||||
CAU_IV0L = iv_initpara->iv_0_low;
|
||||
CAU_IV1H = iv_initpara->iv_1_high;
|
||||
CAU_IV1L = iv_initpara->iv_1_low;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure phase
|
||||
\param[in] phase: gcm or ccm phase
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_PREPARE_PHASE: prepare phase
|
||||
\arg CAU_AAD_PHASE: AAD phase
|
||||
\arg CAU_ENCRYPT_DECRYPT_PHASE: encryption/decryption phase
|
||||
\arg CAU_TAG_PHASE: tag phase
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_phase_config(uint32_t phase)
|
||||
{
|
||||
uint32_t temp;
|
||||
/* Get the CTL register */
|
||||
temp = CAU_CTL;
|
||||
/* Reset the phase configuration bits */
|
||||
temp &= ~CAU_CTL_GCM_CCMPH;
|
||||
/* Set the selected phase */
|
||||
temp |= phase;
|
||||
/* Set the CTL register */
|
||||
CAU_CTL = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief flush the IN and OUT FIFOs
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_fifo_flush(void)
|
||||
{
|
||||
/* reset the read and write pointers of the FIFOs */
|
||||
CAU_CTL |= CAU_CTL_FFLUSH;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief return whether CAU peripheral is enabled or disabled
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ControlStatus: ENABLE or DISABLE
|
||||
*/
|
||||
ControlStatus cau_enable_state_get(void)
|
||||
{
|
||||
ControlStatus ret = DISABLE;
|
||||
if(RESET != (CAU_CTL & CAU_CTL_CAUEN)) {
|
||||
ret = ENABLE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write data to the IN FIFO
|
||||
\param[in] data: data to write (0 - 0xFFFFFFFF)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_data_write(uint32_t data)
|
||||
{
|
||||
CAU_DI = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief return the last data entered into the output FIFO
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval last data entered into the output FIFO
|
||||
*/
|
||||
uint32_t cau_data_read(void)
|
||||
{
|
||||
return CAU_DO;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief save context before context switching
|
||||
\param[in] key_initpara: key init parameter struct
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
\param[out] cau_context:
|
||||
ctl_config: current configuration
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
gcmccmctxs[8]: GCM or CCM mode context switch
|
||||
gcmctxs[8]: GCM mode context switch
|
||||
\retval none
|
||||
*/
|
||||
void cau_context_save(cau_context_parameter_struct *cau_context, cau_key_parameter_struct *key_initpara)
|
||||
{
|
||||
uint32_t checkmask = 0U;
|
||||
uint32_t checkbits = 0U;
|
||||
uint32_t algm_reg = 0U;
|
||||
|
||||
/* stop DMA transfers on the IN FIFO by clearing the DMAIEN bit in the CAU_DMAEN */
|
||||
CAU_DMAEN &= ~CAU_DMA_INFIFO;
|
||||
|
||||
algm_reg = CAU_CTL & CAU_CTL_ALGM;
|
||||
/* AES or DES */
|
||||
if((uint32_t)0 != (algm_reg & (~CAU_MODE_TDES_CBC))) {
|
||||
/* wait until both the IN and OUT FIFOs are empty (IEM=1 and ONE=0 in the CAU_STAT0 register) and BUSY=0 */
|
||||
checkbits = CAU_STAT0_IEM;
|
||||
checkmask = STAT0_AESDES_MASK;
|
||||
/* TDES */
|
||||
} else {
|
||||
/* wait until OUT FIFO is empty (ONE=0 in the CAU_STAT0 register) and BUSY=0 */
|
||||
checkbits = 0U;
|
||||
checkmask = STAT0_TDES_MASK;
|
||||
}
|
||||
|
||||
while((CAU_STAT0 & checkmask) != checkbits) {
|
||||
}
|
||||
|
||||
/* stop DMA transfers on the OUT FIFO by clear CAU_DMAEN_DMAOEN=0 */
|
||||
CAU_DMAEN &= ~CAU_DMAEN_DMAOEN;
|
||||
/* disable CAU */
|
||||
CAU_CTL &= ~CAU_CTL_CAUEN;
|
||||
|
||||
/* save the current configuration (bit 19, bit[17:16] and bit[9:2] in the CAU_CTL register) */
|
||||
cau_context->ctl_config = CAU_CTL & (CAU_CTL_GCM_CCMPH |
|
||||
CAU_CTL_KEYM |
|
||||
CAU_CTL_DATAM |
|
||||
CAU_CTL_ALGM |
|
||||
CAU_CTL_CAUDIR |
|
||||
CAU_CTL_NBPILB);
|
||||
|
||||
/* save the key value */
|
||||
cau_context->key_0_high = key_initpara->key_0_high;
|
||||
cau_context->key_0_low = key_initpara->key_0_low;
|
||||
cau_context->key_1_high = key_initpara->key_1_high;
|
||||
cau_context->key_1_low = key_initpara->key_1_low;
|
||||
cau_context->key_2_high = key_initpara->key_2_high;
|
||||
cau_context->key_2_low = key_initpara->key_2_low;
|
||||
cau_context->key_3_high = key_initpara->key_3_high;
|
||||
cau_context->key_3_low = key_initpara->key_3_low;
|
||||
|
||||
if((CAU_MODE_TDES_ECB != algm_reg) && (CAU_MODE_DES_ECB != algm_reg) && (CAU_MODE_AES_ECB != algm_reg)) {
|
||||
/* if not in ECB mode, save the initialization vectors */
|
||||
cau_context->iv_0_high = CAU_IV0H;
|
||||
cau_context->iv_0_low = CAU_IV0L;
|
||||
cau_context->iv_1_high = CAU_IV1H;
|
||||
cau_context->iv_1_low = CAU_IV1L;
|
||||
}
|
||||
|
||||
/* if in GCM/CCM mode, save the context switch registers */
|
||||
if((CAU_MODE_AES_GCM == algm_reg) || (CAU_MODE_AES_CCM == algm_reg)) {
|
||||
cau_context->gcmccmctxs[0U] = CAU_GCMCCMCTXSx(0U);
|
||||
cau_context->gcmccmctxs[1U] = CAU_GCMCCMCTXSx(1U);
|
||||
cau_context->gcmccmctxs[2U] = CAU_GCMCCMCTXSx(2U);
|
||||
cau_context->gcmccmctxs[3U] = CAU_GCMCCMCTXSx(3U);
|
||||
cau_context->gcmccmctxs[4U] = CAU_GCMCCMCTXSx(4U);
|
||||
cau_context->gcmccmctxs[5U] = CAU_GCMCCMCTXSx(5U);
|
||||
cau_context->gcmccmctxs[6U] = CAU_GCMCCMCTXSx(6U);
|
||||
cau_context->gcmccmctxs[7U] = CAU_GCMCCMCTXSx(7U);
|
||||
}
|
||||
|
||||
/* if in GCM mode, save the context switch registers */
|
||||
if(CAU_MODE_AES_GCM == algm_reg) {
|
||||
cau_context->gcmctxs[0U] = CAU_GCMCTXSx(0U);
|
||||
cau_context->gcmctxs[1U] = CAU_GCMCTXSx(1U);
|
||||
cau_context->gcmctxs[2U] = CAU_GCMCTXSx(2U);
|
||||
cau_context->gcmctxs[3U] = CAU_GCMCTXSx(3U);
|
||||
cau_context->gcmctxs[4U] = CAU_GCMCTXSx(4U);
|
||||
cau_context->gcmctxs[5U] = CAU_GCMCTXSx(5U);
|
||||
cau_context->gcmctxs[6U] = CAU_GCMCTXSx(6U);
|
||||
cau_context->gcmctxs[7U] = CAU_GCMCTXSx(7U);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief restore context after context switching
|
||||
\param[in] cau_context:
|
||||
ctl_config: current configuration
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
gcmccmctxs[8]: GCM or CCM mode context switch
|
||||
gcmctxs[8]: GCM mode context switch
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_context_restore(cau_context_parameter_struct *cau_context)
|
||||
{
|
||||
uint32_t algm_reg, aes_decrypt;
|
||||
|
||||
/* configure the processor with the saved configuration */
|
||||
CAU_CTL = cau_context->ctl_config;
|
||||
|
||||
algm_reg = CAU_CTL & CAU_CTL_ALGM;
|
||||
|
||||
/* restore the key value */
|
||||
CAU_KEY0H = cau_context->key_0_high;
|
||||
CAU_KEY0L = cau_context->key_0_low;
|
||||
CAU_KEY1H = cau_context->key_1_high;
|
||||
CAU_KEY1L = cau_context->key_1_low;
|
||||
CAU_KEY2H = cau_context->key_2_high;
|
||||
CAU_KEY2L = cau_context->key_2_low;
|
||||
CAU_KEY3H = cau_context->key_3_high;
|
||||
CAU_KEY3L = cau_context->key_3_low;
|
||||
|
||||
if((CAU_MODE_TDES_ECB != algm_reg) && (CAU_MODE_DES_ECB != algm_reg) && (CAU_MODE_AES_ECB != algm_reg)) {
|
||||
/* restore the initialization vectors */
|
||||
CAU_IV0H = cau_context->iv_0_high;
|
||||
CAU_IV0L = cau_context->iv_0_low;
|
||||
CAU_IV1H = cau_context->iv_1_high;
|
||||
CAU_IV1L = cau_context->iv_1_low;
|
||||
}
|
||||
|
||||
/* if in GCM/CCM mode, restore the context switch registers */
|
||||
if((CAU_MODE_AES_GCM == algm_reg) || (CAU_MODE_AES_CCM == algm_reg)) {
|
||||
CAU_GCMCCMCTXSx(0U) = cau_context->gcmccmctxs[0U];
|
||||
CAU_GCMCCMCTXSx(1U) = cau_context->gcmccmctxs[1U];
|
||||
CAU_GCMCCMCTXSx(2U) = cau_context->gcmccmctxs[2U];
|
||||
CAU_GCMCCMCTXSx(3U) = cau_context->gcmccmctxs[3U];
|
||||
CAU_GCMCCMCTXSx(4U) = cau_context->gcmccmctxs[4U];
|
||||
CAU_GCMCCMCTXSx(5U) = cau_context->gcmccmctxs[5U];
|
||||
CAU_GCMCCMCTXSx(6U) = cau_context->gcmccmctxs[6U];
|
||||
CAU_GCMCCMCTXSx(7U) = cau_context->gcmccmctxs[7U];
|
||||
}
|
||||
|
||||
/* if in GCM mode, restore the context switch registers */
|
||||
if(CAU_MODE_AES_GCM == algm_reg) {
|
||||
CAU_GCMCTXSx(0U) = cau_context->gcmctxs[0U];
|
||||
CAU_GCMCTXSx(1U) = cau_context->gcmctxs[1U];
|
||||
CAU_GCMCTXSx(2U) = cau_context->gcmctxs[2U];
|
||||
CAU_GCMCTXSx(3U) = cau_context->gcmctxs[3U];
|
||||
CAU_GCMCTXSx(4U) = cau_context->gcmctxs[4U];
|
||||
CAU_GCMCTXSx(5U) = cau_context->gcmctxs[5U];
|
||||
CAU_GCMCTXSx(6U) = cau_context->gcmctxs[6U];
|
||||
CAU_GCMCTXSx(7U) = cau_context->gcmctxs[7U];
|
||||
}
|
||||
|
||||
/* if it is AES ECB/CBC decryption, then first prepare key */
|
||||
aes_decrypt = CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR);
|
||||
if(((CAU_MODE_AES_ECB | CAU_DECRYPT) == aes_decrypt) || ((CAU_MODE_AES_CBC | CAU_DECRYPT) == aes_decrypt)) {
|
||||
uint32_t alg_dir, algo_mode, swapping;
|
||||
|
||||
/* flush IN/OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* parameters for key preparation for AES decryption */
|
||||
alg_dir = CAU_DECRYPT;
|
||||
algo_mode = CAU_MODE_AES_KEY;
|
||||
swapping = CAU_SWAPPING_32BIT;
|
||||
cau_init(alg_dir, algo_mode, swapping);
|
||||
|
||||
/* enable CAU */
|
||||
cau_enable();
|
||||
|
||||
/* wait until BUSY=0 */
|
||||
while((uint32_t)0U != cau_flag_get(CAU_FLAG_BUSY)) {
|
||||
}
|
||||
|
||||
/* parameters for decryption */
|
||||
CAU_CTL = cau_context->ctl_config;
|
||||
}
|
||||
|
||||
/* enable CAU */
|
||||
cau_enable();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the CAU flag status
|
||||
\param[in] flag: CAU flag status
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_FLAG_INFIFO_EMPTY: input FIFO empty
|
||||
\arg CAU_FLAG_INFIFO_NO_FULL: input FIFO is not full
|
||||
\arg CAU_FLAG_OUTFIFO_NO_EMPTY: output FIFO not empty
|
||||
\arg CAU_FLAG_OUTFIFO_FULL: output FIFO is full
|
||||
\arg CAU_FLAG_BUSY: the CAU core is busy
|
||||
\arg CAU_FLAG_INFIFO: input FIFO flag status
|
||||
\arg CAU_FLAG_OUTFIFO: output FIFO flag status
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus cau_flag_get(uint32_t flag)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
FlagStatus ret_flag = RESET;
|
||||
|
||||
/* check if the flag is in CAU_STAT1 register */
|
||||
if(1U == (flag >> 31U)) {
|
||||
reg = CAU_STAT1;
|
||||
} else {
|
||||
/* the flag is in CAU_STAT0 register */
|
||||
reg = CAU_STAT0;
|
||||
}
|
||||
|
||||
/* check the status of the specified CAU flag */
|
||||
if(0U != (reg & flag)) {
|
||||
ret_flag = SET;
|
||||
}
|
||||
|
||||
return ret_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CAU interrupts
|
||||
\param[in] interrupt: specify the CAU interrupt source to be enabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CAU_INT_INFIFO: input FIFO interrupt
|
||||
\arg CAU_INT_OUTFIFO: output FIFO interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
/* enable the selected CAU interrupt */
|
||||
CAU_INTEN |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CAU interrupts
|
||||
\param[in] interrupt: specify the CAU interrupt source to be disabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CAU_INT_INFIFO: input FIFO interrupt
|
||||
\arg CAU_INT_OUTFIFO: output FIFO interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
/* disable the selected CAU interrupt */
|
||||
CAU_INTEN &= ~(interrupt);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the interrupt flag
|
||||
\param[in] int_flag: CAU interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_INT_FLAG_INFIFO: input FIFO interrupt
|
||||
\arg CAU_INT_FLAG_OUTFIFO: output FIFO interrupt
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus cau_interrupt_flag_get(uint32_t int_flag)
|
||||
{
|
||||
FlagStatus flag = RESET;
|
||||
|
||||
/* check the status of the specified CAU interrupt */
|
||||
if(RESET != (CAU_INTF & int_flag)) {
|
||||
flag = SET;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
Reference in New Issue
Block a user