1 /*!
2 \file gd32l23x_cau.c
3 \brief CAU driver
4
5 \version 2021-08-04, V1.0.0, firmware for GD32L23x
6 */
7
8 /*
9 Copyright (c) 2021, GigaDevice Semiconductor Inc.
10
11 Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13
14 1. Redistributions of source code must retain the above copyright notice, this
15 list of conditions and the following disclaimer.
16 2. Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19 3. Neither the name of the copyright holder nor the names of its contributors
20 may be used to endorse or promote products derived from this software without
21 specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 OF SUCH DAMAGE.
33 */
34
35 #include "gd32l23x_cau.h"
36 #include "gd32l23x_rcu.h"
37
38 #define FLAG_MASK ((uint32_t)0x00000020U)
39 #define STAT0_AESDES_MASK ((uint32_t)0x00000015U)
40 #define STAT0_TDES_MASK ((uint32_t)0x00000014U)
41
42 /*!
43 \brief reset the CAU peripheral
44 \param[in] none
45 \param[out] none
46 \retval none
47 */
cau_deinit(void)48 void cau_deinit(void)
49 {
50 /* enable CAU reset state */
51 rcu_periph_reset_enable(RCU_CAURST);
52 /* release CAU from reset state */
53 rcu_periph_reset_disable(RCU_CAURST);
54 /* enable PMU clock */
55 rcu_periph_clock_enable(RCU_PMU);
56 /* wakeup CAU power domain */
57 PMU_CTL1 |= PMU_CORE1_WAKE;
58 /* check CAU power domain is active */
59 while(0U == (PMU_STAT & PMU_STAT_CORE1PS_ACTIVE)) {
60 }
61 }
62
63 /*!
64 \brief initialize the CAU encrypt and decrypt parameter struct with the default values
65 \param[in] none
66 \param[out] cau_parameter:
67 alg_dir: algorithm dirctory
68 CAU_ENCRYPT, CAU_DECRYPT
69 key: key
70 key_size: key size in bytes
71 iv: initialization vector
72 iv_size: iv size in bytes
73 input: input data
74 in_length: input data length in bytes
75 aad: additional authentication data
76 aad_size: header size
77 \retval none
78 */
cau_struct_para_init(cau_parameter_struct * cau_parameter)79 void cau_struct_para_init(cau_parameter_struct *cau_parameter)
80 {
81 /* set the CAU encrypt and decrypt parameters struct with the default values */
82 cau_parameter->alg_dir = CAU_ENCRYPT;
83 cau_parameter->key = 0U;
84 cau_parameter->key_size = 0U;
85 cau_parameter->iv = 0U;
86 cau_parameter->iv_size = 0U;
87 cau_parameter->input = 0U;
88 cau_parameter->in_length = 0U;
89 cau_parameter->aad = 0U;
90 cau_parameter->aad_size = 0U;
91 }
92
93 /*!
94 \brief initialize the key parameter structure with the default values
95 \param[in] none
96 \param[out] key_initpara:
97 key_0_high: key 0 high
98 key_0_low: key 0 low
99 key_1_high: key 1 high
100 key_1_low: key 1 low
101 key_2_high: key 2 high
102 key_2_low: key 2 low
103 key_3_high: key 3 high
104 key_3_low: key 3 low
105 \retval none
106 */
cau_key_struct_para_init(cau_key_parameter_struct * key_initpara)107 void cau_key_struct_para_init(cau_key_parameter_struct *key_initpara)
108 {
109 /* set the key parameters struct with the default values */
110 key_initpara->key_0_high = 0U;
111 key_initpara->key_0_low = 0U;
112 key_initpara->key_1_high = 0U;
113 key_initpara->key_1_low = 0U;
114 key_initpara->key_2_high = 0U;
115 key_initpara->key_2_low = 0U;
116 key_initpara->key_3_high = 0U;
117 key_initpara->key_3_low = 0U;
118 }
119
120 /*!
121 \brief initialize the vectors parameter struct with the default values
122 \param[in] none
123 \param[out] iv_initpara:
124 iv_0_high: init vector 0 high
125 iv_0_low: init vector 0 low
126 iv_1_high: init vector 1 high
127 iv_1_low: init vector 1 low
128 \retval none
129 */
cau_iv_struct_para_init(cau_iv_parameter_struct * iv_initpara)130 void cau_iv_struct_para_init(cau_iv_parameter_struct *iv_initpara)
131 {
132 /* set the vectors parameters struct with the default values */
133 iv_initpara->iv_0_high = 0U;
134 iv_initpara->iv_0_low = 0U;
135 iv_initpara->iv_1_high = 0U;
136 iv_initpara->iv_1_low = 0U;
137 }
138
139 /*!
140 \brief initialize the context parameter struct with the default values
141 \param[in] none
142 \param[out] cau_context:
143 ctl_config: current configuration
144 iv_0_high: init vector 0 high
145 iv_0_low: init vector 0 low
146 iv_1_high: init vector 1 high
147 iv_1_low: init vector 1 low
148 key_0_high: key 0 high
149 key_0_low: key 0 low
150 key_1_high: key 1 high
151 key_1_low: key 1 low
152 key_2_high: key 2 high
153 key_2_low: key 2 low
154 key_3_high: key 3 high
155 key_3_low: key 3 low
156 gcmccmctxs[8]: GCM or CCM mode context switch
157 gcmctxs[8]: GCM mode context switch
158 \retval none
159 */
cau_context_struct_para_init(cau_context_parameter_struct * cau_context)160 void cau_context_struct_para_init(cau_context_parameter_struct *cau_context)
161 {
162 cau_context->ctl_config = 0U;
163
164 /* set the vectors parameters with the default values */
165 cau_context->iv_0_high = 0U;
166 cau_context->iv_0_low = 0U;
167 cau_context->iv_1_high = 0U;
168 cau_context->iv_1_low = 0U;
169
170 /* set the key parameters with the default values */
171 cau_context->key_0_high = 0U;
172 cau_context->key_0_low = 0U;
173 cau_context->key_1_high = 0U;
174 cau_context->key_1_low = 0U;
175 cau_context->key_2_high = 0U;
176 cau_context->key_2_low = 0U;
177 cau_context->key_3_high = 0U;
178 cau_context->key_3_low = 0U;
179
180 /* set the context switch with the default values */
181 cau_context->gcmccmctxs[0] = 0U;
182 cau_context->gcmccmctxs[1] = 0U;
183 cau_context->gcmccmctxs[2] = 0U;
184 cau_context->gcmccmctxs[3] = 0U;
185 cau_context->gcmccmctxs[4] = 0U;
186 cau_context->gcmccmctxs[5] = 0U;
187 cau_context->gcmccmctxs[6] = 0U;
188 cau_context->gcmccmctxs[7] = 0U;
189
190 cau_context->gcmctxs[0] = 0U;
191 cau_context->gcmctxs[1] = 0U;
192 cau_context->gcmctxs[2] = 0U;
193 cau_context->gcmctxs[3] = 0U;
194 cau_context->gcmctxs[4] = 0U;
195 cau_context->gcmctxs[5] = 0U;
196 cau_context->gcmctxs[6] = 0U;
197 cau_context->gcmctxs[7] = 0U;
198 }
199
200 /*!
201 \brief enable the CAU peripheral
202 \param[in] none
203 \param[out] none
204 \retval none
205 */
cau_enable(void)206 void cau_enable(void)
207 {
208 /* enable the CAU processor */
209 CAU_CTL |= CAU_CTL_CAUEN;
210 }
211
212 /*!
213 \brief disable the CAU peripheral
214 \param[in] none
215 \param[out] none
216 \retval none
217 */
cau_disable(void)218 void cau_disable(void)
219 {
220 /* disable the CAU processor */
221 CAU_CTL &= ~CAU_CTL_CAUEN;
222 }
223
224 /*!
225 \brief enable the CAU DMA interface
226 \param[in] dma_req: specify the CAU DMA transfer request to be enabled
227 one or more parameters can be selected which are shown as below:
228 \arg CAU_DMA_INFIFO: DMA for incoming(Rx) data transfer
229 \arg CAU_DMA_OUTFIFO: DMA for outgoing(Tx) data transfer
230 \param[out] none
231 \retval none
232 */
cau_dma_enable(uint32_t dma_req)233 void cau_dma_enable(uint32_t dma_req)
234 {
235 /* enable the selected CAU DMA request */
236 CAU_DMAEN |= dma_req;
237 }
238
239 /*!
240 \brief disable the CAU DMA interface
241 \param[in] dma_req: specify the CAU DMA transfer request to be disabled
242 one or more parameters can be selected which are shown as below:
243 \arg CAU_DMA_INFIFO: DMA for incoming(Rx) data transfer
244 \arg CAU_DMA_OUTFIFO: DMA for outgoing(Tx) data transfer
245 \param[out] none
246 \retval none
247 */
cau_dma_disable(uint32_t dma_req)248 void cau_dma_disable(uint32_t dma_req)
249 {
250 /* disable the selected CAU DMA request */
251 CAU_DMAEN &= ~(dma_req);
252 }
253
254 /*!
255 \brief initialize the CAU peripheral
256 \param[in] alg_dir: algorithm direction
257 only one parameter can be selected which is shown as below:
258 \arg CAU_ENCRYPT: encrypt
259 \arg CAU_DECRYPT: decrypt
260 \param[in] algo_mode: algorithm mode selection
261 only one parameter can be selected which is shown as below:
262 \arg CAU_MODE_TDES_ECB: TDES-ECB (3DES Electronic codebook)
263 \arg CAU_MODE_TDES_CBC: TDES-CBC (3DES Cipher block chaining)
264 \arg CAU_MODE_DES_ECB: DES-ECB (simple DES Electronic codebook)
265 \arg CAU_MODE_DES_CBC: DES-CBC (simple DES Cipher block chaining)
266 \arg CAU_MODE_AES_ECB: AES-ECB (AES Electronic codebook)
267 \arg CAU_MODE_AES_CBC: AES-CBC (AES Cipher block chaining)
268 \arg CAU_MODE_AES_CTR: AES-CTR (AES counter mode)
269 \arg CAU_MODE_AES_KEY: AES decryption key preparation mode
270 \arg CAU_MODE_AES_GCM: AES-GCM (AES Galois/counter mode)
271 \arg CAU_MODE_AES_CCM: AES-CCM (AES combined cipher machine mode)
272 \arg CAU_MODE_AES_CFB: AES-CFB (cipher feedback mode)
273 \arg CAU_MODE_AES_OFB: AES-OFB (output feedback mode)
274 \param[in] swapping: data swapping selection
275 only one parameter can be selected which is shown as below:
276 \arg CAU_SWAPPING_32BIT: no swapping
277 \arg CAU_SWAPPING_16BIT: half-word swapping
278 \arg CAU_SWAPPING_8BIT: bytes swapping
279 \arg CAU_SWAPPING_1BIT: bit swapping
280 \param[out] none
281 \retval none
282 */
cau_init(uint32_t alg_dir,uint32_t algo_mode,uint32_t swapping)283 void cau_init(uint32_t alg_dir, uint32_t algo_mode, uint32_t swapping)
284 {
285 /* select algorithm mode */
286 CAU_CTL &= ~CAU_CTL_ALGM;
287 CAU_CTL |= algo_mode;
288
289 /* select data swapping */
290 CAU_CTL &= ~CAU_CTL_DATAM;
291 CAU_CTL |= swapping;
292
293 /* select algorithm direction */
294 CAU_CTL &= ~CAU_CTL_CAUDIR;
295 CAU_CTL |= alg_dir;
296 }
297
298 /*!
299 \brief configure key size if use AES algorithm
300 \param[in] key_size: key length selection when aes mode
301 only one parameter can be selected which is shown as below:
302 \arg CAU_KEYSIZE_128BIT: 128 bit key length
303 \arg CAU_KEYSIZE_192BIT: 192 bit key length
304 \arg CAU_KEYSIZE_256BIT: 256 bit key length
305 \param[out] none
306 \retval none
307 */
cau_aes_keysize_config(uint32_t key_size)308 void cau_aes_keysize_config(uint32_t key_size)
309 {
310 CAU_CTL &= ~CAU_CTL_KEYM;
311 CAU_CTL |= key_size;
312 }
313
314 /*!
315 \brief initialize the key parameters
316 \param[in] key_initpara: key init parameter struct
317 key_0_high: key 0 high
318 key_0_low: key 0 low
319 key_1_high: key 1 high
320 key_1_low: key 1 low
321 key_2_high: key 2 high
322 key_2_low: key 2 low
323 key_3_high: key 3 high
324 key_3_low: key 3 low
325 \param[out] none
326 \retval none
327 */
cau_key_init(cau_key_parameter_struct * key_initpara)328 void cau_key_init(cau_key_parameter_struct *key_initpara)
329 {
330 CAU_KEY0H = key_initpara->key_0_high;
331 CAU_KEY0L = key_initpara->key_0_low;
332 CAU_KEY1H = key_initpara->key_1_high;
333 CAU_KEY1L = key_initpara->key_1_low;
334 CAU_KEY2H = key_initpara->key_2_high;
335 CAU_KEY2L = key_initpara->key_2_low;
336 CAU_KEY3H = key_initpara->key_3_high;
337 CAU_KEY3L = key_initpara->key_3_low;
338 }
339
340 /*!
341 \brief initialize the vectors parameters
342 \param[in] iv_initpara: vectors init parameter struct
343 iv_0_high: init vector 0 high
344 iv_0_low: init vector 0 low
345 iv_1_high: init vector 1 high
346 iv_1_low: init vector 1 low
347 \param[out] none
348 \retval none
349 */
cau_iv_init(cau_iv_parameter_struct * iv_initpara)350 void cau_iv_init(cau_iv_parameter_struct *iv_initpara)
351 {
352 CAU_IV0H = iv_initpara->iv_0_high;
353 CAU_IV0L = iv_initpara->iv_0_low;
354 CAU_IV1H = iv_initpara->iv_1_high;
355 CAU_IV1L = iv_initpara->iv_1_low;
356 }
357
358 /*!
359 \brief configure phase
360 \param[in] phase: gcm or ccm phase
361 only one parameter can be selected which is shown as below:
362 \arg CAU_PREPARE_PHASE: prepare phase
363 \arg CAU_AAD_PHASE: AAD phase
364 \arg CAU_ENCRYPT_DECRYPT_PHASE: encryption/decryption phase
365 \arg CAU_TAG_PHASE: tag phase
366 \param[out] none
367 \retval none
368 */
cau_phase_config(uint32_t phase)369 void cau_phase_config(uint32_t phase)
370 {
371 uint32_t temp;
372 /* Get the CTL register */
373 temp = CAU_CTL;
374 /* Reset the phase configuration bits */
375 temp &= ~CAU_CTL_GCM_CCMPH;
376 /* Set the selected phase */
377 temp |= phase;
378 /* Set the CTL register */
379 CAU_CTL = temp;
380 }
381
382 /*!
383 \brief flush the IN and OUT FIFOs
384 \param[in] none
385 \param[out] none
386 \retval none
387 */
cau_fifo_flush(void)388 void cau_fifo_flush(void)
389 {
390 /* reset the read and write pointers of the FIFOs */
391 CAU_CTL |= CAU_CTL_FFLUSH;
392 }
393
394 /*!
395 \brief return whether CAU peripheral is enabled or disabled
396 \param[in] none
397 \param[out] none
398 \retval ControlStatus: ENABLE or DISABLE
399 */
cau_enable_state_get(void)400 ControlStatus cau_enable_state_get(void)
401 {
402 ControlStatus ret = DISABLE;
403 if(RESET != (CAU_CTL & CAU_CTL_CAUEN)) {
404 ret = ENABLE;
405 }
406 return ret;
407 }
408
409 /*!
410 \brief write data to the IN FIFO
411 \param[in] data: data to write (0 - 0xFFFFFFFF)
412 \param[out] none
413 \retval none
414 */
cau_data_write(uint32_t data)415 void cau_data_write(uint32_t data)
416 {
417 CAU_DI = data;
418 }
419
420 /*!
421 \brief return the last data entered into the output FIFO
422 \param[in] none
423 \param[out] none
424 \retval last data entered into the output FIFO
425 */
cau_data_read(void)426 uint32_t cau_data_read(void)
427 {
428 return CAU_DO;
429 }
430
431 /*!
432 \brief save context before context switching
433 \param[in] key_initpara: key init parameter struct
434 key_0_high: key 0 high
435 key_0_low: key 0 low
436 key_1_high: key 1 high
437 key_1_low: key 1 low
438 key_2_high: key 2 high
439 key_2_low: key 2 low
440 key_3_high: key 3 high
441 key_3_low: key 3 low
442 \param[out] cau_context:
443 ctl_config: current configuration
444 iv_0_high: init vector 0 high
445 iv_0_low: init vector 0 low
446 iv_1_high: init vector 1 high
447 iv_1_low: init vector 1 low
448 key_0_high: key 0 high
449 key_0_low: key 0 low
450 key_1_high: key 1 high
451 key_1_low: key 1 low
452 key_2_high: key 2 high
453 key_2_low: key 2 low
454 key_3_high: key 3 high
455 key_3_low: key 3 low
456 gcmccmctxs[8]: GCM or CCM mode context switch
457 gcmctxs[8]: GCM mode context switch
458 \retval none
459 */
cau_context_save(cau_context_parameter_struct * cau_context,cau_key_parameter_struct * key_initpara)460 void cau_context_save(cau_context_parameter_struct *cau_context, cau_key_parameter_struct *key_initpara)
461 {
462 uint32_t checkmask = 0U;
463 uint32_t checkbits = 0U;
464 uint32_t algm_reg = 0U;
465
466 /* stop DMA transfers on the IN FIFO by clearing the DMAIEN bit in the CAU_DMAEN */
467 CAU_DMAEN &= ~CAU_DMA_INFIFO;
468
469 algm_reg = CAU_CTL & CAU_CTL_ALGM;
470 /* AES or DES */
471 if((uint32_t)0 != (algm_reg & (~CAU_MODE_TDES_CBC))) {
472 /* wait until both the IN and OUT FIFOs are empty (IEM=1 and ONE=0 in the CAU_STAT0 register) and BUSY=0 */
473 checkbits = CAU_STAT0_IEM;
474 checkmask = STAT0_AESDES_MASK;
475 /* TDES */
476 } else {
477 /* wait until OUT FIFO is empty (ONE=0 in the CAU_STAT0 register) and BUSY=0 */
478 checkbits = 0U;
479 checkmask = STAT0_TDES_MASK;
480 }
481
482 while((CAU_STAT0 & checkmask) != checkbits) {
483 }
484
485 /* stop DMA transfers on the OUT FIFO by clear CAU_DMAEN_DMAOEN=0 */
486 CAU_DMAEN &= ~CAU_DMAEN_DMAOEN;
487 /* disable CAU */
488 CAU_CTL &= ~CAU_CTL_CAUEN;
489
490 /* save the current configuration (bit 19, bit[17:16] and bit[9:2] in the CAU_CTL register) */
491 cau_context->ctl_config = CAU_CTL & (CAU_CTL_GCM_CCMPH |
492 CAU_CTL_KEYM |
493 CAU_CTL_DATAM |
494 CAU_CTL_ALGM |
495 CAU_CTL_CAUDIR |
496 CAU_CTL_NBPILB);
497
498 /* save the key value */
499 cau_context->key_0_high = key_initpara->key_0_high;
500 cau_context->key_0_low = key_initpara->key_0_low;
501 cau_context->key_1_high = key_initpara->key_1_high;
502 cau_context->key_1_low = key_initpara->key_1_low;
503 cau_context->key_2_high = key_initpara->key_2_high;
504 cau_context->key_2_low = key_initpara->key_2_low;
505 cau_context->key_3_high = key_initpara->key_3_high;
506 cau_context->key_3_low = key_initpara->key_3_low;
507
508 if((CAU_MODE_TDES_ECB != algm_reg) && (CAU_MODE_DES_ECB != algm_reg) && (CAU_MODE_AES_ECB != algm_reg)) {
509 /* if not in ECB mode, save the initialization vectors */
510 cau_context->iv_0_high = CAU_IV0H;
511 cau_context->iv_0_low = CAU_IV0L;
512 cau_context->iv_1_high = CAU_IV1H;
513 cau_context->iv_1_low = CAU_IV1L;
514 }
515
516 /* if in GCM/CCM mode, save the context switch registers */
517 if((CAU_MODE_AES_GCM == algm_reg) || (CAU_MODE_AES_CCM == algm_reg)) {
518 cau_context->gcmccmctxs[0U] = CAU_GCMCCMCTXSx(0U);
519 cau_context->gcmccmctxs[1U] = CAU_GCMCCMCTXSx(1U);
520 cau_context->gcmccmctxs[2U] = CAU_GCMCCMCTXSx(2U);
521 cau_context->gcmccmctxs[3U] = CAU_GCMCCMCTXSx(3U);
522 cau_context->gcmccmctxs[4U] = CAU_GCMCCMCTXSx(4U);
523 cau_context->gcmccmctxs[5U] = CAU_GCMCCMCTXSx(5U);
524 cau_context->gcmccmctxs[6U] = CAU_GCMCCMCTXSx(6U);
525 cau_context->gcmccmctxs[7U] = CAU_GCMCCMCTXSx(7U);
526 }
527
528 /* if in GCM mode, save the context switch registers */
529 if(CAU_MODE_AES_GCM == algm_reg) {
530 cau_context->gcmctxs[0U] = CAU_GCMCTXSx(0U);
531 cau_context->gcmctxs[1U] = CAU_GCMCTXSx(1U);
532 cau_context->gcmctxs[2U] = CAU_GCMCTXSx(2U);
533 cau_context->gcmctxs[3U] = CAU_GCMCTXSx(3U);
534 cau_context->gcmctxs[4U] = CAU_GCMCTXSx(4U);
535 cau_context->gcmctxs[5U] = CAU_GCMCTXSx(5U);
536 cau_context->gcmctxs[6U] = CAU_GCMCTXSx(6U);
537 cau_context->gcmctxs[7U] = CAU_GCMCTXSx(7U);
538 }
539 }
540
541 /*!
542 \brief restore context after context switching
543 \param[in] cau_context:
544 ctl_config: current configuration
545 iv_0_high: init vector 0 high
546 iv_0_low: init vector 0 low
547 iv_1_high: init vector 1 high
548 iv_1_low: init vector 1 low
549 key_0_high: key 0 high
550 key_0_low: key 0 low
551 key_1_high: key 1 high
552 key_1_low: key 1 low
553 key_2_high: key 2 high
554 key_2_low: key 2 low
555 key_3_high: key 3 high
556 key_3_low: key 3 low
557 gcmccmctxs[8]: GCM or CCM mode context switch
558 gcmctxs[8]: GCM mode context switch
559 \param[out] none
560 \retval none
561 */
cau_context_restore(cau_context_parameter_struct * cau_context)562 void cau_context_restore(cau_context_parameter_struct *cau_context)
563 {
564 uint32_t algm_reg, aes_decrypt;
565
566 /* configure the processor with the saved configuration */
567 CAU_CTL = cau_context->ctl_config;
568
569 algm_reg = CAU_CTL & CAU_CTL_ALGM;
570
571 /* restore the key value */
572 CAU_KEY0H = cau_context->key_0_high;
573 CAU_KEY0L = cau_context->key_0_low;
574 CAU_KEY1H = cau_context->key_1_high;
575 CAU_KEY1L = cau_context->key_1_low;
576 CAU_KEY2H = cau_context->key_2_high;
577 CAU_KEY2L = cau_context->key_2_low;
578 CAU_KEY3H = cau_context->key_3_high;
579 CAU_KEY3L = cau_context->key_3_low;
580
581 if((CAU_MODE_TDES_ECB != algm_reg) && (CAU_MODE_DES_ECB != algm_reg) && (CAU_MODE_AES_ECB != algm_reg)) {
582 /* restore the initialization vectors */
583 CAU_IV0H = cau_context->iv_0_high;
584 CAU_IV0L = cau_context->iv_0_low;
585 CAU_IV1H = cau_context->iv_1_high;
586 CAU_IV1L = cau_context->iv_1_low;
587 }
588
589 /* if in GCM/CCM mode, restore the context switch registers */
590 if((CAU_MODE_AES_GCM == algm_reg) || (CAU_MODE_AES_CCM == algm_reg)) {
591 CAU_GCMCCMCTXSx(0U) = cau_context->gcmccmctxs[0U];
592 CAU_GCMCCMCTXSx(1U) = cau_context->gcmccmctxs[1U];
593 CAU_GCMCCMCTXSx(2U) = cau_context->gcmccmctxs[2U];
594 CAU_GCMCCMCTXSx(3U) = cau_context->gcmccmctxs[3U];
595 CAU_GCMCCMCTXSx(4U) = cau_context->gcmccmctxs[4U];
596 CAU_GCMCCMCTXSx(5U) = cau_context->gcmccmctxs[5U];
597 CAU_GCMCCMCTXSx(6U) = cau_context->gcmccmctxs[6U];
598 CAU_GCMCCMCTXSx(7U) = cau_context->gcmccmctxs[7U];
599 }
600
601 /* if in GCM mode, restore the context switch registers */
602 if(CAU_MODE_AES_GCM == algm_reg) {
603 CAU_GCMCTXSx(0U) = cau_context->gcmctxs[0U];
604 CAU_GCMCTXSx(1U) = cau_context->gcmctxs[1U];
605 CAU_GCMCTXSx(2U) = cau_context->gcmctxs[2U];
606 CAU_GCMCTXSx(3U) = cau_context->gcmctxs[3U];
607 CAU_GCMCTXSx(4U) = cau_context->gcmctxs[4U];
608 CAU_GCMCTXSx(5U) = cau_context->gcmctxs[5U];
609 CAU_GCMCTXSx(6U) = cau_context->gcmctxs[6U];
610 CAU_GCMCTXSx(7U) = cau_context->gcmctxs[7U];
611 }
612
613 /* if it is AES ECB/CBC decryption, then first prepare key */
614 aes_decrypt = CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR);
615 if(((CAU_MODE_AES_ECB | CAU_DECRYPT) == aes_decrypt) || ((CAU_MODE_AES_CBC | CAU_DECRYPT) == aes_decrypt)) {
616 uint32_t alg_dir, algo_mode, swapping;
617
618 /* flush IN/OUT FIFOs */
619 cau_fifo_flush();
620 /* parameters for key preparation for AES decryption */
621 alg_dir = CAU_DECRYPT;
622 algo_mode = CAU_MODE_AES_KEY;
623 swapping = CAU_SWAPPING_32BIT;
624 cau_init(alg_dir, algo_mode, swapping);
625
626 /* enable CAU */
627 cau_enable();
628
629 /* wait until BUSY=0 */
630 while((uint32_t)0U != cau_flag_get(CAU_FLAG_BUSY)) {
631 }
632
633 /* parameters for decryption */
634 CAU_CTL = cau_context->ctl_config;
635 }
636
637 /* enable CAU */
638 cau_enable();
639 }
640
641 /*!
642 \brief enable the CAU interrupts
643 \param[in] interrupt: specify the CAU interrupt source to be enabled
644 one or more parameters can be selected which are shown as below:
645 \arg CAU_INT_INFIFO: input FIFO interrupt
646 \arg CAU_INT_OUTFIFO: output FIFO interrupt
647 \param[out] none
648 \retval none
649 */
cau_interrupt_enable(uint32_t interrupt)650 void cau_interrupt_enable(uint32_t interrupt)
651 {
652 /* enable the selected CAU interrupt */
653 CAU_INTEN |= interrupt;
654 }
655
656 /*!
657 \brief disable the CAU interrupts
658 \param[in] interrupt: specify the CAU interrupt source to be disabled
659 one or more parameters can be selected which are shown as below:
660 \arg CAU_INT_INFIFO: input FIFO interrupt
661 \arg CAU_INT_OUTFIFO: output FIFO interrupt
662 \param[out] none
663 \retval none
664 */
cau_interrupt_disable(uint32_t interrupt)665 void cau_interrupt_disable(uint32_t interrupt)
666 {
667 /* disable the selected CAU interrupt */
668 CAU_INTEN &= ~(interrupt);
669 }
670
671 /*!
672 \brief get the interrupt flag
673 \param[in] interrupt: CAU interrupt flag
674 only one parameter can be selected which is shown as below:
675 \arg CAU_INT_FLAG_INFIFO: input FIFO interrupt
676 \arg CAU_INT_FLAG_OUTFIFO: output FIFO interrupt
677 \param[out] none
678 \retval FlagStatus: SET or RESET
679 */
cau_interrupt_flag_get(uint32_t interrupt)680 FlagStatus cau_interrupt_flag_get(uint32_t interrupt)
681 {
682 FlagStatus flag = RESET;
683
684 /* check the status of the specified CAU interrupt */
685 if(RESET != (CAU_INTF & interrupt)) {
686 flag = SET;
687 }
688
689 return flag;
690 }
691
692 /*!
693 \brief get the CAU flag status
694 \param[in] flag: CAU flag status
695 only one parameter can be selected which is shown as below:
696 \arg CAU_FLAG_INFIFO_EMPTY: input FIFO empty
697 \arg CAU_FLAG_INFIFO_NO_FULL: input FIFO is not full
698 \arg CAU_FLAG_OUTFIFO_NO_EMPTY: output FIFO not empty
699 \arg CAU_FLAG_OUTFIFO_FULL: output FIFO is full
700 \arg CAU_FLAG_BUSY: the CAU core is busy
701 \arg CAU_FLAG_INFIFO: input FIFO flag status
702 \arg CAU_FLAG_OUTFIFO: output FIFO flag status
703 \param[out] none
704 \retval FlagStatus: SET or RESET
705 */
cau_flag_get(uint32_t flag)706 FlagStatus cau_flag_get(uint32_t flag)
707 {
708 uint32_t reg = 0U;
709 FlagStatus ret_flag = RESET;
710
711 /* check if the flag is in CAU_STAT1 register */
712 if(RESET != (flag & FLAG_MASK)) {
713 reg = CAU_STAT1;
714 } else {
715 /* the flag is in CAU_STAT0 register */
716 reg = CAU_STAT0;
717 }
718
719 /* check the status of the specified CAU flag */
720 if(RESET != (reg & flag)) {
721 ret_flag = SET;
722 }
723
724 return ret_flag;
725 }
726