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