]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/ST_Code/Libraries/STM32L1xx_StdPeriph_Driver/src/stm32l1xx_aes_util.c
Tidy up STM32L low power demo and add 'comprehensive demo' option.
[freertos] / FreeRTOS / Demo / CORTEX_STM32L152_Discovery_IAR / ST_Code / Libraries / STM32L1xx_StdPeriph_Driver / src / stm32l1xx_aes_util.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32l1xx_aes_util.c\r
4   * @author  MCD Application Team\r
5   * @version V1.1.1\r
6   * @date    05-March-2012\r
7   * @brief   This file provides high level functions to encrypt and decrypt an \r
8   *          input message using AES in ECB/CBC/CTR modes.\r
9   *\r
10   *  @verbatim\r
11 \r
12 ================================================================================\r
13                         ##### How to use this driver #####\r
14 ================================================================================\r
15           [..]\r
16            (#) Enable The AES controller clock using \r
17                RCC_AHBPeriphClockCmd(RCC_AHBPeriph_AES, ENABLE); function.\r
18 \r
19            (#) Use AES_ECB_Encrypt() function to encrypt an input message in ECB mode.\r
20            (#) Use AES_ECB_Decrypt() function to decrypt an input message in ECB mode.\r
21 \r
22            (#) Use AES_CBC_Encrypt() function to encrypt an input message in CBC mode.\r
23            (#) Use AES_CBC_Decrypt() function to decrypt an input message in CBC mode.\r
24 \r
25            (#) Use AES_CTR_Encrypt() function to encrypt an input message in CTR mode.\r
26            (#) Use AES_CTR_Decrypt() function to decrypt an input message in CTR mode.\r
27 \r
28   *  @endverbatim\r
29   *\r
30   ******************************************************************************\r
31   * @attention\r
32   *\r
33   * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>\r
34   *\r
35   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");\r
36   * You may not use this file except in compliance with the License.\r
37   * You may obtain a copy of the License at:\r
38   *\r
39   *        http://www.st.com/software_license_agreement_liberty_v2\r
40   *\r
41   * Unless required by applicable law or agreed to in writing, software \r
42   * distributed under the License is distributed on an "AS IS" BASIS, \r
43   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
44   * See the License for the specific language governing permissions and\r
45   * limitations under the License.\r
46   *\r
47   ******************************************************************************\r
48   */\r
49 \r
50 /* Includes ------------------------------------------------------------------*/\r
51 #include "stm32l1xx_aes.h"\r
52 \r
53 /** @addtogroup STM32L1xx_StdPeriph_Driver\r
54   * @{\r
55   */\r
56 \r
57 /** @addtogroup AES \r
58   * @brief AES driver modules\r
59   * @{\r
60   */\r
61 \r
62 /* Private typedef -----------------------------------------------------------*/\r
63 /* Private define ------------------------------------------------------------*/\r
64 #define AES_CC_TIMEOUT    ((uint32_t) 0x00010000)\r
65 \r
66 /* Private macro -------------------------------------------------------------*/\r
67 /* Private variables ---------------------------------------------------------*/\r
68 /* Private function prototypes -----------------------------------------------*/\r
69 /* Private functions ---------------------------------------------------------*/\r
70 \r
71 /** @defgroup AES_Private_Functions\r
72   * @{\r
73   */ \r
74 \r
75 /** @defgroup AES_Group6 High Level AES functions\r
76  *  @brief   High Level AES functions \r
77  *\r
78 @verbatim\r
79 ================================================================================\r
80                          ##### High Level AES functions #####\r
81 ================================================================================\r
82 \r
83 @endverbatim\r
84   * @{\r
85   */\r
86 \r
87 /**\r
88   * @brief  Encrypt using AES in ECB Mode\r
89   * @param  Key: Key used for AES algorithm.\r
90   * @param  Input: pointer to the Input buffer.\r
91   * @param  Ilength: length of the Input buffer, must be a multiple of 16 bytes.\r
92   * @param  Output: pointer to the returned buffer.\r
93   * @retval An ErrorStatus enumeration value:\r
94   *          - SUCCESS: Operation done\r
95   *          - ERROR: Operation failed\r
96   */\r
97 ErrorStatus AES_ECB_Encrypt(uint8_t* Key, uint8_t* Input, uint32_t Ilength, uint8_t* Output)\r
98 {\r
99   AES_InitTypeDef AES_InitStructure;\r
100   AES_KeyInitTypeDef  AES_KeyInitStructure;\r
101   ErrorStatus status = SUCCESS;\r
102   uint32_t keyaddr    = (uint32_t)Key;\r
103   uint32_t inputaddr  = (uint32_t)Input;\r
104   uint32_t outputaddr = (uint32_t)Output;\r
105   __IO uint32_t counter = 0;\r
106   uint32_t ccstatus = 0;\r
107   uint32_t i = 0;\r
108 \r
109   /* AES Key initialisation */\r
110   AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr));\r
111   keyaddr += 4;\r
112   AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr));\r
113   keyaddr += 4;\r
114   AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr));\r
115   keyaddr += 4;\r
116   AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr));\r
117   AES_KeyInit(&AES_KeyInitStructure);\r
118 \r
119   /* AES configuration */\r
120   AES_InitStructure.AES_Operation = AES_Operation_Encryp;\r
121   AES_InitStructure.AES_Chaining = AES_Chaining_ECB;\r
122   AES_InitStructure.AES_DataType = AES_DataType_8b;\r
123   AES_Init(&AES_InitStructure);\r
124 \r
125   /* Enable AES */\r
126   AES_Cmd(ENABLE);\r
127 \r
128   for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16)\r
129   {\r
130     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
131     inputaddr += 4;\r
132     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
133     inputaddr += 4;\r
134     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
135     inputaddr += 4;\r
136     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
137     inputaddr += 4;\r
138     \r
139     /* Wait for CCF flag to be set */\r
140     counter = 0;\r
141     do\r
142     {\r
143       ccstatus = AES_GetFlagStatus(AES_FLAG_CCF);\r
144       counter++;\r
145     }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET));\r
146     \r
147     if (ccstatus == RESET)\r
148     {\r
149       status = ERROR;\r
150     }\r
151     else\r
152     {\r
153       /* Clear CCF flag */\r
154       AES_ClearFlag(AES_FLAG_CCF);\r
155       /* Read cipher text */\r
156       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
157       outputaddr += 4;\r
158       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
159       outputaddr += 4;\r
160       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
161       outputaddr += 4;\r
162       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
163       outputaddr += 4;\r
164     }\r
165   }\r
166   \r
167   /* Disable AES before starting new processing */\r
168   AES_Cmd(DISABLE);\r
169 \r
170   return status;\r
171 }\r
172 \r
173 /**\r
174   * @brief  Decrypt using AES in ECB Mode\r
175   * @param  Key: Key used for AES algorithm.\r
176   * @param  Input: pointer to the Input buffer.\r
177   * @param  Ilength: length of the Input buffer, must be a multiple of 16 bytes.\r
178   * @param  Output: pointer to the returned buffer.\r
179   * @retval An ErrorStatus enumeration value:\r
180   *          - SUCCESS: Operation done\r
181   *          - ERROR: Operation failed\r
182   */\r
183 ErrorStatus AES_ECB_Decrypt(uint8_t* Key, uint8_t* Input, uint32_t Ilength, uint8_t* Output)\r
184 {\r
185   AES_InitTypeDef AES_InitStructure;\r
186   AES_KeyInitTypeDef  AES_KeyInitStructure;\r
187   ErrorStatus status = SUCCESS;\r
188   uint32_t keyaddr    = (uint32_t)Key;\r
189   uint32_t inputaddr  = (uint32_t)Input;\r
190   uint32_t outputaddr = (uint32_t)Output;\r
191   __IO uint32_t counter = 0;\r
192   uint32_t ccstatus = 0;\r
193   uint32_t i = 0;\r
194 \r
195   /* AES Key initialisation */\r
196   AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr));\r
197   keyaddr += 4;\r
198   AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr));\r
199   keyaddr += 4;\r
200   AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr));\r
201   keyaddr += 4;\r
202   AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr));\r
203   AES_KeyInit(&AES_KeyInitStructure);\r
204 \r
205   /* AES configuration */\r
206   AES_InitStructure.AES_Operation = AES_Operation_KeyDerivAndDecryp;\r
207   AES_InitStructure.AES_Chaining = AES_Chaining_ECB;\r
208   AES_InitStructure.AES_DataType = AES_DataType_8b;\r
209   AES_Init(&AES_InitStructure);\r
210 \r
211   /* Enable AES */\r
212   AES_Cmd(ENABLE);\r
213 \r
214   for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16)\r
215   {\r
216     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
217     inputaddr += 4;\r
218     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
219     inputaddr += 4;\r
220     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
221     inputaddr += 4;\r
222     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
223     inputaddr += 4;\r
224     \r
225      /* Wait for CCF flag to be set */\r
226     counter = 0;\r
227     do\r
228     {\r
229       ccstatus = AES_GetFlagStatus(AES_FLAG_CCF);\r
230       counter++;\r
231     }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET));\r
232     \r
233     if (ccstatus == RESET)\r
234     {\r
235       status = ERROR;\r
236     }\r
237     else\r
238     {\r
239       /* Clear CCF flag */\r
240       AES_ClearFlag(AES_FLAG_CCF);\r
241 \r
242       /* Read cipher text */\r
243       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
244       outputaddr += 4;\r
245       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
246       outputaddr += 4;\r
247       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
248       outputaddr += 4;\r
249       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
250       outputaddr += 4;\r
251     }\r
252   }\r
253 \r
254   /* Disable AES before starting new processing */\r
255   AES_Cmd(DISABLE);\r
256 \r
257   return status;\r
258 }\r
259 \r
260 /**\r
261   * @brief  Encrypt using AES in CBC Mode\r
262   * @param  InitVectors: Initialisation Vectors used for AES algorithm.\r
263   * @param  Key: Key used for AES algorithm.\r
264   * @param  Input: pointer to the Input buffer.\r
265   * @param  Ilength: length of the Input buffer, must be a multiple of 16 bytes.\r
266   * @param  Output: pointer to the returned buffer.\r
267   * @retval An ErrorStatus enumeration value:\r
268   *          - SUCCESS: Operation done\r
269   *          - ERROR: Operation failed\r
270   */\r
271 ErrorStatus AES_CBC_Encrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output)\r
272 {\r
273   AES_InitTypeDef AES_InitStructure;\r
274   AES_KeyInitTypeDef  AES_KeyInitStructure;\r
275   AES_IVInitTypeDef AES_IVInitStructure;\r
276   ErrorStatus status = SUCCESS;\r
277   uint32_t keyaddr    = (uint32_t)Key;\r
278   uint32_t inputaddr  = (uint32_t)Input;\r
279   uint32_t outputaddr = (uint32_t)Output;\r
280   uint32_t ivaddr     = (uint32_t)InitVectors;\r
281   __IO uint32_t counter = 0;\r
282   uint32_t ccstatus = 0;\r
283   uint32_t i = 0;\r
284 \r
285   /* AES Key initialisation*/\r
286   AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr));\r
287   keyaddr += 4;\r
288   AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr));\r
289   keyaddr += 4;\r
290   AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr));\r
291   keyaddr += 4;\r
292   AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr));\r
293   AES_KeyInit(&AES_KeyInitStructure);\r
294 \r
295   /* AES Initialization Vectors */\r
296   AES_IVInitStructure.AES_IV3 = __REV(*(uint32_t*)(ivaddr));\r
297   ivaddr += 4;\r
298   AES_IVInitStructure.AES_IV2 = __REV(*(uint32_t*)(ivaddr));\r
299   ivaddr += 4;\r
300   AES_IVInitStructure.AES_IV1 = __REV(*(uint32_t*)(ivaddr));\r
301   ivaddr += 4;\r
302   AES_IVInitStructure.AES_IV0 = __REV(*(uint32_t*)(ivaddr));\r
303   AES_IVInit(&AES_IVInitStructure);\r
304 \r
305   /* AES configuration */\r
306   AES_InitStructure.AES_Operation = AES_Operation_Encryp;\r
307   AES_InitStructure.AES_Chaining = AES_Chaining_CBC;\r
308   AES_InitStructure.AES_DataType = AES_DataType_8b;\r
309   AES_Init(&AES_InitStructure);\r
310 \r
311   /* Enable AES */\r
312   AES_Cmd(ENABLE);\r
313 \r
314   for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16)\r
315   {\r
316     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
317     inputaddr += 4;\r
318     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
319     inputaddr += 4;\r
320     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
321     inputaddr += 4;\r
322     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
323     inputaddr += 4;\r
324     \r
325     /* Wait for CCF flag to be set */\r
326     counter = 0;\r
327     do\r
328     {\r
329       ccstatus = AES_GetFlagStatus(AES_FLAG_CCF);\r
330       counter++;\r
331     }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET));\r
332     \r
333     if (ccstatus == RESET)\r
334     {\r
335       status = ERROR;\r
336     }\r
337     else\r
338     {\r
339       /* Clear CCF flag */\r
340       AES_ClearFlag(AES_FLAG_CCF);\r
341 \r
342       /* Read cipher text */\r
343       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
344       outputaddr += 4;\r
345       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
346       outputaddr += 4;\r
347       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
348       outputaddr += 4;\r
349       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
350       outputaddr += 4;\r
351     }\r
352   }\r
353 \r
354   /* Disable AES before starting new processing */\r
355   AES_Cmd(DISABLE);\r
356 \r
357   return status;\r
358 }\r
359 \r
360 /**\r
361   * @brief  Decrypt using AES in CBC Mode\r
362   * @param  InitVectors: Initialisation Vectors used for AES algorithm.\r
363   * @param  Key: Key used for AES algorithm.\r
364   * @param  Input: pointer to the Input buffer.\r
365   * @param  Ilength: length of the Input buffer, must be a multiple of 16 bytes.\r
366   * @param  Output: pointer to the returned buffer.\r
367   * @retval An ErrorStatus enumeration value:\r
368   *          - SUCCESS: Operation done\r
369   *          - ERROR: Operation failed\r
370   */\r
371 ErrorStatus AES_CBC_Decrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output)\r
372 {\r
373   AES_InitTypeDef AES_InitStructure;\r
374   AES_KeyInitTypeDef  AES_KeyInitStructure;\r
375   AES_IVInitTypeDef AES_IVInitStructure;\r
376   ErrorStatus status = SUCCESS;\r
377   uint32_t keyaddr    = (uint32_t)Key;\r
378   uint32_t inputaddr  = (uint32_t)Input;\r
379   uint32_t outputaddr = (uint32_t)Output;\r
380   uint32_t ivaddr     = (uint32_t)InitVectors;\r
381   __IO uint32_t counter = 0;\r
382   uint32_t ccstatus = 0;\r
383   uint32_t i = 0;\r
384   \r
385   /* AES Key initialisation*/\r
386   AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr));\r
387   keyaddr += 4;\r
388   AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr));\r
389   keyaddr += 4;\r
390   AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr));\r
391   keyaddr += 4;\r
392   AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr));\r
393   AES_KeyInit(&AES_KeyInitStructure);\r
394 \r
395   /* AES Initialization Vectors */\r
396   AES_IVInitStructure.AES_IV3 = __REV(*(uint32_t*)(ivaddr));\r
397   ivaddr += 4;\r
398   AES_IVInitStructure.AES_IV2 = __REV(*(uint32_t*)(ivaddr));\r
399   ivaddr += 4;\r
400   AES_IVInitStructure.AES_IV1 = __REV(*(uint32_t*)(ivaddr));\r
401   ivaddr += 4;\r
402   AES_IVInitStructure.AES_IV0 = __REV(*(uint32_t*)(ivaddr));\r
403   AES_IVInit(&AES_IVInitStructure);\r
404 \r
405   /* AES configuration */\r
406   AES_InitStructure.AES_Operation = AES_Operation_KeyDerivAndDecryp;\r
407   AES_InitStructure.AES_Chaining = AES_Chaining_CBC;\r
408   AES_InitStructure.AES_DataType = AES_DataType_8b;\r
409   AES_Init(&AES_InitStructure);\r
410 \r
411   /* Enable AES */\r
412   AES_Cmd(ENABLE);\r
413 \r
414   for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16)\r
415   {\r
416     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
417     inputaddr += 4;\r
418     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
419     inputaddr += 4;\r
420     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
421     inputaddr += 4;\r
422     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
423     inputaddr += 4;\r
424     \r
425     /* Wait for CCF flag to be set */\r
426     counter = 0;\r
427     do\r
428     {\r
429       ccstatus = AES_GetFlagStatus(AES_FLAG_CCF);\r
430       counter++;\r
431     }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET));\r
432 \r
433     if (ccstatus == RESET)\r
434     {\r
435       status = ERROR;\r
436     }\r
437     else\r
438     {\r
439       /* Clear CCF flag */\r
440       AES_ClearFlag(AES_FLAG_CCF);\r
441 \r
442       /* Read cipher text */\r
443       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
444       outputaddr += 4;\r
445       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
446       outputaddr += 4;\r
447       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
448       outputaddr += 4;\r
449       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
450       outputaddr += 4;\r
451     }\r
452   }\r
453 \r
454   /* Disable AES before starting new processing */\r
455   AES_Cmd(DISABLE);\r
456 \r
457   return status;\r
458 }\r
459 \r
460 /**\r
461   * @brief  Encrypt using AES in CTR Mode\r
462   * @param  InitVectors: Initialisation Vectors used for AES algorithm.\r
463   * @param  Key: Key used for AES algorithm.\r
464   * @param  Input: pointer to the Input buffer.\r
465   * @param  Ilength: length of the Input buffer, must be a multiple of 16 bytes.\r
466   * @param  Output: pointer to the returned buffer.\r
467   * @retval An ErrorStatus enumeration value:\r
468   *          - SUCCESS: Operation done\r
469   *          - ERROR: Operation failed\r
470   */\r
471 ErrorStatus AES_CTR_Encrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output)\r
472 {\r
473   AES_InitTypeDef AES_InitStructure;\r
474   AES_KeyInitTypeDef  AES_KeyInitStructure;\r
475   AES_IVInitTypeDef AES_IVInitStructure;\r
476 \r
477   ErrorStatus status = SUCCESS;\r
478   uint32_t keyaddr    = (uint32_t)Key;\r
479   uint32_t inputaddr  = (uint32_t)Input;\r
480   uint32_t outputaddr = (uint32_t)Output;\r
481   uint32_t ivaddr     = (uint32_t)InitVectors;\r
482   __IO uint32_t counter = 0;\r
483   uint32_t ccstatus = 0;\r
484   uint32_t i = 0;\r
485 \r
486   /* AES key initialisation*/\r
487   AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr));\r
488   keyaddr += 4;\r
489   AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr));\r
490   keyaddr += 4;\r
491   AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr));\r
492   keyaddr += 4;\r
493   AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr));\r
494   AES_KeyInit(&AES_KeyInitStructure);\r
495 \r
496   /* AES Initialization Vectors */\r
497   AES_IVInitStructure.AES_IV3 = __REV(*(uint32_t*)(ivaddr));\r
498   ivaddr += 4;\r
499   AES_IVInitStructure.AES_IV2= __REV(*(uint32_t*)(ivaddr));\r
500   ivaddr += 4;\r
501   AES_IVInitStructure.AES_IV1 = __REV(*(uint32_t*)(ivaddr));\r
502   ivaddr += 4;\r
503   AES_IVInitStructure.AES_IV0= __REV(*(uint32_t*)(ivaddr));\r
504   AES_IVInit(&AES_IVInitStructure);\r
505 \r
506   /* AES configuration */\r
507   AES_InitStructure.AES_Operation = AES_Operation_Encryp;\r
508   AES_InitStructure.AES_Chaining = AES_Chaining_CTR;\r
509   AES_InitStructure.AES_DataType = AES_DataType_8b;\r
510   AES_Init(&AES_InitStructure);\r
511 \r
512   /* Enable AES */\r
513   AES_Cmd(ENABLE);\r
514 \r
515   for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16)\r
516   {\r
517     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
518     inputaddr += 4;\r
519     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
520     inputaddr += 4;\r
521     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
522     inputaddr += 4;\r
523     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
524     inputaddr += 4;\r
525     \r
526     /* Wait for CCF flag to be set */\r
527     counter = 0;\r
528     do\r
529     {\r
530       ccstatus = AES_GetFlagStatus(AES_FLAG_CCF);\r
531       counter++;\r
532     }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET));\r
533 \r
534     if (ccstatus == RESET)\r
535     {\r
536       status = ERROR;\r
537     }\r
538     else\r
539     {\r
540       /* Clear CCF flag */\r
541       AES_ClearFlag(AES_FLAG_CCF);\r
542 \r
543       /* Read cipher text */\r
544       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
545       outputaddr += 4;\r
546       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
547       outputaddr += 4;\r
548       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
549       outputaddr += 4;\r
550       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
551       outputaddr += 4;\r
552     }\r
553   }\r
554 \r
555   /* Disable AES before starting new processing */\r
556   AES_Cmd(DISABLE);\r
557 \r
558   return status;\r
559 }\r
560 \r
561 /**\r
562   * @brief  Decrypt using AES in CTR Mode\r
563   * @param  InitVectors: Initialisation Vectors used for AES algorithm.\r
564   * @param  Key: Key used for AES algorithm.\r
565   * @param  Input: pointer to the Input buffer.\r
566   * @param  Ilength: length of the Input buffer, must be a multiple of 16 bytes.\r
567   * @param  Output: pointer to the returned buffer.\r
568   * @retval An ErrorStatus enumeration value:\r
569   *          - SUCCESS: Operation done\r
570   *          - ERROR: Operation failed\r
571   */\r
572 ErrorStatus AES_CTR_Decrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output)\r
573 {\r
574   AES_InitTypeDef AES_InitStructure;\r
575   AES_KeyInitTypeDef  AES_KeyInitStructure;\r
576   AES_IVInitTypeDef AES_IVInitStructure;\r
577 \r
578   ErrorStatus status = SUCCESS;\r
579   uint32_t keyaddr    = (uint32_t)Key;\r
580   uint32_t inputaddr  = (uint32_t)Input;\r
581   uint32_t outputaddr = (uint32_t)Output;\r
582   uint32_t ivaddr     = (uint32_t)InitVectors;\r
583   __IO uint32_t counter = 0;\r
584   uint32_t ccstatus = 0;\r
585   uint32_t i = 0;\r
586 \r
587   /* AES Key initialisation*/\r
588   AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr));\r
589   keyaddr += 4;\r
590   AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr));\r
591   keyaddr += 4;\r
592   AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr));\r
593   keyaddr += 4;\r
594   AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr));\r
595   AES_KeyInit(&AES_KeyInitStructure);\r
596 \r
597   /* AES Initialization Vectors */\r
598   AES_IVInitStructure.AES_IV3 = __REV(*(uint32_t*)(ivaddr));\r
599   ivaddr += 4;\r
600   AES_IVInitStructure.AES_IV2 = __REV(*(uint32_t*)(ivaddr));\r
601   ivaddr += 4;\r
602   AES_IVInitStructure.AES_IV1 = __REV(*(uint32_t*)(ivaddr));\r
603   ivaddr += 4;\r
604   AES_IVInitStructure.AES_IV0 = __REV(*(uint32_t*)(ivaddr));\r
605   AES_IVInit(&AES_IVInitStructure);\r
606 \r
607   /* AES configuration */\r
608   AES_InitStructure.AES_Operation = AES_Operation_KeyDerivAndDecryp;\r
609   AES_InitStructure.AES_Chaining = AES_Chaining_CTR;\r
610   AES_InitStructure.AES_DataType = AES_DataType_8b;\r
611   AES_Init(&AES_InitStructure);\r
612 \r
613   /* Enable AES */\r
614   AES_Cmd(ENABLE);\r
615 \r
616   for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16)\r
617   {\r
618     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
619     inputaddr += 4;\r
620     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
621     inputaddr += 4;\r
622     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
623     inputaddr += 4;\r
624     AES_WriteSubData(*(uint32_t*)(inputaddr));\r
625     inputaddr += 4;\r
626     \r
627     /* Wait for CCF flag to be set */\r
628     counter = 0;\r
629     do\r
630     {\r
631       ccstatus = AES_GetFlagStatus(AES_FLAG_CCF);\r
632       counter++;\r
633     }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET));\r
634 \r
635     if (ccstatus == RESET)\r
636     {\r
637       status = ERROR;\r
638     }\r
639     else\r
640     {\r
641       /* Clear CCF flag */\r
642       AES_ClearFlag(AES_FLAG_CCF);\r
643     \r
644       /* Read cipher text */\r
645       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
646       outputaddr += 4;\r
647       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
648       outputaddr += 4;\r
649       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
650       outputaddr += 4;\r
651       *(uint32_t*)(outputaddr) = AES_ReadSubData();\r
652       outputaddr += 4;\r
653     }\r
654   }\r
655 \r
656   /* Disable AES before starting new processing */\r
657   AES_Cmd(DISABLE);\r
658 \r
659   return status;\r
660 }\r
661 \r
662 /**\r
663   * @}\r
664   */\r
665 \r
666 /**\r
667   * @}\r
668   */ \r
669 \r
670 /**\r
671   * @}\r
672   */ \r
673 \r
674 /**\r
675   * @}\r
676   */ \r
677 \r
678 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r
679 \r