1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_cryp_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended CRYP HAL module driver
6   *          This file provides firmware functions to manage the following
7   *          functionalities of CRYP extension peripheral:
8   *           + Extended AES processing functions
9   *
10   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2016 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   @verbatim
22   ==============================================================================
23                      ##### How to use this driver #####
24   ==============================================================================
25     [..]
26     The CRYP extension HAL driver can be used as follows:
27     (#)After AES-GCM or AES-CCM  Encryption/Decryption user can start following API
28        to get the  authentication messages :
29       (##) HAL_CRYPEx_AESGCM_GenerateAuthTAG
30       (##) HAL_CRYPEx_AESCCM_GenerateAuthTAG
31 
32   @endverbatim
33   ******************************************************************************
34   */
35 
36 /* Includes ------------------------------------------------------------------*/
37 #include "stm32f4xx_hal.h"
38 
39 /** @addtogroup STM32F4xx_HAL_Driver
40   * @{
41   */
42 #if defined (AES)  || defined (CRYP)
43 #if defined (CRYP_CR_ALGOMODE_AES_GCM)|| defined (AES)
44 /** @defgroup CRYPEx CRYPEx
45   * @brief CRYP Extension HAL module driver.
46   * @{
47   */
48 
49 
50 #ifdef HAL_CRYP_MODULE_ENABLED
51 
52 /* Private typedef -----------------------------------------------------------*/
53 /* Private define ------------------------------------------------------------*/
54 /** @addtogroup CRYPEx_Private_Defines
55   * @{
56   */
57 #if defined(AES)
58 #define CRYP_PHASE_INIT                              0x00000000U             /*!< GCM/GMAC (or CCM) init phase */
59 #define CRYP_PHASE_HEADER                            AES_CR_GCMPH_0          /*!< GCM/GMAC or CCM header phase */
60 #define CRYP_PHASE_PAYLOAD                           AES_CR_GCMPH_1          /*!< GCM(/CCM) payload phase   */
61 #define CRYP_PHASE_FINAL                             AES_CR_GCMPH            /*!< GCM/GMAC or CCM  final phase  */
62 
63 #define CRYP_OPERATINGMODE_ENCRYPT                   0x00000000U             /*!< Encryption mode   */
64 #define CRYP_OPERATINGMODE_KEYDERIVATION             AES_CR_MODE_0           /*!< Key derivation mode  only used when performing ECB and CBC decryptions  */
65 #define CRYP_OPERATINGMODE_DECRYPT                   AES_CR_MODE_1           /*!< Decryption       */
66 #define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT     AES_CR_MODE             /*!< Key derivation and decryption only used when performing ECB and CBC decryptions  */
67 
68 #else /* CRYP */
69 
70 #define CRYP_PHASE_INIT                 0x00000000U
71 #define CRYP_PHASE_HEADER               CRYP_CR_GCM_CCMPH_0
72 #define CRYP_PHASE_PAYLOAD              CRYP_CR_GCM_CCMPH_1
73 #define CRYP_PHASE_FINAL                CRYP_CR_GCM_CCMPH
74 
75 #define CRYP_OPERATINGMODE_ENCRYPT      0x00000000U
76 #define CRYP_OPERATINGMODE_DECRYPT      CRYP_CR_ALGODIR
77 #endif /* End AES or CRYP */
78 
79 #define  CRYPEx_PHASE_PROCESS       0x02U     /*!< CRYP peripheral is in processing phase */
80 #define  CRYPEx_PHASE_FINAL         0x03U     /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
81 
82 /*  CTR0 information to use in CCM algorithm */
83 #define CRYP_CCM_CTR0_0            0x07FFFFFFU
84 #define CRYP_CCM_CTR0_3            0xFFFFFF00U
85 
86 
87 /**
88   * @}
89   */
90 
91 /* Private macro -------------------------------------------------------------*/
92 /* Private variables ---------------------------------------------------------*/
93 /* Private function prototypes -----------------------------------------------*/
94 
95 
96 
97 /* Exported functions---------------------------------------------------------*/
98 /** @addtogroup CRYPEx_Exported_Functions
99   * @{
100   */
101 
102 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
103   *  @brief   Extended processing functions.
104   *
105 @verbatim
106   ==============================================================================
107               ##### Extended AES processing functions #####
108   ==============================================================================
109     [..]  This section provides functions allowing to generate the authentication
110           TAG in Polling mode
111       (#)HAL_CRYPEx_AESGCM_GenerateAuthTAG
112       (#)HAL_CRYPEx_AESCCM_GenerateAuthTAG
113          they should be used after Encrypt/Decrypt operation.
114 
115 @endverbatim
116   * @{
117   */
118 
119 
120 /**
121   * @brief  generate the GCM authentication TAG.
122   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
123   *         the configuration information for CRYP module
124   * @param  AuthTag: Pointer to the authentication buffer
125   * @param  Timeout: Timeout duration
126   * @retval HAL status
127   */
HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,uint32_t * AuthTag,uint32_t Timeout)128 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
129 {
130   uint32_t tickstart;
131   /* Assume first Init.HeaderSize is in words */
132   uint64_t headerlength = (uint64_t)(hcryp->Init.HeaderSize) * 32U; /* Header length in bits */
133   uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
134   uint32_t tagaddr = (uint32_t)AuthTag;
135 
136   /* Correct headerlength if Init.HeaderSize is actually in bytes */
137   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
138   {
139     headerlength /= 4U;
140   }
141 
142   if (hcryp->State == HAL_CRYP_STATE_READY)
143   {
144     /* Process locked */
145     __HAL_LOCK(hcryp);
146 
147     /* Change the CRYP peripheral state */
148     hcryp->State = HAL_CRYP_STATE_BUSY;
149 
150     /* Check if initialization phase has already been performed */
151     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
152     {
153       /* Change the CRYP phase */
154       hcryp->Phase = CRYPEx_PHASE_FINAL;
155     }
156     else /* Initialization phase has not been performed*/
157     {
158       /* Disable the Peripheral */
159       __HAL_CRYP_DISABLE(hcryp);
160 
161       /* Sequence error code field */
162       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
163 
164       /* Change the CRYP peripheral state */
165       hcryp->State = HAL_CRYP_STATE_READY;
166 
167       /* Process unlocked */
168       __HAL_UNLOCK(hcryp);
169       return HAL_ERROR;
170     }
171 
172 #if defined(CRYP)
173 
174     /* Disable CRYP to start the final phase */
175     __HAL_CRYP_DISABLE(hcryp);
176 
177     /* Select final phase */
178     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
179 
180     /*ALGODIR bit must be set to '0'.*/
181     hcryp->Instance->CR &=  ~CRYP_CR_ALGODIR;
182 
183     /* Enable the CRYP peripheral */
184     __HAL_CRYP_ENABLE(hcryp);
185 
186     /* Write the number of bits in header (64 bits) followed by the number of bits
187     in the payload */
188     if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
189     {
190       hcryp->Instance->DIN = 0U;
191       hcryp->Instance->DIN = __RBIT((uint32_t)(headerlength));
192       hcryp->Instance->DIN = 0U;
193       hcryp->Instance->DIN = __RBIT((uint32_t)(inputlength));
194     }
195     else if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
196     {
197       hcryp->Instance->DIN = 0U;
198       hcryp->Instance->DIN = __REV((uint32_t)(headerlength));
199       hcryp->Instance->DIN = 0U;
200       hcryp->Instance->DIN = __REV((uint32_t)(inputlength));
201     }
202     else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
203     {
204       hcryp->Instance->DIN = 0U;
205       hcryp->Instance->DIN = __ROR((uint32_t)headerlength, 16U);
206       hcryp->Instance->DIN = 0U;
207       hcryp->Instance->DIN = __ROR((uint32_t)inputlength, 16U);
208     }
209     else if (hcryp->Init.DataType == CRYP_DATATYPE_32B)
210     {
211       hcryp->Instance->DIN = 0U;
212       hcryp->Instance->DIN = (uint32_t)(headerlength);
213       hcryp->Instance->DIN = 0U;
214       hcryp->Instance->DIN = (uint32_t)(inputlength);
215     }
216     else
217     {
218       /* Nothing to do */
219     }
220 
221     /* Wait for OFNE flag to be raised */
222     tickstart = HAL_GetTick();
223     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
224     {
225       /* Check for the Timeout */
226       if (Timeout != HAL_MAX_DELAY)
227       {
228         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
229         {
230           /* Disable the CRYP Peripheral Clock */
231           __HAL_CRYP_DISABLE(hcryp);
232 
233           /* Change state */
234           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
235           hcryp->State = HAL_CRYP_STATE_READY;
236 
237           /* Process unlocked */
238           __HAL_UNLOCK(hcryp);
239           return HAL_ERROR;
240         }
241       }
242     }
243 
244     /* Read the authentication TAG in the output FIFO */
245     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
246     tagaddr += 4U;
247     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
248     tagaddr += 4U;
249     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
250     tagaddr += 4U;
251     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
252 
253 #else /* AES*/
254 
255     /* Select final phase */
256     MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
257 
258     /* Write the number of bits in header (64 bits) followed by the number of bits
259     in the payload */
260     if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
261     {
262       hcryp->Instance->DINR = 0U;
263       hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength));
264       hcryp->Instance->DINR = 0U;
265       hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength));
266     }
267     else if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
268     {
269       hcryp->Instance->DINR = 0U;
270       hcryp->Instance->DINR = __REV((uint32_t)(headerlength));
271       hcryp->Instance->DINR = 0U;
272       hcryp->Instance->DINR = __REV((uint32_t)(inputlength));
273     }
274     else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
275     {
276       hcryp->Instance->DINR = 0U;
277       hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16U);
278       hcryp->Instance->DINR = 0U;
279       hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16U);
280     }
281     else if (hcryp->Init.DataType == CRYP_DATATYPE_32B)
282     {
283       hcryp->Instance->DINR = 0U;
284       hcryp->Instance->DINR = (uint32_t)(headerlength);
285       hcryp->Instance->DINR = 0U;
286       hcryp->Instance->DINR = (uint32_t)(inputlength);
287     }
288     else
289     {
290       /* Nothing to do */
291     }
292     /* Wait for CCF flag to be raised */
293     tickstart = HAL_GetTick();
294     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
295     {
296       /* Check for the Timeout */
297       if (Timeout != HAL_MAX_DELAY)
298       {
299         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
300         {
301           /* Disable the CRYP peripheral clock */
302           __HAL_CRYP_DISABLE(hcryp);
303 
304           /* Change state */
305           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
306           hcryp->State = HAL_CRYP_STATE_READY;
307 
308           /* Process unlocked */
309           __HAL_UNLOCK(hcryp);
310           return HAL_ERROR;
311         }
312       }
313     }
314 
315     /* Read the authentication TAG in the output FIFO */
316     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
317     tagaddr += 4U;
318     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
319     tagaddr += 4U;
320     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
321     tagaddr += 4U;
322     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
323 
324     /* Clear CCF flag */
325     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
326 
327 #endif /* End AES or CRYP */
328 
329     /* Disable the peripheral */
330     __HAL_CRYP_DISABLE(hcryp);
331 
332     /* Change the CRYP peripheral state */
333     hcryp->State = HAL_CRYP_STATE_READY;
334 
335     /* Process unlocked */
336     __HAL_UNLOCK(hcryp);
337   }
338   else
339   {
340     /* Busy error code field */
341     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
342     return HAL_ERROR;
343   }
344   /* Return function status */
345   return HAL_OK;
346 }
347 
348 /**
349   * @brief  AES CCM Authentication TAG generation.
350   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
351   *         the configuration information for CRYP module
352   * @param  AuthTag: Pointer to the authentication buffer
353   * @param  Timeout: Timeout duration
354   * @retval HAL status
355   */
HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,uint32_t * AuthTag,uint32_t Timeout)356 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
357 {
358   uint32_t tagaddr = (uint32_t)AuthTag;
359   uint32_t ctr0 [4] = {0};
360   uint32_t ctr0addr = (uint32_t)ctr0;
361   uint32_t tickstart;
362 
363   if (hcryp->State == HAL_CRYP_STATE_READY)
364   {
365     /* Process locked */
366     __HAL_LOCK(hcryp);
367 
368     /* Change the CRYP peripheral state */
369     hcryp->State = HAL_CRYP_STATE_BUSY;
370 
371     /* Check if initialization phase has already been performed */
372     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
373     {
374       /* Change the CRYP phase */
375       hcryp->Phase = CRYPEx_PHASE_FINAL;
376     }
377     else /* Initialization phase has not been performed*/
378     {
379       /* Disable the peripheral */
380       __HAL_CRYP_DISABLE(hcryp);
381 
382       /* Sequence error code field */
383       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
384 
385       /* Change the CRYP peripheral state */
386       hcryp->State = HAL_CRYP_STATE_READY;
387 
388       /* Process unlocked */
389       __HAL_UNLOCK(hcryp);
390       return HAL_ERROR;
391     }
392 
393 #if defined(CRYP)
394 
395     /* Disable CRYP to start the final phase */
396     __HAL_CRYP_DISABLE(hcryp);
397 
398     /* Select final phase & ALGODIR bit must be set to '0'. */
399     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH | CRYP_CR_ALGODIR, CRYP_PHASE_FINAL | CRYP_OPERATINGMODE_ENCRYPT);
400 
401     /* Enable the CRYP peripheral */
402     __HAL_CRYP_ENABLE(hcryp);
403 
404     /* Write the counter block in the IN FIFO, CTR0 information from B0
405     data has to be swapped according to the DATATYPE*/
406     ctr0[0] = (hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
407     ctr0[1] = hcryp->Init.B0[1];
408     ctr0[2] = hcryp->Init.B0[2];
409     ctr0[3] = hcryp->Init.B0[3] &  CRYP_CCM_CTR0_3;
410 
411     if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
412     {
413       hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
414       ctr0addr += 4U;
415       hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
416       ctr0addr += 4U;
417       hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
418       ctr0addr += 4U;
419       hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
420     }
421     else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
422     {
423       hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
424       ctr0addr += 4U;
425       hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
426       ctr0addr += 4U;
427       hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
428       ctr0addr += 4U;
429       hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
430     }
431     else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
432     {
433       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
434       ctr0addr += 4U;
435       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
436       ctr0addr += 4U;
437       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
438       ctr0addr += 4U;
439       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
440     }
441     else
442     {
443       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
444       ctr0addr += 4U;
445       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
446       ctr0addr += 4U;
447       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
448       ctr0addr += 4U;
449       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
450     }
451     /* Wait for OFNE flag to be raised */
452     tickstart = HAL_GetTick();
453     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
454     {
455       /* Check for the Timeout */
456       if (Timeout != HAL_MAX_DELAY)
457       {
458         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
459         {
460           /* Disable the CRYP peripheral Clock */
461           __HAL_CRYP_DISABLE(hcryp);
462 
463           /* Change state */
464           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
465           hcryp->State = HAL_CRYP_STATE_READY;
466 
467           /* Process unlocked */
468           __HAL_UNLOCK(hcryp);
469           return HAL_ERROR;
470         }
471       }
472     }
473 
474     /* Read the Auth TAG in the IN FIFO */
475     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
476     tagaddr += 4U;
477     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
478     tagaddr += 4U;
479     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
480     tagaddr += 4U;
481     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
482 
483 #else /* AES */
484 
485     /* Select final phase */
486     MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
487 
488     /* Write the counter block in the IN FIFO, CTR0 information from B0
489     data has to be swapped according to the DATATYPE*/
490     if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
491     {
492       ctr0[0] = (__REV(hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0);
493       ctr0[1] = __REV(hcryp->Init.B0[1]);
494       ctr0[2] = __REV(hcryp->Init.B0[2]);
495       ctr0[3] = (__REV(hcryp->Init.B0[3])& CRYP_CCM_CTR0_3);
496 
497       hcryp->Instance->DINR = __REV(*(uint32_t *)(ctr0addr));
498       ctr0addr += 4U;
499       hcryp->Instance->DINR = __REV(*(uint32_t *)(ctr0addr));
500       ctr0addr += 4U;
501       hcryp->Instance->DINR = __REV(*(uint32_t *)(ctr0addr));
502       ctr0addr += 4U;
503       hcryp->Instance->DINR = __REV(*(uint32_t *)(ctr0addr));
504     }
505     else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
506     {
507       ctr0[0] = (__ROR((hcryp->Init.B0[0]), 16U)& CRYP_CCM_CTR0_0);
508       ctr0[1] =   __ROR((hcryp->Init.B0[1]), 16U);
509       ctr0[2] =   __ROR((hcryp->Init.B0[2]), 16U);
510       ctr0[3] = (__ROR((hcryp->Init.B0[3]), 16U)& CRYP_CCM_CTR0_3);
511 
512       hcryp->Instance->DINR = __ROR(*(uint32_t *)(ctr0addr), 16U);
513       ctr0addr += 4U;
514       hcryp->Instance->DINR = __ROR(*(uint32_t *)(ctr0addr), 16U);
515       ctr0addr += 4U;
516       hcryp->Instance->DINR = __ROR(*(uint32_t *)(ctr0addr), 16U);
517       ctr0addr += 4U;
518       hcryp->Instance->DINR = __ROR(*(uint32_t *)(ctr0addr), 16U);
519     }
520     else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
521     {
522       ctr0[0] = (__RBIT(hcryp->Init.B0[0])& CRYP_CCM_CTR0_0);
523       ctr0[1] = __RBIT(hcryp->Init.B0[1]);
524       ctr0[2] = __RBIT(hcryp->Init.B0[2]);
525       ctr0[3] = (__RBIT(hcryp->Init.B0[3])& CRYP_CCM_CTR0_3);
526 
527       hcryp->Instance->DINR = __RBIT(*(uint32_t *)(ctr0addr));
528       ctr0addr += 4U;
529       hcryp->Instance->DINR = __RBIT(*(uint32_t *)(ctr0addr));
530       ctr0addr += 4U;
531       hcryp->Instance->DINR = __RBIT(*(uint32_t *)(ctr0addr));
532       ctr0addr += 4U;
533       hcryp->Instance->DINR = __RBIT(*(uint32_t *)(ctr0addr));
534     }
535     else
536     {
537       ctr0[0] = (hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
538       ctr0[1] = hcryp->Init.B0[1];
539       ctr0[2] = hcryp->Init.B0[2];
540       ctr0[3] = hcryp->Init.B0[3] &  CRYP_CCM_CTR0_3;
541 
542       hcryp->Instance->DINR = *(uint32_t *)(ctr0addr);
543       ctr0addr += 4U;
544       hcryp->Instance->DINR = *(uint32_t *)(ctr0addr);
545       ctr0addr += 4U;
546       hcryp->Instance->DINR = *(uint32_t *)(ctr0addr);
547       ctr0addr += 4U;
548       hcryp->Instance->DINR = *(uint32_t *)(ctr0addr);
549     }
550 
551     /* Wait for CCF flag to be raised */
552     tickstart = HAL_GetTick();
553     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
554     {
555       /* Check for the Timeout */
556       if (Timeout != HAL_MAX_DELAY)
557       {
558         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
559         {
560           /* Disable the CRYP peripheral Clock */
561           __HAL_CRYP_DISABLE(hcryp);
562 
563           /* Change state */
564           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
565           hcryp->State = HAL_CRYP_STATE_READY;
566 
567           /* Process unlocked */
568           __HAL_UNLOCK(hcryp);
569           return HAL_ERROR;
570         }
571       }
572     }
573 
574     /* Read the authentication TAG in the output FIFO */
575     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
576     tagaddr += 4U;
577     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
578     tagaddr += 4U;
579     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
580     tagaddr += 4U;
581     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
582 
583     /* Clear CCF Flag */
584     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
585 
586 #endif /* End of AES || CRYP */
587 
588     /* Change the CRYP peripheral state */
589     hcryp->State = HAL_CRYP_STATE_READY;
590 
591     /* Process unlocked */
592     __HAL_UNLOCK(hcryp);
593 
594     /* Disable CRYP  */
595     __HAL_CRYP_DISABLE(hcryp);
596   }
597   else
598   {
599     /* Busy error code field */
600     hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
601     return HAL_ERROR;
602   }
603   /* Return function status */
604   return HAL_OK;
605 }
606 
607 /**
608   * @}
609   */
610 
611 #if defined (AES)
612 /** @defgroup CRYPEx_Exported_Functions_Group2 Key Derivation functions
613   *  @brief   AutoKeyDerivation functions
614   *
615 @verbatim
616   ==============================================================================
617               ##### Key Derivation functions #####
618   ==============================================================================
619     [..]  This section provides functions allowing to Enable or Disable the
620           the AutoKeyDerivation parameter in CRYP_HandleTypeDef structure
621           These function are allowed only in TinyAES IP.
622 
623 @endverbatim
624   * @{
625   */
626 
627 /**
628   * @brief  AES enable key derivation functions
629   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure.
630   * @retval None
631   */
HAL_CRYPEx_EnableAutoKeyDerivation(CRYP_HandleTypeDef * hcryp)632 void  HAL_CRYPEx_EnableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
633 {
634   if (hcryp->State == HAL_CRYP_STATE_READY)
635   {
636     hcryp->AutoKeyDerivation = ENABLE;
637   }
638   else
639   {
640     /* Busy error code field */
641     hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
642   }
643 }
644 /**
645   * @brief  AES disable key derivation functions
646   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure.
647   * @retval None
648   */
HAL_CRYPEx_DisableAutoKeyDerivation(CRYP_HandleTypeDef * hcryp)649 void  HAL_CRYPEx_DisableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
650 {
651   if (hcryp->State == HAL_CRYP_STATE_READY)
652   {
653     hcryp->AutoKeyDerivation = DISABLE;
654   }
655   else
656   {
657     /* Busy error code field */
658     hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
659   }
660 }
661 
662 /**
663   * @}
664   */
665 #endif /* AES or GCM CCM defined*/
666 #endif /* AES */
667 #endif /* HAL_CRYP_MODULE_ENABLED */
668 
669 /**
670   * @}
671   */
672 #endif /* TinyAES or CRYP*/
673 /**
674   * @}
675   */
676 
677 /**
678   * @}
679   */
680 
681