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