Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Modules / PowerManagement_1-1 / Boot / lib / stdperiphlib / STM32F4xx_StdPeriph_Driver / src / stm32f4xx_cryp_aes.c @ 367c0652

History | View | Annotate | Download (56.4 KB)

1
/**
2
  ******************************************************************************
3
  * @file    stm32f4xx_cryp_aes.c
4
  * @author  MCD Application Team
5
  * @version V1.1.0
6
  * @date    11-January-2013
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 2013 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
  */
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
  */
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
  */
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
  */
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
    /***************************** header phase *******************************/
958
    if(HLength != 0)
959
    {
960
      /* Select header phase */
961
      CRYP_PhaseConfig(CRYP_Phase_Header);
962
      
963
      /* Enable Crypto processor */
964
      CRYP_Cmd(ENABLE);
965
      
966
      if(CRYP_GetCmdStatus() == DISABLE)
967
      {
968
        /* The CRYP peripheral clock is not enabled or the device doesn't embedd 
969
           the CRYP peripheral (please check the device sales type. */
970
        return(ERROR);
971
      }
972
      
973
      for(loopcounter = 0; (loopcounter < HLength); loopcounter+=16)
974
      {
975
        /* Wait until the IFEM flag is reset */
976
        while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET);
977
        
978
        /* Write the Input block in the IN FIFO */
979
        CRYP_DataIn(*(uint32_t*)(headeraddr));
980
        headeraddr+=4;
981
        CRYP_DataIn(*(uint32_t*)(headeraddr));
982
        headeraddr+=4;
983
        CRYP_DataIn(*(uint32_t*)(headeraddr));
984
        headeraddr+=4;
985
        CRYP_DataIn(*(uint32_t*)(headeraddr));
986
        headeraddr+=4;
987
      }
988
      
989
      /* Wait until the complete message has been processed */
990
      counter = 0;
991
      do
992
      {
993
        busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
994
        counter++;
995
      }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
996

    
997
      if (busystatus != RESET)
998
      {
999
        status = ERROR;
1000
      }
1001
    }
1002
    
1003
    /**************************** payload phase *******************************/
1004
    if(ILength != 0)
1005
    {
1006
      /* Select payload phase */
1007
      CRYP_PhaseConfig(CRYP_Phase_Payload);
1008

    
1009
      /* Enable Crypto processor */
1010
      CRYP_Cmd(ENABLE);
1011
      
1012
      if(CRYP_GetCmdStatus() == DISABLE)
1013
      {
1014
        /* The CRYP peripheral clock is not enabled or the device doesn't embedd 
1015
           the CRYP peripheral (please check the device sales type. */
1016
        return(ERROR);
1017
      }
1018
      
1019
      for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
1020
      {
1021
        /* Wait until the IFEM flag is reset */
1022
        while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET);
1023
        /* Write the Input block in the IN FIFO */
1024
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1025
        inputaddr+=4;
1026
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1027
        inputaddr+=4;
1028
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1029
        inputaddr+=4;
1030
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1031
        inputaddr+=4;
1032
        
1033
        /* Wait until the complete message has been processed */
1034
        counter = 0;
1035
        do
1036
        {
1037
          busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1038
          counter++;
1039
        }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1040

    
1041
        if (busystatus != RESET)
1042
        {
1043
          status = ERROR;
1044
        }
1045
        else
1046
        {
1047
          /* Wait until the OFNE flag is reset */
1048
          while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET);
1049
          
1050
          /* Read the Output block from the Output FIFO */
1051
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1052
          outputaddr+=4;
1053
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1054
          outputaddr+=4;
1055
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1056
          outputaddr+=4;
1057
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1058
          outputaddr+=4;
1059
        }
1060
      }
1061
    }
1062
    
1063
    /***************************** final phase ********************************/
1064
    /* Select final phase */
1065
    CRYP_PhaseConfig(CRYP_Phase_Final);
1066

    
1067
    /* Enable Crypto processor */
