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