stm32f7xx_hal_cryp_ex.c 21.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/**
  ******************************************************************************
  * @file    stm32f7xx_hal_cryp_ex.c
  * @author  MCD Application Team
  * @brief   Extended CRYP HAL module driver
  *          This file provides firmware functions to manage the following 
  *          functionalities of CRYP extension peripheral:
  *           + Extended AES processing functions     
  *  
  @verbatim
  ==============================================================================
                     ##### How to use this driver #####
  ==============================================================================
    [..]
15 16 17 18 19
    The CRYP extension HAL driver can be used as follows:
    (#)After AES-GCM or AES-CCM  Encryption/Decryption user can start following API 
       to get the  authentication messages :
      (##) HAL_CRYPEx_AESGCM_GenerateAuthTAG
      (##) HAL_CRYPEx_AESCCM_GenerateAuthTAG
20 21 22 23 24

  @endverbatim
  ******************************************************************************
  * @attention
  *
25 26
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics. 
  * All rights reserved.</center></h2>
27
  *
28 29 30 31
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the 
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
32 33 34 35 36 37 38 39 40 41
  *
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "stm32f7xx_hal.h"

/** @addtogroup STM32F7xx_HAL_Driver
  * @{
  */
42 43
#if defined (AES)  || defined (CRYP)

44 45 46 47 48 49 50 51 52 53
/** @defgroup CRYPEx CRYPEx
  * @brief CRYP Extension HAL module driver.
  * @{
  */


#ifdef HAL_CRYP_MODULE_ENABLED

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
54
/** @addtogroup CRYPEx_Private_Defines
55 56
  * @{
  */
57 58 59 60 61
#if defined(AES)
#define CRYP_PHASE_INIT                              0x00000000U             /*!< GCM/GMAC (or CCM) init phase */ 
#define CRYP_PHASE_HEADER                            AES_CR_GCMPH_0          /*!< GCM/GMAC or CCM header phase */ 
#define CRYP_PHASE_PAYLOAD                           AES_CR_GCMPH_1          /*!< GCM(/CCM) payload phase   */ 
#define CRYP_PHASE_FINAL                             AES_CR_GCMPH            /*!< GCM/GMAC or CCM  final phase  */ 
62

63 64 65 66
#define CRYP_OPERATINGMODE_ENCRYPT                   0x00000000U             /*!< Encryption mode   */
#define CRYP_OPERATINGMODE_KEYDERIVATION             AES_CR_MODE_0           /*!< Key derivation mode  only used when performing ECB and CBC decryptions  */
#define CRYP_OPERATINGMODE_DECRYPT                   AES_CR_MODE_1           /*!< Decryption       */
#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 71 72 73
#define CRYP_PHASE_INIT                 0x00000000U
#define CRYP_PHASE_HEADER               CRYP_CR_GCM_CCMPH_0
#define CRYP_PHASE_PAYLOAD              CRYP_CR_GCM_CCMPH_1
#define CRYP_PHASE_FINAL                CRYP_CR_GCM_CCMPH
74

75 76 77
#define CRYP_OPERATINGMODE_ENCRYPT      0x00000000U
#define CRYP_OPERATINGMODE_DECRYPT      CRYP_CR_ALGODIR
#endif /* End AES or CRYP */
78

79 80
#define  CRYPEx_PHASE_PROCESS       0x02U     /*!< CRYP peripheral is in processing phase */
#define  CRYPEx_PHASE_FINAL         0x03U     /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */   
81

82 83 84
 /*  CTR0 information to use in CCM algorithm */
#define CRYP_CCM_CTR0_0            0x07FFFFFFU         
#define CRYP_CCM_CTR0_3            0xFFFFFF00U         
85 86 87


/**
88
  * @}
89 90
  */

91 92 93
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108



/* Exported functions---------------------------------------------------------*/
/** @addtogroup CRYPEx_Exported_Functions
  * @{
  */

/** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions 
 *  @brief   Extended processing functions. 
 *
@verbatim   
  ==============================================================================
              ##### Extended AES processing functions #####
  ==============================================================================  
109 110 111 112 113
    [..]  This section provides functions allowing to generate the authentication 
          TAG in Polling mode 
      (#)HAL_CRYPEx_AESGCM_GenerateAuthTAG
      (#)HAL_CRYPEx_AESCCM_GenerateAuthTAG
         they should be used after Encrypt/Decrypt operation.
114 115 116 117 118 119 120

@endverbatim
  * @{
  */


/**
121 122
  * @brief  generate the GCM authentication TAG.
  * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
123
  *         the configuration information for CRYP module
124 125
  * @param  AuthTag: Pointer to the authentication buffer
  * @param  Timeout: Timeout duration
126 127
  * @retval HAL status
  */
128
HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
129
{
130 131 132 133
  uint32_t tickstart;    
  uint64_t headerlength = (uint64_t)(hcryp->Init.HeaderSize) * 32U; /* Header length in bits */
  uint64_t inputlength = (uint64_t)(hcryp->Size) * 8U; /* input length in bits */
  uint32_t tagaddr = (uint32_t)AuthTag;  
134
  
135 136 137 138
  if(hcryp->State == HAL_CRYP_STATE_READY)
  {  
    /* Process locked */
    __HAL_LOCK(hcryp);
139
    
140 141
    /* Change the CRYP peripheral state */
    hcryp->State = HAL_CRYP_STATE_BUSY;
142
    
143 144
    /* Check if initialization phase has already been performed */
    if(hcryp->Phase == CRYPEx_PHASE_PROCESS)
145
    {
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
      /* Change the CRYP phase */
      hcryp->Phase = CRYPEx_PHASE_FINAL;
    }
    else /* Initialization phase has not been performed*/
    { 
      /* Disable the Peripheral */
      __HAL_CRYP_DISABLE(hcryp);
      
      /* Sequence error code field */ 
      hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE; 
      
      /* Change the CRYP peripheral state */
      hcryp->State = HAL_CRYP_STATE_READY;    
      
      /* Process unlocked */
      __HAL_UNLOCK(hcryp);
      return HAL_ERROR;
163 164
    }
    
165
#if defined(CRYP)
166
    
167 168
    /* Disable CRYP to start the final phase */
    __HAL_CRYP_DISABLE(hcryp);
169
    
170 171
    /* Select final phase */  
    MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);  
172
    
173 174
    /*ALGODIR bit must be set to 0.*/ 
    hcryp->Instance->CR &=  ~CRYP_CR_ALGODIR;
175 176 177 178
    
    /* Enable the CRYP peripheral */
    __HAL_CRYP_ENABLE(hcryp);
    
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
    /* Write the number of bits in header (64 bits) followed by the number of bits
    in the payload */
    if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
    {
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __RBIT((uint32_t)(headerlength));
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __RBIT((uint32_t)(inputlength));
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
    {
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __REV((uint32_t)(headerlength));
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __REV((uint32_t)(inputlength));    
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
    {
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __ROR((uint32_t)headerlength, 16U);
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __ROR((uint32_t)inputlength, 16U);
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
    {
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = (uint32_t)(headerlength);
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = (uint32_t)(inputlength);
    }
    else
    {
      /* Nothing to do */
    }
    
    /* Wait for OFNE flag to be raised */
215
    tickstart = HAL_GetTick();
216
    while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
217 218 219 220
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
221 222 223 224 225
        if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U))
        {       
          /* Disable the CRYP Peripheral Clock */
          __HAL_CRYP_DISABLE(hcryp);
          
226
          /* Change state */
227 228
          hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
          hcryp->State = HAL_CRYP_STATE_READY;  
229
          
230 231 232
          /* Process unlocked */          
          __HAL_UNLOCK(hcryp); 
          return HAL_ERROR;
233 234
        }
      }
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
    }          
    
    /* Read the authentication TAG in the output FIFO */
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;      
    
#else /* AES*/
    
    /* Select final phase */
    MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);    
    
    /* Write the number of bits in header (64 bits) followed by the number of bits
    in the payload */ 
    if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
    {
      hcryp->Instance->DINR = 0U;
      hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength));
      hcryp->Instance->DINR = 0U;
      hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength));
