]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_cryp_ex.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F4 / stm32f4xx_hal_cryp_ex.c
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_cryp_ex.c
4   * @author  MCD Application Team
5   * @version V1.1.0
6   * @date    19-June-2014
7   * @brief   Extended CRYP HAL module driver
8   *          This file provides firmware functions to manage the following 
9   *          functionalities of CRYP extension peripheral:
10   *           + Extended AES processing functions     
11   *  
12   @verbatim
13   ==============================================================================
14                      ##### How to use this driver #####
15   ==============================================================================
16     [..]
17     The CRYP Extension HAL driver can be used as follows:
18     (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
19         (##) Enable the CRYP interface clock using __CRYP_CLK_ENABLE()
20         (##) In case of using interrupts (e.g. HAL_CRYPEx_AESGCM_Encrypt_IT())
21             (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
22             (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
23             (+) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
24         (##) In case of using DMA to control data transfer (e.g. HAL_AES_ECB_Encrypt_DMA())
25             (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
26             (+++) Configure and enable two DMA streams one for managing data transfer from
27                 memory to peripheral (input stream) and another stream for managing data
28                 transfer from peripheral to memory (output stream)
29             (+++) Associate the initilalized DMA handle to the CRYP DMA handle
30                 using  __HAL_LINKDMA()
31             (+++) Configure the priority and enable the NVIC for the transfer complete
32                 interrupt on the two DMA Streams. The output stream should have higher
33                 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
34     (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly:
35         (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit
36         (##) The key size: 128, 192 and 256. This parameter is relevant only for AES
37         (##) The encryption/decryption key. Its size depends on the algorithm
38                 used for encryption/decryption
39         (##) The initialization vector (counter). It is not used ECB mode.
40     (#)Three processing (encryption/decryption) functions are available:
41         (##) Polling mode: encryption and decryption APIs are blocking functions
42              i.e. they process the data and wait till the processing is finished
43              e.g. HAL_CRYPEx_AESGCM_Encrypt()
44         (##) Interrupt mode: encryption and decryption APIs are not blocking functions
45                 i.e. they process the data under interrupt
46                 e.g. HAL_CRYPEx_AESGCM_Encrypt_IT()
47         (##) DMA mode: encryption and decryption APIs are not blocking functions
48                 i.e. the data transfer is ensured by DMA
49                 e.g. HAL_CRYPEx_AESGCM_Encrypt_DMA()
50     (#)When the processing function is called at first time after HAL_CRYP_Init()
51        the CRYP peripheral is initialized and processes the buffer in input.
52        At second call, the processing function performs an append of the already
53        processed buffer.
54        When a new data block is to be processed, call HAL_CRYP_Init() then the
55        processing function.
56     (#)In AES-GCM and AES-CCM modes are an authenticated encryption algorithms
57        which provide authentication messages.
58        HAL_AES_GCM_Finish() and HAL_AES_CCM_Finish() are used to provide those
59        authentication messages.
60        Call those functions after the processing ones (polling, interrupt or DMA).
61        e.g. in AES-CCM mode call HAL_CRYPEx_AESCCM_Encrypt() to encrypt the plain data
62             then call HAL_CRYPEx_AESCCM_Finish() to get the authentication message
63     (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
64
65   @endverbatim
66   ******************************************************************************
67   * @attention
68   *
69   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
70   *
71   * Redistribution and use in source and binary forms, with or without modification,
72   * are permitted provided that the following conditions are met:
73   *   1. Redistributions of source code must retain the above copyright notice,
74   *      this list of conditions and the following disclaimer.
75   *   2. Redistributions in binary form must reproduce the above copyright notice,
76   *      this list of conditions and the following disclaimer in the documentation
77   *      and/or other materials provided with the distribution.
78   *   3. Neither the name of STMicroelectronics nor the names of its contributors
79   *      may be used to endorse or promote products derived from this software
80   *      without specific prior written permission.
81   *
82   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
83   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
85   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
86   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
87   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
88   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
89   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
90   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
91   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92   *
93   ******************************************************************************
94   */ 
95
96 /* Includes ------------------------------------------------------------------*/
97 #include "stm32f4xx_hal.h"
98
99 /** @addtogroup STM32F4xx_HAL_Driver
100   * @{
101   */
102
103 /** @defgroup CRYPEx 
104   * @brief CRYP Extension HAL module driver.
105   * @{
106   */
107
108 #ifdef HAL_CRYP_MODULE_ENABLED
109
110 #if defined(STM32F437xx) || defined(STM32F439xx)
111
112 /* Private typedef -----------------------------------------------------------*/
113 /* Private define ------------------------------------------------------------*/
114 #define CRYPEx_TIMEOUT_VALUE  1
115 /* Private macro -------------------------------------------------------------*/
116 /* Private variables ---------------------------------------------------------*/
117 /* Private function prototypes -----------------------------------------------*/
118 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector, uint32_t IVSize);
119 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize);
120 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout);
121 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout);
122 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma);
123 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma);
124 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma);
125 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
126
127 /* Private functions ---------------------------------------------------------*/
128
129 /** @defgroup CRYPEx_Private_Functions
130   * @{
131   */
132
133 /** @defgroup CRYPEx_Group1 Extended AES processing functions 
134  *  @brief   Extended processing functions. 
135  *
136 @verbatim   
137   ==============================================================================
138               ##### Extended AES processing functions #####
139   ==============================================================================  
140     [..]  This section provides functions allowing to:
141       (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes
142       (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes
143       (+) Finish the processing. This function is available only for GCM and CCM
144     [..]  Three processing methods are available:
145       (+) Polling mode
146       (+) Interrupt mode
147       (+) DMA mode
148
149 @endverbatim
150   * @{
151   */
152
153
154 /**
155   * @brief  Initializes the CRYP peripheral in AES CCM encryption mode then 
156   *         encrypt pPlainData. The cypher data are available in pCypherData.
157   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
158   *         the configuration information for CRYP module
159   * @param  pPlainData: Pointer to the plaintext buffer
160   * @param  Size: Length of the plaintext buffer, must be a multiple of 16
161   * @param  pCypherData: Pointer to the cyphertext buffer
162   * @param  Timeout: Timeout duration
163   * @retval HAL status
164   */
165 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
166 {
167   uint32_t tickstart = 0;
168   uint32_t headersize = hcryp->Init.HeaderSize;
169   uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
170   uint32_t loopcounter = 0;
171   uint32_t bufferidx = 0;
172   uint8_t blockb0[16] = {0};/* Block B0 */
173   uint8_t ctr[16] = {0}; /* Counter */
174   uint32_t b0addr = (uint32_t)blockb0;
175   
176   /* Process Locked */
177   __HAL_LOCK(hcryp);
178   
179   /* Change the CRYP peripheral state */
180   hcryp->State = HAL_CRYP_STATE_BUSY;
181   
182   /* Check if initialization phase has already been performed */
183   if(hcryp->Phase == HAL_CRYP_PHASE_READY)
184   {
185     /************************ Formatting the header block *********************/
186     if(headersize != 0)
187     {
188       /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
189       if(headersize < 65280)
190       {
191         hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
192         hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
193         headersize += 2;
194       }
195       else
196       {
197         /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
198         hcryp->Init.pScratch[bufferidx++] = 0xFF;
199         hcryp->Init.pScratch[bufferidx++] = 0xFE;
200         hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
201         hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
202         hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
203         hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
204         headersize += 6;
205       }
206       /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
207       for(loopcounter = 0; loopcounter < headersize; loopcounter++)
208       {
209         hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
210       }
211       /* Check if the header size is modulo 16 */
212       if ((headersize % 16) != 0)
213       {
214         /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
215         for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
216         {
217           hcryp->Init.pScratch[loopcounter] = 0;
218         }
219         /* Set the header size to modulo 16 */
220         headersize = ((headersize/16) + 1) * 16;
221       }
222       /* Set the pointer headeraddr to hcryp->Init.pScratch */
223       headeraddr = (uint32_t)hcryp->Init.pScratch;
224     }
225     /*********************** Formatting the block B0 **************************/
226     if(headersize != 0)
227     {
228       blockb0[0] = 0x40;
229     }
230     /* Flags byte */
231     /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
232     blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
233     blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
234  
235     for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
236     {
237       blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
238     }
239     for ( ; loopcounter < 13; loopcounter++)
240     {
241       blockb0[loopcounter+1] = 0;
242     }
243     
244     blockb0[14] = (Size >> 8);
245     blockb0[15] = (Size & 0xFF);
246     
247     /************************* Formatting the initial counter *****************/
248     /* Byte 0:
249        Bits 7 and 6 are reserved and shall be set to 0
250        Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
251        are distinct from B0
252        Bits 0, 1, and 2 contain the same encoding of q as in B0
253     */
254     ctr[0] = blockb0[0] & 0x07;
255     /* byte 1 to NonceSize is the IV (Nonce) */
256     for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
257     {
258       ctr[loopcounter] = blockb0[loopcounter];
259     }
260     /* Set the LSB to 1 */
261     ctr[15] |= 0x01;
262     
263     /* Set the key */
264     CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
265     
266     /* Set the CRYP peripheral in AES CCM mode */
267     __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
268     
269     /* Set the Initialization Vector */
270     CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, CRYP_KEYSIZE_128B);
271     
272     /* Select init phase */
273     __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
274     
275     b0addr = (uint32_t)blockb0;
276     /* Write the blockb0 block in the IN FIFO */
277     CRYP->DR = *(uint32_t*)(b0addr);
278     b0addr+=4;
279     CRYP->DR = *(uint32_t*)(b0addr);
280     b0addr+=4;
281     CRYP->DR = *(uint32_t*)(b0addr);
282     b0addr+=4;
283     CRYP->DR = *(uint32_t*)(b0addr);
284     
285     /* Enable the CRYP peripheral */
286     __HAL_CRYP_ENABLE();
287     
288     /* Get tick */
289     tickstart = HAL_GetTick();
290
291     while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
292     {
293       /* Check for the Timeout */
294       if(Timeout != HAL_MAX_DELAY)
295       {
296         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
297         {
298           /* Change state */
299           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
300           
301           /* Process Unlocked */
302           __HAL_UNLOCK(hcryp);
303         
304           return HAL_TIMEOUT;
305         }
306       }
307     }
308     /***************************** Header phase *******************************/
309     if(headersize != 0)
310     {
311       /* Select header phase */
312       __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
313       
314       /* Enable the CRYP peripheral */
315       __HAL_CRYP_ENABLE();
316       
317       for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
318       {
319         /* Get tick */
320         tickstart = HAL_GetTick();
321
322         while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
323         {
324           {
325             /* Check for the Timeout */
326             if(Timeout != HAL_MAX_DELAY)
327             {
328               if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
329               {
330                 /* Change state */
331                 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
332                 
333                 /* Process Unlocked */
334                 __HAL_UNLOCK(hcryp);
335                 
336                 return HAL_TIMEOUT;
337               }
338             }
339           }
340         }
341         /* Write the header block in the IN FIFO */
342         CRYP->DR = *(uint32_t*)(headeraddr);
343         headeraddr+=4;
344         CRYP->DR = *(uint32_t*)(headeraddr);
345         headeraddr+=4;
346         CRYP->DR = *(uint32_t*)(headeraddr);
347         headeraddr+=4;
348         CRYP->DR = *(uint32_t*)(headeraddr);
349         headeraddr+=4;
350       }
351       
352       /* Get tick */
353       tickstart = HAL_GetTick();
354
355       while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
356       {
357         /* Check for the Timeout */
358         if(Timeout != HAL_MAX_DELAY)
359         {
360           if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
361           {
362             /* Change state */
363             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
364             
365             /* Process Unlocked */
366             __HAL_UNLOCK(hcryp);
367             
368             return HAL_TIMEOUT;
369           }
370         }
371       }
372     }
373     /* Save formatted counter into the scratch buffer pScratch */
374     for(loopcounter = 0; (loopcounter < 16); loopcounter++)
375     {
376       hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
377     }
378     /* Reset bit 0 */
379     hcryp->Init.pScratch[15] &= 0xfe;
380     
381     /* Select payload phase once the header phase is performed */
382     __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
383     
384     /* Flush FIFO */
385     __HAL_CRYP_FIFO_FLUSH();
386     
387     /* Enable the CRYP peripheral */
388     __HAL_CRYP_ENABLE();
389     
390     /* Set the phase */
391     hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
392   }
393   
394   /* Write Plain Data and Get Cypher Data */
395   if(CRYPEx_GCMCCM_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK)
396   {
397     return HAL_TIMEOUT;
398   }
399   
400   /* Change the CRYP peripheral state */
401   hcryp->State = HAL_CRYP_STATE_READY;
402   
403   /* Process Unlocked */
404   __HAL_UNLOCK(hcryp);
405   
406   /* Return function status */
407   return HAL_OK;
408 }
409
410 /**
411   * @brief  Initializes the CRYP peripheral in AES GCM encryption mode then 
412   *         encrypt pPlainData. The cypher data are available in pCypherData.
413   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
414   *         the configuration information for CRYP module
415   * @param  pPlainData: Pointer to the plaintext buffer
416   * @param  Size: Length of the plaintext buffer, must be a multiple of 16
417   * @param  pCypherData: Pointer to the cyphertext buffer
418   * @param  Timeout: Timeout duration
419   * @retval HAL status
420   */
421 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
422 {
423   uint32_t tickstart = 0;
424   
425   /* Process Locked */
426   __HAL_LOCK(hcryp);
427   
428   /* Change the CRYP peripheral state */
429   hcryp->State = HAL_CRYP_STATE_BUSY;
430   
431   /* Check if initialization phase has already been performed */
432   if(hcryp->Phase == HAL_CRYP_PHASE_READY)
433   {
434     /* Set the key */
435     CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
436     
437     /* Set the CRYP peripheral in AES GCM mode */
438     __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
439     
440     /* Set the Initialization Vector */
441     CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
442     
443     /* Flush FIFO */
444     __HAL_CRYP_FIFO_FLUSH();
445     
446     /* Enable the CRYP peripheral */
447     __HAL_CRYP_ENABLE();
448     
449     /* Get tick */
450     tickstart = HAL_GetTick();
451
452     while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
453     {
454       /* Check for the Timeout */
455       if(Timeout != HAL_MAX_DELAY)
456       {
457         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
458         {
459           /* Change state */
460           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
461           
462           /* Process Unlocked */
463           __HAL_UNLOCK(hcryp);
464           
465           return HAL_TIMEOUT;
466         }
467       }
468     }
469     
470     /* Set the header phase */
471     if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
472     {
473       return HAL_TIMEOUT;
474     }
475     
476     /* Disable the CRYP peripheral */
477     __HAL_CRYP_DISABLE();
478     
479     /* Select payload phase once the header phase is performed */
480     __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
481     
482     /* Flush FIFO */
483     __HAL_CRYP_FIFO_FLUSH();
484     
485     /* Enable the CRYP peripheral */
486     __HAL_CRYP_ENABLE();
487     
488     /* Set the phase */
489     hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
490   }
491   
492   /* Write Plain Data and Get Cypher Data */
493   if(CRYPEx_GCMCCM_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK)
494   {
495     return HAL_TIMEOUT;
496   }
497   
498   /* Change the CRYP peripheral state */
499   hcryp->State = HAL_CRYP_STATE_READY;
500   
501   /* Process Unlocked */
502   __HAL_UNLOCK(hcryp);
503   
504   /* Return function status */
505   return HAL_OK;
506 }
507
508 /**
509   * @brief  Initializes the CRYP peripheral in AES GCM decryption mode then
510   *         decrypted pCypherData. The cypher data are available in pPlainData.
511   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
512   *         the configuration information for CRYP module
513   * @param  pCypherData: Pointer to the cyphertext buffer
514   * @param  Size: Length of the cyphertext buffer, must be a multiple of 16
515   * @param  pPlainData: Pointer to the plaintext buffer 
516   * @param  Timeout: Timeout duration
517   * @retval HAL status
518   */
519 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
520 {
521   uint32_t tickstart = 0;   
522   
523   /* Process Locked */
524   __HAL_LOCK(hcryp);
525   
526   /* Change the CRYP peripheral state */
527   hcryp->State = HAL_CRYP_STATE_BUSY;
528   
529   /* Check if initialization phase has already been performed */
530   if(hcryp->Phase == HAL_CRYP_PHASE_READY)
531   {
532     /* Set the key */
533     CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
534     
535     /* Set the CRYP peripheral in AES GCM decryption mode */
536     __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
537     
538     /* Set the Initialization Vector */
539     CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
540     
541     /* Flush FIFO */
542     __HAL_CRYP_FIFO_FLUSH();
543     
544     /* Enable the CRYP peripheral */
545     __HAL_CRYP_ENABLE();
546     
547     /* Get tick */
548     tickstart = HAL_GetTick();
549
550     while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
551     {
552       /* Check for the Timeout */
553       if(Timeout != HAL_MAX_DELAY)
554       {
555         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
556         {
557           /* Change state */
558           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
559           
560           /* Process Unlocked */
561           __HAL_UNLOCK(hcryp);
562           
563           return HAL_TIMEOUT;
564         }
565       }
566     }
567     
568     /* Set the header phase */
569     if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
570     {
571       return HAL_TIMEOUT;
572     }
573     /* Disable the CRYP peripheral */
574     __HAL_CRYP_DISABLE();
575     
576     /* Select payload phase once the header phase is performed */
577     __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
578     
579     /* Enable the CRYP peripheral */
580     __HAL_CRYP_ENABLE();
581     
582     /* Set the phase */
583     hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
584   }
585   
586   /* Write Plain Data and Get Cypher Data */
587   if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
588   {
589     return HAL_TIMEOUT;
590   }
591   
592   /* Change the CRYP peripheral state */
593   hcryp->State = HAL_CRYP_STATE_READY;
594   
595   /* Process Unlocked */
596   __HAL_UNLOCK(hcryp);
597   
598   /* Return function status */
599   return HAL_OK;
600 }
601
602 /**
603   * @brief  Computes the authentication TAG.
604   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
605   *         the configuration information for CRYP module
606   * @param  Size: Total length of the plain/cyphertext buffer
607   * @param  AuthTag: Pointer to the authentication buffer
608   * @param  Timeout: Timeout duration
609   * @retval HAL status
610   */
611 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint16_t Size, uint8_t *AuthTag, uint32_t Timeout)
612 {
613   uint32_t tickstart = 0;   
614   uint32_t headerlength = hcryp->Init.HeaderSize * 8; /* Header length in bits */
615   uint32_t inputlength = Size * 8; /* input length in bits */
616   uint32_t tagaddr = (uint32_t)AuthTag;
617   
618   /* Process Locked */
619   __HAL_LOCK(hcryp);
620   
621   /* Change the CRYP peripheral state */
622   hcryp->State = HAL_CRYP_STATE_BUSY;
623   
624   /* Check if initialization phase has already been performed */
625   if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
626   {
627     /* Change the CRYP phase */
628     hcryp->Phase = HAL_CRYP_PHASE_FINAL;
629     
630     /* Disable CRYP to start the final phase */
631     __HAL_CRYP_DISABLE();
632     
633     /* Select final phase */
634     __HAL_CRYP_SET_PHASE(CRYP_PHASE_FINAL);
635     
636     /* Enable the CRYP peripheral */
637     __HAL_CRYP_ENABLE();
638     
639     /* Write the number of bits in header (64 bits) followed by the number of bits
640        in the payload */
641     if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
642     {
643       CRYP->DR = 0;
644       CRYP->DR = __RBIT(headerlength);
645       CRYP->DR = 0;
646       CRYP->DR = __RBIT(inputlength);
647     }
648     else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
649     {
650       CRYP->DR = 0;
651       CRYP->DR = __REV(headerlength);
652       CRYP->DR = 0;
653       CRYP->DR = __REV(inputlength);
654     }
655     else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
656     {
657       CRYP->DR = 0;
658       CRYP->DR = __REV16(headerlength);
659       CRYP->DR = 0;
660       CRYP->DR = __REV16(inputlength);
661     }
662     else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
663     {
664       CRYP->DR = 0;
665       CRYP->DR = (uint32_t)(headerlength);
666       CRYP->DR = 0;
667       CRYP->DR = (uint32_t)(inputlength);
668     }
669     /* Get tick */
670     tickstart = HAL_GetTick();
671
672     while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_OFNE))
673     {
674       /* Check for the Timeout */
675       if(Timeout != HAL_MAX_DELAY)
676       {
677         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
678         {
679           /* Change state */
680           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
681           
682           /* Process Unlocked */
683           __HAL_UNLOCK(hcryp);
684         
685           return HAL_TIMEOUT;
686         }
687       }
688     }
689     
690     /* Read the Auth TAG in the IN FIFO */
691     *(uint32_t*)(tagaddr) = CRYP->DOUT;
692     tagaddr+=4;
693     *(uint32_t*)(tagaddr) = CRYP->DOUT;
694     tagaddr+=4;
695     *(uint32_t*)(tagaddr) = CRYP->DOUT;
696     tagaddr+=4;
697     *(uint32_t*)(tagaddr) = CRYP->DOUT;
698   }
699   
700   /* Change the CRYP peripheral state */
701   hcryp->State = HAL_CRYP_STATE_READY;
702   
703   /* Process Unlocked */
704   __HAL_UNLOCK(hcryp);
705   
706   /* Return function status */
707   return HAL_OK;
708 }
709
710 /**
711   * @brief  Computes the authentication TAG for AES CCM mode.
712   * @note   This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt()   
713   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
714   *         the configuration information for CRYP module
715   * @param  AuthTag: Pointer to the authentication buffer
716   * @param  Timeout: Timeout duration
717   * @retval HAL status
718   */
719 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout)
720 {
721   uint32_t tickstart = 0;   
722   uint32_t tagaddr = (uint32_t)AuthTag;
723   uint32_t ctraddr = (uint32_t)hcryp->Init.pScratch;
724   uint32_t temptag[4] = {0}; /* Temporary TAG (MAC) */
725   uint32_t loopcounter;
726   
727   /* Process Locked */
728   __HAL_LOCK(hcryp);
729   
730   /* Change the CRYP peripheral state */
731   hcryp->State = HAL_CRYP_STATE_BUSY;
732   
733   /* Check if initialization phase has already been performed */
734   if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
735   {
736     /* Change the CRYP phase */
737     hcryp->Phase = HAL_CRYP_PHASE_FINAL;
738     
739     /* Disable CRYP to start the final phase */
740     __HAL_CRYP_DISABLE();
741     
742     /* Select final phase */
743     __HAL_CRYP_SET_PHASE(CRYP_PHASE_FINAL);
744     
745     /* Enable the CRYP peripheral */
746     __HAL_CRYP_ENABLE();
747     
748     /* Write the counter block in the IN FIFO */
749     CRYP->DR = *(uint32_t*)ctraddr;
750     ctraddr+=4;
751     CRYP->DR = *(uint32_t*)ctraddr;
752     ctraddr+=4;
753     CRYP->DR = *(uint32_t*)ctraddr;
754     ctraddr+=4;
755     CRYP->DR = *(uint32_t*)ctraddr;
756     
757     /* Get tick */
758     tickstart = HAL_GetTick();
759
760     while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_OFNE))
761     {
762       /* Check for the Timeout */
763       if(Timeout != HAL_MAX_DELAY)
764       {
765         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
766         {
767           /* Change state */
768           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
769           
770           /* Process Unlocked */
771           __HAL_UNLOCK(hcryp);
772           
773           return HAL_TIMEOUT;
774         }
775       }
776     }
777     
778     /* Read the Auth TAG in the IN FIFO */
779     temptag[0] = CRYP->DOUT;
780     temptag[1] = CRYP->DOUT;
781     temptag[2] = CRYP->DOUT;
782     temptag[3] = CRYP->DOUT;
783   }
784   
785   /* Copy temporary authentication TAG in user TAG buffer */
786   for(loopcounter = 0; loopcounter < hcryp->Init.TagSize ; loopcounter++)
787   {
788     /* Set the authentication TAG buffer */
789     *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
790   }
791   
792   /* Change the CRYP peripheral state */
793   hcryp->State = HAL_CRYP_STATE_READY;
794   
795   /* Process Unlocked */
796   __HAL_UNLOCK(hcryp);
797   
798   /* Return function status */
799   return HAL_OK;
800 }
801
802 /**
803   * @brief  Initializes the CRYP peripheral in AES CCM decryption mode then
804   *         decrypted pCypherData. The cypher data are available in pPlainData.
805   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
806   *         the configuration information for CRYP module
807   * @param  pPlainData: Pointer to the plaintext buffer
808   * @param  Size: Length of the plaintext buffer, must be a multiple of 16
809   * @param  pCypherData: Pointer to the cyphertext buffer
810   * @param  Timeout: Timeout duration
811   * @retval HAL status
812   */
813 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
814 {
815   uint32_t tickstart = 0;   
816   uint32_t headersize = hcryp->Init.HeaderSize;
817   uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
818   uint32_t loopcounter = 0;
819   uint32_t bufferidx = 0;
820   uint8_t blockb0[16] = {0};/* Block B0 */
821   uint8_t ctr[16] = {0}; /* Counter */
822   uint32_t b0addr = (uint32_t)blockb0;
823   
824   /* Process Locked */
825   __HAL_LOCK(hcryp);
826   
827   /* Change the CRYP peripheral state */
828   hcryp->State = HAL_CRYP_STATE_BUSY;
829   
830   /* Check if initialization phase has already been performed */
831   if(hcryp->Phase == HAL_CRYP_PHASE_READY)
832   {
833     /************************ Formatting the header block *********************/
834     if(headersize != 0)
835     {
836       /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
837       if(headersize < 65280)
838       {
839         hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
840         hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
841         headersize += 2;
842       }
843       else
844       {
845         /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
846         hcryp->Init.pScratch[bufferidx++] = 0xFF;
847         hcryp->Init.pScratch[bufferidx++] = 0xFE;
848         hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
849         hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
850         hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
851         hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
852         headersize += 6;
853       }
854       /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
855       for(loopcounter = 0; loopcounter < headersize; loopcounter++)
856       {
857         hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
858       }
859       /* Check if the header size is modulo 16 */
860       if ((headersize % 16) != 0)
861       {
862         /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
863         for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
864         {
865           hcryp->Init.pScratch[loopcounter] = 0;
866         }
867         /* Set the header size to modulo 16 */
868         headersize = ((headersize/16) + 1) * 16;
869       }
870       /* Set the pointer headeraddr to hcryp->Init.pScratch */
871       headeraddr = (uint32_t)hcryp->Init.pScratch;
872     }
873     /*********************** Formatting the block B0 **************************/
874     if(headersize != 0)
875     {
876       blockb0[0] = 0x40;
877     }
878     /* Flags byte */
879     /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
880     blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
881     blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
882     
883     for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
884     {
885       blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
886     }
887     for ( ; loopcounter < 13; loopcounter++)
888     {
889       blockb0[loopcounter+1] = 0;
890     }
891     
892     blockb0[14] = (Size >> 8);
893     blockb0[15] = (Size & 0xFF);
894     
895     /************************* Formatting the initial counter *****************/
896     /* Byte 0:
897        Bits 7 and 6 are reserved and shall be set to 0
898        Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
899        blocks are distinct from B0
900        Bits 0, 1, and 2 contain the same encoding of q as in B0
901     */
902     ctr[0] = blockb0[0] & 0x07;
903     /* byte 1 to NonceSize is the IV (Nonce) */
904     for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
905     {
906       ctr[loopcounter] = blockb0[loopcounter];
907     }
908     /* Set the LSB to 1 */
909     ctr[15] |= 0x01;
910     
911     /* Set the key */
912     CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
913     
914     /* Set the CRYP peripheral in AES CCM mode */
915     __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
916     
917     /* Set the Initialization Vector */
918     CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, CRYP_KEYSIZE_128B);
919     
920     /* Select init phase */
921     __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
922     
923     b0addr = (uint32_t)blockb0;
924     /* Write the blockb0 block in the IN FIFO */
925     CRYP->DR = *(uint32_t*)(b0addr);
926     b0addr+=4;
927     CRYP->DR = *(uint32_t*)(b0addr);
928     b0addr+=4;
929     CRYP->DR = *(uint32_t*)(b0addr);
930     b0addr+=4;
931     CRYP->DR = *(uint32_t*)(b0addr);
932     
933     /* Enable the CRYP peripheral */
934     __HAL_CRYP_ENABLE();
935     
936     /* Get tick */
937     tickstart = HAL_GetTick();
938  
939     while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
940     {
941       /* Check for the Timeout */
942       if(Timeout != HAL_MAX_DELAY)
943       {
944         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
945         {
946           /* Change state */
947           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
948           
949           /* Process Unlocked */
950           __HAL_UNLOCK(hcryp);
951         
952           return HAL_TIMEOUT;
953         }
954       }
955     }
956     /***************************** Header phase *******************************/
957     if(headersize != 0)
958     {
959       /* Select header phase */
960       __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
961       
962       /* Enable Crypto processor */
963       __HAL_CRYP_ENABLE();
964       
965       for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
966       {
967         /* Get tick */
968         tickstart = HAL_GetTick();
969
970         while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
971         {
972           /* Check for the Timeout */
973           if(Timeout != HAL_MAX_DELAY)
974           {
975             if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
976             {
977               /* Change state */
978               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
979               
980               /* Process Unlocked */
981               __HAL_UNLOCK(hcryp);
982               
983               return HAL_TIMEOUT;
984             }
985           }
986         }
987         /* Write the header block in the IN FIFO */
988         CRYP->DR = *(uint32_t*)(headeraddr);
989         headeraddr+=4;
990         CRYP->DR = *(uint32_t*)(headeraddr);
991         headeraddr+=4;
992         CRYP->DR = *(uint32_t*)(headeraddr);
993         headeraddr+=4;
994         CRYP->DR = *(uint32_t*)(headeraddr);
995         headeraddr+=4;
996       }
997       
998       /* Get tick */
999       tickstart = HAL_GetTick();
1000
1001       while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1002       {
1003       /* Check for the Timeout */
1004         if(Timeout != HAL_MAX_DELAY)
1005         {
1006           if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1007           {
1008             /* Change state */
1009             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1010             
1011             /* Process Unlocked */
1012             __HAL_UNLOCK(hcryp);
1013             
1014             return HAL_TIMEOUT;
1015           }
1016         }
1017       }
1018     }
1019     /* Save formatted counter into the scratch buffer pScratch */
1020     for(loopcounter = 0; (loopcounter < 16); loopcounter++)
1021     {
1022       hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1023     }
1024     /* Reset bit 0 */
1025     hcryp->Init.pScratch[15] &= 0xfe;
1026     /* Select payload phase once the header phase is performed */
1027     __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1028     
1029     /* Flush FIFO */
1030     __HAL_CRYP_FIFO_FLUSH();
1031     
1032     /* Enable the CRYP peripheral */
1033     __HAL_CRYP_ENABLE();
1034     
1035     /* Set the phase */
1036     hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1037   }
1038   
1039   /* Write Plain Data and Get Cypher Data */
1040   if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
1041   {
1042     return HAL_TIMEOUT;
1043   }
1044   
1045   /* Change the CRYP peripheral state */
1046   hcryp->State = HAL_CRYP_STATE_READY;
1047   
1048   /* Process Unlocked */
1049   __HAL_UNLOCK(hcryp);
1050   
1051   /* Return function status */
1052   return HAL_OK;
1053 }
1054
1055 /**
1056   * @brief  Initializes the CRYP peripheral in AES GCM encryption mode using IT.
1057   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1058   *         the configuration information for CRYP module
1059   * @param  pPlainData: Pointer to the plaintext buffer
1060   * @param  Size: Length of the plaintext buffer, must be a multiple of 16
1061   * @param  pCypherData: Pointer to the cyphertext buffer
1062   * @retval HAL status
1063   */
1064 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1065 {
1066   uint32_t tickstart = 0;   
1067   uint32_t inputaddr;
1068   uint32_t outputaddr;
1069   
1070   if(hcryp->State == HAL_CRYP_STATE_READY)
1071   {
1072     /* Process Locked */
1073     __HAL_LOCK(hcryp);
1074     
1075     /* Get the buffer addresses and sizes */    
1076     hcryp->CrypInCount = Size;
1077     hcryp->pCrypInBuffPtr = pPlainData;
1078     hcryp->pCrypOutBuffPtr = pCypherData;
1079     hcryp->CrypOutCount = Size;
1080     
1081     /* Change the CRYP peripheral state */
1082     hcryp->State = HAL_CRYP_STATE_BUSY;
1083     
1084     /* Check if initialization phase has already been performed */
1085     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1086     {
1087       /* Set the key */
1088       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1089       
1090       /* Set the CRYP peripheral in AES GCM mode */
1091       __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
1092       
1093       /* Set the Initialization Vector */
1094       CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
1095       
1096       /* Flush FIFO */
1097       __HAL_CRYP_FIFO_FLUSH();
1098       
1099       /* Enable CRYP to start the init phase */
1100       __HAL_CRYP_ENABLE();
1101       
1102      /* Get tick */
1103      tickstart = HAL_GetTick();
1104
1105       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1106       {
1107         /* Check for the Timeout */
1108         
1109         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1110         {
1111           /* Change state */
1112           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1113           
1114           /* Process Unlocked */
1115           __HAL_UNLOCK(hcryp);
1116           
1117           return HAL_TIMEOUT;
1118           
1119         }
1120       }
1121       
1122       /* Set the header phase */
1123       if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
1124       {
1125         return HAL_TIMEOUT;
1126       }
1127       /* Disable the CRYP peripheral */
1128       __HAL_CRYP_DISABLE();
1129       
1130       /* Select payload phase once the header phase is performed */
1131       __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1132       
1133       /* Flush FIFO */
1134       __HAL_CRYP_FIFO_FLUSH();
1135       
1136       /* Set the phase */
1137       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1138     }
1139     
1140     if(Size != 0)
1141     {
1142       /* Enable Interrupts */
1143       __HAL_CRYP_ENABLE_IT(CRYP_IT_INI | CRYP_IT_OUTI);
1144       /* Enable the CRYP peripheral */
1145       __HAL_CRYP_ENABLE();
1146     }
1147     else
1148     {
1149       /* Process Locked */
1150       __HAL_UNLOCK(hcryp);
1151       /* Change the CRYP state and phase */
1152       hcryp->State = HAL_CRYP_STATE_READY;
1153     }
1154     /* Return function status */
1155     return HAL_OK;
1156   }
1157   else if (__HAL_CRYP_GET_IT(CRYP_IT_INI))
1158   {
1159     inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1160     /* Write the Input block in the IN FIFO */
1161     CRYP->DR = *(uint32_t*)(inputaddr);
1162     inputaddr+=4;
1163     CRYP->DR = *(uint32_t*)(inputaddr);
1164     inputaddr+=4;
1165     CRYP->DR  = *(uint32_t*)(inputaddr);
1166     inputaddr+=4;
1167     CRYP->DR = *(uint32_t*)(inputaddr);
1168     hcryp->pCrypInBuffPtr += 16;
1169     hcryp->CrypInCount -= 16;
1170     if(hcryp->CrypInCount == 0)
1171     {
1172       __HAL_CRYP_DISABLE_IT(CRYP_IT_INI);
1173       /* Call the Input data transfer complete callback */
1174       HAL_CRYP_InCpltCallback(hcryp);
1175     }
1176   }
1177   else if (__HAL_CRYP_GET_IT(CRYP_IT_OUTI))
1178   {
1179     outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1180     /* Read the Output block from the Output FIFO */
1181     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1182     outputaddr+=4;
1183     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1184     outputaddr+=4;
1185     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1186     outputaddr+=4;
1187     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1188     hcryp->pCrypOutBuffPtr += 16;
1189     hcryp->CrypOutCount -= 16;
1190     if(hcryp->CrypOutCount == 0)
1191     {
1192       __HAL_CRYP_DISABLE_IT(CRYP_IT_OUTI);
1193       /* Process Unlocked */
1194       __HAL_UNLOCK(hcryp);
1195       /* Change the CRYP peripheral state */
1196       hcryp->State = HAL_CRYP_STATE_READY;
1197       /* Call Input transfer complete callback */
1198       HAL_CRYP_OutCpltCallback(hcryp);
1199     }
1200   }
1201   
1202   /* Return function status */
1203   return HAL_OK;
1204 }
1205
1206 /**
1207   * @brief  Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
1208   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1209   *         the configuration information for CRYP module
1210   * @param  pPlainData: Pointer to the plaintext buffer
1211   * @param  Size: Length of the plaintext buffer, must be a multiple of 16
1212   * @param  pCypherData: Pointer to the cyphertext buffer
1213   * @retval HAL status
1214   */
1215 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1216 {
1217   uint32_t tickstart = 0;   
1218   uint32_t inputaddr;
1219   uint32_t outputaddr;
1220   
1221   uint32_t headersize = hcryp->Init.HeaderSize;
1222   uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
1223   uint32_t loopcounter = 0;
1224   uint32_t bufferidx = 0;
1225   uint8_t blockb0[16] = {0};/* Block B0 */
1226   uint8_t ctr[16] = {0}; /* Counter */
1227   uint32_t b0addr = (uint32_t)blockb0;
1228   
1229   if(hcryp->State == HAL_CRYP_STATE_READY)
1230   {
1231     /* Process Locked */
1232     __HAL_LOCK(hcryp);
1233     
1234     hcryp->CrypInCount = Size;
1235     hcryp->pCrypInBuffPtr = pPlainData;
1236     hcryp->pCrypOutBuffPtr = pCypherData;
1237     hcryp->CrypOutCount = Size;
1238     
1239     /* Change the CRYP peripheral state */
1240     hcryp->State = HAL_CRYP_STATE_BUSY;
1241     
1242     /* Check if initialization phase has already been performed */
1243     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1244     {    
1245       /************************ Formatting the header block *******************/
1246       if(headersize != 0)
1247       {
1248         /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1249         if(headersize < 65280)
1250         {
1251           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
1252           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
1253           headersize += 2;
1254         }
1255         else
1256         {
1257           /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1258           hcryp->Init.pScratch[bufferidx++] = 0xFF;
1259           hcryp->Init.pScratch[bufferidx++] = 0xFE;
1260           hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
1261           hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
1262           hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
1263           hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
1264           headersize += 6;
1265         }
1266         /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1267         for(loopcounter = 0; loopcounter < headersize; loopcounter++)
1268         {
1269           hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
1270         }
1271         /* Check if the header size is modulo 16 */
1272         if ((headersize % 16) != 0)
1273         {
1274           /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1275           for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
1276           {
1277             hcryp->Init.pScratch[loopcounter] = 0;
1278           }
1279           /* Set the header size to modulo 16 */
1280           headersize = ((headersize/16) + 1) * 16;
1281         }
1282         /* Set the pointer headeraddr to hcryp->Init.pScratch */
1283         headeraddr = (uint32_t)hcryp->Init.pScratch;
1284       }
1285       /*********************** Formatting the block B0 ************************/
1286       if(headersize != 0)
1287       {
1288         blockb0[0] = 0x40;
1289       }
1290       /* Flags byte */
1291       /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
1292       blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
1293       blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
1294       
1295       for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
1296       {
1297         blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
1298       }
1299       for ( ; loopcounter < 13; loopcounter++)
1300       {
1301         blockb0[loopcounter+1] = 0;
1302       }
1303       
1304       blockb0[14] = (Size >> 8);
1305       blockb0[15] = (Size & 0xFF);
1306       
1307       /************************* Formatting the initial counter ***************/
1308       /* Byte 0:
1309          Bits 7 and 6 are reserved and shall be set to 0
1310          Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
1311          blocks are distinct from B0
1312          Bits 0, 1, and 2 contain the same encoding of q as in B0
1313       */
1314       ctr[0] = blockb0[0] & 0x07;
1315       /* byte 1 to NonceSize is the IV (Nonce) */
1316       for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
1317       {
1318         ctr[loopcounter] = blockb0[loopcounter];
1319       }
1320       /* Set the LSB to 1 */
1321       ctr[15] |= 0x01;
1322       
1323       /* Set the key */
1324       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1325       
1326       /* Set the CRYP peripheral in AES CCM mode */
1327       __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
1328       
1329       /* Set the Initialization Vector */
1330       CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, hcryp->Init.KeySize);
1331       
1332       /* Select init phase */
1333       __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
1334       
1335       b0addr = (uint32_t)blockb0;
1336       /* Write the blockb0 block in the IN FIFO */
1337       CRYP->DR = *(uint32_t*)(b0addr);
1338       b0addr+=4;
1339       CRYP->DR = *(uint32_t*)(b0addr);
1340       b0addr+=4;
1341       CRYP->DR = *(uint32_t*)(b0addr);
1342       b0addr+=4;
1343       CRYP->DR = *(uint32_t*)(b0addr);
1344       
1345       /* Enable the CRYP peripheral */
1346       __HAL_CRYP_ENABLE();
1347       
1348      /* Get tick */
1349      tickstart = HAL_GetTick();
1350
1351       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1352       {
1353         /* Check for the Timeout */
1354         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1355         {
1356           /* Change state */
1357           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1358           
1359           /* Process Unlocked */
1360           __HAL_UNLOCK(hcryp);
1361           
1362           return HAL_TIMEOUT;
1363         }
1364       }
1365       /***************************** Header phase *****************************/
1366       if(headersize != 0)
1367       {
1368         /* Select header phase */
1369         __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
1370         
1371         /* Enable Crypto processor */
1372         __HAL_CRYP_ENABLE();
1373         
1374         for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1375         {
1376          /* Get tick */
1377          tickstart = HAL_GetTick();
1378
1379           while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
1380           {
1381             /* Check for the Timeout */
1382             if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1383             {
1384               /* Change state */
1385               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1386               
1387               /* Process Unlocked */
1388               __HAL_UNLOCK(hcryp);
1389               
1390               return HAL_TIMEOUT;
1391             }
1392           }
1393           /* Write the header block in the IN FIFO */
1394           CRYP->DR = *(uint32_t*)(headeraddr);
1395           headeraddr+=4;
1396           CRYP->DR = *(uint32_t*)(headeraddr);
1397           headeraddr+=4;
1398           CRYP->DR = *(uint32_t*)(headeraddr);
1399           headeraddr+=4;
1400           CRYP->DR = *(uint32_t*)(headeraddr);
1401           headeraddr+=4;
1402         }
1403
1404         /* Get tick */
1405         tickstart = HAL_GetTick();
1406
1407         while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1408         {
1409           /* Check for the Timeout */
1410           if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1411           {
1412             /* Change state */
1413             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1414             
1415             /* Process Unlocked */
1416             __HAL_UNLOCK(hcryp);
1417             
1418             return HAL_TIMEOUT;
1419           }
1420         }
1421       }
1422       /* Save formatted counter into the scratch buffer pScratch */
1423       for(loopcounter = 0; (loopcounter < 16); loopcounter++)
1424       {
1425         hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1426       }
1427       /* Reset bit 0 */
1428       hcryp->Init.pScratch[15] &= 0xfe;
1429       
1430       /* Select payload phase once the header phase is performed */
1431       __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1432       
1433       /* Flush FIFO */
1434       __HAL_CRYP_FIFO_FLUSH();
1435       
1436       /* Set the phase */
1437       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1438     }
1439     
1440     if(Size != 0)
1441     {
1442       /* Enable Interrupts */
1443       __HAL_CRYP_ENABLE_IT(CRYP_IT_INI | CRYP_IT_OUTI);
1444       /* Enable the CRYP peripheral */
1445       __HAL_CRYP_ENABLE();
1446     }
1447     else
1448     {
1449       /* Change the CRYP state and phase */
1450       hcryp->State = HAL_CRYP_STATE_READY;
1451     }
1452     
1453     /* Return function status */
1454     return HAL_OK;
1455   }
1456   else if (__HAL_CRYP_GET_IT(CRYP_IT_INI))
1457   {
1458     inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1459     /* Write the Input block in the IN FIFO */
1460     CRYP->DR = *(uint32_t*)(inputaddr);
1461     inputaddr+=4;
1462     CRYP->DR = *(uint32_t*)(inputaddr);
1463     inputaddr+=4;
1464     CRYP->DR  = *(uint32_t*)(inputaddr);
1465     inputaddr+=4;
1466     CRYP->DR = *(uint32_t*)(inputaddr);
1467     hcryp->pCrypInBuffPtr += 16;
1468     hcryp->CrypInCount -= 16;
1469     if(hcryp->CrypInCount == 0)
1470     {
1471       __HAL_CRYP_DISABLE_IT(CRYP_IT_INI);
1472       /* Call Input transfer complete callback */
1473       HAL_CRYP_InCpltCallback(hcryp);
1474     }
1475   }
1476   else if (__HAL_CRYP_GET_IT(CRYP_IT_OUTI))
1477   {
1478     outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1479     /* Read the Output block from the Output FIFO */
1480     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1481     outputaddr+=4;
1482     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1483     outputaddr+=4;
1484     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1485     outputaddr+=4;
1486     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1487     hcryp->pCrypOutBuffPtr += 16;
1488     hcryp->CrypOutCount -= 16;
1489     if(hcryp->CrypOutCount == 0)
1490     {
1491       __HAL_CRYP_DISABLE_IT(CRYP_IT_OUTI);
1492       /* Process Unlocked */
1493       __HAL_UNLOCK(hcryp);
1494       /* Change the CRYP peripheral state */
1495       hcryp->State = HAL_CRYP_STATE_READY;
1496       /* Call Input transfer complete callback */
1497       HAL_CRYP_OutCpltCallback(hcryp);
1498     }
1499   }
1500   
1501   /* Return function status */
1502   return HAL_OK;
1503 }
1504
1505 /**
1506   * @brief  Initializes the CRYP peripheral in AES GCM decryption mode using IT.
1507   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1508   *         the configuration information for CRYP module
1509   * @param  pCypherData: Pointer to the cyphertext buffer
1510   * @param  Size: Length of the cyphertext buffer, must be a multiple of 16
1511   * @param  pPlainData: Pointer to the plaintext buffer
1512   * @retval HAL status
1513   */
1514 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
1515 {
1516   uint32_t tickstart = 0;   
1517   uint32_t inputaddr;
1518   uint32_t outputaddr;
1519   
1520   if(hcryp->State == HAL_CRYP_STATE_READY)
1521   {
1522     /* Process Locked */
1523     __HAL_LOCK(hcryp);
1524     
1525     /* Get the buffer addresses and sizes */    
1526     hcryp->CrypInCount = Size;
1527     hcryp->pCrypInBuffPtr = pCypherData;
1528     hcryp->pCrypOutBuffPtr = pPlainData;
1529     hcryp->CrypOutCount = Size;
1530     
1531     /* Change the CRYP peripheral state */
1532     hcryp->State = HAL_CRYP_STATE_BUSY;
1533     
1534     /* Check if initialization phase has already been performed */
1535     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1536     {
1537       /* Set the key */
1538       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1539       
1540       /* Set the CRYP peripheral in AES GCM decryption mode */
1541       __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
1542       
1543       /* Set the Initialization Vector */
1544       CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
1545       
1546       /* Flush FIFO */
1547       __HAL_CRYP_FIFO_FLUSH();
1548       
1549       /* Enable CRYP to start the init phase */
1550       __HAL_CRYP_ENABLE();
1551
1552         /* Get tick */
1553         tickstart = HAL_GetTick();
1554
1555       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1556       {
1557         /* Check for the Timeout */
1558         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1559         {
1560           /* Change state */
1561           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1562           
1563           /* Process Unlocked */
1564           __HAL_UNLOCK(hcryp);
1565           
1566           return HAL_TIMEOUT;
1567         }
1568       }
1569       
1570       /* Set the header phase */
1571       if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
1572       {
1573         return HAL_TIMEOUT;
1574       }
1575       /* Disable the CRYP peripheral */
1576       __HAL_CRYP_DISABLE();
1577       
1578       /* Select payload phase once the header phase is performed */
1579       __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1580       
1581       /* Set the phase */
1582       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1583     }
1584     
1585     if(Size != 0)
1586     {
1587       /* Enable Interrupts */
1588       __HAL_CRYP_ENABLE_IT(CRYP_IT_INI | CRYP_IT_OUTI);
1589       /* Enable the CRYP peripheral */
1590       __HAL_CRYP_ENABLE();
1591     }
1592     else
1593     {
1594       /* Process Locked */
1595       __HAL_UNLOCK(hcryp);
1596       /* Change the CRYP state and phase */
1597       hcryp->State = HAL_CRYP_STATE_READY;
1598     }
1599     
1600     /* Return function status */
1601     return HAL_OK;
1602   }
1603   else if (__HAL_CRYP_GET_IT(CRYP_IT_INI))
1604   {
1605     inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1606     /* Write the Input block in the IN FIFO */
1607     CRYP->DR = *(uint32_t*)(inputaddr);
1608     inputaddr+=4;
1609     CRYP->DR = *(uint32_t*)(inputaddr);
1610     inputaddr+=4;
1611     CRYP->DR  = *(uint32_t*)(inputaddr);
1612     inputaddr+=4;
1613     CRYP->DR = *(uint32_t*)(inputaddr);
1614     hcryp->pCrypInBuffPtr += 16;
1615     hcryp->CrypInCount -= 16;
1616     if(hcryp->CrypInCount == 0)
1617     {
1618       __HAL_CRYP_DISABLE_IT(CRYP_IT_INI);
1619       /* Call the Input data transfer complete callback */
1620       HAL_CRYP_InCpltCallback(hcryp);
1621     }
1622   }
1623   else if (__HAL_CRYP_GET_IT(CRYP_IT_OUTI))
1624   {
1625     outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1626     /* Read the Output block from the Output FIFO */
1627     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1628     outputaddr+=4;
1629     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1630     outputaddr+=4;
1631     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1632     outputaddr+=4;
1633     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1634     hcryp->pCrypOutBuffPtr += 16;
1635     hcryp->CrypOutCount -= 16;
1636     if(hcryp->CrypOutCount == 0)
1637     {
1638       __HAL_CRYP_DISABLE_IT(CRYP_IT_OUTI);
1639       /* Process Unlocked */
1640       __HAL_UNLOCK(hcryp);
1641       /* Change the CRYP peripheral state */
1642       hcryp->State = HAL_CRYP_STATE_READY;
1643       /* Call Input transfer complete callback */
1644       HAL_CRYP_OutCpltCallback(hcryp);
1645     }
1646   }
1647   
1648   /* Return function status */
1649   return HAL_OK;
1650 }
1651
1652 /**
1653   * @brief  Initializes the CRYP peripheral in AES CCM decryption mode using interrupt
1654   *         then decrypted pCypherData. The cypher data are available in pPlainData.
1655   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1656   *         the configuration information for CRYP module
1657   * @param  pCypherData: Pointer to the cyphertext buffer 
1658   * @param  Size: Length of the plaintext buffer, must be a multiple of 16
1659   * @param  pPlainData: Pointer to the plaintext buffer  
1660   * @retval HAL status
1661   */
1662 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
1663 {
1664   uint32_t inputaddr;
1665   uint32_t outputaddr;
1666   uint32_t tickstart = 0;
1667   uint32_t headersize = hcryp->Init.HeaderSize;
1668   uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
1669   uint32_t loopcounter = 0;
1670   uint32_t bufferidx = 0;
1671   uint8_t blockb0[16] = {0};/* Block B0 */
1672   uint8_t ctr[16] = {0}; /* Counter */
1673   uint32_t b0addr = (uint32_t)blockb0;
1674   
1675   if(hcryp->State == HAL_CRYP_STATE_READY)
1676   {
1677     /* Process Locked */
1678     __HAL_LOCK(hcryp);
1679     
1680     hcryp->CrypInCount = Size;
1681     hcryp->pCrypInBuffPtr = pCypherData;
1682     hcryp->pCrypOutBuffPtr = pPlainData;
1683     hcryp->CrypOutCount = Size;
1684     
1685     /* Change the CRYP peripheral state */
1686     hcryp->State = HAL_CRYP_STATE_BUSY;
1687     
1688     /* Check if initialization phase has already been performed */
1689     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1690     {
1691       /************************ Formatting the header block *******************/
1692       if(headersize != 0)
1693       {
1694         /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1695         if(headersize < 65280)
1696         {
1697           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
1698           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
1699           headersize += 2;
1700         }
1701         else
1702         {
1703           /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1704           hcryp->Init.pScratch[bufferidx++] = 0xFF;
1705           hcryp->Init.pScratch[bufferidx++] = 0xFE;
1706           hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
1707           hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
1708           hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
1709           hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
1710           headersize += 6;
1711         }
1712         /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1713         for(loopcounter = 0; loopcounter < headersize; loopcounter++)
1714         {
1715           hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
1716         }
1717         /* Check if the header size is modulo 16 */
1718         if ((headersize % 16) != 0)
1719         {
1720           /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1721           for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
1722           {
1723             hcryp->Init.pScratch[loopcounter] = 0;
1724           }
1725           /* Set the header size to modulo 16 */
1726           headersize = ((headersize/16) + 1) * 16;
1727         }
1728         /* Set the pointer headeraddr to hcryp->Init.pScratch */
1729         headeraddr = (uint32_t)hcryp->Init.pScratch;
1730       }
1731       /*********************** Formatting the block B0 ************************/
1732       if(headersize != 0)
1733       {
1734         blockb0[0] = 0x40;
1735       }
1736       /* Flags byte */
1737       /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
1738       blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
1739       blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
1740       
1741       for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
1742       {
1743         blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
1744       }
1745       for ( ; loopcounter < 13; loopcounter++)
1746       {
1747         blockb0[loopcounter+1] = 0;
1748       }
1749       
1750       blockb0[14] = (Size >> 8);
1751       blockb0[15] = (Size & 0xFF);
1752       
1753       /************************* Formatting the initial counter ***************/
1754       /* Byte 0:
1755          Bits 7 and 6 are reserved and shall be set to 0
1756          Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
1757          blocks are distinct from B0
1758          Bits 0, 1, and 2 contain the same encoding of q as in B0
1759       */
1760       ctr[0] = blockb0[0] & 0x07;
1761       /* byte 1 to NonceSize is the IV (Nonce) */
1762       for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
1763       {
1764         ctr[loopcounter] = blockb0[loopcounter];
1765       }
1766       /* Set the LSB to 1 */
1767       ctr[15] |= 0x01;
1768       
1769       /* Set the key */
1770       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1771       
1772       /* Set the CRYP peripheral in AES CCM mode */
1773       __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
1774       
1775       /* Set the Initialization Vector */
1776       CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, hcryp->Init.KeySize);
1777       
1778       /* Select init phase */
1779       __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
1780       
1781       b0addr = (uint32_t)blockb0;
1782       /* Write the blockb0 block in the IN FIFO */
1783       CRYP->DR = *(uint32_t*)(b0addr);
1784       b0addr+=4;
1785       CRYP->DR = *(uint32_t*)(b0addr);
1786       b0addr+=4;
1787       CRYP->DR = *(uint32_t*)(b0addr);
1788       b0addr+=4;
1789       CRYP->DR = *(uint32_t*)(b0addr);
1790       
1791       /* Enable the CRYP peripheral */
1792       __HAL_CRYP_ENABLE();
1793
1794       /* Get tick */
1795       tickstart = HAL_GetTick();
1796
1797       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1798       {
1799         /* Check for the Timeout */
1800         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1801         {
1802           /* Change state */
1803           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1804           
1805           /* Process Unlocked */
1806           __HAL_UNLOCK(hcryp);
1807           
1808           return HAL_TIMEOUT;
1809         }
1810       }
1811       /***************************** Header phase *****************************/
1812       if(headersize != 0)
1813       {
1814         /* Select header phase */
1815         __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
1816         
1817         /* Enable Crypto processor */
1818         __HAL_CRYP_ENABLE();
1819         
1820         for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1821         {
1822          /* Get tick */
1823          tickstart = HAL_GetTick();
1824
1825           while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
1826           {
1827             /* Check for the Timeout */
1828             if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1829             {
1830               /* Change state */
1831               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1832               
1833               /* Process Unlocked */
1834               __HAL_UNLOCK(hcryp);
1835               
1836               return HAL_TIMEOUT;
1837             }
1838           }
1839           /* Write the header block in the IN FIFO */
1840           CRYP->DR = *(uint32_t*)(headeraddr);
1841           headeraddr+=4;
1842           CRYP->DR = *(uint32_t*)(headeraddr);
1843           headeraddr+=4;
1844           CRYP->DR = *(uint32_t*)(headeraddr);
1845           headeraddr+=4;
1846           CRYP->DR = *(uint32_t*)(headeraddr);
1847           headeraddr+=4;
1848         }
1849
1850         /* Get tick */
1851         tickstart = HAL_GetTick();
1852
1853         while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1854         {
1855           /* Check for the Timeout */
1856           if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1857           {
1858             /* Change state */
1859             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1860             
1861             /* Process Unlocked */
1862             __HAL_UNLOCK(hcryp);
1863             
1864             return HAL_TIMEOUT;
1865           }
1866         }
1867       }
1868       /* Save formatted counter into the scratch buffer pScratch */
1869       for(loopcounter = 0; (loopcounter < 16); loopcounter++)
1870       {
1871         hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1872       }
1873       /* Reset bit 0 */
1874       hcryp->Init.pScratch[15] &= 0xfe;
1875       /* Select payload phase once the header phase is performed */
1876       __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1877       
1878       /* Flush FIFO */
1879       __HAL_CRYP_FIFO_FLUSH();
1880       
1881       /* Set the phase */
1882       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1883     }
1884     
1885     /* Enable Interrupts */
1886     __HAL_CRYP_ENABLE_IT(CRYP_IT_INI | CRYP_IT_OUTI);
1887     
1888     /* Enable the CRYP peripheral */
1889     __HAL_CRYP_ENABLE();
1890     
1891     /* Return function status */
1892     return HAL_OK;
1893   }
1894   else if (__HAL_CRYP_GET_IT(CRYP_IT_INI))
1895   {
1896     inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1897     /* Write the Input block in the IN FIFO */
1898     CRYP->DR = *(uint32_t*)(inputaddr);
1899     inputaddr+=4;
1900     CRYP->DR = *(uint32_t*)(inputaddr);
1901     inputaddr+=4;
1902     CRYP->DR  = *(uint32_t*)(inputaddr);
1903     inputaddr+=4;
1904     CRYP->DR = *(uint32_t*)(inputaddr);
1905     hcryp->pCrypInBuffPtr += 16;
1906     hcryp->CrypInCount -= 16;
1907     if(hcryp->CrypInCount == 0)
1908     {
1909       __HAL_CRYP_DISABLE_IT(CRYP_IT_INI);
1910       /* Call the Input data transfer complete callback */
1911       HAL_CRYP_InCpltCallback(hcryp);
1912     }
1913   }
1914   else if (__HAL_CRYP_GET_IT(CRYP_IT_OUTI))
1915   {
1916     outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1917     /* Read the Output block from the Output FIFO */
1918     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1919     outputaddr+=4;
1920     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1921     outputaddr+=4;
1922     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1923     outputaddr+=4;
1924     *(uint32_t*)(outputaddr) = CRYP->DOUT;
1925     hcryp->pCrypOutBuffPtr += 16;
1926     hcryp->CrypOutCount -= 16;
1927     if(hcryp->CrypOutCount == 0)
1928     {
1929       __HAL_CRYP_DISABLE_IT(CRYP_IT_OUTI);
1930       /* Process Unlocked */
1931       __HAL_UNLOCK(hcryp);
1932       /* Change the CRYP peripheral state */
1933       hcryp->State = HAL_CRYP_STATE_READY;
1934       /* Call Input transfer complete callback */
1935       HAL_CRYP_OutCpltCallback(hcryp);
1936     }
1937   }
1938   
1939   /* Return function status */
1940   return HAL_OK;
1941 }
1942
1943 /**
1944   * @brief  Initializes the CRYP peripheral in AES GCM encryption mode using DMA.
1945   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1946   *         the configuration information for CRYP module
1947   * @param  pPlainData: Pointer to the plaintext buffer
1948   * @param  Size: Length of the plaintext buffer, must be a multiple of 16
1949   * @param  pCypherData: Pointer to the cyphertext buffer
1950   * @retval HAL status
1951   */
1952 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1953 {
1954   uint32_t tickstart = 0;
1955   uint32_t inputaddr;
1956   uint32_t outputaddr;
1957   
1958   if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
1959   {
1960     /* Process Locked */
1961     __HAL_LOCK(hcryp);
1962     
1963     inputaddr  = (uint32_t)pPlainData;
1964     outputaddr = (uint32_t)pCypherData;
1965     
1966     /* Change the CRYP peripheral state */
1967     hcryp->State = HAL_CRYP_STATE_BUSY;
1968     
1969     /* Check if initialization phase has already been performed */
1970     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1971     {
1972       /* Set the key */
1973       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1974       
1975       /* Set the CRYP peripheral in AES GCM mode */
1976       __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
1977       
1978       /* Set the Initialization Vector */
1979       CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
1980       
1981       /* Flush FIFO */
1982       __HAL_CRYP_FIFO_FLUSH();
1983       
1984       /* Enable CRYP to start the init phase */
1985       __HAL_CRYP_ENABLE();
1986       
1987       /* Get tick */
1988       tickstart = HAL_GetTick();
1989
1990       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1991       {
1992         /* Check for the Timeout */
1993         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1994         {
1995           /* Change state */
1996           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1997           
1998           /* Process Unlocked */
1999           __HAL_UNLOCK(hcryp);
2000           
2001           return HAL_TIMEOUT;
2002         }
2003       }
2004       /* Flush FIFO */
2005       __HAL_CRYP_FIFO_FLUSH();
2006       
2007       /* Set the header phase */
2008       if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
2009       {
2010         return HAL_TIMEOUT;
2011       }
2012       /* Disable the CRYP peripheral */
2013       __HAL_CRYP_DISABLE();
2014       
2015       /* Select payload phase once the header phase is performed */
2016       __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
2017       
2018       /* Flush FIFO */
2019       __HAL_CRYP_FIFO_FLUSH();
2020       
2021       /* Set the phase */
2022       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2023     }
2024     
2025     /* Set the input and output addresses and start DMA transfer */ 
2026     CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2027     
2028     /* Unlock process */
2029     __HAL_UNLOCK(hcryp);
2030     
2031     /* Return function status */
2032     return HAL_OK;
2033   }
2034   else
2035   {
2036     return HAL_ERROR;   
2037   }
2038 }
2039
2040 /**
2041   * @brief  Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
2042   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2043   *         the configuration information for CRYP module
2044   * @param  pPlainData: Pointer to the plaintext buffer
2045   * @param  Size: Length of the plaintext buffer, must be a multiple of 16
2046   * @param  pCypherData: Pointer to the cyphertext buffer
2047   * @retval HAL status
2048   */
2049 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
2050 {
2051   uint32_t tickstart = 0;   
2052   uint32_t inputaddr;
2053   uint32_t outputaddr;
2054   uint32_t headersize;
2055   uint32_t headeraddr;
2056   uint32_t loopcounter = 0;
2057   uint32_t bufferidx = 0;
2058   uint8_t blockb0[16] = {0};/* Block B0 */
2059   uint8_t ctr[16] = {0}; /* Counter */
2060   uint32_t b0addr = (uint32_t)blockb0;
2061   
2062   if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2063   {
2064     /* Process Locked */
2065     __HAL_LOCK(hcryp);
2066     
2067     inputaddr  = (uint32_t)pPlainData;
2068     outputaddr = (uint32_t)pCypherData;
2069     
2070     headersize = hcryp->Init.HeaderSize;
2071     headeraddr = (uint32_t)hcryp->Init.Header;
2072     
2073     hcryp->CrypInCount = Size;
2074     hcryp->pCrypInBuffPtr = pPlainData;
2075     hcryp->pCrypOutBuffPtr = pCypherData;
2076     hcryp->CrypOutCount = Size;
2077     
2078     /* Change the CRYP peripheral state */
2079     hcryp->State = HAL_CRYP_STATE_BUSY;
2080     
2081     /* Check if initialization phase has already been performed */
2082     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2083     {
2084       /************************ Formatting the header block *******************/
2085       if(headersize != 0)
2086       {
2087         /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2088         if(headersize < 65280)
2089         {
2090           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
2091           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
2092           headersize += 2;
2093         }
2094         else
2095         {
2096           /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2097           hcryp->Init.pScratch[bufferidx++] = 0xFF;
2098           hcryp->Init.pScratch[bufferidx++] = 0xFE;
2099           hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
2100           hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
2101           hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
2102           hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
2103           headersize += 6;
2104         }
2105         /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2106         for(loopcounter = 0; loopcounter < headersize; loopcounter++)
2107         {
2108           hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2109         }
2110         /* Check if the header size is modulo 16 */
2111         if ((headersize % 16) != 0)
2112         {
2113           /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2114           for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
2115           {
2116             hcryp->Init.pScratch[loopcounter] = 0;
2117           }
2118           /* Set the header size to modulo 16 */
2119           headersize = ((headersize/16) + 1) * 16;
2120         }
2121         /* Set the pointer headeraddr to hcryp->Init.pScratch */
2122         headeraddr = (uint32_t)hcryp->Init.pScratch;
2123       }
2124       /*********************** Formatting the block B0 ************************/
2125       if(headersize != 0)
2126       {
2127         blockb0[0] = 0x40;
2128       }
2129       /* Flags byte */
2130       /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2131       blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2132       blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2133       
2134       for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
2135       {
2136         blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
2137       }
2138       for ( ; loopcounter < 13; loopcounter++)
2139       {
2140         blockb0[loopcounter+1] = 0;
2141       }
2142       
2143       blockb0[14] = (Size >> 8);
2144       blockb0[15] = (Size & 0xFF);
2145       
2146       /************************* Formatting the initial counter ***************/
2147       /* Byte 0:
2148          Bits 7 and 6 are reserved and shall be set to 0
2149          Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
2150          blocks are distinct from B0
2151          Bits 0, 1, and 2 contain the same encoding of q as in B0
2152       */
2153       ctr[0] = blockb0[0] & 0x07;
2154       /* byte 1 to NonceSize is the IV (Nonce) */
2155       for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
2156       {
2157         ctr[loopcounter] = blockb0[loopcounter];
2158       }
2159       /* Set the LSB to 1 */
2160       ctr[15] |= 0x01;
2161       
2162       /* Set the key */
2163       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2164       
2165       /* Set the CRYP peripheral in AES CCM mode */
2166       __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
2167       
2168       /* Set the Initialization Vector */
2169       CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, CRYP_KEYSIZE_128B);
2170       
2171       /* Select init phase */
2172       __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
2173       
2174       b0addr = (uint32_t)blockb0;
2175       /* Write the blockb0 block in the IN FIFO */
2176       CRYP->DR = *(uint32_t*)(b0addr);
2177       b0addr+=4;
2178       CRYP->DR = *(uint32_t*)(b0addr);
2179       b0addr+=4;
2180       CRYP->DR = *(uint32_t*)(b0addr);
2181       b0addr+=4;
2182       CRYP->DR = *(uint32_t*)(b0addr);
2183       
2184       /* Enable the CRYP peripheral */
2185       __HAL_CRYP_ENABLE();
2186       
2187       /* Get tick */
2188       tickstart = HAL_GetTick();
2189  
2190       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2191       {
2192         /* Check for the Timeout */
2193         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2194         {
2195           /* Change state */
2196           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2197           
2198           /* Process Unlocked */
2199           __HAL_UNLOCK(hcryp);
2200           
2201           return HAL_TIMEOUT;
2202         }
2203       }
2204       /***************************** Header phase *****************************/
2205       if(headersize != 0)
2206       {
2207         /* Select header phase */
2208         __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
2209         
2210         /* Enable Crypto processor */
2211         __HAL_CRYP_ENABLE();
2212         
2213         for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
2214         {
2215          /* Get tick */
2216          tickstart = HAL_GetTick();
2217
2218           while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
2219           {
2220             /* Check for the Timeout */
2221             if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2222             {
2223               /* Change state */
2224               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2225               
2226               /* Process Unlocked */
2227               __HAL_UNLOCK(hcryp);
2228               
2229               return HAL_TIMEOUT;
2230             }
2231           }
2232           /* Write the header block in the IN FIFO */
2233           CRYP->DR = *(uint32_t*)(headeraddr);
2234           headeraddr+=4;
2235           CRYP->DR = *(uint32_t*)(headeraddr);
2236           headeraddr+=4;
2237           CRYP->DR = *(uint32_t*)(headeraddr);
2238           headeraddr+=4;
2239           CRYP->DR = *(uint32_t*)(headeraddr);
2240           headeraddr+=4;
2241         }
2242         
2243         /* Get tick */
2244         tickstart = HAL_GetTick();
2245
2246         while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2247         {
2248           /* Check for the Timeout */
2249           if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2250           {
2251             /* Change state */
2252             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2253             
2254             /* Process Unlocked */
2255             __HAL_UNLOCK(hcryp);
2256             
2257             return HAL_TIMEOUT;
2258           }
2259         }
2260       }
2261       /* Save formatted counter into the scratch buffer pScratch */
2262       for(loopcounter = 0; (loopcounter < 16); loopcounter++)
2263       {
2264         hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2265       }
2266       /* Reset bit 0 */
2267       hcryp->Init.pScratch[15] &= 0xfe;
2268       
2269       /* Select payload phase once the header phase is performed */
2270       __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
2271       
2272       /* Flush FIFO */
2273       __HAL_CRYP_FIFO_FLUSH();
2274       
2275       /* Set the phase */
2276       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2277     }
2278     
2279     /* Set the input and output addresses and start DMA transfer */ 
2280     CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2281     
2282     /* Unlock process */
2283     __HAL_UNLOCK(hcryp);
2284     
2285     /* Return function status */
2286     return HAL_OK;
2287   }
2288   else
2289   {
2290     return HAL_ERROR;   
2291   }
2292 }
2293
2294 /**
2295   * @brief  Initializes the CRYP peripheral in AES GCM decryption mode using DMA.
2296   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2297   *         the configuration information for CRYP module
2298   * @param  pCypherData: Pointer to the cyphertext buffer.
2299   * @param  Size: Length of the cyphertext buffer, must be a multiple of 16
2300   * @param  pPlainData: Pointer to the plaintext buffer
2301   * @retval HAL status
2302   */
2303 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2304 {
2305   uint32_t tickstart = 0;   
2306   uint32_t inputaddr;
2307   uint32_t outputaddr;
2308   
2309   if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2310   {
2311     /* Process Locked */
2312     __HAL_LOCK(hcryp);
2313     
2314     inputaddr  = (uint32_t)pCypherData;
2315     outputaddr = (uint32_t)pPlainData;
2316     
2317     /* Change the CRYP peripheral state */
2318     hcryp->State = HAL_CRYP_STATE_BUSY;
2319     
2320     /* Check if initialization phase has already been performed */
2321     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2322     {
2323       /* Set the key */
2324       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2325       
2326       /* Set the CRYP peripheral in AES GCM decryption mode */
2327       __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
2328       
2329       /* Set the Initialization Vector */
2330       CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
2331       
2332       /* Enable CRYP to start the init phase */
2333       __HAL_CRYP_ENABLE();
2334       
2335       /* Get tick */
2336       tickstart = HAL_GetTick();
2337
2338       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2339       {
2340         /* Check for the Timeout */
2341         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2342         {
2343           /* Change state */
2344           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2345           
2346           /* Process Unlocked */
2347           __HAL_UNLOCK(hcryp);
2348           
2349           return HAL_TIMEOUT;
2350         }
2351       }
2352       
2353       /* Set the header phase */
2354       if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
2355       {
2356         return HAL_TIMEOUT;
2357       }
2358       /* Disable the CRYP peripheral */
2359       __HAL_CRYP_DISABLE();
2360       
2361       /* Select payload phase once the header phase is performed */
2362       __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
2363       
2364       /* Set the phase */
2365       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2366     }
2367     
2368     /* Set the input and output addresses and start DMA transfer */ 
2369     CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2370     
2371     /* Unlock process */
2372     __HAL_UNLOCK(hcryp);
2373     
2374     /* Return function status */
2375     return HAL_OK;
2376   }
2377   else
2378   {
2379     return HAL_ERROR;   
2380   }
2381 }
2382
2383 /**
2384   * @brief  Initializes the CRYP peripheral in AES CCM decryption mode using DMA
2385   *         then decrypted pCypherData. The cypher data are available in pPlainData.
2386   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2387   *         the configuration information for CRYP module
2388   * @param  pCypherData: Pointer to the cyphertext buffer  
2389   * @param  Size: Length of the plaintext buffer, must be a multiple of 16
2390   * @param  pPlainData: Pointer to the plaintext buffer  
2391   * @retval HAL status
2392   */
2393 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2394 {
2395   uint32_t tickstart = 0;   
2396   uint32_t inputaddr;
2397   uint32_t outputaddr;
2398   uint32_t headersize;
2399   uint32_t headeraddr;
2400   uint32_t loopcounter = 0;
2401   uint32_t bufferidx = 0;
2402   uint8_t blockb0[16] = {0};/* Block B0 */
2403   uint8_t ctr[16] = {0}; /* Counter */
2404   uint32_t b0addr = (uint32_t)blockb0;
2405   
2406   if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2407   {
2408     /* Process Locked */
2409     __HAL_LOCK(hcryp);
2410     
2411     inputaddr  = (uint32_t)pCypherData;
2412     outputaddr = (uint32_t)pPlainData;
2413     
2414     headersize = hcryp->Init.HeaderSize;
2415     headeraddr = (uint32_t)hcryp->Init.Header;
2416     
2417     hcryp->CrypInCount = Size;
2418     hcryp->pCrypInBuffPtr = pCypherData;
2419     hcryp->pCrypOutBuffPtr = pPlainData;
2420     hcryp->CrypOutCount = Size;
2421     
2422     /* Change the CRYP peripheral state */
2423     hcryp->State = HAL_CRYP_STATE_BUSY;
2424     
2425     /* Check if initialization phase has already been performed */
2426     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2427     {
2428       /************************ Formatting the header block *******************/
2429       if(headersize != 0)
2430       {
2431         /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2432         if(headersize < 65280)
2433         {
2434           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
2435           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
2436           headersize += 2;
2437         }
2438         else
2439         {
2440           /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2441           hcryp->Init.pScratch[bufferidx++] = 0xFF;
2442           hcryp->Init.pScratch[bufferidx++] = 0xFE;
2443           hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
2444           hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
2445           hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
2446           hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
2447           headersize += 6;
2448         }
2449         /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2450         for(loopcounter = 0; loopcounter < headersize; loopcounter++)
2451         {
2452           hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2453         }
2454         /* Check if the header size is modulo 16 */
2455         if ((headersize % 16) != 0)
2456         {
2457           /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2458           for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
2459           {
2460             hcryp->Init.pScratch[loopcounter] = 0;
2461           }
2462           /* Set the header size to modulo 16 */
2463           headersize = ((headersize/16) + 1) * 16;
2464         }
2465         /* Set the pointer headeraddr to hcryp->Init.pScratch */
2466         headeraddr = (uint32_t)hcryp->Init.pScratch;
2467       }
2468       /*********************** Formatting the block B0 ************************/
2469       if(headersize != 0)
2470       {
2471         blockb0[0] = 0x40;
2472       }
2473       /* Flags byte */
2474       /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2475       blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2476       blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2477       
2478       for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
2479       {
2480         blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
2481       }
2482       for ( ; loopcounter < 13; loopcounter++)
2483       {
2484         blockb0[loopcounter+1] = 0;
2485       }
2486       
2487       blockb0[14] = (Size >> 8);
2488       blockb0[15] = (Size & 0xFF);
2489       
2490       /************************* Formatting the initial counter ***************/
2491       /* Byte 0:
2492          Bits 7 and 6 are reserved and shall be set to 0
2493          Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
2494          blocks are distinct from B0
2495          Bits 0, 1, and 2 contain the same encoding of q as in B0
2496       */
2497       ctr[0] = blockb0[0] & 0x07;
2498       /* byte 1 to NonceSize is the IV (Nonce) */
2499       for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
2500       {
2501         ctr[loopcounter] = blockb0[loopcounter];
2502       }
2503       /* Set the LSB to 1 */
2504       ctr[15] |= 0x01;
2505       
2506       /* Set the key */
2507       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2508       
2509       /* Set the CRYP peripheral in AES CCM mode */
2510       __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
2511       
2512       /* Set the Initialization Vector */
2513       CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, CRYP_KEYSIZE_128B);
2514       
2515       /* Select init phase */
2516       __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
2517       
2518       b0addr = (uint32_t)blockb0;
2519       /* Write the blockb0 block in the IN FIFO */
2520       CRYP->DR = *(uint32_t*)(b0addr);
2521       b0addr+=4;
2522       CRYP->DR = *(uint32_t*)(b0addr);
2523       b0addr+=4;
2524       CRYP->DR = *(uint32_t*)(b0addr);
2525       b0addr+=4;
2526       CRYP->DR = *(uint32_t*)(b0addr);
2527       
2528       /* Enable the CRYP peripheral */
2529       __HAL_CRYP_ENABLE();
2530       
2531       /* Get tick */
2532       tickstart = HAL_GetTick();
2533  
2534       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2535       {
2536         /* Check for the Timeout */
2537         
2538         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2539         {
2540           /* Change state */
2541           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2542           
2543           /* Process Unlocked */
2544           __HAL_UNLOCK(hcryp);
2545           
2546           return HAL_TIMEOUT;
2547           
2548         }
2549       }
2550       /***************************** Header phase *****************************/
2551       if(headersize != 0)
2552       {
2553         /* Select header phase */
2554         __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
2555         
2556         /* Enable Crypto processor */
2557         __HAL_CRYP_ENABLE();
2558         
2559         for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
2560         {
2561          /* Get tick */
2562          tickstart = HAL_GetTick();
2563  
2564           while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
2565           {
2566             /* Check for the Timeout */
2567             if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2568             {
2569               /* Change state */
2570               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2571               
2572               /* Process Unlocked */
2573               __HAL_UNLOCK(hcryp);
2574               
2575               return HAL_TIMEOUT;
2576             }
2577           }
2578           /* Write the header block in the IN FIFO */
2579           CRYP->DR = *(uint32_t*)(headeraddr);
2580           headeraddr+=4;
2581           CRYP->DR = *(uint32_t*)(headeraddr);
2582           headeraddr+=4;
2583           CRYP->DR = *(uint32_t*)(headeraddr);
2584           headeraddr+=4;
2585           CRYP->DR = *(uint32_t*)(headeraddr);
2586           headeraddr+=4;
2587         }
2588         
2589         /* Get tick */
2590         tickstart = HAL_GetTick();
2591
2592         while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2593         {
2594           /* Check for the Timeout */
2595           if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2596           {
2597             /* Change state */
2598             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2599             
2600             /* Process Unlocked */
2601             __HAL_UNLOCK(hcryp);
2602             
2603             return HAL_TIMEOUT;
2604           }
2605         }
2606       }
2607       /* Save formatted counter into the scratch buffer pScratch */
2608       for(loopcounter = 0; (loopcounter < 16); loopcounter++)
2609       {
2610         hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2611       }
2612       /* Reset bit 0 */
2613       hcryp->Init.pScratch[15] &= 0xfe;
2614       /* Select payload phase once the header phase is performed */
2615       __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
2616       
2617       /* Flush FIFO */
2618       __HAL_CRYP_FIFO_FLUSH();
2619       
2620       /* Set the phase */
2621       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2622     }
2623     /* Set the input and output addresses and start DMA transfer */ 
2624     CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2625     
2626     /* Unlock process */
2627     __HAL_UNLOCK(hcryp);
2628     
2629     /* Return function status */
2630     return HAL_OK;
2631   }
2632   else
2633   {
2634     return HAL_ERROR;   
2635   }
2636 }
2637
2638 /**
2639   * @brief  This function handles CRYP interrupt request.
2640   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2641   *         the configuration information for CRYP module
2642   * @retval None
2643   */
2644 void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp)
2645 {
2646   switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION)
2647   {    
2648   case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT:
2649     HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp, HAL_NULL, 0, HAL_NULL);
2650     break;
2651     
2652   case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT:
2653     HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp, HAL_NULL, 0, HAL_NULL);
2654     break;
2655     
2656   case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT:
2657     HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp, HAL_NULL, 0, HAL_NULL);
2658     break;
2659     
2660   case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT:
2661     HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp, HAL_NULL, 0, HAL_NULL);
2662     break;
2663     
2664   default:
2665     break;
2666   }
2667 }
2668
2669 /**
2670   * @}
2671   */
2672
2673 /**
2674   * @brief  DMA CRYP Input Data process complete callback. 
2675   * @param  hdma: DMA handle
2676   * @retval None
2677   */
2678 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma)  
2679 {
2680   CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2681   
2682   /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit
2683      in the DMACR register */
2684   CRYP->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
2685   
2686   /* Call input data transfer complete callback */
2687   HAL_CRYP_InCpltCallback(hcryp);
2688 }
2689
2690 /**
2691   * @brief  DMA CRYP Output Data process complete callback.
2692   * @param  hdma: DMA handle
2693   * @retval None
2694   */
2695 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma)
2696 {
2697   CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2698   
2699   /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit
2700      in the DMACR register */
2701   CRYP->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
2702   
2703   /* Enable the CRYP peripheral */
2704   __HAL_CRYP_DISABLE();
2705   
2706   /* Change the CRYP peripheral state */
2707   hcryp->State = HAL_CRYP_STATE_READY;
2708   
2709   /* Call output data transfer complete callback */
2710   HAL_CRYP_OutCpltCallback(hcryp);
2711 }
2712
2713 /**
2714   * @brief  DMA CRYP communication error callback. 
2715   * @param  hdma: DMA handle
2716   * @retval None
2717   */
2718 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma)
2719 {
2720   CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2721   hcryp->State= HAL_CRYP_STATE_READY;
2722   HAL_CRYP_ErrorCallback(hcryp);
2723 }
2724
2725 /**
2726   * @brief  Writes the Key in Key registers. 
2727   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2728   *         the configuration information for CRYP module
2729   * @param  Key: Pointer to Key buffer
2730   * @param  KeySize: Size of Key
2731   * @retval None
2732   */
2733 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize)
2734 {
2735   uint32_t keyaddr = (uint32_t)Key;
2736   
2737   switch(KeySize)
2738   {
2739   case CRYP_KEYSIZE_256B:
2740     /* Key Initialisation */
2741     CRYP->K0LR = __REV(*(uint32_t*)(keyaddr));
2742     keyaddr+=4;
2743     CRYP->K0RR = __REV(*(uint32_t*)(keyaddr));
2744     keyaddr+=4;
2745     CRYP->K1LR = __REV(*(uint32_t*)(keyaddr));
2746     keyaddr+=4;
2747     CRYP->K1RR = __REV(*(uint32_t*)(keyaddr));
2748     keyaddr+=4;
2749     CRYP->K2LR = __REV(*(uint32_t*)(keyaddr));
2750     keyaddr+=4;
2751     CRYP->K2RR = __REV(*(uint32_t*)(keyaddr));
2752     keyaddr+=4;
2753     CRYP->K3LR = __REV(*(uint32_t*)(keyaddr));
2754     keyaddr+=4;
2755     CRYP->K3RR = __REV(*(uint32_t*)(keyaddr));
2756     break;
2757   case CRYP_KEYSIZE_192B:
2758     CRYP->K1LR = __REV(*(uint32_t*)(keyaddr));
2759     keyaddr+=4;
2760     CRYP->K1RR = __REV(*(uint32_t*)(keyaddr));
2761     keyaddr+=4;
2762     CRYP->K2LR = __REV(*(uint32_t*)(keyaddr));
2763     keyaddr+=4;
2764     CRYP->K2RR = __REV(*(uint32_t*)(keyaddr));
2765     keyaddr+=4;
2766     CRYP->K3LR = __REV(*(uint32_t*)(keyaddr));
2767     keyaddr+=4;
2768     CRYP->K3RR = __REV(*(uint32_t*)(keyaddr));
2769     break;
2770   case CRYP_KEYSIZE_128B:       
2771     CRYP->K2LR = __REV(*(uint32_t*)(keyaddr));
2772     keyaddr+=4;
2773     CRYP->K2RR = __REV(*(uint32_t*)(keyaddr));
2774     keyaddr+=4;
2775     CRYP->K3LR = __REV(*(uint32_t*)(keyaddr));
2776     keyaddr+=4;
2777     CRYP->K3RR = __REV(*(uint32_t*)(keyaddr));
2778     break;
2779   default:
2780     break;
2781   }
2782 }
2783
2784 /**
2785   * @brief  Writes the InitVector/InitCounter in IV registers.
2786   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2787   *         the configuration information for CRYP module
2788   * @param  InitVector: Pointer to InitVector/InitCounter buffer
2789   * @param  IVSize: Size of the InitVector/InitCounter
2790   * @retval None
2791   */
2792 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector, uint32_t IVSize)
2793 {
2794   uint32_t ivaddr = (uint32_t)InitVector;
2795   
2796   switch(IVSize)
2797   {
2798   case CRYP_KEYSIZE_128B:
2799     CRYP->IV0LR = __REV(*(uint32_t*)(ivaddr));
2800     ivaddr+=4;
2801     CRYP->IV0RR = __REV(*(uint32_t*)(ivaddr));
2802     ivaddr+=4;
2803     CRYP->IV1LR = __REV(*(uint32_t*)(ivaddr));
2804     ivaddr+=4;
2805     CRYP->IV1RR = __REV(*(uint32_t*)(ivaddr));
2806     break;
2807     /* Whatever key size 192 or 256, Init vector is written in IV0LR and IV0RR */
2808   case CRYP_KEYSIZE_192B:
2809     CRYP->IV0LR = __REV(*(uint32_t*)(ivaddr));
2810     ivaddr+=4;
2811     CRYP->IV0RR = __REV(*(uint32_t*)(ivaddr));
2812     break;
2813   case CRYP_KEYSIZE_256B:
2814     CRYP->IV0LR = __REV(*(uint32_t*)(ivaddr));
2815     ivaddr+=4;
2816     CRYP->IV0RR = __REV(*(uint32_t*)(ivaddr));
2817     break;
2818   default:
2819     break;
2820   }
2821 }
2822
2823 /**
2824   * @brief  Process Data: Writes Input data in polling mode and read the Output data.
2825   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2826   *         the configuration information for CRYP module
2827   * @param  Input: Pointer to the Input buffer.
2828   * @param  Ilength: Length of the Input buffer, must be a multiple of 16
2829   * @param  Output: Pointer to the returned buffer
2830   * @param  Timeout: Timeout value 
2831   * @retval None
2832   */
2833 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout)
2834 {
2835   uint32_t tickstart = 0;   
2836   uint32_t i = 0;
2837   uint32_t inputaddr  = (uint32_t)Input;
2838   uint32_t outputaddr = (uint32_t)Output;
2839   
2840   for(i=0; (i < Ilength); i+=16)
2841   {
2842     /* Write the Input block in the IN FIFO */
2843     CRYP->DR = *(uint32_t*)(inputaddr);
2844     inputaddr+=4;
2845     CRYP->DR = *(uint32_t*)(inputaddr);
2846     inputaddr+=4;
2847     CRYP->DR  = *(uint32_t*)(inputaddr);
2848     inputaddr+=4;
2849     CRYP->DR = *(uint32_t*)(inputaddr);
2850     inputaddr+=4;
2851     
2852     /* Get tick */
2853     tickstart = HAL_GetTick();
2854  
2855     while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_OFNE))
2856     {
2857       /* Check for the Timeout */
2858       if(Timeout != HAL_MAX_DELAY)
2859       {
2860         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2861         {
2862           /* Change state */
2863           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2864           
2865           /* Process Unlocked */
2866           __HAL_UNLOCK(hcryp);
2867           
2868           return HAL_TIMEOUT;
2869         }
2870       }
2871     }
2872     /* Read the Output block from the OUT FIFO */
2873     *(uint32_t*)(outputaddr) = CRYP->DOUT;
2874     outputaddr+=4;
2875     *(uint32_t*)(outputaddr) = CRYP->DOUT;
2876     outputaddr+=4;
2877     *(uint32_t*)(outputaddr) = CRYP->DOUT;
2878     outputaddr+=4;
2879     *(uint32_t*)(outputaddr) = CRYP->DOUT;
2880     outputaddr+=4;
2881   }
2882   /* Return function status */
2883   return HAL_OK;
2884 }
2885
2886 /**
2887   * @brief  Sets the header phase
2888   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2889   *         the configuration information for CRYP module
2890   * @param  Input: Pointer to the Input buffer.
2891   * @param  Ilength: Length of the Input buffer, must be a multiple of 16
2892   * @param  Timeout: Timeout value   
2893   * @retval None
2894   */
2895 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout)
2896 {
2897   uint32_t tickstart = 0;   
2898   uint32_t loopcounter = 0;
2899   uint32_t headeraddr = (uint32_t)Input;
2900   
2901   /***************************** Header phase *********************************/
2902   if(hcryp->Init.HeaderSize != 0)
2903   {
2904     /* Select header phase */
2905     __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
2906     /* Enable the CRYP peripheral */
2907     __HAL_CRYP_ENABLE();
2908     
2909     for(loopcounter = 0; (loopcounter < hcryp->Init.HeaderSize); loopcounter+=16)
2910     {
2911       /* Get tick */
2912       tickstart = HAL_GetTick();
2913       
2914       while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
2915       {
2916         /* Check for the Timeout */
2917         if(Timeout != HAL_MAX_DELAY)
2918         {
2919           if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
2920           {
2921             /* Change state */
2922             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2923             
2924             /* Process Unlocked */
2925             __HAL_UNLOCK(hcryp);
2926             
2927             return HAL_TIMEOUT;
2928           }
2929         }
2930       }
2931       /* Write the Input block in the IN FIFO */
2932       CRYP->DR = *(uint32_t*)(headeraddr);
2933       headeraddr+=4;
2934       CRYP->DR = *(uint32_t*)(headeraddr);
2935       headeraddr+=4;
2936       CRYP->DR = *(uint32_t*)(headeraddr);
2937       headeraddr+=4;
2938       CRYP->DR = *(uint32_t*)(headeraddr);
2939       headeraddr+=4;
2940     }
2941     
2942     /* Wait until the complete message has been processed */
2943
2944     /* Get tick */
2945     tickstart = HAL_GetTick();
2946
2947     while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2948     {
2949       /* Check for the Timeout */
2950       if(Timeout != HAL_MAX_DELAY)
2951       {
2952         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
2953         {
2954           /* Change state */
2955           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2956           
2957           /* Process Unlocked */
2958           __HAL_UNLOCK(hcryp);
2959           
2960           return HAL_TIMEOUT;
2961         }
2962       }
2963     }
2964   }
2965   /* Return function status */
2966   return HAL_OK;
2967 }
2968
2969 /**
2970   * @brief  Sets the DMA configuration and start the DMA transfert.
2971   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2972   *         the configuration information for CRYP module
2973   * @param  inputaddr: Address of the Input buffer
2974   * @param  Size: Size of the Input buffer, must be a multiple of 16
2975   * @param  outputaddr: Address of the Output buffer
2976   * @retval None
2977   */
2978 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2979 {
2980   /* Set the CRYP DMA transfer complete callback */
2981   hcryp->hdmain->XferCpltCallback = CRYPEx_GCMCCM_DMAInCplt;
2982   /* Set the DMA error callback */
2983   hcryp->hdmain->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
2984   
2985   /* Set the CRYP DMA transfer complete callback */
2986   hcryp->hdmaout->XferCpltCallback = CRYPEx_GCMCCM_DMAOutCplt;
2987   /* Set the DMA error callback */
2988   hcryp->hdmaout->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
2989   
2990   /* Enable the CRYP peripheral */
2991   __HAL_CRYP_ENABLE();
2992   
2993   /* Enable the DMA In DMA Stream */
2994   HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&CRYP->DR, Size/4);
2995   
2996   /* Enable In DMA request */
2997   CRYP->DMACR = CRYP_DMACR_DIEN;
2998   
2999   /* Enable the DMA Out DMA Stream */
3000   HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&CRYP->DOUT, outputaddr, Size/4);
3001   
3002   /* Enable Out DMA request */
3003   CRYP->DMACR |= CRYP_DMACR_DOEN;
3004 }
3005
3006 /**
3007   * @}
3008   */
3009 #endif /* STM32F437xx || STM32F439xx */
3010
3011 #endif /* HAL_CRYP_MODULE_ENABLED */
3012 /**
3013   * @}
3014   */
3015
3016 /**
3017   * @}
3018   */
3019
3020 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/