1068
    CRYP_Cmd(ENABLE);
1069
    
1070
    if(CRYP_GetCmdStatus() == DISABLE)
1071
    {
1072
      /* The CRYP peripheral clock is not enabled or the device doesn't embedd 
1073
         the CRYP peripheral (please check the device sales type. */
1074
      return(ERROR);
1075
    }
1076
    
1077
    /* Write number of bits concatenated with header in the IN FIFO */
1078
    CRYP_DataIn(__REV(headerlength>>32));
1079
    CRYP_DataIn(__REV(headerlength));
1080
    CRYP_DataIn(__REV(inputlength>>32));
1081
    CRYP_DataIn(__REV(inputlength));
1082
    /* Wait until the OFNE flag is reset */
1083
    while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET);
1084
    
1085
    tagaddr = (uint32_t)AuthTAG;
1086
    /* Read the Auth TAG in the IN FIFO */
1087
    *(uint32_t*)(tagaddr) = CRYP_DataOut();
1088
    tagaddr+=4;
1089
    *(uint32_t*)(tagaddr) = CRYP_DataOut();
1090
    tagaddr+=4;
1091
    *(uint32_t*)(tagaddr) = CRYP_DataOut();
1092
    tagaddr+=4;
1093
    *(uint32_t*)(tagaddr) = CRYP_DataOut();
1094
    tagaddr+=4;
1095
  }
1096
  /* Disable Crypto */
1097
  CRYP_Cmd(DISABLE);
1098

    
1099
  return status;
1100
}
1101

    
1102
/**
1103
  * @brief  Encrypt and decrypt using AES in CCM Mode. The GCM and CCM modes
1104
  *         are available only on STM32F437x Devices.
1105
  * @param  Mode: encryption or decryption Mode.
1106
  *          This parameter can be one of the following values:
1107
  *            @arg MODE_ENCRYPT: Encryption
1108
  *            @arg MODE_DECRYPT: Decryption
1109
  * @param  Nonce: the nounce used for AES algorithm. It shall be unique for each processing.
1110
  * @param  Key: Key used for AES algorithm.
1111
  * @param  Keysize: length of the Key, must be a 128, 192 or 256.
1112
  * @param  Input: pointer to the Input buffer.
1113
  * @param  Ilength: length of the Input buffer in bytes, must be a multiple of 16.
1114
  * @param  Header: pointer to the header buffer.
1115
  * @param  Hlength: length of the header buffer in bytes.
1116
  * @param  HBuffer: pointer to temporary buffer used to append the header
1117
  *         HBuffer size must be equal to Hlength + 21
1118
  * @param  Output: pointer to the returned buffer.
1119
  * @param  AuthTAG: pointer to the authentication TAG buffer.
1120
  * @param  TAGSize: the size of the TAG (called also MAC).
1121
  * @retval An ErrorStatus enumeration value:
1122
  *          - SUCCESS: Operation done
1123
  *          - ERROR: Operation failed
1124
  */
1125
ErrorStatus CRYP_AES_CCM(uint8_t Mode, 
1126
                         uint8_t* Nonce, uint32_t NonceSize,
1127
                         uint8_t *Key, uint16_t Keysize,
1128
                         uint8_t *Input, uint32_t ILength,
1129
                         uint8_t *Header, uint32_t HLength, uint8_t *HBuffer,
1130
                         uint8_t *Output,
1131
                         uint8_t *AuthTAG, uint32_t TAGSize)
