• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_cryp_aes.c
4   * @author  MCD Application Team
5   * @version V1.4.0
6   * @date    04-August-2014
7   * @brief   This file provides high level functions to encrypt and decrypt an
8   *          input message using AES in ECB/CBC/CTR/GCM/CCM modes.
9   *          It uses the stm32f4xx_cryp.c/.h drivers to access the STM32F4xx CRYP
10   *          peripheral.
11   *          AES-ECB/CBC/CTR/GCM/CCM modes are available on STM32F437x Devices.
12   *          For STM32F41xx Devices, only AES-ECB/CBC/CTR modes are available.
13   *
14 @verbatim
15  ===================================================================
16                   ##### How to use this driver #####
17  ===================================================================
18  [..]
19    (#) Enable The CRYP controller clock using
20       RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function.
21 
22    (#) Encrypt and decrypt using AES in ECB Mode using CRYP_AES_ECB() function.
23 
24    (#) Encrypt and decrypt using AES in CBC Mode using CRYP_AES_CBC() function.
25 
26    (#) Encrypt and decrypt using AES in CTR Mode using CRYP_AES_CTR() function.
27 
28    (#) Encrypt and decrypt using AES in GCM Mode using CRYP_AES_GCM() function.
29 
30    (#) Encrypt and decrypt using AES in CCM Mode using CRYP_AES_CCM() function.
31 
32 @endverbatim
33   *
34   ******************************************************************************
35   * @attention
36   *
37   * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
38   *
39   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
40   * You may not use this file except in compliance with the License.
41   * You may obtain a copy of the License at:
42   *
43   *        http://www.st.com/software_license_agreement_liberty_v2
44   *
45   * Unless required by applicable law or agreed to in writing, software
46   * distributed under the License is distributed on an "AS IS" BASIS,
47   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48   * See the License for the specific language governing permissions and
49   * limitations under the License.
50   *
51   ******************************************************************************
52   */
53 
54 /* Includes ------------------------------------------------------------------*/
55 #include "stm32f4xx_cryp.h"
56 
57 /** @addtogroup STM32F4xx_StdPeriph_Driver
58   * @{
59   */
60 
61 /** @defgroup CRYP
62   * @brief CRYP driver modules
63   * @{
64   */
65 
66 /* Private typedef -----------------------------------------------------------*/
67 /* Private define ------------------------------------------------------------*/
68 #define AESBUSY_TIMEOUT    ((uint32_t) 0x00010000)
69 
70 /* Private macro -------------------------------------------------------------*/
71 /* Private variables ---------------------------------------------------------*/
72 /* Private function prototypes -----------------------------------------------*/
73 /* Private functions ---------------------------------------------------------*/
74 
75 /** @defgroup CRYP_Private_Functions
76   * @{
77   */
78 
79 /** @defgroup CRYP_Group6 High Level AES functions
80  *  @brief   High Level AES functions
81  *
82 @verbatim
83  ===============================================================================
84                        ##### High Level AES functions #####
85  ===============================================================================
86 
87 @endverbatim
88   * @{
89   */
90 
91 /**
92   * @brief  Encrypt and decrypt using AES in ECB Mode
93   * @param  Mode: encryption or decryption Mode.
94   *          This parameter can be one of the following values:
95   *            @arg MODE_ENCRYPT: Encryption
96   *            @arg MODE_DECRYPT: Decryption
97   * @param  Key: Key used for AES algorithm.
98   * @param  Keysize: length of the Key, must be a 128, 192 or 256.
99   * @param  Input: pointer to the Input buffer.
100   * @param  Ilength: length of the Input buffer, must be a multiple of 16.
101   * @param  Output: pointer to the returned buffer.
102   * @retval An ErrorStatus enumeration value:
103   *          - SUCCESS: Operation done
104   *          - ERROR: Operation failed
105   */
CRYP_AES_ECB(uint8_t Mode,uint8_t * Key,uint16_t Keysize,uint8_t * Input,uint32_t Ilength,uint8_t * Output)106 ErrorStatus CRYP_AES_ECB(uint8_t Mode, uint8_t* Key, uint16_t Keysize,
107                          uint8_t* Input, uint32_t Ilength, uint8_t* Output)
108 {
109   CRYP_InitTypeDef AES_CRYP_InitStructure;
110   CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
111   __IO uint32_t counter = 0;
112   uint32_t busystatus = 0;
113   ErrorStatus status = SUCCESS;
114   uint32_t keyaddr    = (uint32_t)Key;
115   uint32_t inputaddr  = (uint32_t)Input;
116   uint32_t outputaddr = (uint32_t)Output;
117   uint32_t i = 0;
118 
119   /* Crypto structures initialisation*/
120   CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
121 
122   switch(Keysize)
123   {
124     case 128:
125     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
126     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
127     keyaddr+=4;
128     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
129     keyaddr+=4;
130     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
131     keyaddr+=4;
132     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
133     break;
134     case 192:
135     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_192b;
136     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
137     keyaddr+=4;
138     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
139     keyaddr+=4;
140     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
141     keyaddr+=4;
142     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
143     keyaddr+=4;
144     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
145     keyaddr+=4;
146     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
147     break;
148     case 256:
149     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_256b;
150     AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
151     keyaddr+=4;
152     AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
153     keyaddr+=4;
154     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
155     keyaddr+=4;
156     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
157     keyaddr+=4;
158     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
159     keyaddr+=4;
160     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
161     keyaddr+=4;
162     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
163     keyaddr+=4;
164     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
165     break;
166     default:
167     break;
168   }
169 
170   /*------------------ AES Decryption ------------------*/
171   if(Mode == MODE_DECRYPT) /* AES decryption */
172   {
173     /* Flush IN/OUT FIFOs */
174     CRYP_FIFOFlush();
175 
176     /* Crypto Init for Key preparation for decryption process */
177     AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
178     AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
179     AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
180     CRYP_Init(&AES_CRYP_InitStructure);
181 
182     /* Key Initialisation */
183     CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
184 
185     /* Enable Crypto processor */
186     CRYP_Cmd(ENABLE);
187 
188     /* wait until the Busy flag is RESET */
189     do
190     {
191       busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
192       counter++;
193     }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
194 
195     if (busystatus != RESET)
196    {
197        status = ERROR;
198     }
199     else
200     {
201       /* Crypto Init for decryption process */
202       AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
203     }
204   }
205   /*------------------ AES Encryption ------------------*/
206   else /* AES encryption */
207   {
208 
209     CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
210 
211     /* Crypto Init for Encryption process */
212     AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
213   }
214 
215   AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
216   AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
217   CRYP_Init(&AES_CRYP_InitStructure);
218 
219   /* Flush IN/OUT FIFOs */
220   CRYP_FIFOFlush();
221 
222   /* Enable Crypto processor */
223   CRYP_Cmd(ENABLE);
224 
225   if(CRYP_GetCmdStatus() == DISABLE)
226   {
227     /* The CRYP peripheral clock is not enabled or the device doesn't embedd
228        the CRYP peripheral (please check the device sales type. */
229     return(ERROR);
230   }
231 
232   for(i=0; ((i<Ilength) && (status != ERROR)); i+=16)
233   {
234 
235     /* Write the Input block in the IN FIFO */
236     CRYP_DataIn(*(uint32_t*)(inputaddr));
237     inputaddr+=4;
238     CRYP_DataIn(*(uint32_t*)(inputaddr));
239     inputaddr+=4;
240     CRYP_DataIn(*(uint32_t*)(inputaddr));
241     inputaddr+=4;
242     CRYP_DataIn(*(uint32_t*)(inputaddr));
243     inputaddr+=4;
244 
245     /* Wait until the complete message has been processed */
246     counter = 0;
247     do
248     {
249       busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
250       counter++;
251     }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
252 
253     if (busystatus != RESET)
254    {
255        status = ERROR;
256     }
257     else
258     {
259 
260       /* Read the Output block from the Output FIFO */
261       *(uint32_t*)(outputaddr) = CRYP_DataOut();
262       outputaddr+=4;
263       *(uint32_t*)(outputaddr) = CRYP_DataOut();
264       outputaddr+=4;
265       *(uint32_t*)(outputaddr) = CRYP_DataOut();
266       outputaddr+=4;
267       *(uint32_t*)(outputaddr) = CRYP_DataOut();
268       outputaddr+=4;
269     }
270   }
271 
272   /* Disable Crypto */
273   CRYP_Cmd(DISABLE);
274 
275   return status;
276 }
277 
278 /**
279   * @brief  Encrypt and decrypt using AES in CBC Mode
280   * @param  Mode: encryption or decryption Mode.
281   *          This parameter can be one of the following values:
282   *            @arg MODE_ENCRYPT: Encryption
283   *            @arg MODE_DECRYPT: Decryption
284   * @param  InitVectors: Initialisation Vectors used for AES algorithm.
285   * @param  Key: Key used for AES algorithm.
286   * @param  Keysize: length of the Key, must be a 128, 192 or 256.
287   * @param  Input: pointer to the Input buffer.
288   * @param  Ilength: length of the Input buffer, must be a multiple of 16.
289   * @param  Output: pointer to the returned buffer.
290   * @retval An ErrorStatus enumeration value:
291   *          - SUCCESS: Operation done
292   *          - ERROR: Operation failed
293   */
CRYP_AES_CBC(uint8_t Mode,uint8_t InitVectors[16],uint8_t * Key,uint16_t Keysize,uint8_t * Input,uint32_t Ilength,uint8_t * Output)294 ErrorStatus CRYP_AES_CBC(uint8_t Mode, uint8_t InitVectors[16], uint8_t *Key,
295                          uint16_t Keysize, uint8_t *Input, uint32_t Ilength,
296                          uint8_t *Output)
297 {
298   CRYP_InitTypeDef AES_CRYP_InitStructure;
299   CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
300   CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
301   __IO uint32_t counter = 0;
302   uint32_t busystatus = 0;
303   ErrorStatus status = SUCCESS;
304   uint32_t keyaddr    = (uint32_t)Key;
305   uint32_t inputaddr  = (uint32_t)Input;
306   uint32_t outputaddr = (uint32_t)Output;
307   uint32_t ivaddr = (uint32_t)InitVectors;
308   uint32_t i = 0;
309 
310   /* Crypto structures initialisation*/
311   CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
312 
313   switch(Keysize)
314   {
315     case 128:
316     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
317     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
318     keyaddr+=4;
319     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
320     keyaddr+=4;
321     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
322     keyaddr+=4;
323     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
324     break;
325     case 192:
326     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_192b;
327     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
328     keyaddr+=4;
329     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
330     keyaddr+=4;
331     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
332     keyaddr+=4;
333     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
334     keyaddr+=4;
335     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
336     keyaddr+=4;
337     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
338     break;
339     case 256:
340     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_256b;
341     AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
342     keyaddr+=4;
343     AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
344     keyaddr+=4;
345     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
346     keyaddr+=4;
347     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
348     keyaddr+=4;
349     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
350     keyaddr+=4;
351     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
352     keyaddr+=4;
353     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
354     keyaddr+=4;
355     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
356     break;
357     default:
358     break;
359   }
360 
361   /* CRYP Initialization Vectors */
362   AES_CRYP_IVInitStructure.CRYP_IV0Left = __REV(*(uint32_t*)(ivaddr));
363   ivaddr+=4;
364   AES_CRYP_IVInitStructure.CRYP_IV0Right= __REV(*(uint32_t*)(ivaddr));
365   ivaddr+=4;
366   AES_CRYP_IVInitStructure.CRYP_IV1Left = __REV(*(uint32_t*)(ivaddr));
367   ivaddr+=4;
368   AES_CRYP_IVInitStructure.CRYP_IV1Right= __REV(*(uint32_t*)(ivaddr));
369 
370 
371   /*------------------ AES Decryption ------------------*/
372   if(Mode == MODE_DECRYPT) /* AES decryption */
373   {
374     /* Flush IN/OUT FIFOs */
375     CRYP_FIFOFlush();
376 
377     /* Crypto Init for Key preparation for decryption process */
378     AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
379     AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
380     AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
381 
382     CRYP_Init(&AES_CRYP_InitStructure);
383 
384     /* Key Initialisation */
385     CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
386 
387     /* Enable Crypto processor */
388     CRYP_Cmd(ENABLE);
389 
390     /* wait until the Busy flag is RESET */
391     do
392     {
393       busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
394       counter++;
395     }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
396 
397     if (busystatus != RESET)
398    {
399        status = ERROR;
400     }
401     else
402     {
403       /* Crypto Init for decryption process */
404       AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
405     }
406   }
407   /*------------------ AES Encryption ------------------*/
408   else /* AES encryption */
409   {
410     CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
411 
412     /* Crypto Init for Encryption process */
413     AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
414   }
415   AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
416   AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
417   CRYP_Init(&AES_CRYP_InitStructure);
418 
419   /* CRYP Initialization Vectors */
420   CRYP_IVInit(&AES_CRYP_IVInitStructure);
421 
422   /* Flush IN/OUT FIFOs */
423   CRYP_FIFOFlush();
424 
425   /* Enable Crypto processor */
426   CRYP_Cmd(ENABLE);
427 
428   if(CRYP_GetCmdStatus() == DISABLE)
429   {
430     /* The CRYP peripheral clock is not enabled or the device doesn't embedd
431        the CRYP peripheral (please check the device sales type. */
432     return(ERROR);
433   }
434 
435   for(i=0; ((i<Ilength) && (status != ERROR)); i+=16)
436   {
437 
438     /* Write the Input block in the IN FIFO */
439     CRYP_DataIn(*(uint32_t*)(inputaddr));
440     inputaddr+=4;
441     CRYP_DataIn(*(uint32_t*)(inputaddr));
442     inputaddr+=4;
443     CRYP_DataIn(*(uint32_t*)(inputaddr));
444     inputaddr+=4;
445     CRYP_DataIn(*(uint32_t*)(inputaddr));
446     inputaddr+=4;
447     /* Wait until the complete message has been processed */
448     counter = 0;
449     do
450     {
451       busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
452       counter++;
453     }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
454 
455     if (busystatus != RESET)
456    {
457        status = ERROR;
458     }
459     else
460     {
461 
462       /* Read the Output block from the Output FIFO */
463       *(uint32_t*)(outputaddr) = CRYP_DataOut();
464       outputaddr+=4;
465       *(uint32_t*)(outputaddr) = CRYP_DataOut();
466       outputaddr+=4;
467       *(uint32_t*)(outputaddr) = CRYP_DataOut();
468       outputaddr+=4;
469       *(uint32_t*)(outputaddr) = CRYP_DataOut();
470       outputaddr+=4;
471     }
472   }
473 
474   /* Disable Crypto */
475   CRYP_Cmd(DISABLE);
476 
477   return status;
478 }
479 
480 /**
481   * @brief  Encrypt and decrypt using AES in CTR Mode
482   * @param  Mode: encryption or decryption Mode.
483   *           This parameter can be one of the following values:
484   *            @arg MODE_ENCRYPT: Encryption
485   *            @arg MODE_DECRYPT: Decryption
486   * @param  InitVectors: Initialisation Vectors used for AES algorithm.
487   * @param  Key: Key used for AES algorithm.
488   * @param  Keysize: length of the Key, must be a 128, 192 or 256.
489   * @param  Input: pointer to the Input buffer.
490   * @param  Ilength: length of the Input buffer, must be a multiple of 16.
491   * @param  Output: pointer to the returned buffer.
492   * @retval An ErrorStatus enumeration value:
493   *          - SUCCESS: Operation done
494   *          - ERROR: Operation failed
495   */
CRYP_AES_CTR(uint8_t Mode,uint8_t InitVectors[16],uint8_t * Key,uint16_t Keysize,uint8_t * Input,uint32_t Ilength,uint8_t * Output)496 ErrorStatus CRYP_AES_CTR(uint8_t Mode, uint8_t InitVectors[16], uint8_t *Key,
497                          uint16_t Keysize, uint8_t *Input, uint32_t Ilength,
498                          uint8_t *Output)
499 {
500   CRYP_InitTypeDef AES_CRYP_InitStructure;
501   CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
502   CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
503   __IO uint32_t counter = 0;
504   uint32_t busystatus = 0;
505   ErrorStatus status = SUCCESS;
506   uint32_t keyaddr    = (uint32_t)Key;
507   uint32_t inputaddr  = (uint32_t)Input;
508   uint32_t outputaddr = (uint32_t)Output;
509   uint32_t ivaddr     = (uint32_t)InitVectors;
510   uint32_t i = 0;
511 
512   /* Crypto structures initialisation*/
513   CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
514 
515   switch(Keysize)
516   {
517     case 128:
518     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
519     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
520     keyaddr+=4;
521     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
522     keyaddr+=4;
523     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
524     keyaddr+=4;
525     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
526     break;
527     case 192:
528     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_192b;
529     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
530     keyaddr+=4;
531     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
532     keyaddr+=4;
533     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
534     keyaddr+=4;
535     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
536     keyaddr+=4;
537     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
538     keyaddr+=4;
539     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
540     break;
541     case 256:
542     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_256b;
543     AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
544     keyaddr+=4;
545     AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
546     keyaddr+=4;
547     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
548     keyaddr+=4;
549     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
550     keyaddr+=4;
551     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
552     keyaddr+=4;
553     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
554     keyaddr+=4;
555     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
556     keyaddr+=4;
557     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
558     break;
559     default:
560     break;
561   }
562   /* CRYP Initialization Vectors */
563   AES_CRYP_IVInitStructure.CRYP_IV0Left = __REV(*(uint32_t*)(ivaddr));
564   ivaddr+=4;
565   AES_CRYP_IVInitStructure.CRYP_IV0Right= __REV(*(uint32_t*)(ivaddr));
566   ivaddr+=4;
567   AES_CRYP_IVInitStructure.CRYP_IV1Left = __REV(*(uint32_t*)(ivaddr));
568   ivaddr+=4;
569   AES_CRYP_IVInitStructure.CRYP_IV1Right= __REV(*(uint32_t*)(ivaddr));
570 
571   /* Key Initialisation */
572   CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
573 
574   /*------------------ AES Decryption ------------------*/
575   if(Mode == MODE_DECRYPT) /* AES decryption */
576   {
577     /* Crypto Init for decryption process */
578     AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
579   }
580   /*------------------ AES Encryption ------------------*/
581   else /* AES encryption */
582   {
583     /* Crypto Init for Encryption process */
584     AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
585   }
586   AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
587   AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
588   CRYP_Init(&AES_CRYP_InitStructure);
589 
590   /* CRYP Initialization Vectors */
591   CRYP_IVInit(&AES_CRYP_IVInitStructure);
592 
593   /* Flush IN/OUT FIFOs */
594   CRYP_FIFOFlush();
595 
596   /* Enable Crypto processor */
597   CRYP_Cmd(ENABLE);
598 
599   if(CRYP_GetCmdStatus() == DISABLE)
600   {
601     /* The CRYP peripheral clock is not enabled or the device doesn't embedd
602        the CRYP peripheral (please check the device sales type. */
603     return(ERROR);
604   }
605 
606   for(i=0; ((i<Ilength) && (status != ERROR)); i+=16)
607   {
608 
609     /* Write the Input block in the IN FIFO */
610     CRYP_DataIn(*(uint32_t*)(inputaddr));
611     inputaddr+=4;
612     CRYP_DataIn(*(uint32_t*)(inputaddr));
613     inputaddr+=4;
614     CRYP_DataIn(*(uint32_t*)(inputaddr));
615     inputaddr+=4;
616     CRYP_DataIn(*(uint32_t*)(inputaddr));
617     inputaddr+=4;
618     /* Wait until the complete message has been processed */
619     counter = 0;
620     do
621     {
622       busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
623       counter++;
624     }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
625 
626     if (busystatus != RESET)
627    {
628        status = ERROR;
629     }
630     else
631     {
632 
633       /* Read the Output block from the Output FIFO */
634       *(uint32_t*)(outputaddr) = CRYP_DataOut();
635       outputaddr+=4;
636       *(uint32_t*)(outputaddr) = CRYP_DataOut();
637       outputaddr+=4;
638       *(uint32_t*)(outputaddr) = CRYP_DataOut();
639       outputaddr+=4;
640       *(uint32_t*)(outputaddr) = CRYP_DataOut();
641       outputaddr+=4;
642     }
643   }
644   /* Disable Crypto */
645   CRYP_Cmd(DISABLE);
646 
647   return status;
648 }
649 
650 /**
651   * @brief  Encrypt and decrypt using AES in GCM Mode. The GCM and CCM modes
652   *         are available only on STM32F437x Devices.
653   * @param  Mode: encryption or decryption Mode.
654   *          This parameter can be one of the following values:
655   *            @arg MODE_ENCRYPT: Encryption
656   *            @arg MODE_DECRYPT: Decryption
657   * @param  InitVectors: Initialisation Vectors used for AES algorithm.
658   * @param  Key: Key used for AES algorithm.
659   * @param  Keysize: length of the Key, must be a 128, 192 or 256.
660   * @param  Input: pointer to the Input buffer.
661   * @param  Ilength: length of the Input buffer in bytes, must be a multiple of 16.
662   * @param  Header: pointer to the header buffer.
663   * @param  Hlength: length of the header buffer in bytes, must be a multiple of 16.
664   * @param  Output: pointer to the returned buffer.
665   * @param  AuthTAG: pointer to the authentication TAG buffer.
666   * @retval An ErrorStatus enumeration value:
667   *          - SUCCESS: Operation done
668   *          - ERROR: Operation failed
669   */
CRYP_AES_GCM(uint8_t Mode,uint8_t InitVectors[16],uint8_t * Key,uint16_t Keysize,uint8_t * Input,uint32_t ILength,uint8_t * Header,uint32_t HLength,uint8_t * Output,uint8_t * AuthTAG)670 ErrorStatus CRYP_AES_GCM(uint8_t Mode, uint8_t InitVectors[16],
671                          uint8_t *Key, uint16_t Keysize,
672                          uint8_t *Input, uint32_t ILength,
673                          uint8_t *Header, uint32_t HLength,
674                          uint8_t *Output, uint8_t *AuthTAG)
675 {
676   CRYP_InitTypeDef AES_CRYP_InitStructure;
677   CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
678   CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
679   __IO uint32_t counter = 0;
680   uint32_t busystatus = 0;
681   ErrorStatus status = SUCCESS;
682   uint32_t keyaddr    = (uint32_t)Key;
683   uint32_t inputaddr  = (uint32_t)Input;
684   uint32_t outputaddr = (uint32_t)Output;
685   uint32_t ivaddr     = (uint32_t)InitVectors;
686   uint32_t headeraddr = (uint32_t)Header;
687   uint32_t tagaddr = (uint32_t)AuthTAG;
688   uint64_t headerlength = HLength * 8;/* header length in bits */
689   uint64_t inputlength = ILength * 8;/* input length in bits */
690   uint32_t loopcounter = 0;
691 
692   /* Crypto structures initialisation*/
693   CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
694 
695   switch(Keysize)
696   {
697     case 128:
698     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
699     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
700     keyaddr+=4;
701     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
702     keyaddr+=4;
703     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
704     keyaddr+=4;
705     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
706     break;
707     case 192:
708     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_192b;
709     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
710     keyaddr+=4;
711     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
712     keyaddr+=4;
713     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
714     keyaddr+=4;
715     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
716     keyaddr+=4;
717     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
718     keyaddr+=4;
719     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
720     break;
721     case 256:
722     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_256b;
723     AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
724     keyaddr+=4;
725     AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
726     keyaddr+=4;
727     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
728     keyaddr+=4;
729     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
730     keyaddr+=4;
731     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
732     keyaddr+=4;
733     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
734     keyaddr+=4;
735     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
736     keyaddr+=4;
737     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
738     break;
739     default:
740     break;
741   }
742 
743   /* CRYP Initialization Vectors */
744   AES_CRYP_IVInitStructure.CRYP_IV0Left = __REV(*(uint32_t*)(ivaddr));
745   ivaddr+=4;
746   AES_CRYP_IVInitStructure.CRYP_IV0Right= __REV(*(uint32_t*)(ivaddr));
747   ivaddr+=4;
748   AES_CRYP_IVInitStructure.CRYP_IV1Left = __REV(*(uint32_t*)(ivaddr));
749   ivaddr+=4;
750   AES_CRYP_IVInitStructure.CRYP_IV1Right= __REV(*(uint32_t*)(ivaddr));
751 
752   /*------------------ AES Encryption ------------------*/
753   if(Mode == MODE_ENCRYPT) /* AES encryption */
754   {
755     /* Flush IN/OUT FIFOs */
756     CRYP_FIFOFlush();
757 
758     /* Key Initialisation */
759     CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
760 
761     /* CRYP Initialization Vectors */
762     CRYP_IVInit(&AES_CRYP_IVInitStructure);
763 
764     /* Crypto Init for Key preparation for decryption process */
765     AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
766     AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_GCM;
767     AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
768     CRYP_Init(&AES_CRYP_InitStructure);
769 
770     /***************************** Init phase *********************************/
771     /* Select init phase */
772     CRYP_PhaseConfig(CRYP_Phase_Init);
773 
774     /* Enable Crypto processor */
775     CRYP_Cmd(ENABLE);
776 
777     /* Wait for CRYPEN bit to be 0 */
778     while(CRYP_GetCmdStatus() == ENABLE)
779     {
780     }
781 
782     /***************************** header phase *******************************/
783     if(HLength != 0)
784     {
785       /* Select header phase */
786       CRYP_PhaseConfig(CRYP_Phase_Header);
787 
788       /* Enable Crypto processor */
789       CRYP_Cmd(ENABLE);
790 
791       if(CRYP_GetCmdStatus() == DISABLE)
792       {
793          /* The CRYP peripheral clock is not enabled or the device doesn't embedd
794             the CRYP peripheral (please check the device sales type. */
795          return(ERROR);
796       }
797 
798       for(loopcounter = 0; (loopcounter < HLength); loopcounter+=16)
799       {
800         /* Wait until the IFEM flag is reset */
801         while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
802         {
803         }
804 
805         /* Write the Input block in the IN FIFO */
806         CRYP_DataIn(*(uint32_t*)(headeraddr));
807         headeraddr+=4;
808         CRYP_DataIn(*(uint32_t*)(headeraddr));
809         headeraddr+=4;
810         CRYP_DataIn(*(uint32_t*)(headeraddr));
811         headeraddr+=4;
812         CRYP_DataIn(*(uint32_t*)(headeraddr));
813         headeraddr+=4;
814       }
815 
816       /* Wait until the complete message has been processed */
817       counter = 0;
818       do
819       {
820         busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
821         counter++;
822       }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
823 
824       if (busystatus != RESET)
825       {
826         status = ERROR;
827       }
828     }
829 
830     /**************************** payload phase *******************************/
831     if(ILength != 0)
832     {
833       /* Select payload phase */
834       CRYP_PhaseConfig(CRYP_Phase_Payload);
835 
836       /* Enable Crypto processor */
837       CRYP_Cmd(ENABLE);
838 
839       if(CRYP_GetCmdStatus() == DISABLE)
840       {
841         /* The CRYP peripheral clock is not enabled or the device doesn't embedd
842            the CRYP peripheral (please check the device sales type. */
843         return(ERROR);
844       }
845 
846       for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
847       {
848         /* Wait until the IFEM flag is reset */
849         while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
850         {
851         }
852         /* Write the Input block in the IN FIFO */
853         CRYP_DataIn(*(uint32_t*)(inputaddr));
854         inputaddr+=4;
855         CRYP_DataIn(*(uint32_t*)(inputaddr));
856         inputaddr+=4;
857         CRYP_DataIn(*(uint32_t*)(inputaddr));
858         inputaddr+=4;
859         CRYP_DataIn(*(uint32_t*)(inputaddr));
860         inputaddr+=4;
861 
862         /* Wait until the complete message has been processed */
863         counter = 0;
864         do
865         {
866           busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
867           counter++;
868         }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
869 
870         if (busystatus != RESET)
871         {
872           status = ERROR;
873         }
874         else
875         {
876           /* Wait until the OFNE flag is reset */
877           while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
878           {
879           }
880 
881           /* Read the Output block from the Output FIFO */
882           *(uint32_t*)(outputaddr) = CRYP_DataOut();
883           outputaddr+=4;
884           *(uint32_t*)(outputaddr) = CRYP_DataOut();
885           outputaddr+=4;
886           *(uint32_t*)(outputaddr) = CRYP_DataOut();
887           outputaddr+=4;
888           *(uint32_t*)(outputaddr) = CRYP_DataOut();
889           outputaddr+=4;
890         }
891       }
892     }
893 
894     /***************************** final phase ********************************/
895     /* Select final phase */
896     CRYP_PhaseConfig(CRYP_Phase_Final);
897 
898     /* Enable Crypto processor */
899     CRYP_Cmd(ENABLE);
900 
901     if(CRYP_GetCmdStatus() == DISABLE)
902     {
903       /* The CRYP peripheral clock is not enabled or the device doesn't embedd
904          the CRYP peripheral (please check the device sales type. */
905       return(ERROR);
906     }
907 
908     /* Write number of bits concatenated with header in the IN FIFO */
909     CRYP_DataIn(__REV(headerlength>>32));
910     CRYP_DataIn(__REV(headerlength));
911     CRYP_DataIn(__REV(inputlength>>32));
912     CRYP_DataIn(__REV(inputlength));
913     /* Wait until the OFNE flag is reset */
914     while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
915     {
916     }
917 
918     tagaddr = (uint32_t)AuthTAG;
919     /* Read the Auth TAG in the IN FIFO */
920     *(uint32_t*)(tagaddr) = CRYP_DataOut();
921     tagaddr+=4;
922     *(uint32_t*)(tagaddr) = CRYP_DataOut();
923     tagaddr+=4;
924     *(uint32_t*)(tagaddr) = CRYP_DataOut();
925     tagaddr+=4;
926     *(uint32_t*)(tagaddr) = CRYP_DataOut();
927     tagaddr+=4;
928   }
929   /*------------------ AES Decryption ------------------*/
930   else /* AES decryption */
931   {
932     /* Flush IN/OUT FIFOs */
933     CRYP_FIFOFlush();
934 
935     /* Key Initialisation */
936     CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
937 
938     /* CRYP Initialization Vectors */
939     CRYP_IVInit(&AES_CRYP_IVInitStructure);
940 
941     /* Crypto Init for Key preparation for decryption process */
942     AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
943     AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_GCM;
944     AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
945     CRYP_Init(&AES_CRYP_InitStructure);
946 
947     /***************************** Init phase *********************************/
948     /* Select init phase */
949     CRYP_PhaseConfig(CRYP_Phase_Init);
950 
951     /* Enable Crypto processor */
952     CRYP_Cmd(ENABLE);
953 
954     /* Wait for CRYPEN bit to be 0 */
955     while(CRYP_GetCmdStatus() == ENABLE)
956     {
957     }
958 
959     /***************************** header phase *******************************/
960     if(HLength != 0)
961     {
962       /* Select header phase */
963       CRYP_PhaseConfig(CRYP_Phase_Header);
964 
965       /* Enable Crypto processor */
966       CRYP_Cmd(ENABLE);
967 
968       if(CRYP_GetCmdStatus() == DISABLE)
969       {
970         /* The CRYP peripheral clock is not enabled or the device doesn't embedd
971            the CRYP peripheral (please check the device sales type. */
972         return(ERROR);
973       }
974 
975       for(loopcounter = 0; (loopcounter < HLength); loopcounter+=16)
976       {
977         /* Wait until the IFEM flag is reset */
978         while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
979         {
980         }
981 
982         /* Write the Input block in the IN FIFO */
983         CRYP_DataIn(*(uint32_t*)(headeraddr));
984         headeraddr+=4;
985         CRYP_DataIn(*(uint32_t*)(headeraddr));
986         headeraddr+=4;
987         CRYP_DataIn(*(uint32_t*)(headeraddr));
988         headeraddr+=4;
989         CRYP_DataIn(*(uint32_t*)(headeraddr));
990         headeraddr+=4;
991       }
992 
993       /* Wait until the complete message has been processed */
994       counter = 0;
995       do
996       {
997         busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
998         counter++;
999       }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1000 
1001       if (busystatus != RESET)
1002       {
1003         status = ERROR;
1004       }
1005     }
1006 
1007     /**************************** payload phase *******************************/
1008     if(ILength != 0)
1009     {
1010       /* Select payload phase */
1011       CRYP_PhaseConfig(CRYP_Phase_Payload);
1012 
1013       /* Enable Crypto processor */
1014       CRYP_Cmd(ENABLE);
1015 
1016       if(CRYP_GetCmdStatus() == DISABLE)
1017       {
1018         /* The CRYP peripheral clock is not enabled or the device doesn't embedd
1019            the CRYP peripheral (please check the device sales type. */
1020         return(ERROR);
1021       }
1022 
1023       for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
1024       {
1025         /* Wait until the IFEM flag is reset */
1026         while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1027         {
1028         }
1029         /* Write the Input block in the IN FIFO */
1030         CRYP_DataIn(*(uint32_t*)(inputaddr));
1031         inputaddr+=4;
1032         CRYP_DataIn(*(uint32_t*)(inputaddr));
1033         inputaddr+=4;
1034         CRYP_DataIn(*(uint32_t*)(inputaddr));
1035         inputaddr+=4;
1036         CRYP_DataIn(*(uint32_t*)(inputaddr));
1037         inputaddr+=4;
1038 
1039         /* Wait until the complete message has been processed */
1040         counter = 0;
1041         do
1042         {
1043           busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1044           counter++;
1045         }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1046 
1047         if (busystatus != RESET)
1048         {
1049           status = ERROR;
1050         }
1051         else
1052         {
1053           /* Wait until the OFNE flag is reset */
1054           while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1055           {
1056           }
1057 
1058           /* Read the Output block from the Output FIFO */
1059           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1060           outputaddr+=4;
1061           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1062           outputaddr+=4;
1063           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1064           outputaddr+=4;
1065           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1066           outputaddr+=4;
1067         }
1068       }
1069     }
1070 
1071     /***************************** final phase ********************************/
1072     /* Select final phase */
1073     CRYP_PhaseConfig(CRYP_Phase_Final);
1074 
1075     /* Enable Crypto processor */
1076     CRYP_Cmd(ENABLE);
1077 
1078     if(CRYP_GetCmdStatus() == DISABLE)
1079     {
1080       /* The CRYP peripheral clock is not enabled or the device doesn't embedd
1081          the CRYP peripheral (please check the device sales type. */
1082       return(ERROR);
1083     }
1084 
1085     /* Write number of bits concatenated with header in the IN FIFO */
1086     CRYP_DataIn(__REV(headerlength>>32));
1087     CRYP_DataIn(__REV(headerlength));
1088     CRYP_DataIn(__REV(inputlength>>32));
1089     CRYP_DataIn(__REV(inputlength));
1090     /* Wait until the OFNE flag is reset */
1091     while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1092     {
1093     }
1094 
1095     tagaddr = (uint32_t)AuthTAG;
1096     /* Read the Auth TAG in the IN FIFO */
1097     *(uint32_t*)(tagaddr) = CRYP_DataOut();
1098     tagaddr+=4;
1099     *(uint32_t*)(tagaddr) = CRYP_DataOut();
1100     tagaddr+=4;
1101     *(uint32_t*)(tagaddr) = CRYP_DataOut();
1102     tagaddr+=4;
1103     *(uint32_t*)(tagaddr) = CRYP_DataOut();
1104     tagaddr+=4;
1105   }
1106   /* Disable Crypto */
1107   CRYP_Cmd(DISABLE);
1108 
1109   return status;
1110 }
1111 
1112 /**
1113   * @brief  Encrypt and decrypt using AES in CCM Mode. The GCM and CCM modes
1114   *         are available only on STM32F437x Devices.
1115   * @param  Mode: encryption or decryption Mode.
1116   *          This parameter can be one of the following values:
1117   *            @arg MODE_ENCRYPT: Encryption
1118   *            @arg MODE_DECRYPT: Decryption
1119   * @param  Nonce: the nounce used for AES algorithm. It shall be unique for each processing.
1120   * @param  Key: Key used for AES algorithm.
1121   * @param  Keysize: length of the Key, must be a 128, 192 or 256.
1122   * @param  Input: pointer to the Input buffer.
1123   * @param  Ilength: length of the Input buffer in bytes, must be a multiple of 16.
1124   * @param  Header: pointer to the header buffer.
1125   * @param  Hlength: length of the header buffer in bytes.
1126   * @param  HBuffer: pointer to temporary buffer used to append the header
1127   *         HBuffer size must be equal to Hlength + 21
1128   * @param  Output: pointer to the returned buffer.
1129   * @param  AuthTAG: pointer to the authentication TAG buffer.
1130   * @param  TAGSize: the size of the TAG (called also MAC).
1131   * @retval An ErrorStatus enumeration value:
1132   *          - SUCCESS: Operation done
1133   *          - ERROR: Operation failed
1134   */
CRYP_AES_CCM(uint8_t Mode,uint8_t * Nonce,uint32_t NonceSize,uint8_t * Key,uint16_t Keysize,uint8_t * Input,uint32_t ILength,uint8_t * Header,uint32_t HLength,uint8_t * HBuffer,uint8_t * Output,uint8_t * AuthTAG,uint32_t TAGSize)1135 ErrorStatus CRYP_AES_CCM(uint8_t Mode,
1136                          uint8_t* Nonce, uint32_t NonceSize,
1137                          uint8_t *Key, uint16_t Keysize,
1138                          uint8_t *Input, uint32_t ILength,
1139                          uint8_t *Header, uint32_t HLength, uint8_t *HBuffer,
1140                          uint8_t *Output,
1141                          uint8_t *AuthTAG, uint32_t TAGSize)
1142 {
1143   CRYP_InitTypeDef AES_CRYP_InitStructure;
1144   CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
1145   CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
1146   __IO uint32_t counter = 0;
1147   uint32_t busystatus = 0;
1148   ErrorStatus status = SUCCESS;
1149   uint32_t keyaddr    = (uint32_t)Key;
1150   uint32_t inputaddr  = (uint32_t)Input;
1151   uint32_t outputaddr = (uint32_t)Output;
1152   uint32_t headeraddr = (uint32_t)Header;
1153   uint32_t tagaddr = (uint32_t)AuthTAG;
1154   uint32_t headersize = HLength;
1155   uint32_t loopcounter = 0;
1156   uint32_t bufferidx = 0;
1157   uint8_t blockb0[16] = {0};/* Block B0 */
1158   uint8_t ctr[16] = {0}; /* Counter */
1159   uint32_t temptag[4] = {0}; /* temporary TAG (MAC) */
1160   uint32_t ctraddr = (uint32_t)ctr;
1161   uint32_t b0addr = (uint32_t)blockb0;
1162 
1163   /************************ Formatting the header block ***********************/
1164   if(headersize != 0)
1165   {
1166     /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1167     if(headersize < 65280)
1168     {
1169       HBuffer[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
1170       HBuffer[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
1171       headersize += 2;
1172     }
1173     else
1174     {
1175       /* header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1176       HBuffer[bufferidx++] = 0xFF;
1177       HBuffer[bufferidx++] = 0xFE;
1178       HBuffer[bufferidx++] = headersize & 0xff000000;
1179       HBuffer[bufferidx++] = headersize & 0x00ff0000;
1180       HBuffer[bufferidx++] = headersize & 0x0000ff00;
1181       HBuffer[bufferidx++] = headersize & 0x000000ff;
1182       headersize += 6;
1183     }
1184     /* Copy the header buffer in internal buffer "HBuffer" */
1185     for(loopcounter = 0; loopcounter < headersize; loopcounter++)
1186     {
1187       HBuffer[bufferidx++] = Header[loopcounter];
1188     }
1189     /* Check if the header size is modulo 16 */
1190     if ((headersize % 16) != 0)
1191     {
1192       /* Padd the header buffer with 0s till the HBuffer length is modulo 16 */
1193       for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
1194       {
1195         HBuffer[loopcounter] = 0;
1196       }
1197       /* Set the header size to modulo 16 */
1198       headersize = ((headersize/16) + 1) * 16;
1199     }
1200     /* set the pointer headeraddr to HBuffer */
1201     headeraddr = (uint32_t)HBuffer;
1202   }
1203   /************************* Formatting the block B0 **************************/
1204   if(headersize != 0)
1205   {
1206     blockb0[0] = 0x40;
1207   }
1208   /* Flags byte */
1209   blockb0[0] |= 0u | (((( (uint8_t) TAGSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - NonceSize) - 1) & 0x07);
1210 
1211   for (loopcounter = 0; loopcounter < NonceSize; loopcounter++)
1212   {
1213     blockb0[loopcounter+1] = Nonce[loopcounter];
1214   }
1215   for ( ; loopcounter < 13; loopcounter++)
1216   {
1217     blockb0[loopcounter+1] = 0;
1218   }
1219 
1220   blockb0[14] = ((ILength >> 8) & 0xFF);
1221   blockb0[15] = (ILength & 0xFF);
1222 
1223   /************************* Formatting the initial counter *******************/
1224   /* Byte 0:
1225      Bits 7 and 6 are reserved and shall be set to 0
1226      Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
1227      are distinct from B0
1228      Bits 0, 1, and 2 contain the same encoding of q as in B0
1229   */
1230   ctr[0] = blockb0[0] & 0x07;
1231   /* byte 1 to NonceSize is the IV (Nonce) */
1232   for(loopcounter = 1; loopcounter < NonceSize + 1; loopcounter++)
1233   {
1234     ctr[loopcounter] = blockb0[loopcounter];
1235   }
1236   /* Set the LSB to 1 */
1237   ctr[15] |= 0x01;
1238 
1239   /* Crypto structures initialisation*/
1240   CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
1241 
1242   switch(Keysize)
1243   {
1244     case 128:
1245     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
1246     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
1247     keyaddr+=4;
1248     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
1249     keyaddr+=4;
1250     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
1251     keyaddr+=4;
1252     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
1253     break;
1254     case 192:
1255     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_192b;
1256     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
1257     keyaddr+=4;
1258     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
1259     keyaddr+=4;
1260     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
1261     keyaddr+=4;
1262     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
1263     keyaddr+=4;
1264     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
1265     keyaddr+=4;
1266     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
1267     break;
1268     case 256:
1269     AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_256b;
1270     AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
1271     keyaddr+=4;
1272     AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
1273     keyaddr+=4;
1274     AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
1275     keyaddr+=4;
1276     AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
1277     keyaddr+=4;
1278     AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
1279     keyaddr+=4;
1280     AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
1281     keyaddr+=4;
1282     AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
1283     keyaddr+=4;
1284     AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
1285     break;
1286     default:
1287     break;
1288   }
1289 
1290   /* CRYP Initialization Vectors */
1291   AES_CRYP_IVInitStructure.CRYP_IV0Left = (__REV(*(uint32_t*)(ctraddr)));
1292   ctraddr+=4;
1293   AES_CRYP_IVInitStructure.CRYP_IV0Right= (__REV(*(uint32_t*)(ctraddr)));
1294   ctraddr+=4;
1295   AES_CRYP_IVInitStructure.CRYP_IV1Left = (__REV(*(uint32_t*)(ctraddr)));
1296   ctraddr+=4;
1297   AES_CRYP_IVInitStructure.CRYP_IV1Right= (__REV(*(uint32_t*)(ctraddr)));
1298 
1299   /*------------------ AES Encryption ------------------*/
1300   if(Mode == MODE_ENCRYPT) /* AES encryption */
1301   {
1302     /* Flush IN/OUT FIFOs */
1303     CRYP_FIFOFlush();
1304 
1305     /* Key Initialisation */
1306     CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
1307 
1308     /* CRYP Initialization Vectors */
1309     CRYP_IVInit(&AES_CRYP_IVInitStructure);
1310 
1311     /* Crypto Init for Key preparation for decryption process */
1312     AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
1313     AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CCM;
1314     AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
1315     CRYP_Init(&AES_CRYP_InitStructure);
1316 
1317     /***************************** Init phase *********************************/
1318     /* Select init phase */
1319     CRYP_PhaseConfig(CRYP_Phase_Init);
1320 
1321     b0addr = (uint32_t)blockb0;
1322     /* Write the blockb0 block in the IN FIFO */
1323     CRYP_DataIn((*(uint32_t*)(b0addr)));
1324     b0addr+=4;
1325     CRYP_DataIn((*(uint32_t*)(b0addr)));
1326     b0addr+=4;
1327     CRYP_DataIn((*(uint32_t*)(b0addr)));
1328     b0addr+=4;
1329     CRYP_DataIn((*(uint32_t*)(b0addr)));
1330 
1331     /* Enable Crypto processor */
1332     CRYP_Cmd(ENABLE);
1333 
1334     /* Wait for CRYPEN bit to be 0 */
1335     while(CRYP_GetCmdStatus() == ENABLE)
1336     {
1337     }
1338     /***************************** header phase *******************************/
1339     if(headersize != 0)
1340     {
1341       /* Select header phase */
1342       CRYP_PhaseConfig(CRYP_Phase_Header);
1343 
1344       /* Enable Crypto processor */
1345       CRYP_Cmd(ENABLE);
1346 
1347       if(CRYP_GetCmdStatus() == DISABLE)
1348       {
1349          /* The CRYP peripheral clock is not enabled or the device doesn't embedd
1350             the CRYP peripheral (please check the device sales type. */
1351          return(ERROR);
1352       }
1353 
1354       for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1355       {
1356         /* Wait until the IFEM flag is reset */
1357         while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1358         {
1359         }
1360 
1361         /* Write the Input block in the IN FIFO */
1362         CRYP_DataIn(*(uint32_t*)(headeraddr));
1363         headeraddr+=4;
1364         CRYP_DataIn(*(uint32_t*)(headeraddr));
1365         headeraddr+=4;
1366         CRYP_DataIn(*(uint32_t*)(headeraddr));
1367         headeraddr+=4;
1368         CRYP_DataIn(*(uint32_t*)(headeraddr));
1369         headeraddr+=4;
1370       }
1371 
1372       /* Wait until the complete message has been processed */
1373       counter = 0;
1374       do
1375       {
1376         busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1377         counter++;
1378       }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1379 
1380       if (busystatus != RESET)
1381       {
1382         status = ERROR;
1383       }
1384     }
1385 
1386     /**************************** payload phase *******************************/
1387     if(ILength != 0)
1388     {
1389       /* Select payload phase */
1390       CRYP_PhaseConfig(CRYP_Phase_Payload);
1391 
1392       /* Enable Crypto processor */
1393       CRYP_Cmd(ENABLE);
1394 
1395       if(CRYP_GetCmdStatus() == DISABLE)
1396       {
1397         /* The CRYP peripheral clock is not enabled or the device doesn't embedd
1398            the CRYP peripheral (please check the device sales type. */
1399         return(ERROR);
1400       }
1401 
1402       for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
1403       {
1404         /* Wait until the IFEM flag is reset */
1405         while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1406         {
1407         }
1408 
1409         /* Write the Input block in the IN FIFO */
1410         CRYP_DataIn(*(uint32_t*)(inputaddr));
1411         inputaddr+=4;
1412         CRYP_DataIn(*(uint32_t*)(inputaddr));
1413         inputaddr+=4;
1414         CRYP_DataIn(*(uint32_t*)(inputaddr));
1415         inputaddr+=4;
1416         CRYP_DataIn(*(uint32_t*)(inputaddr));
1417         inputaddr+=4;
1418 
1419         /* Wait until the complete message has been processed */
1420         counter = 0;
1421         do
1422         {
1423           busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1424           counter++;
1425         }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1426 
1427         if (busystatus != RESET)
1428         {
1429           status = ERROR;
1430         }
1431         else
1432         {
1433           /* Wait until the OFNE flag is reset */
1434           while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1435           {
1436           }
1437 
1438           /* Read the Output block from the Output FIFO */
1439           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1440           outputaddr+=4;
1441           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1442           outputaddr+=4;
1443           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1444           outputaddr+=4;
1445           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1446           outputaddr+=4;
1447         }
1448       }
1449     }
1450 
1451     /***************************** final phase ********************************/
1452     /* Select final phase */
1453     CRYP_PhaseConfig(CRYP_Phase_Final);
1454 
1455     /* Enable Crypto processor */
1456     CRYP_Cmd(ENABLE);
1457 
1458     if(CRYP_GetCmdStatus() == DISABLE)
1459     {
1460       /* The CRYP peripheral clock is not enabled or the device doesn't embedd
1461          the CRYP peripheral (please check the device sales type. */
1462       return(ERROR);
1463     }
1464 
1465     ctraddr = (uint32_t)ctr;
1466     /* Write the counter block in the IN FIFO */
1467     CRYP_DataIn(*(uint32_t*)(ctraddr));
1468     ctraddr+=4;
1469     CRYP_DataIn(*(uint32_t*)(ctraddr));
1470     ctraddr+=4;
1471     CRYP_DataIn(*(uint32_t*)(ctraddr));
1472     ctraddr+=4;
1473     /* Reset bit 0 (after 8-bit swap) is equivalent to reset bit 24 (before 8-bit swap) */
1474     CRYP_DataIn(*(uint32_t*)(ctraddr) & 0xfeffffff);
1475 
1476     /* Wait until the OFNE flag is reset */
1477     while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1478     {
1479     }
1480 
1481     /* Read the Auth TAG in the IN FIFO */
1482     temptag[0] = CRYP_DataOut();
1483     temptag[1] = CRYP_DataOut();
1484     temptag[2] = CRYP_DataOut();
1485     temptag[3] = CRYP_DataOut();
1486   }
1487   /*------------------ AES Decryption ------------------*/
1488   else /* AES decryption */
1489   {
1490     /* Flush IN/OUT FIFOs */
1491     CRYP_FIFOFlush();
1492 
1493     /* Key Initialisation */
1494     CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
1495 
1496     /* CRYP Initialization Vectors */
1497     CRYP_IVInit(&AES_CRYP_IVInitStructure);
1498 
1499     /* Crypto Init for Key preparation for decryption process */
1500     AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
1501     AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CCM;
1502     AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
1503     CRYP_Init(&AES_CRYP_InitStructure);
1504 
1505     /***************************** Init phase *********************************/
1506     /* Select init phase */
1507     CRYP_PhaseConfig(CRYP_Phase_Init);
1508 
1509     b0addr = (uint32_t)blockb0;
1510     /* Write the blockb0 block in the IN FIFO */
1511     CRYP_DataIn((*(uint32_t*)(b0addr)));
1512     b0addr+=4;
1513     CRYP_DataIn((*(uint32_t*)(b0addr)));
1514     b0addr+=4;
1515     CRYP_DataIn((*(uint32_t*)(b0addr)));
1516     b0addr+=4;
1517     CRYP_DataIn((*(uint32_t*)(b0addr)));
1518 
1519     /* Enable Crypto processor */
1520     CRYP_Cmd(ENABLE);
1521 
1522     /* Wait for CRYPEN bit to be 0 */
1523     while(CRYP_GetCmdStatus() == ENABLE)
1524     {
1525     }
1526 
1527     /***************************** header phase *******************************/
1528     if(headersize != 0)
1529     {
1530       /* Select header phase */
1531       CRYP_PhaseConfig(CRYP_Phase_Header);
1532 
1533       /* Enable Crypto processor */
1534       CRYP_Cmd(ENABLE);
1535 
1536       if(CRYP_GetCmdStatus() == DISABLE)
1537       {
1538         /* The CRYP peripheral clock is not enabled or the device doesn't embedd
1539            the CRYP peripheral (please check the device sales type. */
1540         return(ERROR);
1541       }
1542 
1543       for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1544       {
1545         /* Wait until the IFEM flag is reset */
1546         while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1547         {
1548         }
1549 
1550         /* Write the Input block in the IN FIFO */
1551         CRYP_DataIn(*(uint32_t*)(headeraddr));
1552         headeraddr+=4;
1553         CRYP_DataIn(*(uint32_t*)(headeraddr));
1554         headeraddr+=4;
1555         CRYP_DataIn(*(uint32_t*)(headeraddr));
1556         headeraddr+=4;
1557         CRYP_DataIn(*(uint32_t*)(headeraddr));
1558         headeraddr+=4;
1559       }
1560 
1561       /* Wait until the complete message has been processed */
1562       counter = 0;
1563       do
1564       {
1565         busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1566         counter++;
1567       }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1568 
1569       if (busystatus != RESET)
1570       {
1571         status = ERROR;
1572       }
1573     }
1574 
1575     /**************************** payload phase *******************************/
1576     if(ILength != 0)
1577     {
1578       /* Select payload phase */
1579       CRYP_PhaseConfig(CRYP_Phase_Payload);
1580 
1581       /* Enable Crypto processor */
1582       CRYP_Cmd(ENABLE);
1583 
1584       if(CRYP_GetCmdStatus() == DISABLE)
1585       {
1586         /* The CRYP peripheral clock is not enabled or the device doesn't embedd
1587            the CRYP peripheral (please check the device sales type. */
1588         return(ERROR);
1589       }
1590 
1591       for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
1592       {
1593         /* Wait until the IFEM flag is reset */
1594         while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1595         {
1596         }
1597 
1598         /* Write the Input block in the IN FIFO */
1599         CRYP_DataIn(*(uint32_t*)(inputaddr));
1600         inputaddr+=4;
1601         CRYP_DataIn(*(uint32_t*)(inputaddr));
1602         inputaddr+=4;
1603         CRYP_DataIn(*(uint32_t*)(inputaddr));
1604         inputaddr+=4;
1605         CRYP_DataIn(*(uint32_t*)(inputaddr));
1606         inputaddr+=4;
1607 
1608         /* Wait until the complete message has been processed */
1609         counter = 0;
1610         do
1611         {
1612           busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1613           counter++;
1614         }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1615 
1616         if (busystatus != RESET)
1617         {
1618           status = ERROR;
1619         }
1620         else
1621         {
1622           /* Wait until the OFNE flag is reset */
1623           while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1624           {
1625           }
1626 
1627           /* Read the Output block from the Output FIFO */
1628           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1629           outputaddr+=4;
1630           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1631           outputaddr+=4;
1632           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1633           outputaddr+=4;
1634           *(uint32_t*)(outputaddr) = CRYP_DataOut();
1635           outputaddr+=4;
1636         }
1637       }
1638     }
1639 
1640     /***************************** final phase ********************************/
1641     /* Select final phase */
1642     CRYP_PhaseConfig(CRYP_Phase_Final);
1643 
1644     /* Enable Crypto processor */
1645     CRYP_Cmd(ENABLE);
1646 
1647     if(CRYP_GetCmdStatus() == DISABLE)
1648     {
1649       /* The CRYP peripheral clock is not enabled or the device doesn't embedd
1650          the CRYP peripheral (please check the device sales type. */
1651       return(ERROR);
1652     }
1653 
1654     ctraddr = (uint32_t)ctr;
1655     /* Write the counter block in the IN FIFO */
1656     CRYP_DataIn(*(uint32_t*)(ctraddr));
1657     ctraddr+=4;
1658     CRYP_DataIn(*(uint32_t*)(ctraddr));
1659     ctraddr+=4;
1660     CRYP_DataIn(*(uint32_t*)(ctraddr));
1661     ctraddr+=4;
1662     /* Reset bit 0 (after 8-bit swap) is equivalent to reset bit 24 (before 8-bit swap) */
1663     CRYP_DataIn(*(uint32_t*)(ctraddr) & 0xfeffffff);
1664 
1665     /* Wait until the OFNE flag is reset */
1666     while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1667     {
1668     }
1669 
1670     /* Read the Authentaication TAG (MAC) in the IN FIFO */
1671     temptag[0] = CRYP_DataOut();
1672     temptag[1] = CRYP_DataOut();
1673     temptag[2] = CRYP_DataOut();
1674     temptag[3] = CRYP_DataOut();
1675   }
1676 
1677   /* Copy temporary authentication TAG in user TAG buffer */
1678   for(loopcounter = 0; (loopcounter < TAGSize); loopcounter++)
1679   {
1680     /* Set the authentication TAG buffer */
1681     *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
1682   }
1683 
1684   /* Disable Crypto */
1685   CRYP_Cmd(DISABLE);
1686 
1687   return status;
1688 }
1689 
1690 /**
1691   * @}
1692   */
1693 
1694 /**
1695   * @}
1696   */
1697 
1698 /**
1699   * @}
1700   */
1701 
1702 /**
1703   * @}
1704   */
1705 
1706 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1707 
1708