1 /*********************************************************************************************************//**
2  * @file    ht32f5xxxx_aes.c
3  * @version $Rev:: 8205         $
4  * @date    $Date:: 2024-10-15 #$
5  * @brief   This file provides all the AES firmware functions.
6  *************************************************************************************************************
7  * @attention
8  *
9  * Firmware Disclaimer Information
10  *
11  * 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
12  *    code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
13  *    proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
14  *    other intellectual property laws.
15  *
16  * 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
17  *    code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
18  *    other than HOLTEK and the customer.
19  *
20  * 3. The program technical documentation, including the code, is provided "as is" and for customer reference
21  *    only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
22  *    the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
23  *    the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
24  *
25  * <h2><center>Copyright (C) Holtek Semiconductor Inc. All rights reserved</center></h2>
26  ************************************************************************************************************/
27 
28 /* Includes ------------------------------------------------------------------------------------------------*/
29 #include "ht32f5xxxx_aes.h"
30 
31 /** @addtogroup HT32F5xxxx_Peripheral_Driver HT32F5xxxx Peripheral Driver
32   * @{
33   */
34 
35 /** @defgroup AES AES
36   * @brief AES driver modules
37   * @{
38   */
39 
40 
41 /* Global variables ----------------------------------------------------------------------------------------*/
42 u32 *gpu32OutputBuff;
43 u32 gu32OutputIndex = 0;
44 
45 u32 *gpu32InputBuff;
46 u32 gu32InputSize = 0;
47 u32 gu32InputIndex = 0;
48 
49 /* Private functions ---------------------------------------------------------------------------------------*/
50 static void _AES_Init(HT_AES_TypeDef* HT_AESn, AES_InitTypeDef* AES_InitStruct);
51 
52 /* Global functions ----------------------------------------------------------------------------------------*/
53 /** @defgroup AES_Exported_Functions AES exported functions
54   * @{
55   */
56 /*********************************************************************************************************//**
57  * @brief Deinitialize the AES peripheral registers to their default reset values.
58  * @param  HT_AESn: where HT_AESn is the selected AES from the AES peripherals.
59  * @retval None
60  ************************************************************************************************************/
AES_DeInit(HT_AES_TypeDef * HT_AESn)61 void AES_DeInit(HT_AES_TypeDef* HT_AESn)
62 {
63   RSTCU_PeripReset_TypeDef RSTCUReset = {{0}};
64 
65   if (HT_AESn == NULL) // Remove the compiler warning
66   {
67   }
68 
69   RSTCUReset.Bit.AES = 1;
70   RSTCU_PeripReset(RSTCUReset, ENABLE);
71 }
72 
73 /*********************************************************************************************************//**
74  * @brief Flush the FIFO.
75  * @param  HT_AESn: where HT_AESn is the selected AES from the AES peripherals.
76  * @retval None
77  ************************************************************************************************************/
AES_FIFOFlush(HT_AES_TypeDef * HT_AESn)78 void AES_FIFOFlush(HT_AES_TypeDef* HT_AESn)
79 {
80   AES_Cmd(HT_AESn, DISABLE);
81   HT_AESn->CR |= AES_FLUSH_ENABLE;
82   AES_Cmd(HT_AESn, ENABLE);
83 }
84 
85 /*********************************************************************************************************//**
86  * @brief Enable or Disable the specified AES.
87  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals.
88  * @param NewState: This parameter can be ENABLE or DISABLE.
89  * @retval None
90  ************************************************************************************************************/
AES_Cmd(HT_AES_TypeDef * HT_AESn,ControlStatus NewState)91 void AES_Cmd(HT_AES_TypeDef* HT_AESn, ControlStatus NewState)
92 {
93   /* Check the parameters                                                                                   */
94   Assert_Param(IS_AES(HT_AESn));
95   Assert_Param(IS_CONTROL_STATUS(NewState));
96 
97   if (NewState != DISABLE)
98   {
99     HT_AESn->CR |= AES_ENABLE;
100   }
101   else
102   {
103     HT_AESn->CR &= ~AES_ENABLE;
104   }
105 }
106 
107 /*********************************************************************************************************//**
108  * @brief Start the AES key.
109  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals.
110  * @retval None
111  ************************************************************************************************************/
AES_StartKey(HT_AES_TypeDef * HT_AESn)112 void AES_StartKey(HT_AES_TypeDef* HT_AESn)
113 {
114   HT_AESn->CR |= (1 << 4);
115 }
116 
117 /*********************************************************************************************************//**
118  * @brief Initialize the AES peripheral according to the specified parameters in the AES_InitStruct.
119  * @param HT_AESn: where AES is the selected AES peripheral.
120  * @param AES_InitStruct: pointer to a AES_InitTypeDef structure.
121  * @retval None
122  ************************************************************************************************************/
_AES_Init(HT_AES_TypeDef * HT_AESn,AES_InitTypeDef * AES_InitStruct)123 void _AES_Init(HT_AES_TypeDef* HT_AESn, AES_InitTypeDef* AES_InitStruct)
124 {
125   /* Check the parameters                                                                                   */
126   Assert_Param(IS_AES(HT_AESn));
127   Assert_Param(IS_AES_KEY_SIZE(AES_InitStruct->AES_KeySize));
128   Assert_Param(IS_AES_DIR(AES_InitStruct->AES_Dir));
129   Assert_Param(IS_AES_MODE(AES_InitStruct->AES_Mode));
130   Assert_Param(IS_AES_SWAP(AES_InitStruct->AES_Swap));
131 
132   HT_AESn->CR = (HT_AESn->CR & 0xFFFFFE81) | AES_InitStruct->AES_KeySize |
133                  AES_InitStruct->AES_Dir | AES_InitStruct->AES_Mode |
134                  AES_InitStruct->AES_Swap;
135 
136   AES_Cmd(HT_AESn, ENABLE);
137 }
138 
139 /*********************************************************************************************************//**
140  * @brief Initialize the AES peripheral on ECB mode according to the specified parameters in the AES_InitStruct.
141  * @param HT_AESn: where AES is the selected AES peripheral.
142  * @param AES_InitStruct: pointer to a AES_InitTypeDef structure.
143  * @retval None
144  ************************************************************************************************************/
AES_ECB_Init(HT_AES_TypeDef * HT_AESn,AES_InitTypeDef * AES_InitStruct)145 void AES_ECB_Init(HT_AES_TypeDef* HT_AESn, AES_InitTypeDef* AES_InitStruct)
146 {
147   AES_InitStruct->AES_Mode = AES_MODE_ECB;
148   _AES_Init(HT_AESn, AES_InitStruct);
149 
150   AES_IntConfig(HT_AESn, AES_IER_OFINTEN, ENABLE);
151   NVIC_EnableIRQ(AES_IRQn);
152 }
153 
154 /*********************************************************************************************************//**
155  * @brief Initialize the AES peripheral on CBC mode according to the specified parameters in the AES_InitStruct.
156  * @param HT_AESn: where AES is the selected AES peripheral.
157  * @param AES_InitStruct: pointer to a AES_InitTypeDef structure.
158  * @retval None
159  ************************************************************************************************************/
AES_CBC_Init(HT_AES_TypeDef * HT_AESn,AES_InitTypeDef * AES_InitStruct)160 void AES_CBC_Init(HT_AES_TypeDef* HT_AESn, AES_InitTypeDef* AES_InitStruct)
161 {
162   AES_InitStruct->AES_Mode = AES_MODE_CBC;
163   _AES_Init(HT_AESn, AES_InitStruct);
164 
165   AES_IntConfig(HT_AESn, AES_IER_OFINTEN, ENABLE);
166   NVIC_EnableIRQ(AES_IRQn);
167 }
168 
169 /*********************************************************************************************************//**
170  * @brief Initialize the AES peripheral on CTR mode according to the specified parameters in the AES_InitStruct.
171  * @param HT_AESn: where HT_AESn is the selected AES peripheral.
172  * @param AES_InitStruct: pointer to a AES_InitTypeDef structure.
173  * @retval None
174  ************************************************************************************************************/
AES_CTR_Init(HT_AES_TypeDef * HT_AESn,AES_InitTypeDef * AES_InitStruct)175 void AES_CTR_Init(HT_AES_TypeDef* HT_AESn, AES_InitTypeDef* AES_InitStruct)
176 {
177   AES_InitStruct->AES_Mode = AES_MODE_CTR;
178   _AES_Init(HT_AESn, AES_InitStruct);
179 
180   AES_IntConfig(HT_AESn, AES_IER_OFINTEN, ENABLE);
181   NVIC_EnableIRQ(AES_IRQn);
182 }
183 
184 /*********************************************************************************************************//**
185  * @brief Check whether the specified AES status has been set.
186  * @param HT_AESn: where HT_AESn is the selected AES peripheral.
187  * @param AES_SR_x: specify the flag to be check.
188  *   This parameter can be one of the following values:
189  *     @arg AES_SR_IFEMPTY  : AES Input FIFO is Empty
190  *     @arg AES_SR_IFNFULL  : AES Input FIFO is not Full
191  *     @arg AES_SR_OFNEMPTY : AES Output FIFO is not Empty
192  *     @arg AES_SR_OFFULL   : AES Output FIFO is Full
193  *     @arg AES_SR_BUSY     : AES is busy when AES is in encrypt/decrypt action and key expansion
194  * @retval SET or RESET
195  ************************************************************************************************************/
AES_GetStatus(HT_AES_TypeDef * HT_AESn,u32 AES_SR_x)196 FlagStatus AES_GetStatus(HT_AES_TypeDef* HT_AESn, u32 AES_SR_x)
197 {
198   Assert_Param(IS_AES(HT_AESn));
199   Assert_Param(IS_AES_STATUS(AES_SR_x));
200 
201   if ((HT_AESn->SR & AES_SR_x) != (u32)RESET)
202   {
203     return (SET);
204   }
205   else
206   {
207     return (RESET);
208   }
209 }
210 
211 /*********************************************************************************************************//**
212  * @brief Enable or Disable the AES PDMA interface.
213  * @param HT_AESn: where HT_AESn is the selected HT_AESn peripheral.
214  * @param AES_PDMA_xFDMAEN: specify the AES FIFO DMA to be enabled or disabled.
215  *   This parameter can be any combination of the following values:
216  *     @arg AES_PDMA_IFDMAEN : input FIFO PDMA
217  *     @arg AES_PDMA_OFDMAEN : Output FIFO PDMA
218  * @param  NewState: This parameter can be ENABLE or DISABLE.
219  * @retval None
220  ************************************************************************************************************/
AES_PDMACmd(HT_AES_TypeDef * HT_AESn,u32 AES_PDMA_xFDMAEN,ControlStatus NewState)221 void AES_PDMACmd(HT_AES_TypeDef* HT_AESn, u32 AES_PDMA_xFDMAEN, ControlStatus NewState)
222 {
223   /* Check the parameters                                                                                   */
224   Assert_Param(IS_AES(HT_AESn));
225   Assert_Param(IS_CONTROL_STATUS(NewState));
226 
227   if (NewState != DISABLE)
228   {
229     HT_AESn->PDMAR |= AES_PDMA_xFDMAEN;
230   }
231   else
232   {
233     HT_AESn->PDMAR &= ~AES_PDMA_xFDMAEN;
234   }
235 }
236 
237 /*********************************************************************************************************//**
238  * @brief Check whether the specified AES interrupt has occurred.
239  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals.
240  * @param AES_INTSR_x: Specify the interrupt status to check.
241  *   This parameter can be any combination of the following values:
242  *     @arg AES_INTSR_IFINT :
243  *     @arg AES_INTSR_OFINT :
244  * @return SET or RESET
245  ************************************************************************************************************/
AES_GetIntStatus(HT_AES_TypeDef * HT_AESn,u32 AES_INTSR_x)246 FlagStatus AES_GetIntStatus(HT_AES_TypeDef* HT_AESn, u32 AES_INTSR_x)
247 {
248   FlagStatus Status;
249   u32 aes_isr = HT_AESn->ISR;
250   u32 aes_ier = HT_AESn->IER;
251 
252   /* Check the parameters                                                                                   */
253   Assert_Param(IS_AES(HT_AESn));
254   Assert_Param(IS_AES_INTSR(AES_INTSR_x));
255 
256   Status = (FlagStatus)(aes_isr & aes_ier);
257   if ((Status & AES_INTSR_x) != RESET)
258   {
259     Status = SET;
260   }
261   else
262   {
263     Status = RESET;
264   }
265 
266   return Status;
267 }
268 
269 /*********************************************************************************************************//**
270  * @brief Enable or Disable the specified AES interrupts.
271  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals.
272  * @param AES_IER_x: Specify the AES interrupt sources that is to be enabled or disabled.
273  *   This parameter can be any combination of the following values:
274  *     @arg AES_IER_IFINTEN :
275  *     @arg AES_IER_OFINTEN :
276  * @param NewState: This parameter can be ENABLE or DISABLE.
277  * @retval None
278  ************************************************************************************************************/
AES_IntConfig(HT_AES_TypeDef * HT_AESn,u32 AES_IER_x,ControlStatus NewState)279 void AES_IntConfig(HT_AES_TypeDef* HT_AESn, u32 AES_IER_x, ControlStatus NewState)
280 {
281   /* Check the parameters                                                                                   */
282   Assert_Param(IS_AES(HT_AESn));
283   Assert_Param(IS_AES_IER(AES_IER_x));
284   Assert_Param(IS_CONTROL_STATUS(NewState));
285 
286   if (NewState != DISABLE)
287   {
288     HT_AESn->IER |= AES_IER_x;
289   }
290   else
291   {
292     HT_AESn->IER &= ~AES_IER_x;
293   }
294 }
295 
296 /*********************************************************************************************************//**
297  * @brief Set the specified AES Input data.
298  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals
299  * @param AES_Data: Data input
300  * @retval None
301  ************************************************************************************************************/
AES_SetInputData(HT_AES_TypeDef * HT_AESn,uc32 AES_Data)302 void AES_SetInputData(HT_AES_TypeDef* HT_AESn, uc32 AES_Data)
303 {
304   Assert_Param(IS_AES(HT_AESn));
305   #if (LIBCFG_AES_SWAP)
306   HT_AESn->DINR = __REV(AES_Data);
307   #else
308   HT_AESn->DINR = AES_Data;
309   #endif
310 }
311 
312 /*********************************************************************************************************//**
313  * @brief Get the specified AES output data.
314  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals
315  * @retval Output Data
316  ************************************************************************************************************/
AES_GetOutputData(HT_AES_TypeDef * HT_AESn)317 u32 AES_GetOutputData(HT_AES_TypeDef* HT_AESn)
318 {
319   Assert_Param(IS_AES(HT_AESn));
320   #if (LIBCFG_AES_SWAP)
321   return __REV(HT_AESn->DOUTR);
322   #else
323   return HT_AESn->DOUTR;
324   #endif
325 }
326 
327 /*********************************************************************************************************//**
328  * @brief Set the specified AES key table.
329  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals.
330  * @param Key: Key table
331  * @param keySize: Key table's size
332  * @retval None
333  ************************************************************************************************************/
AES_SetKeyTable(HT_AES_TypeDef * HT_AESn,u32 * Key,u32 keySize)334 void AES_SetKeyTable(HT_AES_TypeDef* HT_AESn, u32 *Key, u32 keySize)
335 {
336   u32 i;
337   u32 uCRTemp = HT_AESn->CR & (~(0x00000060UL));
338   if (keySize == 128/8)
339   {
340     uCRTemp |= AES_KEYSIZE_128B;
341   }
342   #if (LIBCFG_AES_KEYSIZE_256B)
343   else if (keySize == 192/8)
344   {
345     uCRTemp |= AES_KEYSIZE_192B;
346   }
347   else if (keySize == 256/8)
348   {
349     uCRTemp |= AES_KEYSIZE_256B;
350   }
351   #endif
352   else
353   {
354     return;
355   }
356   HT_AESn->CR = uCRTemp;
357 
358   for (i = 0; i < (keySize / 4); i++)
359   {
360     #if (LIBCFG_AES_SWAP)
361     HT_AESn->KEYR[i] = __REV(*&Key[i]);
362     #else
363     HT_AESn->KEYR[i] = *&Key[i];
364     #endif
365   }
366 
367   AES_StartKey(HT_AES);
368 }
369 
370 /*********************************************************************************************************//**
371  * @brief Set the specified AES Vector table.
372  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals.
373  * @param Vector:
374  * @retval None
375  ************************************************************************************************************/
AES_SetVectorTable(HT_AES_TypeDef * HT_AESn,u32 * Vector)376 void AES_SetVectorTable(HT_AES_TypeDef* HT_AESn, u32 *Vector)
377 {
378   int i;
379   Assert_Param(IS_AES(HT_AESn));
380 
381   for (i = 0; i < 4; i++)
382   {
383     #if (LIBCFG_AES_SWAP)
384     HT_AESn->IVR[i] = __REV(*&Vector[i]);
385     #else
386     HT_AESn->IVR[i] = *&Vector[i];
387     #endif
388   }
389 }
390 
391 /*********************************************************************************************************//**
392  * @brief AES Crypt Data
393  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals
394  * @param dir: Crypt Data's direction
395  * @param iv: initial vector table
396  * @param length: data size
397  * @param inputData: InputData
398  * @param outputData: Output Data
399  * @retval SUCCESS or ERROR
400  ************************************************************************************************************/
_AES_CryptData(HT_AES_TypeDef * HT_AESn,AES_DIR_Enum dir,u32 * iv,u32 length,u32 * inputData,u32 * outputData)401 ErrStatus _AES_CryptData(HT_AES_TypeDef* HT_AESn,
402                          AES_DIR_Enum dir,
403                          u32 *iv,
404                          u32 length,
405                          u32 *inputData,
406                          u32 *outputData)
407 {
408   /*AES Data blocks 16 byte                                                                                 */
409   if ((length % 16) != 0)
410   {
411     /* Data size can not be divisible by 16.                                                                */
412     return ERROR;
413   }
414 
415   /*Set inital Vector                                                                                       */
416   if (iv != NULL)
417   {
418     AES_SetVectorTable(HT_AESn, iv);
419   }
420 
421   /*FIFO Flush                                                                                              */
422   AES_FIFOFlush(HT_AES);
423 
424   /*Set direction                                                                                           */
425   HT_AESn->CR = (HT_AESn->CR & 0xFFFFFFFD) | dir;
426 
427   /*Create input/output data                                                                                */
428   gpu32InputBuff = inputData;
429   gpu32OutputBuff = outputData;
430 
431   /*Init Index                                                                                              */
432   gu32OutputIndex = 0;
433   gu32InputSize  = length/4;
434 
435   /*Set input data                                                                                          */
436   AES_IntConfig(HT_AES, AES_IER_IFINTEN, ENABLE);
437 
438   /*Waitting for conversion                                                                                 */
439   while (AES_GetStatus(HT_AES, AES_SR_OFNEMPTY));
440   return SUCCESS;
441 }
442 
443 #if 0
444 /*********************************************************************************************************//**
445  * @brief AES Crypt Data on ECB mode
446  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals
447  * @param dir: Crypt Data's direction
448  * @param length: data size
449  * @param inputData: InputData
450  * @param outputData: Output Data
451  * @retval SUCCESS or ERROR
452  ************************************************************************************************************/
453 ErrStatus AES_ECB_CryptData(HT_AES_TypeDef* HT_AESn,
454                        AES_DIR_Enum dir,
455                        u32 length,
456                        u32 *inputData,
457                        u32 *outputData)
458 {
459   return _AES_CryptData(HT_AESn,
460                         dir,
461                         NULL,
462                         length,
463                         inputData,
464                         outputData);
465 }
466 
467 /*********************************************************************************************************//**
468  * @brief AES Crypt Data on CBC mode
469  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals
470  * @param dir: Crypt Data's direction
471  * @param iv: initial vector table
472  * @param length: data size
473  * @param inputData: InputData
474  * @param outputData: Output Data
475  * @retval SUCCESS or ERROR
476  ************************************************************************************************************/
477 ErrStatus AES_CBC_CryptData(HT_AES_TypeDef* HT_AESn,
478                        AES_DIR_Enum dir,
479                        u32 *iv,
480                        u32 length,
481                        u32 *inputData,
482                        u32 *outputData)
483 {
484   return _AES_CryptData(HT_AESn,
485                         dir,
486                         iv,
487                         length,
488                         inputData,
489                         outputData);
490 }
491 
492 /*********************************************************************************************************//**
493  * @brief AES Crypt Data on CTR mode
494  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals
495  * @param iv: initial vector table
496  * @param length: data size
497  * @param inputData: InputData
498  * @param outputData: Output Data
499  * @retval SUCCESS or ERROR
500  ************************************************************************************************************/
501 ErrStatus AES_CTR_CryptData(HT_AES_TypeDef* HT_AESn,
502                        u32 *iv,
503                        u32 length,
504                        u32 *inputData,
505                        u32 *outputData)
506 {
507   return _AES_CryptData(HT_AESn,
508                         AES_DIR_ENCRYPT,
509                         iv,
510                         length,
511                         inputData,
512                         outputData);
513 }
514 #endif
515 
516 /*********************************************************************************************************//**
517  * @brief This function handles AES Core interrupt.
518  * @param HT_AESn: where HT_AESn is the selected AES from the AES peripherals.
519  * @retval None
520  ************************************************************************************************************/
AESCore_IRQHandler(HT_AES_TypeDef * HT_AESn)521 void AESCore_IRQHandler(HT_AES_TypeDef* HT_AESn)
522 {
523   if (AES_GetIntStatus(HT_AES, AES_INTSR_OFINT))
524   {
525     gpu32OutputBuff[gu32OutputIndex++] = AES_GetOutputData(HT_AES);
526   }
527   if (AES_GetIntStatus(HT_AES, AES_INTSR_IFINT))
528   {
529     if (gu32InputIndex < gu32InputSize)
530     {
531       AES_SetInputData(HT_AES, gpu32InputBuff[gu32InputIndex]);
532       gu32InputIndex++;
533     }
534     else
535     {
536       AES_IntConfig(HT_AES, AES_IER_IFINTEN, DISABLE);
537       gu32InputIndex = 0;
538     }
539   }
540 }
541 /**
542   * @}
543   */
544 
545 
546 /**
547   * @}
548   */
549 
550 /**
551   * @}
552   */
553