1132
{
1133
  CRYP_InitTypeDef AES_CRYP_InitStructure;
1134
  CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
1135
  CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
1136
  __IO uint32_t counter = 0;
1137
  uint32_t busystatus = 0;
1138
  ErrorStatus status = SUCCESS;
1139
  uint32_t keyaddr    = (uint32_t)Key;
1140
  uint32_t inputaddr  = (uint32_t)Input;
1141
  uint32_t outputaddr = (uint32_t)Output;
1142
  uint32_t headeraddr = (uint32_t)Header;
1143
  uint32_t tagaddr = (uint32_t)AuthTAG;
1144
  uint32_t headersize = HLength;
1145
  uint32_t loopcounter = 0;
1146
  uint32_t bufferidx = 0;
1147
  uint8_t blockb0[16] = {0};/* Block B0 */
1148
  uint8_t ctr[16] = {0}; /* Counter */
1149
  uint32_t temptag[4] = {0}; /* temporary TAG (MAC) */
1150
  uint32_t ctraddr = (uint32_t)ctr;
1151
  uint32_t b0addr = (uint32_t)blockb0;
1152
  
1153
  /************************ Formatting the header block ***********************/
1154
  if(headersize != 0)
1155
  {
1156
    /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1157
    if(headersize < 65280)
1158
    {
1159
      HBuffer[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
1160
      HBuffer[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
1161
      headersize += 2;
1162
    }
1163
    else
1164
    {
1165
      /* header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1166
      HBuffer[bufferidx++] = 0xFF;
1167
      HBuffer[bufferidx++] = 0xFE;
1168
      HBuffer[bufferidx++] = headersize & 0xff000000;
1169
      HBuffer[bufferidx++] = headersize & 0x00ff0000;
1170
      HBuffer[bufferidx++] = headersize & 0x0000ff00;
1171
      HBuffer[bufferidx++] = headersize & 0x000000ff;
1172
      headersize += 6;
1173
    }
1174
    /* Copy the header buffer in internal buffer "HBuffer" */
1175
    for(loopcounter = 0; loopcounter < headersize; loopcounter++)
1176
    {
1177
      HBuffer[bufferidx++] = Header[loopcounter];
1178
    }
1179
    /* Check if the header size is modulo 16 */
1180
    if ((headersize % 16) != 0)
1181
    {
1182
      /* Padd the header buffer with 0s till the HBuffer length is modulo 16 */
1183
      for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
1184
      {
1185
        HBuffer[loopcounter] = 0;
1186
      }
1187
      /* Set the header size to modulo 16 */
1188
      headersize = ((headersize/16) + 1) * 16;
1189
    }
1190
    /* set the pointer headeraddr to HBuffer */
1191
    headeraddr = (uint32_t)HBuffer;
1192
  }
1193
  /************************* Formatting the block B0 **************************/
1194
  if(headersize != 0)
1195
  {
1196
    blockb0[0] = 0x40;
1197
  }
1198
  /* Flags byte */
1199
  blockb0[0] |= 0u | (((( (uint8_t) TAGSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - NonceSize) - 1) & 0x07);
1200
  
1201
  for (loopcounter = 0; loopcounter < NonceSize; loopcounter++)
1202
  {
1203
    blockb0[loopcounter+1] = Nonce[loopcounter];
1204
  }
1205
  for ( ; loopcounter < 13; loopcounter++)
1206
  {
1207
    blockb0[loopcounter+1] = 0;
1208
  }
1209
  
1210
  blockb0[14] = ((ILength >> 8) & 0xFF);
1211
  blockb0[15] = (ILength & 0xFF);
1212
  
1213
  /************************* Formatting the initial counter *******************/
1214
  /* Byte 0:
1215
     Bits 7 and 6 are reserved and shall be set to 0
1216
     Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
1217
     are distinct from B0
1218
     Bits 0, 1, and 2 contain the same encoding of q as in B0
1219
  */
1220
  ctr[0] = blockb0[0] & 0x07;
1221
  /* byte 1 to NonceSize is the IV (Nonce) */
1222
  for(loopcounter = 1; loopcounter < NonceSize + 1; loopcounter++)
1223
  {
1224
    ctr[loopcounter] = blockb0[loopcounter];
1225
  }
1226
  /* Set the LSB to 1 */
1227
  ctr[15] |= 0x01;
1228
  
1229
  /* Crypto structures initialisation*/
1230
  CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
1231
  
1232
  switch(Keysize)
1233
  {
1234
    case 128:
1235
    AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
1236
    AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
1237
    keyaddr+=4;
1238
    AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
1239
    keyaddr+=4;
1240
    AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
1241
    keyaddr+=4;
1242
    AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
1243
    break;
1244
    case 192:
1245
    AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_192b;
1246
    AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
1247
    keyaddr+=4;
1248
    AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
1249
    keyaddr+=4;
1250
    AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
1251
    keyaddr+=4;
1252
    AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
1253
    keyaddr+=4;
1254
    AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
1255
    keyaddr+=4;
1256
    AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
1257
    break;
1258
    case 256:
1259
    AES_CRYP_InitStructure.CRYP_KeySize  = CRYP_KeySize_256b;
1260
    AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
1261
    keyaddr+=4;
1262
    AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
1263
    keyaddr+=4;
1264
    AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
1265
    keyaddr+=4;
1266
    AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
1267
    keyaddr+=4;
1268
    AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
1269
    keyaddr+=4;
1270
    AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
1271
    keyaddr+=4;
1272
    AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
1273
    keyaddr+=4;
1274
    AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
1275
    break;
1276
    default:
1277
    break;
1278
  }
1279
  
1280
  /* CRYP Initialization Vectors */
1281
  AES_CRYP_IVInitStructure.CRYP_IV0Left = (__REV(*(uint32_t*)(ctraddr)));
1282
  ctraddr+=4;
1283
  AES_CRYP_IVInitStructure.CRYP_IV0Right= (__REV(*(uint32_t*)(ctraddr)));
1284
  ctraddr+=4;
1285
  AES_CRYP_IVInitStructure.CRYP_IV1Left = (__REV(*(uint32_t*)(ctraddr)));
1286
  ctraddr+=4;
1287
  AES_CRYP_IVInitStructure.CRYP_IV1Right= (__REV(*(uint32_t*)(ctraddr)));
1288
  
1289
  /*------------------ AES Encryption ------------------*/
1290
  if(Mode == MODE_ENCRYPT) /* AES encryption */
1291
  {
1292
    /* Flush IN/OUT FIFOs */
1293
    CRYP_FIFOFlush();
1294
    
1295
    /* Key Initialisation */
1296
    CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
1297
    
1298
    /* CRYP Initialization Vectors */
1299
    CRYP_IVInit(&AES_CRYP_IVInitStructure);
1300
    
1301
    /* Crypto Init for Key preparation for decryption process */
1302
    AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
1303
    AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CCM;
1304
    AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
1305
    CRYP_Init(&AES_CRYP_InitStructure);
1306
    
1307
    /***************************** Init phase *********************************/
1308
    /* Select init phase */
1309
    CRYP_PhaseConfig(CRYP_Phase_Init);
1310
    
1311
    b0addr = (uint32_t)blockb0;
1312
    /* Write the blockb0 block in the IN FIFO */
1313
    CRYP_DataIn((*(uint32_t*)(b0addr)));
1314
    b0addr+=4;
1315
    CRYP_DataIn((*(uint32_t*)(b0addr)));
1316
    b0addr+=4;
1317
    CRYP_DataIn((*(uint32_t*)(b0addr)));
1318
    b0addr+=4;
1319
    CRYP_DataIn((*(uint32_t*)(b0addr)));
1320
    
1321
    /* Enable Crypto processor */
1322
    CRYP_Cmd(ENABLE);
1323
    
1324
    /* Wait for CRYPEN bit to be 0 */
1325
    while(CRYP_GetCmdStatus() == ENABLE);
1326
    
1327
    /***************************** header phase *******************************/
1328
    if(headersize != 0)
1329
    {
1330
      /* Select header phase */
1331
      CRYP_PhaseConfig(CRYP_Phase_Header);
1332
      
1333
      /* Enable Crypto processor */
1334
      CRYP_Cmd(ENABLE);
1335
      
1336
      if(CRYP_GetCmdStatus() == DISABLE)
1337
      {
1338
         /* The CRYP peripheral clock is not enabled or the device doesn't embedd 
1339
            the CRYP peripheral (please check the device sales type. */
1340
         return(ERROR);
1341
      }
1342
      
1343
      for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1344
      {
1345
        /* Wait until the IFEM flag is reset */
1346
        while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET);
1347
        
1348
        /* Write the Input block in the IN FIFO */
1349
        CRYP_DataIn(*(uint32_t*)(headeraddr));
1350
        headeraddr+=4;
1351
        CRYP_DataIn(*(uint32_t*)(headeraddr));
1352
        headeraddr+=4;
1353
        CRYP_DataIn(*(uint32_t*)(headeraddr));
1354
        headeraddr+=4;
1355
        CRYP_DataIn(*(uint32_t*)(headeraddr));
1356
        headeraddr+=4;
1357
      }
1358
      
1359
      /* Wait until the complete message has been processed */
1360
      counter = 0;
1361
      do
1362
      {
1363
        busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1364
        counter++;
1365
      }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1366

    
1367
      if (busystatus != RESET)
1368
      {
1369
        status = ERROR;
1370
      }
1371
    }
1372
    
1373
    /**************************** payload phase *******************************/
1374
    if(ILength != 0)
1375
    {
1376
      /* Select payload phase */
1377
      CRYP_PhaseConfig(CRYP_Phase_Payload);
1378
      
1379
      /* Enable Crypto processor */
1380
      CRYP_Cmd(ENABLE);
1381
      
1382
      if(CRYP_GetCmdStatus() == DISABLE)
1383
      {
1384
        /* The CRYP peripheral clock is not enabled or the device doesn't embedd 
1385
           the CRYP peripheral (please check the device sales type. */
1386
        return(ERROR);
1387
      }
1388
      
1389
      for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
1390
      {
1391
        /* Wait until the IFEM flag is reset */
1392
        while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET);
1393
        /* Write the Input block in the IN FIFO */
1394
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1395
        inputaddr+=4;
1396
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1397
        inputaddr+=4;
1398
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1399
        inputaddr+=4;
1400
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1401
        inputaddr+=4;
1402
        
1403
        /* Wait until the complete message has been processed */
1404
        counter = 0;
1405
        do
1406
        {
1407
          busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1408
          counter++;
1409
        }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1410

    
1411
        if (busystatus != RESET)
1412
        {
1413
          status = ERROR;
1414
        }
1415
        else
1416
        {
1417
          /* Wait until the OFNE flag is reset */
1418
          while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET);
1419
          
1420
          /* Read the Output block from the Output FIFO */
1421
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1422
          outputaddr+=4;
1423
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1424
          outputaddr+=4;
1425
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1426
          outputaddr+=4;
1427
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1428
          outputaddr+=4;
1429
        }
1430
      }
1431
    }
1432
    
1433
    /***************************** final phase ********************************/
1434
    /* Select final phase */
1435
    CRYP_PhaseConfig(CRYP_Phase_Final);
1436
    
1437
    /* Enable Crypto processor */
1438
    CRYP_Cmd(ENABLE);
1439
    
1440
    if(CRYP_GetCmdStatus() == DISABLE)
1441
    {
1442
      /* The CRYP peripheral clock is not enabled or the device doesn't embedd 
1443
         the CRYP peripheral (please check the device sales type. */
1444
      return(ERROR);
1445
    }
1446
    
1447
    ctraddr = (uint32_t)ctr;
1448
    /* Write the counter block in the IN FIFO */
1449
    CRYP_DataIn(*(uint32_t*)(ctraddr));
1450
    ctraddr+=4;
1451
    CRYP_DataIn(*(uint32_t*)(ctraddr));
1452
    ctraddr+=4;
1453
    CRYP_DataIn(*(uint32_t*)(ctraddr));
1454
    ctraddr+=4;
1455
    /* Reset bit 0 (after 8-bit swap) is equivalent to reset bit 24 (before 8-bit swap) */
1456
    CRYP_DataIn(*(uint32_t*)(ctraddr) & 0xfeffffff);
1457
    
1458
    /* Wait until the OFNE flag is reset */
1459
    while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET);
1460
    
1461
    /* Read the Auth TAG in the IN FIFO */
1462
    temptag[0] = CRYP_DataOut();
1463
    temptag[1] = CRYP_DataOut();
1464
    temptag[2] = CRYP_DataOut();
1465
    temptag[3] = CRYP_DataOut();
1466
  }
1467
  /*------------------ AES Decryption ------------------*/
1468
  else /* AES decryption */
1469
  {
1470
    /* Flush IN/OUT FIFOs */
1471
    CRYP_FIFOFlush();
1472
    
1473
    /* Key Initialisation */
1474
    CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
1475
    
1476
    /* CRYP Initialization Vectors */
1477
    CRYP_IVInit(&AES_CRYP_IVInitStructure);
1478
    
1479
    /* Crypto Init for Key preparation for decryption process */
1480
    AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
1481
    AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CCM;
1482
    AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
1483
    CRYP_Init(&AES_CRYP_InitStructure);
1484
    
1485
    /***************************** Init phase *********************************/
1486
    /* Select init phase */
1487
    CRYP_PhaseConfig(CRYP_Phase_Init);
1488
    
1489
    b0addr = (uint32_t)blockb0;
1490
    /* Write the blockb0 block in the IN FIFO */
1491
    CRYP_DataIn((*(uint32_t*)(b0addr)));
1492
    b0addr+=4;
1493
    CRYP_DataIn((*(uint32_t*)(b0addr)));
1494
    b0addr+=4;
1495
    CRYP_DataIn((*(uint32_t*)(b0addr)));
1496
    b0addr+=4;
1497
    CRYP_DataIn((*(uint32_t*)(b0addr)));
1498
    
1499
    /* Enable Crypto processor */
1500
    CRYP_Cmd(ENABLE);
1501
    
1502
    /* Wait for CRYPEN bit to be 0 */
1503
    while(CRYP_GetCmdStatus() == ENABLE);
1504
    
1505
    /***************************** header phase *******************************/
1506
    if(headersize != 0)
1507
    {
1508
      /* Select header phase */
1509
      CRYP_PhaseConfig(CRYP_Phase_Header);
1510
      
1511
      /* Enable Crypto processor */
1512
      CRYP_Cmd(ENABLE);
1513
      
1514
      if(CRYP_GetCmdStatus() == DISABLE)
1515
      {
1516
        /* The CRYP peripheral clock is not enabled or the device doesn't embedd 
1517
           the CRYP peripheral (please check the device sales type. */
1518
        return(ERROR);
1519
      }
1520
      
1521
      for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1522
      {
1523
        /* Wait until the IFEM flag is reset */
1524
        while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET);
1525
        
1526
        /* Write the Input block in the IN FIFO */
1527
        CRYP_DataIn(*(uint32_t*)(headeraddr));
1528
        headeraddr+=4;
1529
        CRYP_DataIn(*(uint32_t*)(headeraddr));
1530
        headeraddr+=4;
1531
        CRYP_DataIn(*(uint32_t*)(headeraddr));
1532
        headeraddr+=4;
1533
        CRYP_DataIn(*(uint32_t*)(headeraddr));
1534
        headeraddr+=4;
1535
      }
1536
      
1537
      /* Wait until the complete message has been processed */
1538
      counter = 0;
1539
      do
1540
      {
1541
        busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1542
        counter++;
1543
      }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1544

    
1545
      if (busystatus != RESET)
1546
      {
1547
        status = ERROR;
1548
      }
1549
    }
1550
    
1551
    /**************************** payload phase *******************************/
1552
    if(ILength != 0)
1553
    {
1554
      /* Select payload phase */
1555
      CRYP_PhaseConfig(CRYP_Phase_Payload);
1556

    
1557
      /* Enable Crypto processor */
1558
      CRYP_Cmd(ENABLE);
1559
      
1560
      if(CRYP_GetCmdStatus() == DISABLE)
1561
      {
1562
        /* The CRYP peripheral clock is not enabled or the device doesn't embedd 
1563
           the CRYP peripheral (please check the device sales type. */
1564
        return(ERROR);
1565
      }
1566
      
1567
      for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
1568
      {
1569
        /* Wait until the IFEM flag is reset */
1570
        while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET);
1571
        /* Write the Input block in the IN FIFO */
1572
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1573
        inputaddr+=4;
1574
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1575
        inputaddr+=4;
1576
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1577
        inputaddr+=4;
1578
        CRYP_DataIn(*(uint32_t*)(inputaddr));
1579
        inputaddr+=4;
1580
        
1581
        /* Wait until the complete message has been processed */
1582
        counter = 0;
1583
        do
1584
        {
1585
          busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1586
          counter++;
1587
        }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1588

    
1589
        if (busystatus != RESET)
1590
        {
1591
          status = ERROR;
1592
        }
1593
        else
1594
        {
1595
          /* Wait until the OFNE flag is reset */
1596
          while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET);
1597
          
1598
          /* Read the Output block from the Output FIFO */
1599
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1600
          outputaddr+=4;
1601
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1602
          outputaddr+=4;
1603
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1604
          outputaddr+=4;
1605
          *(uint32_t*)(outputaddr) = CRYP_DataOut();
1606
          outputaddr+=4;
1607
        }
1608
      }
