1 /*!
2  * @file        apm32f4xx_cryp_aes.c
3  *
4  * @brief       This file provides high level functions to encrypt and decrypt,
5  *              Input message using AES in ECB/CBC/CTR modes.
6  *
7  * @version     V1.0.2
8  *
9  * @date        2022-06-23
10  *
11  * @attention
12  *
13  *  Copyright (C) 2021-2022 Geehy Semiconductor
14  *
15  *  You may not use this file except in compliance with the
16  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
17  *
18  *  The program is only for reference, which is distributed in the hope
19  *  that it will be usefull and instructional for customers to develop
20  *  their software. Unless required by applicable law or agreed to in
21  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
22  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
23  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
24  *  and limitations under the License.
25  */
26 
27 #include "apm32f4xx_cryp.h"
28 
29 /** @addtogroup APM32F4xx_StdPeriphDriver
30   @{
31 */
32 
33 /** @defgroup CRYP_AES_Driver
34   * @brief CRYP AES driver modules
35   @{
36 */
37 
38 /** @defgroup CRYP_AES_Functions
39   @{
40 */
41 
42 /*!
43  * @brief     Encrypt and decrypt using AES in EBC Mode
44  *
45  * @param     mode: Pointer to a CRYP_MODE_T structure.
46  *            This parameter can be one of the following values:
47  *                @arg CRYP_MODE_DECRYPT: Encryption
48  *                @arg CRYP_MODE_ENCRYPT: Decryption
49  *
50  * @param     key:     Key used for AES algorithm.
51  * @param     keysize: length of the Key, must be a 128, 192 or 256.
52  * @param     input:   Input buffer.
53  * @param     length:  length of the Input buffer, must be a multiple of 16.
54  * @param     output:  Output buffer.
55  *
56  * @retval    SUCCESS or ERROR
57  */
CRYP_AES_ECB(CRYP_MODE_T mode,uint8_t * key,uint16_t keysize,uint8_t * input,uint32_t length,uint8_t * output)58 uint8_t CRYP_AES_ECB(CRYP_MODE_T mode, uint8_t *key,    uint16_t keysize,
59                      uint8_t *input, uint32_t length, uint8_t  *output)
60 {
61     CRYP_Config_T    AES_crypConfig;
62     CRYP_KeyConfig_T AES_keyConfig;
63 
64     uint32_t keyAddr    = (uint32_t)key;
65     uint32_t inputAddr  = (uint32_t)input;
66     uint32_t outputAddr = (uint32_t)output;
67 
68     uint32_t i = 0;
69     uint32_t flag = 0;
70     uint32_t status = SUCCESS;
71     __IO uint32_t counter = 0;
72 
73     CRYP_ConfigKeyStructInit(&AES_keyConfig);
74 
75     switch (keysize)
76     {
77     case 128:
78         AES_crypConfig.keySize = CRYP_KEYSIZE_128B;
79         AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
80         keyAddr += 0x04;
81         AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
82         keyAddr += 0x04;
83         AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
84         keyAddr += 0x04;
85         AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
86         break;
87 
88     case 192:
89         AES_crypConfig.keySize = CRYP_KEYSIZE_192B;
90         AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
91         keyAddr += 0x04;
92         AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
93         keyAddr += 0x04;
94         AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
95         keyAddr += 0x04;
96         AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
97         keyAddr += 0x04;
98         AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
99         keyAddr += 0x04;
100         AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
101         break;
102 
103     case 256:
104         AES_crypConfig.keySize = CRYP_KEYSIZE_256B;
105         AES_keyConfig.key0Left  = __REV(*(uint32_t *)(keyAddr));
106         keyAddr += 0x04;
107         AES_keyConfig.key0Right = __REV(*(uint32_t *)(keyAddr));
108         keyAddr += 0x04;
109         AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
110         keyAddr += 0x04;
111         AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
112         keyAddr += 0x04;
113         AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
114         keyAddr += 0x04;
115         AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
116         keyAddr += 0x04;
117         AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
118         keyAddr += 0x04;
119         AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
120         break;
121 
122     default:
123         break;
124     }
125 
126     if (mode == CRYP_MODE_DECRYPT)
127     {
128         CRYP_FlushFIFO();
129 
130         AES_crypConfig.algoDir  = CRYP_ALGODIR_DECRYPT;
131         AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_KEY;
132         AES_crypConfig.dataType = CRYP_DATATYPE_32B;
133         CRYP_Config(&AES_crypConfig);
134         CRYP_ConfigKey(&AES_keyConfig);
135         CRYP_Enable();
136 
137         counter = 0;
138         do
139         {
140             flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
141             counter++;
142         }
143         while ((counter != 0x00010000) && (flag != RESET));
144 
145         if (flag == SET)
146         {
147             status = ERROR;
148         }
149         else
150         {
151             AES_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
152         }
153     }
154     else
155     {
156         CRYP_ConfigKey(&AES_keyConfig);
157         AES_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
158     }
159 
160     AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_ECB;
161     AES_crypConfig.dataType = CRYP_DATATYPE_8B,
162     CRYP_Config(&AES_crypConfig);
163 
164     CRYP_FlushFIFO();
165     CRYP_Enable();
166 
167     if (CRYP_ReadCmdStatus() == DISABLE)
168     {
169         status = ERROR;
170     }
171 
172     for (i = 0; i < length; i += 16)
173     {
174         CRYP_InData(*(uint32_t *)(inputAddr));
175         inputAddr += 0x04;
176         CRYP_InData(*(uint32_t *)(inputAddr));
177         inputAddr += 0x04;
178         CRYP_InData(*(uint32_t *)(inputAddr));
179         inputAddr += 0x04;
180         CRYP_InData(*(uint32_t *)(inputAddr));
181         inputAddr += 0x04;
182 
183         counter = 0;
184         do
185         {
186             flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
187             counter++;
188         }
189         while ((counter != 0x00010000) && (flag != RESET));
190 
191         if (flag == SET)
192         {
193             status = ERROR;
194         }
195         else
196         {
197             *(uint32_t *)(outputAddr) = CRYP_OutData();
198             outputAddr += 0x04;
199             *(uint32_t *)(outputAddr) = CRYP_OutData();
200             outputAddr += 0x04;
201             *(uint32_t *)(outputAddr) = CRYP_OutData();
202             outputAddr += 0x04;
203             *(uint32_t *)(outputAddr) = CRYP_OutData();
204             outputAddr += 0x04;
205         }
206     }
207     CRYP_Disable();
208     return status;
209 }
210 
211 /*!
212  * @brief     Encrypt and decrypt using AES in CBC Mode
213  *
214  * @param     mode: Pointer to a CRYP_MODE_T structure.
215  *            This parameter can be one of the following values:
216  *                @arg CRYP_MODE_DECRYPT: Encryption
217  *                @arg CRYP_MODE_ENCRYPT: Decryption
218  *
219  * @param     key:     Key used for AES algorithm.
220  * @param     keysize: length of the Key, must be a 128, 192 or 256.
221  * @param     IV:      Initialisation Vectors used for AES algorithm.
222  * @param     input:   Input buffer.
223  * @param     length:  length of the Input buffer, must be a multiple of 16.
224  * @param     output:  Output buffer.
225  *
226  * @retval    SUCCESS or ERROR
227  */
CRYP_AES_CBC(CRYP_MODE_T mode,uint8_t * key,uint16_t keysize,uint8_t IV[16],uint8_t * input,uint32_t length,uint8_t * output)228 uint8_t CRYP_AES_CBC(CRYP_MODE_T mode, uint8_t *key,    uint16_t keysize,
229                      uint8_t IV[16],  uint8_t  *input,
230                      uint32_t length, uint8_t  *output)
231 {
232     CRYP_Config_T    AES_crypConfig;
233     CRYP_KeyConfig_T AES_keyConfig;
234     CRYP_IVConfig_T  AES_IVConfig;
235 
236     uint32_t keyAddr    = (uint32_t)key;
237     uint32_t inputAddr  = (uint32_t)input;
238     uint32_t outputAddr = (uint32_t)output;
239     uint32_t IVAddr     = (uint32_t)IV;
240 
241     uint32_t i = 0;
242     uint32_t flag = 0;
243     uint32_t status = SUCCESS;
244     __IO uint32_t counter = 0;
245 
246     CRYP_ConfigKeyStructInit(&AES_keyConfig);
247 
248     switch (keysize)
249     {
250     case 128:
251         AES_crypConfig.keySize = CRYP_KEYSIZE_128B;
252         AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
253         keyAddr += 0x04;
254         AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
255         keyAddr += 0x04;
256         AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
257         keyAddr += 0x04;
258         AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
259         break;
260 
261     case 192:
262         AES_crypConfig.keySize = CRYP_KEYSIZE_192B;
263         AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
264         keyAddr += 0x04;
265         AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
266         keyAddr += 0x04;
267         AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
268         keyAddr += 0x04;
269         AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
270         keyAddr += 0x04;
271         AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
272         keyAddr += 0x04;
273         AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
274         break;
275 
276     case 256:
277         AES_crypConfig.keySize = CRYP_KEYSIZE_256B;
278         AES_keyConfig.key0Left  = __REV(*(uint32_t *)(keyAddr));
279         keyAddr += 0x04;
280         AES_keyConfig.key0Right = __REV(*(uint32_t *)(keyAddr));
281         keyAddr += 0x04;
282         AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
283         keyAddr += 0x04;
284         AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
285         keyAddr += 0x04;
286         AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
287         keyAddr += 0x04;
288         AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
289         keyAddr += 0x04;
290         AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
291         keyAddr += 0x04;
292         AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
293         break;
294 
295     default:
296         break;
297     }
298 
299     AES_IVConfig.IV0Left  = __REV(*(uint32_t *)(IVAddr));
300     keyAddr += 0x04;
301     AES_IVConfig.IV0Right = __REV(*(uint32_t *)(IVAddr));
302     keyAddr += 0x04;
303     AES_IVConfig.IV1Left  = __REV(*(uint32_t *)(IVAddr));
304     keyAddr += 0x04;
305     AES_IVConfig.IV1Right = __REV(*(uint32_t *)(IVAddr));
306 
307     if (mode == CRYP_MODE_DECRYPT)
308     {
309         CRYP_FlushFIFO();
310 
311         AES_crypConfig.algoDir  = CRYP_ALGODIR_DECRYPT;
312         AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_KEY;
313         AES_crypConfig.dataType = CRYP_DATATYPE_32B;
314         CRYP_Config(&AES_crypConfig);
315         CRYP_ConfigKey(&AES_keyConfig);
316         CRYP_Enable();
317 
318         counter = 0;
319         do
320         {
321             flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
322             counter++;
323         }
324         while ((counter != 0x00010000) && (flag != RESET));
325 
326         if (flag == SET)
327         {
328             status = ERROR;
329         }
330         else
331         {
332             AES_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
333         }
334     }
335     else
336     {
337         CRYP_ConfigKey(&AES_keyConfig);
338         AES_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
339     }
340 
341     AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_CBC;
342     AES_crypConfig.dataType = CRYP_DATATYPE_8B,
343     CRYP_Config(&AES_crypConfig);
344     CRYP_ConfigIV(&AES_IVConfig);
345     CRYP_FlushFIFO();
346     CRYP_Enable();
347 
348     if (CRYP_ReadCmdStatus() == DISABLE)
349     {
350         status = ERROR;
351     }
352 
353     for (i = 0; i < length; i += 16)
354     {
355         CRYP_InData(*(uint32_t *)(inputAddr));
356         inputAddr += 0x04;
357         CRYP_InData(*(uint32_t *)(inputAddr));
358         inputAddr += 0x04;
359         CRYP_InData(*(uint32_t *)(inputAddr));
360         inputAddr += 0x04;
361         CRYP_InData(*(uint32_t *)(inputAddr));
362         inputAddr += 0x04;
363 
364         counter = 0;
365         do
366         {
367             flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
368             counter++;
369         }
370         while ((counter != 0x00010000) && (flag != RESET));
371 
372         if (flag == SET)
373         {
374             status = ERROR;
375         }
376         else
377         {
378             *(uint32_t *)(outputAddr) = CRYP_OutData();
379             outputAddr += 0x04;
380             *(uint32_t *)(outputAddr) = CRYP_OutData();
381             outputAddr += 0x04;
382             *(uint32_t *)(outputAddr) = CRYP_OutData();
383             outputAddr += 0x04;
384             *(uint32_t *)(outputAddr) = CRYP_OutData();
385             outputAddr += 0x04;
386         }
387     }
388     CRYP_Disable();
389     return status;
390 }
391 
392 /*!
393  * @brief     Encrypt and decrypt using AES in CTR Mode
394  *
395  * @param     mode: Pointer to a CRYP_MODE_T structure.
396  *            This parameter can be one of the following values:
397  *                @arg CRYP_MODE_DECRYPT: Encryption
398  *                @arg CRYP_MODE_ENCRYPT: Decryption
399  *
400  * @param     key:     Key used for AES algorithm.
401  * @param     keysize: length of the Key, must be a 128, 192 or 256.
402  * @param     IV:      Initialisation Vectors used for AES algorithm.
403  * @param     input:   Input buffer.
404  * @param     length:  length of the Input buffer, must be a multiple of 16.
405  * @param     output:  Output buffer.
406  *
407  * @retval    SUCCESS or ERROR
408  */
CRYP_AES_CTR(CRYP_MODE_T mode,uint8_t * key,uint16_t keysize,uint8_t IV[16],uint8_t * input,uint32_t length,uint8_t * output)409 uint8_t CRYP_AES_CTR(CRYP_MODE_T mode, uint8_t  *key,   uint16_t keysize,
410                      uint8_t  IV[16], uint8_t  *input,
411                      uint32_t length, uint8_t  *output)
412 {
413     CRYP_Config_T    AES_crypConfig;
414     CRYP_KeyConfig_T AES_keyConfig;
415     CRYP_IVConfig_T  AES_IVConfig;
416 
417     uint32_t keyAddr    = (uint32_t)key;
418     uint32_t inputAddr  = (uint32_t)input;
419     uint32_t outputAddr = (uint32_t)output;
420     uint32_t IVAddr     = (uint32_t)IV;
421 
422     uint32_t i = 0;
423     uint32_t flag = 0;
424     uint32_t status = SUCCESS;
425     __IO uint32_t counter = 0;
426 
427     CRYP_ConfigKeyStructInit(&AES_keyConfig);
428 
429     switch (keysize)
430     {
431     case 128:
432         AES_crypConfig.keySize = CRYP_KEYSIZE_128B;
433         AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
434         keyAddr += 0x04;
435         AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
436         keyAddr += 0x04;
437         AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
438         keyAddr += 0x04;
439         AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
440         break;
441 
442     case 192:
443         AES_crypConfig.keySize = CRYP_KEYSIZE_192B;
444         AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
445         keyAddr += 0x04;
446         AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
447         keyAddr += 0x04;
448         AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
449         keyAddr += 0x04;
450         AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
451         keyAddr += 0x04;
452         AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
453         keyAddr += 0x04;
454         AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
455         break;
456 
457     case 256:
458         AES_crypConfig.keySize = CRYP_KEYSIZE_256B;
459         AES_keyConfig.key0Left  = __REV(*(uint32_t *)(keyAddr));
460         keyAddr += 0x04;
461         AES_keyConfig.key0Right = __REV(*(uint32_t *)(keyAddr));
462         keyAddr += 0x04;
463         AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
464         keyAddr += 0x04;
465         AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
466         keyAddr += 0x04;
467         AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
468         keyAddr += 0x04;
469         AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
470         keyAddr += 0x04;
471         AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
472         keyAddr += 0x04;
473         AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
474         break;
475 
476     default:
477         break;
478     }
479 
480     AES_IVConfig.IV0Left  = __REV(*(uint32_t *)(IVAddr));
481     keyAddr += 0x04;
482     AES_IVConfig.IV0Right = __REV(*(uint32_t *)(IVAddr));
483     keyAddr += 0x04;
484     AES_IVConfig.IV1Left  = __REV(*(uint32_t *)(IVAddr));
485     keyAddr += 0x04;
486     AES_IVConfig.IV1Right = __REV(*(uint32_t *)(IVAddr));
487 
488     CRYP_ConfigKey(&AES_keyConfig);
489 
490     if (mode == CRYP_MODE_DECRYPT)
491     {
492         AES_crypConfig.algoDir  = CRYP_ALGODIR_DECRYPT;
493     }
494     else
495     {
496         AES_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
497     }
498 
499     AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_CTR;
500     AES_crypConfig.dataType = CRYP_DATATYPE_8B,
501 
502     CRYP_Config(&AES_crypConfig);
503     CRYP_ConfigIV(&AES_IVConfig);
504     CRYP_FlushFIFO();
505     CRYP_Enable();
506 
507     if (CRYP_ReadCmdStatus() == DISABLE)
508     {
509         status = ERROR;
510     }
511 
512     for (i = 0; i < length; i += 16)
513     {
514         CRYP_InData(*(uint32_t *)(inputAddr));
515         inputAddr += 0x04;
516         CRYP_InData(*(uint32_t *)(inputAddr));
517         inputAddr += 0x04;
518         CRYP_InData(*(uint32_t *)(inputAddr));
519         inputAddr += 0x04;
520         CRYP_InData(*(uint32_t *)(inputAddr));
521         inputAddr += 0x04;
522 
523         counter = 0;
524         do
525         {
526             flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
527             counter++;
528         }
529         while ((counter != 0x00010000) && (flag != RESET));
530 
531         if (flag == SET)
532         {
533             status = ERROR;
534         }
535         else
536         {
537             *(uint32_t *)(outputAddr) = CRYP_OutData();
538             outputAddr += 0x04;
539             *(uint32_t *)(outputAddr) = CRYP_OutData();
540             outputAddr += 0x04;
541             *(uint32_t *)(outputAddr) = CRYP_OutData();
542             outputAddr += 0x04;
543             *(uint32_t *)(outputAddr) = CRYP_OutData();
544             outputAddr += 0x04;
545         }
546     }
547     CRYP_Disable();
548     return status;
549 }
550 
551 /**@} end of group CRYP_AES_Functions */
552 /**@} end of group CRYP_AES_Driver */
553 /**@} end of group APM32F4xx_StdPeriphDriver */
554