1 /*!
2  * @file        apm32f4xx_cryp.c
3  *
4  * @brief       This file provides all the CRYP firmware functions
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-06-23
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be usefull and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 #include "apm32f4xx_cryp.h"
27 #include "apm32f4xx_rcm.h"
28 
29 /** @addtogroup APM32F4xx_StdPeriphDriver
30   @{
31 */
32 
33 /** @defgroup CRYP_Driver
34   * @brief CRYP driver modules
35   @{
36 */
37 
38 /** @defgroup CRYP_Functions
39   @{
40 */
41 
42 /*!
43  * @brief     Reset CRYP
44  *
45  * @param     None
46  *
47  * @retval    None
48  */
CRYP_Reset(void)49 void CRYP_Reset(void)
50 {
51     RCM_EnableAHB2PeriphReset(RCM_AHB2_PERIPH_CRYP);
52     RCM_DisableAHB2PeriphReset(RCM_AHB2_PERIPH_CRYP);
53 }
54 
55 /*!
56  * @brief     Configure CRYP
57  *
58  * @param     crypConfig: pointer to a CRYP_Config_T structure
59  *
60  * @retval    None
61  */
CRYP_Config(CRYP_Config_T * crypConfig)62 void CRYP_Config(CRYP_Config_T *crypConfig)
63 {
64     CRYP->CTRL_B.ALGODIRSEL = crypConfig->algoDir;
65     CRYP->CTRL_B.ALGOMSEL   = crypConfig->algoMode;
66     CRYP->CTRL_B.DTSEL      = crypConfig->dataType;
67 
68     /* select Key size (only AES algorithm)*/
69     if (crypConfig->algoMode >= CRYP_ALGOMODE_AES_ECB)
70     {
71         CRYP->CTRL_B.KSIZESEL = crypConfig->keySize;
72     }
73 }
74 
75 /*!
76  * @brief     Default the CRYP_ConfigStructInit member value.
77  *
78  * @param     crcyConfig: pointer to a CRYP_Config_T structure
79  *
80  * @retval    None
81  */
CRYP_ConfigStructInit(CRYP_Config_T * crypConfig)82 void CRYP_ConfigStructInit(CRYP_Config_T *crypConfig)
83 {
84     crypConfig->algoDir  = CRYP_ALGODIR_ENCRYPT;
85     crypConfig->algoMode = CRYP_ALGOMODE_TDES_ECB;
86     crypConfig->dataType = CRYP_DATATYPE_32B;
87     crypConfig->keySize  = CRYP_KEYSIZE_128B;
88 }
89 
90 /*!
91  * @brief     Configure CRYP Keys
92  *
93  * @param     keyConfig: pointer to a CRYP_KeyConfig_T structure.
94  *
95  * @retval    None
96  */
CRYP_ConfigKey(CRYP_KeyConfig_T * keyConfig)97 void CRYP_ConfigKey(CRYP_KeyConfig_T *keyConfig)
98 {
99     /* Key Initialisation */
100     CRYP->K0L = keyConfig->key0Left;
101     CRYP->K0R = keyConfig->key0Right;
102     CRYP->K1L = keyConfig->key1Left;
103     CRYP->K1R = keyConfig->key1Right;
104     CRYP->K2L = keyConfig->key2Left;
105     CRYP->K2R = keyConfig->key2Right;
106     CRYP->K3L = keyConfig->key3Left;
107     CRYP->K3R = keyConfig->key3Right;
108 }
109 
110 /*!
111  * @brief     Default the CRYP_KeyConfigStructInit member value.
112  *
113  * @param     keyConfig: pointer to a CRYP_KeyConfig_T structure.
114  *
115  * @retval    None
116  */
CRYP_ConfigKeyStructInit(CRYP_KeyConfig_T * keyConfig)117 void CRYP_ConfigKeyStructInit(CRYP_KeyConfig_T *keyConfig)
118 {
119     keyConfig->key0Left  = 0;
120     keyConfig->key0Right = 0;
121     keyConfig->key1Left  = 0;
122     keyConfig->key1Right = 0;
123     keyConfig->key2Left  = 0;
124     keyConfig->key2Right = 0;
125     keyConfig->key3Left  = 0;
126     keyConfig->key3Right = 0;
127 }
128 
129 /*!
130  * @brief     Configure CRYP Initialization Vectors(IV)
131  *
132  * @param     IVConfig: pointer to a CRYP_IVConfig_T structure.
133  *
134  * @retval    None
135  */
CRYP_ConfigIV(CRYP_IVConfig_T * IVConfig)136 void CRYP_ConfigIV(CRYP_IVConfig_T *IVConfig)
137 {
138     CRYP->IV0L = IVConfig->IV0Left;
139     CRYP->IV0R = IVConfig->IV0Right;
140     CRYP->IV1L = IVConfig->IV1Left;
141     CRYP->IV1R = IVConfig->IV1Right;
142 }
143 
144 /*!
145  * @brief     Default the CRYP_ConfigIVStructInit member value.
146  *
147  * @param     keyConfig: pointer to a CRYP_IVConfig_T structure.
148  *
149  * @retval    None
150  */
CRYP_ConfigIVStructInit(CRYP_IVConfig_T * IVConfig)151 void CRYP_ConfigIVStructInit(CRYP_IVConfig_T *IVConfig)
152 {
153     IVConfig->IV0Left  = 0;
154     IVConfig->IV0Right = 0;
155     IVConfig->IV1Left  = 0;
156     IVConfig->IV1Right = 0;
157 }
158 
159 /*!
160  * @brief     Flushes the IN and OUT FIFOs
161  *
162  * @param     None
163  *
164  * @retval    None
165  *
166  * @note      The FIFOs must be flushed only when BUSY flag is reset.
167  */
CRYP_FlushFIFO(void)168 void CRYP_FlushFIFO(void)
169 {
170     CRYP->CTRL_B.FFLUSH = SET;
171 }
172 
173 /*!
174  * @brief     Enables the CRYP peripheral.
175  *
176  * @param     None
177  *
178  * @retval    None
179  */
CRYP_Enable(void)180 void CRYP_Enable(void)
181 {
182     CRYP->CTRL_B.CRYPEN = SET;
183 }
184 /*!
185  * @brief     Disable the CRYP peripheral.
186  *
187  * @param     None
188  *
189  * @retval    None
190  */
CRYP_Disable(void)191 void CRYP_Disable(void)
192 {
193     CRYP->CTRL_B.CRYPEN = RESET;
194 }
195 
196 /*!
197  * @brief     Writes data in the Data Input register.
198  *
199  * @param     Data: data to write in Data Input register
200  *
201  * @retval    None
202  *
203  * @note      After the DATAIN register has been read once or several times,
204  *            the FIFO must be flushed (using CRYP_FlushFIFO()).
205  */
CRYP_InData(uint32_t Data)206 void CRYP_InData(uint32_t Data)
207 {
208     CRYP->DATAIN = Data;
209 }
210 
211 /*!
212  * @brief     Returns the last data into the output FIFO.
213  *
214  * @param     None
215  *
216  * @retval    Last data into the output FIFO.
217  */
CRYP_OutData(void)218 uint32_t CRYP_OutData(void)
219 {
220     return CRYP->DATAOUT;
221 }
222 
223 /*!
224  * @brief     Saves the CRYP peripheral Context.
225  *
226  * @param     context: pointer to a CRYP_Context_T structure.
227  *
228  * @param     keyConfig: pointer to a CRYP_IVConfig_T structure.
229  *
230  * @retval    None
231  *
232  * @note      This function stops DMA transfer before to save the context. After
233  *            restoring the context, you have to enable the DMA again (if the DMA
234  *            was previously used).
235  */
CRYP_SaveContext(CRYP_Context_T * context,CRYP_KeyConfig_T * keyConfig)236 uint32_t CRYP_SaveContext(CRYP_Context_T *context, CRYP_KeyConfig_T *keyConfig)
237 {
238     uint32_t flag = 0;
239     uint32_t bitstatus = 0;
240     uint32_t timeout = 0;
241     uint32_t status = 0;
242 
243     /* Stop DMA transfers on the IN FIFO */
244     CRYP->DMACTRL_B.INEN = RESET;
245 
246     if (CRYP->CTRL_B.ALGOMSEL <= 0x01)
247     {
248         flag =  CRYP_FLAG_IFEMPT | CRYP_FLAG_BUSY ;
249     }
250     else /* AES or DES */
251     {
252         flag =  CRYP_FLAG_IFEMPT | CRYP_FLAG_BUSY | CRYP_FLAG_OFEMPT;
253     }
254 
255     do
256     {
257         bitstatus = CRYP->STS & flag;
258         timeout++;
259     }
260     while ((timeout != 0xFFFF) && (bitstatus != CRYP_FLAG_IFEMPT));
261 
262     if ((CRYP->STS & flag) != CRYP_FLAG_IFEMPT)
263     {
264         status = ERROR;
265     }
266     else
267     {
268         /* Stop DMA transfers on the OUT FIFO  */
269         CRYP->DMACTRL_B.OUTEN = BIT_RESET;
270         CRYP->CTRL_B.CRYPEN = BIT_RESET;
271 
272         /* Save the current configuration (bits [9:2] in the CRYP_CTRL register) */
273         context->curCTRL  = CRYP->CTRL & 0xFC;
274 
275         /* Save the initialization vectors */
276         context->IV0L = CRYP->IV0L;
277         context->IV0R = CRYP->IV0R;
278         context->IV1L = CRYP->IV1L;
279         context->IV1R = CRYP->IV1R;
280 
281         /* Save the key value */
282         context->K0L = keyConfig->key0Left;
283         context->K0R = keyConfig->key0Right;
284         context->K1L = keyConfig->key1Left;
285         context->K1R = keyConfig->key1Right;
286         context->K2L = keyConfig->key2Left;
287         context->K2R = keyConfig->key2Right;
288         context->K3L = keyConfig->key3Left;
289         context->K3R = keyConfig->key3Right;
290 
291         status = SUCCESS;
292     }
293 
294     return status;
295 }
296 
297 /*!
298  * @brief     Restores the CRYP peripheral Context.
299  *
300  * @param     context: pointer to a CRYP_Context_T structure
301  *
302  * @retval    None
303  *
304  * @note      Since the DMA transfer is stopped in CRYP_SaveContext() function,
305  *            after restoring the context, you have to enable the DMA again (if the
306  *            DMA was previously used).
307  */
CRYP_RestoreContext(CRYP_Context_T * context)308 void CRYP_RestoreContext(CRYP_Context_T *context)
309 {
310     /* Restore The CTRL value */
311     CRYP->CTRL = context->curCTRL;
312 
313     /* Restore The key value */
314     CRYP->K0L = context->K0L;
315     CRYP->K0R = context->K0R;
316     CRYP->K1L = context->K1L;
317     CRYP->K1R = context->K1R;
318     CRYP->K2L = context->K2L;
319     CRYP->K2R = context->K2R;
320     CRYP->K3L = context->K3L;
321     CRYP->K3R = context->K3R;
322 
323     /* Restore the IV */
324     CRYP->IV0L = context->IV0L;
325     CRYP->IV0R = context->IV0R;
326     CRYP->IV1L = context->IV1L;
327     CRYP->IV1R = context->IV1R;
328 
329     /* Enable the cryptographic processor */
330     CRYP->CTRL_B.CRYPEN = BIT_SET;
331 }
332 /*!
333  * @brief     Enable the CRYP DMA.
334  *
335  * @param     dmaReq: CRYP DMA transfer request
336  *              This parameter can be one of the following values:
337  *              @arg CRYP_DMAREQ_DATAIN     : DMA Input Enable
338  *              @arg CRYP_DMAREQ_DATAOUT    : DMA Output Enable
339  *
340  * @retval    None
341  */
CRYP_EnableDMA(CRYP_DMAREQ_T dmaReq)342 void CRYP_EnableDMA(CRYP_DMAREQ_T dmaReq)
343 {
344     if (dmaReq == CRYP_DMAREQ_DATAIN)
345     {
346         CRYP->DMACTRL_B.INEN = SET;
347     }
348     else if (dmaReq == CRYP_DMAREQ_DATAOUT)
349     {
350         CRYP->DMACTRL_B.OUTEN = SET;
351     }
352 }
353 
354 /*!
355  * @brief     Disable  the CRYP DMA.
356  *
357  * @param     dmaReq: CRYP DMA transfer request
358  *              This parameter can be one of the following values:
359  *              @arg CRYP_DMAREQ_DATAIN     : DMA Input Enable
360  *              @arg CRYP_DMAREQ_DATAOUT    : DMA Output Enable
361  *
362  * @retval    None
363  */
CRYP_DisableDMA(CRYP_DMAREQ_T dmaReq)364 void CRYP_DisableDMA(CRYP_DMAREQ_T dmaReq)
365 {
366     if (dmaReq == CRYP_DMAREQ_DATAIN)
367     {
368         CRYP->DMACTRL_B.INEN = RESET;
369     }
370     else if (dmaReq == CRYP_DMAREQ_DATAOUT)
371     {
372         CRYP->DMACTRL_B.OUTEN = RESET;
373     }
374 }
375 
376 /*!
377  * @brief     Enable the CRYP Interrupt.
378  *
379  * @param     interrupt: specifies the CRYP interrupt sources
380  *            This parameter can be any combination of the following values:
381  *              @arg CRYP_INT_IN:  Input FIFO interrupt
382  *              @arg CRYP_INT_OUT: Output FIFO interrupt
383  *
384  * @retval    None
385  */
CRYP_EnableInterrupt(uint8_t interrupt)386 void CRYP_EnableInterrupt(uint8_t interrupt)
387 {
388     CRYP->INTMASK |= interrupt;
389 }
390 
391 /*!
392  * @brief     Disable the CRYP Interrupt.
393  *
394  * @param     interrupt: specifies the CRYP interrupt sources
395  *            This parameter can be any combination of the following values:
396  *              @arg CRYP_INT_IN:  Input FIFO interrupt
397  *              @arg CRYP_INT_OUT: Output FIFO interrupt
398  *
399  * @retval    None
400  */
CRYP_DisableInterrupt(uint8_t interrupt)401 void CRYP_DisableInterrupt(uint8_t interrupt)
402 {
403     CRYP->INTMASK &= ~interrupt;
404 }
405 
406 /*!
407  * @brief     Read the CRYP Interrupt flag.
408  *
409  * @param     flag: specifies the CRYP flag
410  *            This parameter can be one of the following values:
411  *              @arg CRYP_INT_IN:  Input FIFO interrupt
412  *              @arg CRYP_INT_OUT: Output FIFO interrupt
413  *
414  * @retval    SET or RESET
415  */
416 
CRYP_ReadIntFlag(CRYP_INT_T flag)417 uint8_t CRYP_ReadIntFlag(CRYP_INT_T flag)
418 {
419     return (CRYP->INTMASK & flag) ? SET : RESET;
420 }
421 
422 /*!
423  * @brief     Reads the CRYP flag.
424  *
425  * @param     flag: specifies the flag to check.
426  *            This parameter can be one of the following values:
427  *              @arg CRYP_FLAG_IFEMPT:  Input FIFO Empty flag.
428  *              @arg CRYP_FLAG_IFFULL:  Input FIFO Not Full flag.
429  *              @arg CRYP_FLAG_OFEMPT:  Output FIFO Not Empty flag
430  *              @arg CRYP_FLAG_OFFULL:  Output FIFO Full flag.
431  *              @arg CRYP_FLAG_BUSY:    Busy flag.
432  *              @arg CRYP_FLAG_INISTS:  Input FIFO raw interrupt flag.
433  *              @arg CRYP_FLAG_OUTISTS: Output FIFO raw interrupt flag.
434  *
435  * @retval    SET or RESET.
436  */
CRYP_ReadStatusFlag(CRYP_FLAG_T flag)437 uint8_t CRYP_ReadStatusFlag(CRYP_FLAG_T flag)
438 {
439     if (flag & 0x20)
440     {
441         return (CRYP->INTSTS & flag) ? SET : RESET;
442     }
443     else
444     {
445         return (CRYP->STS & flag) ? SET : RESET;
446     }
447 }
448 
449 /*!
450  * @brief     Returns the CRYP peripheral Cmd
451  *
452  * @param     None
453  *
454  * @retval    ENABLE or DISABLE
455  */
CRYP_ReadCmdStatus(void)456 uint8_t CRYP_ReadCmdStatus(void)
457 {
458     return (CRYP->CTRL_B.CRYPEN);
459 }
460 
461 /**@} end of group CRYP_Functions */
462 /**@} end of group CRYP_Driver */
463 /**@} end of group APM32F4xx_StdPeriphDriver */
464