259
    }
260
    else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
261
    {
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
      hcryp->Instance->DINR = 0U;
      hcryp->Instance->DINR = __REV((uint32_t)(headerlength));
      hcryp->Instance->DINR = 0U;
      hcryp->Instance->DINR = __REV((uint32_t)(inputlength));    
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
    {
      hcryp->Instance->DINR = 0U;
      hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16U);
      hcryp->Instance->DINR = 0U;
      hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16U);
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
    {
      hcryp->Instance->DINR = 0U;
      hcryp->Instance->DINR = (uint32_t)(headerlength);
      hcryp->Instance->DINR = 0U;
      hcryp->Instance->DINR = (uint32_t)(inputlength);
280
    }
281
    else
282
    {
283
      /* Nothing to do */
284
    }
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
    /* Wait for CCF flag to be raised */
    tickstart = HAL_GetTick();
    while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U))
        {       
          /* Disable the CRYP peripheral clock */
          __HAL_CRYP_DISABLE(hcryp);
          
          /* Change state */
          hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
          hcryp->State = HAL_CRYP_STATE_READY;  
          
          /* Process unlocked */          
          __HAL_UNLOCK(hcryp); 
          return HAL_ERROR;
        }
      }
    }         
307
    
308 309 310 311 312 313 314 315
    /* Read the authentication TAG in the output FIFO */
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 
316
    
317 318
    /* Clear CCF flag */
    __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);       
319
    
320 321 322 323 324 325 326
#endif /* End AES or CRYP */ 
    
    /* Disable the peripheral */
    __HAL_CRYP_DISABLE(hcryp);
    
    /* Change the CRYP peripheral state */
    hcryp->State = HAL_CRYP_STATE_READY;    
327
    
328 329
    /* Process unlocked */
    __HAL_UNLOCK(hcryp);
330
  }
331
  else
332
  {
333 334 335 336
    /* Busy error code field */
    hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 
    return HAL_ERROR;
  }   
337 338 339 340 341
  /* Return function status */
  return HAL_OK;
}

/**
342 343
  * @brief  AES CCM Authentication TAG generation.
  * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
344
  *         the configuration information for CRYP module
345 346
  * @param  AuthTag: Pointer to the authentication buffer
  * @param  Timeout: Timeout duration
347 348
  * @retval HAL status
  */
349
HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
350
{
351 352 353 354 355 356
  uint32_t tagaddr = (uint32_t)AuthTag;
  uint32_t ctr0 [4]={0};
  uint32_t ctr0addr = (uint32_t)ctr0;
  uint32_t tickstart;

  if(hcryp->State == HAL_CRYP_STATE_READY)
357
  {
358
    /* Process locked */
359 360
    __HAL_LOCK(hcryp);

361 362
    /* Change the CRYP peripheral state */
    hcryp->State = HAL_CRYP_STATE_BUSY;
363

364 365
    /* Check if initialization phase has already been performed */
    if(hcryp->Phase == CRYPEx_PHASE_PROCESS)
366
    {
367 368
      /* Change the CRYP phase */
      hcryp->Phase = CRYPEx_PHASE_FINAL;
369
    }
370
    else /* Initialization phase has not been performed*/
371
    {
372 373
      /* Disable the peripheral */
      __HAL_CRYP_DISABLE(hcryp);
374

375 376
      /* Sequence error code field */
      hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
377

378 379
      /* Change the CRYP peripheral state */
      hcryp->State = HAL_CRYP_STATE_READY;
380

381 382 383
      /* Process unlocked */
      __HAL_UNLOCK(hcryp);
      return HAL_ERROR;
384 385
    }

386
#if defined(CRYP) 
387

388 389
    /* Disable CRYP to start the final phase */
    __HAL_CRYP_DISABLE(hcryp);
390

391 392
    /* Select final phase & ALGODIR bit must be set to 0. */
    MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH|CRYP_CR_ALGODIR, CRYP_PHASE_FINAL|CRYP_OPERATINGMODE_ENCRYPT);
393

394 395
    /* Enable the CRYP peripheral */
    __HAL_CRYP_ENABLE(hcryp);
396

397 398 399 400 401 402
    /* Write the counter block in the IN FIFO, CTR0 information from B0
    data has to be swapped according to the DATATYPE*/
    ctr0[0]=(hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
    ctr0[1]=hcryp->Init.B0[1];
    ctr0[2]=hcryp->Init.B0[2];
    ctr0[3]=hcryp->Init.B0[3] &  CRYP_CCM_CTR0_3;
403

404
    if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
405
    {
406 407 408 409 410 411 412
      hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
413
    }
414
    else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
415
    {
416 417 418 419 420 421 422
      hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
      ctr0addr+=4U;
      hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
      ctr0addr+=4U;
      hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
      ctr0addr+=4U;
      hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
423
    }
424
    else if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
425
    {
426 427 428 429 430 431 432
      hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
433
    }
434
    else
435
    {
436 437 438 439 440 441 442 443 444 445 446 447 448 449
      hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
      ctr0addr+=4U;
      hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
      ctr0addr+=4U;
      hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
      ctr0addr+=4U;
      hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
    }
    /* Wait for OFNE flag to be raised */
    tickstart = HAL_GetTick();
    while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
450
      {
451
        if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U))
452
        {
453 454 455 456 457
          /* Disable the CRYP peripheral Clock */
          __HAL_CRYP_DISABLE(hcryp);

          /* Change state */
          hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
458
          hcryp->State = HAL_CRYP_STATE_READY;
459 460

          /* Process unlocked */
461
          __HAL_UNLOCK(hcryp);
462
          return HAL_ERROR;
463 464 465 466
        }
      }
    }