1609
    }
1610
    
1611
    /***************************** final phase ********************************/
1612
    /* Select final phase */
1613
    CRYP_PhaseConfig(CRYP_Phase_Final);
1614
    
1615
    /* Enable Crypto processor */
1616
    CRYP_Cmd(ENABLE);
1617
    
1618
    if(CRYP_GetCmdStatus() == DISABLE)
1619
    {
1620
      /* The CRYP peripheral clock is not enabled or the device doesn't embedd 
1621
         the CRYP peripheral (please check the device sales type. */
1622
      return(ERROR);
1623
    }
1624
    
1625
    ctraddr = (uint32_t)ctr;
1626
    /* Write the counter block in the IN FIFO */
1627
    CRYP_DataIn(*(uint32_t*)(ctraddr));
1628
    ctraddr+=4;
1629
    CRYP_DataIn(*(uint32_t*)(ctraddr));
1630
    ctraddr+=4;
1631
    CRYP_DataIn(*(uint32_t*)(ctraddr));
1632
    ctraddr+=4;
1633
    /* Reset bit 0 (after 8-bit swap) is equivalent to reset bit 24 (before 8-bit swap) */
1634
    CRYP_DataIn(*(uint32_t*)(ctraddr) & 0xfeffffff);
1635
    
1636
    /* Wait until the OFNE flag is reset */
1637
    while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET);
1638
    
1639
    /* Read the Authentaication TAG (MAC) in the IN FIFO */
1640
    temptag[0] = CRYP_DataOut();
1641
    temptag[1] = CRYP_DataOut();
1642
    temptag[2] = CRYP_DataOut();
1643
    temptag[3] = CRYP_DataOut();
1644
  }
1645
  
1646
  /* Copy temporary authentication TAG in user TAG buffer */
1647
  for(loopcounter = 0; (loopcounter < TAGSize); loopcounter++)
1648
  {
1649
    /* Set the authentication TAG buffer */
1650
    *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
1651
  }
1652
  
1653
  /* Disable Crypto */
1654
  CRYP_Cmd(DISABLE);
1655

    
1656
  return status;
1657
}
1658

    
1659
/**
1660
  * @}
1661
  */ 
1662

    
1663
/**
1664
  * @}
1665
  */ 
1666

    
1667
/**
1668
  * @}
1669
  */ 
1670

    
1671
/**
1672
  * @}
1673
  */ 
1674

    
1675
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1676