467 468 469 470 471 472 473 474
    /* Read the Auth TAG in the IN FIFO */
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
475

476
#else /* AES */
477

478 479
    /* Select final phase */
    MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
480

481 482 483 484 485 486 487 488
    /* Write the counter block in the IN FIFO, CTR0 information from B0
    data has to be swapped according to the DATATYPE*/
    if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
    {
      ctr0[0]=(__REV(hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0);
      ctr0[1]=__REV(hcryp->Init.B0[1]);
      ctr0[2]=__REV(hcryp->Init.B0[2]);
      ctr0[3]=(__REV(hcryp->Init.B0[3])& CRYP_CCM_CTR0_3);
489

490 491 492 493 494 495 496
      hcryp->Instance->DINR = __REV(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DINR = __REV(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DINR = __REV(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DINR = __REV(*(uint32_t*)(ctr0addr));
497
    }
498
    else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
499
    {
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
      ctr0[0]= ( __ROR((hcryp->Init.B0[0]), 16U)& CRYP_CCM_CTR0_0);
      ctr0[1]=   __ROR((hcryp->Init.B0[1]), 16U);
      ctr0[2]=   __ROR((hcryp->Init.B0[2]), 16U);
      ctr0[3]= ( __ROR((hcryp->Init.B0[3]), 16U)& CRYP_CCM_CTR0_3);

      hcryp->Instance->DINR = __ROR(*(uint32_t*)(ctr0addr), 16U);
      ctr0addr+=4U;
      hcryp->Instance->DINR = __ROR(*(uint32_t*)(ctr0addr), 16U);
      ctr0addr+=4U;
      hcryp->Instance->DINR = __ROR(*(uint32_t*)(ctr0addr), 16U);
      ctr0addr+=4U;
      hcryp->Instance->DINR = __ROR(*(uint32_t*)(ctr0addr), 16U);
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
    {
      ctr0[0]=(__RBIT(hcryp->Init.B0[0])& CRYP_CCM_CTR0_0);
      ctr0[1]=__RBIT(hcryp->Init.B0[1]);
      ctr0[2]=__RBIT(hcryp->Init.B0[2]);
      ctr0[3]=(__RBIT(hcryp->Init.B0[3])& CRYP_CCM_CTR0_3);

      hcryp->Instance->DINR = __RBIT(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DINR = __RBIT(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DINR = __RBIT(*(uint32_t*)(ctr0addr));
      ctr0addr+=4U;
      hcryp->Instance->DINR = __RBIT(*(uint32_t*)(ctr0addr));
527
    }
528 529 530 531 532 533
    else
    {
      ctr0[0]=(hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
      ctr0[1]=hcryp->Init.B0[1];
      ctr0[2]=hcryp->Init.B0[2];
      ctr0[3]=hcryp->Init.B0[3] &  CRYP_CCM_CTR0_3;
534

535 536 537 538 539 540 541 542
      hcryp->Instance->DINR = *(uint32_t*)(ctr0addr);
      ctr0addr+=4U;
      hcryp->Instance->DINR = *(uint32_t*)(ctr0addr);
      ctr0addr+=4U;
      hcryp->Instance->DINR = *(uint32_t*)(ctr0addr);
      ctr0addr+=4U;
      hcryp->Instance->DINR = *(uint32_t*)(ctr0addr);
    }
543

544 545 546 547 548 549 550 551 552 553 554
    /* Wait for CCF flag to be raised */
    tickstart = HAL_GetTick();
    while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U))
        {
          /* Disable the CRYP peripheral Clock */
          __HAL_CRYP_DISABLE(hcryp);
555

556 557 558
          /* Change state */
          hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
          hcryp->State = HAL_CRYP_STATE_READY;
559

560 561 562 563 564 565
          /* Process unlocked */
          __HAL_UNLOCK(hcryp);
          return HAL_ERROR;
        }
      }
    }
566

567 568 569 570 571 572 573 574
    /* Read the authentication TAG in the output FIFO */
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
575

576 577
    /* Clear CCF Flag */
    __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
578

579
#endif /* End of AES || CRYP */
580

581 582
    /* Change the CRYP peripheral state */
    hcryp->State = HAL_CRYP_STATE_READY;
583

584 585
    /* Process unlocked */
    __HAL_UNLOCK(hcryp);
586

587 588
    /* Disable CRYP  */
    __HAL_CRYP_DISABLE(hcryp);
589
  }
590 591 592 593 594
  else
  {
    /* Busy error code field */
    hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
    return HAL_ERROR;
595
  }
596 597
  /* Return function status */
  return HAL_OK;   
598 599 600
}

/**
601
  * @}
602 603
  */

604 605 606 607 608 609 610 611 612 613 614
#if defined (AES)
/** @defgroup CRYPEx_Exported_Functions_Group2 Key Derivation functions
 *  @brief   AutoKeyDerivation functions 
 *
@verbatim
  ==============================================================================
              ##### Key Derivation functions #####
  ==============================================================================  
    [..]  This section provides functions allowing to Enable or Disable the
          the AutoKeyDerivation parameter in CRYP_HandleTypeDef structure
          These function are allowed only in TinyAES IP.
615

616 617 618
@endverbatim
  * @{
  */
619 620

/**
621 622
  * @brief  AES enable key derivation functions
  * @param  hcryp: pointer to a CRYP_HandleTypeDef structure.
623 624
  * @retval None
  */
625
void  HAL_CRYPEx_EnableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
626
{
627 628 629 630 631 632 633 634 635
  if(hcryp->State == HAL_CRYP_STATE_READY)
  {  
    hcryp->AutoKeyDerivation = ENABLE;
  }
  else
  {
    /* Busy error code field */
    hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY; 
  } 
636 637
}
/**
638 639
  * @brief  AES disable key derivation functions
  * @param  hcryp: pointer to a CRYP_HandleTypeDef structure.
640 641
  * @retval None
  */
642
void  HAL_CRYPEx_DisableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
643
{
644
  if(hcryp->State == HAL_CRYP_STATE_READY)
645
  {
646
    hcryp->AutoKeyDerivation = DISABLE;
647
  }
648
  else
649
  {
650 651 652
    /* Busy error code field */
    hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY; 
  }  
653 654 655 656 657 658
}

/**
  * @}
  */

659 660 661
#endif /* AES */ 
#endif /* HAL_CRYP_MODULE_ENABLED */

662 663 664
/**
  * @}
  */
665
#endif /* TinyAES or CRYP*/
666 667 668 669 670 671 672 673 674
/**
  * @}
  */

/**
  * @}
  */

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