/**
  ******************************************************************************
  * @file    stm32l4xx_hal_cryp_ex.c
  * @author  MCD Application Team
  * @brief   CRYPEx HAL module driver.
  *          This file provides firmware functions to manage the extended
  *          functionalities of the Cryptography (CRYP) peripheral.
  *
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file in
  * the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  ******************************************************************************
  */

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

#ifdef HAL_CRYP_MODULE_ENABLED

#if defined(AES)

/** @addtogroup STM32L4xx_HAL_Driver
  * @{
  */

/** @defgroup CRYPEx CRYPEx
  * @brief CRYP Extended HAL module driver
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants
  * @{
  */
#define CRYP_CCF_TIMEOUTVALUE                      22000  /*!< CCF flag raising time-out value */
#define CRYP_BUSY_TIMEOUTVALUE                     22000  /*!< BUSY flag reset time-out value  */

#define CRYP_POLLING_OFF                             0x0  /*!< No polling when padding */
#define CRYP_POLLING_ON                              0x1  /*!< Polling when padding    */

#if defined(AES_CR_NPBLB)
#define AES_POSITION_CR_NPBLB     (uint32_t)POSITION_VAL(AES_CR_NPBLB)    /*!< Required left shift to set background CLUT size */
#endif
/**
  * @}
  */

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions
 * @{
 */
static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout);
static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout);
static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma);
static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma);
static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma);
static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling);
/**
  * @}
  */

/* Exported functions ---------------------------------------------------------*/

/** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions
  * @{
  */


/** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function
 *  @brief    Extended callback functions.
 *
@verbatim
 ===============================================================================
                 ##### Extended callback functions #####
 ===============================================================================
    [..]  This section provides callback function:
      (+) Computation completed.

@endverbatim
  * @{
  */


/**
  * @brief  Computation completed callbacks.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @retval None
  */
__weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hcryp);

  /* NOTE : This function should not be modified; when the callback is needed,
            the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file
   */
}

/**
  * @}
  */

/** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions
 *  @brief   Extended processing functions.
 *
@verbatim
  ==============================================================================
                      ##### AES extended processing functions #####
  ==============================================================================
    [..]  This section provides functions allowing to:
      (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes.
          Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated
          based on the processing type. Three processing types are available:
          (++) Polling mode
          (++) Interrupt mode
          (++) DMA mode
      (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES
          algorithm in different chaining modes.
          Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase
          so that steps can be skipped if so required. Functions are only differentiated based on the processing type.
          Three processing types are available:
          (++) Polling mode
          (++) Interrupt mode
          (++) DMA mode

@endverbatim
  * @{
  */

/**
  * @brief  Carry out in polling mode the ciphering or deciphering operation according to
  *         hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
  *         chaining modes ECB, CBC and CTR are managed by this function in polling mode.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @param  pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
  *                     or key derivation+decryption.
  *                     Parameter is meaningless in case of key derivation.
  * @param  Size Length of the input data buffer in bytes, must be a multiple of 16.
  *               Parameter is meaningless in case of key derivation.
  * @param  pOutputData Pointer to the cipher text in case of encryption or plain text in case of
  *                     decryption/key derivation+decryption, or pointer to the derivative keys in
  *                     case of key derivation only.
  * @param  Timeout Specify Timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout)
{

  if (hcryp->State == HAL_CRYP_STATE_READY)
  {
    /* Check parameters setting */
    if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
    {
      if (pOutputData == NULL)
      {
        return  HAL_ERROR;
      }
    }
    else
    {
      if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
      {
        return  HAL_ERROR;
      }
    }

    /* Process Locked */
    __HAL_LOCK(hcryp);

    /* Change the CRYP state */
    hcryp->State = HAL_CRYP_STATE_BUSY;

    /* Call CRYP_ReadKey() API if the operating mode is set to
       key derivation, CRYP_ProcessData() otherwise  */
    if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
    {
      if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
    }
    else
    {
      if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
    }

    /* If the state has not been set to SUSPENDED, set it to
       READY, otherwise keep it as it is */
    if (hcryp->State != HAL_CRYP_STATE_SUSPENDED)
    {
      hcryp->State = HAL_CRYP_STATE_READY;
    }

    /* Process Unlocked */
    __HAL_UNLOCK(hcryp);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}



/**
  * @brief  Carry out in interrupt mode the ciphering or deciphering operation according to
  *         hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
  *         chaining modes ECB, CBC and CTR are managed by this function in interrupt mode.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @param  pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
  *                     or key derivation+decryption.
  *                     Parameter is meaningless in case of key derivation.
  * @param  Size Length of the input data buffer in bytes, must be a multiple of 16.
  *               Parameter is meaningless in case of key derivation.
  * @param  pOutputData Pointer to the cipher text in case of encryption or plain text in case of
  *                     decryption/key derivation+decryption, or pointer to the derivative keys in
  *                     case of key derivation only.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp,  uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
{
  uint32_t inputaddr;

  if(hcryp->State == HAL_CRYP_STATE_READY)
  {
    /* Check parameters setting */
    if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
    {
      if (pOutputData == NULL)
      {
        return  HAL_ERROR;
      }
    }
    else
    {
      if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
      {
        return  HAL_ERROR;
      }
    }
    /* Process Locked */
    __HAL_LOCK(hcryp);

    /* If operating mode is not limited to key derivation only,
       get the buffers addresses and sizes */
    if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
    {

      hcryp->CrypInCount = Size;
      hcryp->pCrypInBuffPtr = pInputData;
      hcryp->pCrypOutBuffPtr = pOutputData;
      hcryp->CrypOutCount = Size;
    }
    else
    {
      /* For key derivation, set output buffer only
        (will point at derivated key) */
      hcryp->pCrypOutBuffPtr = pOutputData;
    }

    /* Change the CRYP state */
    hcryp->State = HAL_CRYP_STATE_BUSY;

      /* Process Unlocked */
    __HAL_UNLOCK(hcryp);

    /* Enable Computation Complete Flag and Error Interrupts */
    __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);


    /* If operating mode is key derivation only, the input data have
       already been entered during the initialization process. For
       the other operating modes, they are fed to the CRYP hardware
       block at this point. */
    if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
    {
      /* Initiate the processing under interrupt in entering
         the first input data */
      inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
      /* Increment/decrement instance pointer/counter */
      hcryp->pCrypInBuffPtr += 16;
      hcryp->CrypInCount -= 16U;
      /* Write the first input block in the Data Input register */
      hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
      inputaddr+=4U;
      hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
      inputaddr+=4U;
      hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
      inputaddr+=4U;
      hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
    }

    /* Return function status */
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}





/**
  * @brief  Carry out in DMA mode the ciphering or deciphering operation according to
  *         hcryp->Init structure fields.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @param  pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
  *                     or key derivation+decryption.
  * @param  Size Length of the input data buffer in bytes, must be a multiple of 16.
  * @param  pOutputData Pointer to the cipher text in case of encryption or plain text in case of
  *                     decryption/key derivation+decryption.
  * @note   Chaining modes ECB, CBC and CTR are managed by this function in DMA mode.
  * @note   Supported operating modes are encryption, decryption and key derivation with decryption.
  * @note   No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx
  *         registers must be done by software.
  * @note   This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx
  *         registers must be done by software through HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs.
  * @note   pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp,  uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
{
  uint32_t inputaddr;
  uint32_t outputaddr;

  if (hcryp->State == HAL_CRYP_STATE_READY)
  {
    /* Check parameters setting */
    if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
    {
      /* no DMA channel is provided for key derivation operating mode,
         access to AES_KEYRx registers must be done by software */
      return  HAL_ERROR;
    }
    else
    {
      if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
      {
        return  HAL_ERROR;
      }
    }


    /* Process Locked */
    __HAL_LOCK(hcryp);

    inputaddr  = (uint32_t)pInputData;
    outputaddr = (uint32_t)pOutputData;

    /* Change the CRYP state */
    hcryp->State = HAL_CRYP_STATE_BUSY;

    /* Set the input and output addresses and start DMA transfer */
    CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);

    /* Process Unlocked */
    __HAL_UNLOCK(hcryp);

    /* Return function status */
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}






/**
  * @brief  Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering
  *         operation according to hcryp->Init structure fields.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @param  pInputData
  *         - pointer to payload data in GCM or CCM payload phase,
  *         - pointer to B0 block in CMAC header phase,
  *         - pointer to C block in CMAC final phase.
  *         - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
  * @param  Size
  *         - length of the input payload data buffer in bytes in GCM or CCM payload phase,
  *         - length of B0 block (in bytes) in CMAC header phase,
  *         - length of C block (in bytes) in CMAC final phase.
  *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  *         - Parameter is meaningless in case of CCM final phase.
  *         - Parameter is message length in bytes in case of GCM final phase.
  *         - Parameter must be set to zero in case of GMAC final phase.
  * @param  pOutputData
  *         - pointer to plain or cipher text in GCM/CCM payload phase,
  *         - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
  *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  *         - Parameter is meaningless in case of CMAC header phase.
  * @param  Timeout Specify Timeout value
  * @note   Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable.
  * @note   Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
  *         can be skipped by the user if so required.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout)
{
  uint32_t index             ;
  uint32_t inputaddr         ;
  uint32_t outputaddr        ;
  uint32_t tagaddr           ;
  uint64_t headerlength      ;
  uint64_t inputlength       ;
  uint64_t payloadlength     ;
  uint32_t difflength     = 0;
  uint32_t addhoc_process = 0;

  if (hcryp->State == HAL_CRYP_STATE_READY)
  {
    /* input/output parameters check */
    if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
    {
       /* No processing required */
    }
    else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
    {
      if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
          ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
      {
        return  HAL_ERROR;
      }
#if defined(AES_CR_NPBLB)
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
#else
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
#endif
      {
        /* In case of CMAC or CCM (when applicable) header phase resumption, we can have pInputData = NULL and  Size = 0 */
        if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
        {
          return  HAL_ERROR;
        }
      }
    }
    else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
    {
      if (((pInputData == NULL) && (Size != 0U)) || \
          ((pInputData != NULL) && (Size == 0U)) || \
          ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL)))
      {
        return  HAL_ERROR;
      }
    }
    else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
    {
      if (pOutputData == NULL)
      {
        return  HAL_ERROR;
      }
#if !defined(AES_CR_NPBLB)
      if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
      {
        return  HAL_ERROR;
      }
#endif
    }
    else
    {
      /* Unspecified Phase */
      return  HAL_ERROR;
    }


    /* Process Locked */
    __HAL_LOCK(hcryp);

    /* Change the CRYP state */
    hcryp->State = HAL_CRYP_STATE_BUSY;

    /*==============================================*/
    /* GCM/GMAC (or CCM when applicable) init phase */
    /*==============================================*/
    /* In case of init phase, the input data (Key and Initialization Vector) have
       already been entered during the initialization process. Therefore, the
       API just waits for the CCF flag to be set. */
    if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
    {
      /* just wait for hash computation */
      if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
      {
        hcryp->State = HAL_CRYP_STATE_READY;
        __HAL_UNLOCK(hcryp);
        return HAL_TIMEOUT;
      }

      /* Clear CCF Flag */
      __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
      /* Mark that the initialization phase is over */
      hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
    }
    /*=======================================================*/
    /* GCM/GMAC or (CCM / CMAC when applicable) header phase */
    /*=======================================================*/
    else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
    {
#if !defined(AES_CR_NPBLB)
      /* Set header phase; for GCM or GMAC, set data-byte at this point */
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
      {
        MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
      }
      else
#endif
      {
        MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
      }

      /* Enable the Peripheral */
      __HAL_CRYP_ENABLE(hcryp);

#if !defined(AES_CR_NPBLB)
      /* in case of CMAC, enter B0 block in header phase, before the header itself. */
      /* If Size = 0 (possible case of resumption after CMAC header phase suspension),
         skip these steps and go directly to header buffer feeding to the HW */
      if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U))
      {
        uint64_t index_test;
        inputaddr = (uint32_t)pInputData;

        for(index=0U ; (index < Size); index += 16U)
        {
          /* Write the Input block in the Data Input register */
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
          hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
          inputaddr+=4U;

          if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
          {
            hcryp->State = HAL_CRYP_STATE_READY;
            __HAL_UNLOCK(hcryp);
            return HAL_TIMEOUT;
          }
          /* Clear CCF Flag */
          __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);

          /* If the suspension flag has been raised and if the processing is not about
           to end, suspend processing */
          index_test = (uint64_t)index + 16U;
          if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_test < Size))
          {
            /* reset SuspendRequest */
            hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
            /* Change the CRYP state */
            hcryp->State = HAL_CRYP_STATE_SUSPENDED;
            /* Mark that the header phase is over */
            hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;

           /* Save current reading and writing locations of Input and Output buffers */
           hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
           /* Save the total number of bytes (B blocks + header) that remain to be
              processed at this point */
           hcryp->CrypInCount     =  (uint32_t) (hcryp->Init.HeaderSize + Size - index_test);

           /* Process Unlocked */
            __HAL_UNLOCK(hcryp);

            return HAL_OK;
          }
        } /* for(index=0; (index < Size); index += 16) */
      }
#endif /* !defined(AES_CR_NPBLB) */

      /* Enter header */
      inputaddr = (uint32_t)hcryp->Init.Header;
      /* Local variable headerlength is a number of bytes multiple of 128 bits,
         remaining header data (if any) are handled after this loop */
      headerlength =  (((hcryp->Init.HeaderSize)/16U)*16U) ;
      if ((hcryp->Init.HeaderSize % 16U) != 0U)
      {
        difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength);
      }
      for(index=0U ; index < headerlength; index += 16U)
      {
        uint64_t index_temp;
        /* Write the Input block in the Data Input register */
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;

        if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
        {
          hcryp->State = HAL_CRYP_STATE_READY;
          __HAL_UNLOCK(hcryp);
          return HAL_TIMEOUT;
        }
        /* Clear CCF Flag */
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);

        /* If the suspension flag has been raised and if the processing is not about
         to end, suspend processing */
        index_temp = (uint64_t)index + 16U;
        if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < headerlength))
        {
          /* reset SuspendRequest */
          hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
          /* Change the CRYP state */
          hcryp->State = HAL_CRYP_STATE_SUSPENDED;
          /* Mark that the header phase is over */
          hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;

         /* Save current reading and writing locations of Input and Output buffers */
         hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
         /* Save the total number of bytes that remain to be processed at this point */
          hcryp->CrypInCount =  (uint32_t) (hcryp->Init.HeaderSize - index_temp);

         /* Process Unlocked */
          __HAL_UNLOCK(hcryp);

          return HAL_OK;
        }
      }

      /* Case header length is not a multiple of 16 bytes */
      if (difflength != 0U)
      {
        hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
        CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
      }

      /* Mark that the header phase is over */
      hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
    }
    /*============================================*/
    /* GCM (or CCM when applicable) payload phase */
    /*============================================*/
    else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
    {

      MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);

      /* if the header phase has been bypassed, AES must be enabled again */
      if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
      {
        __HAL_CRYP_ENABLE(hcryp);
      }

      inputaddr  = (uint32_t)pInputData;
      outputaddr = (uint32_t)pOutputData;

      /* Enter payload */
      /* Specific handling to manage payload last block size less than 128 bits */
      if ((Size % 16U) != 0U)
      {
        payloadlength = (Size/16U) * 16U;
        difflength = (uint32_t) (Size - payloadlength);
        addhoc_process = 1;
      }
      else
      {
        payloadlength = Size;
      }

      /* Feed payload */
      for(index=0U ; index < payloadlength; index += 16U)
      {
        uint64_t index_temp;
        /* Write the Input block in the Data Input register */
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;

        if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
        {
          hcryp->State = HAL_CRYP_STATE_READY;
          __HAL_UNLOCK(hcryp);
          return HAL_TIMEOUT;
        }

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

        /* Retrieve output data: read the output block
           from the Data Output Register */
        *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
        outputaddr+=4U;
        *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
        outputaddr+=4U;
        *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
        outputaddr+=4U;
        *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
        outputaddr+=4U;

        /* If the suspension flag has been raised and if the processing is not about
         to end, suspend processing */
        index_temp = (uint64_t)index + 16U;
        if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < payloadlength))
        {
          /* no flag waiting under IRQ handling */
          if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
          {
            /* Ensure that Busy flag is reset */
            if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
            {
              hcryp->State = HAL_CRYP_STATE_READY;
              __HAL_UNLOCK(hcryp);
              return HAL_TIMEOUT;
            }
          }
          /* reset SuspendRequest */
          hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
          /* Change the CRYP state */
          hcryp->State = HAL_CRYP_STATE_SUSPENDED;
          /* Mark that the header phase is over */
          hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;

          /* Save current reading and writing locations of Input and Output buffers */
          hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
          hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
          /* Save the number of bytes that remain to be processed at this point */
          hcryp->CrypInCount     =  (uint32_t) (Size - index_temp);

          /* Process Unlocked */
          __HAL_UNLOCK(hcryp);

          return HAL_OK;
        }

      }

      /* Additional processing to manage GCM(/CCM) encryption and decryption cases when
         payload last block size less than 128 bits */
      if (addhoc_process == 1U)
      {

        hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
        hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
        CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);

      } /* (addhoc_process == 1) */

      /* Mark that the payload phase is over */
      hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
    }
    /*==================================*/
    /* GCM/GMAC/CCM or CMAC final phase */
    /*==================================*/
    else
    {
      tagaddr = (uint32_t)pOutputData;

#if defined(AES_CR_NPBLB)
     /* By default, clear NPBLB field */
      CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
#endif

      MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);

      /* if the header and payload phases have been bypassed, AES must be enabled again */
      if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
      {
        __HAL_CRYP_ENABLE(hcryp);
      }

      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
      {
        headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
        inputlength = Size * 8U;                    /* input length in bits */

#if !defined(AES_CR_NPBLB)
        if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
        {
          hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
          hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
          hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
          hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
        }
        else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
        {
          hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
          hcryp->Instance->DINR = __REV((uint32_t)headerlength);
          hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
          hcryp->Instance->DINR = __REV((uint32_t)inputlength);
        }
        else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
        {
          hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
          hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
          hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
          hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
        }
        else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
        {
          hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
          hcryp->Instance->DINR = (uint32_t)(headerlength);
          hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
          hcryp->Instance->DINR = (uint32_t)(inputlength);
        }
        else
        {
          /* Unspecified Data Type */
         return  HAL_ERROR;
        }
#else
        hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
        hcryp->Instance->DINR = (uint32_t)(headerlength);
        hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
        hcryp->Instance->DINR = (uint32_t)(inputlength);
#endif
      }
#if !defined(AES_CR_NPBLB)
      else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
      {
        inputaddr  = (uint32_t)pInputData;
        /* Enter the last block made of a 128-bit value formatted
           from the original B0 packet. */
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
      }
      else
      {
         /* Unspecified Chaining Mode */
         return  HAL_ERROR;
       }
#endif


      if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
      {
          hcryp->State = HAL_CRYP_STATE_READY;
          __HAL_UNLOCK(hcryp);
          return HAL_TIMEOUT;
      }

      /* Read the Auth TAG in the Data Out register */
      *(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;


      /* Clear CCF Flag */
      __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
      /* Mark that the final phase is over */
      hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
      /* Disable the Peripheral */
      __HAL_CRYP_DISABLE(hcryp);
    }

    /* Change the CRYP state */
    hcryp->State = HAL_CRYP_STATE_READY;

    /* Process Unlocked */
    __HAL_UNLOCK(hcryp);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}




/**
  * @brief  Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering
  *         operation according to hcryp->Init structure fields.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @param  pInputData
  *         - pointer to payload data in GCM or CCM payload phase,
  *         - pointer to B0 block in CMAC header phase,
  *         - pointer to C block in CMAC final phase.
  *         - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
  * @param  Size
  *         - length of the input payload data buffer in bytes in GCM or CCM payload phase,
  *         - length of B0 block (in bytes) in CMAC header phase,
  *         - length of C block (in bytes) in CMAC final phase.
  *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  *         - Parameter is meaningless in case of CCM final phase.
  *         - Parameter is message length in bytes in case of GCM final phase.
  *         - Parameter must be set to zero in case of GMAC final phase.
  * @param  pOutputData
  *         - pointer to plain or cipher text in GCM/CCM payload phase,
  *         - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
  *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  *         - Parameter is meaningless in case of CMAC header phase.
  * @note   Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
  * @note   Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
  *         can be skipped by the user if so required.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
{

  uint32_t inputaddr         ;
  uint64_t headerlength      ;
  uint64_t inputlength       ;
  uint32_t index             ;
  uint32_t addhoc_process = 0;
  uint32_t difflength     = 0;
  uint32_t difflengthmod4 = 0;
  uint32_t mask[4][3];

  uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;

  mask[0][0] = 0xFF000000U;  mask[0][1] = 0xFFFF0000U;  mask[0][2] = 0xFFFFFF00U;  /* 32-bit data */
  mask[1][0] = 0x0000FF00U;  mask[1][1] = 0x0000FFFFU;  mask[1][2] = 0xFF00FFFFU;  /* 16-bit data */
  mask[2][0] = 0x000000FFU;  mask[2][1] = 0x0000FFFFU;  mask[2][2] = 0x00FFFFFFU;  /* 8-bit data  */
  mask[3][0] = 0x000000FFU;  mask[3][1] = 0x0000FFFFU;  mask[3][2] = 0x00FFFFFFU;  /* Bit data    */

  if (hcryp->State == HAL_CRYP_STATE_READY)
  {
    /* input/output parameters check */
    if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
    {
       /* No processing required */
    }
    else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
    {
      if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
          ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
      {
        return  HAL_ERROR;
      }
#if defined(AES_CR_NPBLB)
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
#else
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
#endif
      {
        /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and  Size = 0 */
        if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
        {
          return  HAL_ERROR;
        }
      }
    }
    else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
    {
      if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
      {
        return  HAL_ERROR;
      }
    }
    else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
    {
      if (pOutputData == NULL)
      {
        return  HAL_ERROR;
      }
#if !defined(AES_CR_NPBLB)
      if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
      {
        return  HAL_ERROR;
      }
#endif
    }
    else
    {
      /* Unspecified Phase */
      return  HAL_ERROR;
     }


    /* Process Locked */
    __HAL_LOCK(hcryp);

    /* Change the CRYP state */
    hcryp->State = HAL_CRYP_STATE_BUSY;

    /* Process Unlocked */
    __HAL_UNLOCK(hcryp);

    /* Enable Computation Complete Flag and Error Interrupts */
    __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);



    /*==============================================*/
    /* GCM/GMAC (or CCM when applicable) init phase */
    /*==============================================*/
    if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
    {
    /* In case of init phase, the input data (Key and Initialization Vector) have
       already been entered during the initialization process. Therefore, the
       software just waits for the CCF interrupt to be raised and which will
       be handled by CRYP_AES_Auth_IT() API. */
    }
    /*===================================*/
    /* GCM/GMAC/CCM or CMAC header phase */
    /*===================================*/
    else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
    {

#if defined(AES_CR_NPBLB)
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
#else
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
#endif
      {
        /* In case of CMAC, B blocks are first entered, before the header.
           Therefore, B blocks and the header are entered back-to-back
           as if it was only one single block.
           However, in case of resumption after suspension, if all the
           B blocks have been entered (in that case, Size = 0), only the
           remainder of the non-processed header bytes are entered. */
          if (Size != 0U)
          {
            hcryp->CrypInCount = (uint32_t)(Size + hcryp->Init.HeaderSize);
            hcryp->pCrypInBuffPtr = pInputData;
          }
          else
          {
            hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
            hcryp->pCrypInBuffPtr = hcryp->Init.Header;
          }
      }
      else
      {
        /* Get the header addresses and sizes */
        hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
        hcryp->pCrypInBuffPtr = hcryp->Init.Header;
      }

      inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;


#if !defined(AES_CR_NPBLB)
      /* Set header phase; for GCM or GMAC, set data-byte at this point */
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
      {
        MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
      }
      else
#endif
      {
        MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
      }

      /* Enable the Peripheral */
      __HAL_CRYP_ENABLE(hcryp);

      /* Increment/decrement instance pointer/counter */
      if (hcryp->CrypInCount == 0U)
      {
        /* Case of no header */
        hcryp->State = HAL_CRYP_STATE_READY;
        /* Mark that the header phase is over */
        hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
        return HAL_OK;
      }
      else if (hcryp->CrypInCount < 16U)
      {
        hcryp->CrypInCount = 0;
        addhoc_process = 1;
        difflength = (uint32_t) (hcryp->Init.HeaderSize);
        difflengthmod4 = difflength%4U;
      }
      else
      {
        hcryp->pCrypInBuffPtr += 16;
        hcryp->CrypInCount -= 16U;
      }


#if defined(AES_CR_NPBLB)
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
#else
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
#endif
      {
        if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
        {
          /* All B blocks will have been entered after the next
             four DINR writing, so point at header buffer for
             the next iteration */
          hcryp->pCrypInBuffPtr = hcryp->Init.Header;
        }
      }

      /* Enter header first block to initiate the process
         in the Data Input register */
      if (addhoc_process == 0U)
      {
        /* Header has size equal or larger than 128 bits */
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
      }
      else
      {
        /* Header has size less than 128 bits */
        /* Enter complete words when possible */
        for(index=0U ; index < (difflength/4U); index ++)
        {
          /* Write the Input block in the Data Input register */
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
        }
        /* Enter incomplete word padded with zeroes if applicable
          (case of header length not a multiple of 32-bits) */
        if (difflengthmod4 != 0U)
        {
          hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
        }
        /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
        for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
        {
          hcryp->Instance->DINR = 0;
        }

      }
    }
    /*============================================*/
    /* GCM (or CCM when applicable) payload phase */
    /*============================================*/
    else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
    {
      /* Get the buffer addresses and sizes */
      hcryp->CrypInCount = (uint32_t)Size;
      hcryp->pCrypInBuffPtr = pInputData;
      hcryp->pCrypOutBuffPtr = pOutputData;
      hcryp->CrypOutCount = (uint32_t)Size;

      inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;

      MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);

      /* if the header phase has been bypassed, AES must be enabled again */
      if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
      {
        __HAL_CRYP_ENABLE(hcryp);
      }

      /* No payload case */
      if (pInputData == NULL)
      {
        hcryp->State = HAL_CRYP_STATE_READY;
        /* Mark that the header phase is over */
        hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
        /* Process Unlocked */
        __HAL_UNLOCK(hcryp);

        return HAL_OK;
      }

     /* Specific handling to manage payload size less than 128 bits */
      if (Size < 16U)
      {
        difflength = (uint32_t) (Size);
#if defined(AES_CR_NPBLB)
        /* In case of GCM encryption or CCM decryption, specify the number of padding
           bytes in last block of payload */
        if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
        {
          uint32_t cr_temp = hcryp->Instance->CR;

          if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
           ||  ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
          {
            /* Set NPBLB field in writing the number of padding bytes
               for the last block of payload */
            MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
          }
        }
#else
        /* Software workaround applied to GCM encryption only */
        if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
        {
          /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
          __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
        }
#endif


        /* Set hcryp->CrypInCount to 0 (no more data to enter) */
        hcryp->CrypInCount = 0;

        /*  Insert the last block (which size is inferior to 128 bits) padded with zeroes,
            to have a complete block of 128 bits */
        difflengthmod4 = difflength%4U;
        /*  Insert the last block (which size is inferior to 128 bits) padded with zeroes
            to have a complete block of 128 bits */
        for(index=0U; index < (difflength/4U); index ++)
        {
          /* Write the Input block in the Data Input register */
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
        }
        /* If required, manage input data size not multiple of 32 bits */
        if (difflengthmod4 != 0U)
        {
          hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
        }
        /* Wrap-up in padding with zero-words if applicable */
        for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
        {
          hcryp->Instance->DINR = 0;
        }
      }
      else
      {
        /* Increment/decrement instance pointer/counter */
        hcryp->pCrypInBuffPtr += 16;
        hcryp->CrypInCount -= 16U;

        /* Enter payload first block to initiate the process
           in the Data Input register */
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
      }
    }
    /*==================================*/
    /* GCM/GMAC/CCM or CMAC final phase */
    /*==================================*/
    else
    {
       hcryp->pCrypOutBuffPtr = pOutputData;

#if defined(AES_CR_NPBLB)
     /* By default, clear NPBLB field */
      CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
#endif

       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);

      /* if the header and payload phases have been bypassed, AES must be enabled again */
      if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
      {
        __HAL_CRYP_ENABLE(hcryp);
      }

      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
      {
        headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
        inputlength = Size * 8U;                    /* Input length in bits */
        /* Write the number of bits in the header on 64 bits followed by the number
           of bits in the payload on 64 bits as well */

#if !defined(AES_CR_NPBLB)
        if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
        {
          hcryp->Instance->DINR = __RBIT((uint32_t)((headerlength)>>32));
          hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
          hcryp->Instance->DINR = __RBIT((uint32_t)((inputlength)>>32));
          hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
        }
        else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
        {
          hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
          hcryp->Instance->DINR = __REV((uint32_t)headerlength);
          hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
          hcryp->Instance->DINR = __REV((uint32_t)inputlength);
        }
        else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
        {
          hcryp->Instance->DINR = __ROR((uint32_t)((headerlength)>>32), 16);
          hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
          hcryp->Instance->DINR = __ROR((uint32_t)((inputlength)>>32), 16);
          hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
        }
        else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
        {
          hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
          hcryp->Instance->DINR = (uint32_t)(headerlength);
          hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
          hcryp->Instance->DINR = (uint32_t)(inputlength);
        }
        else
        {
          /* Unspecified Data Type */
          return  HAL_ERROR;
        }
#else
        hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
        hcryp->Instance->DINR = (uint32_t)(headerlength);
        hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
        hcryp->Instance->DINR = (uint32_t)(inputlength);
#endif
      }
#if !defined(AES_CR_NPBLB)
      else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
      {
        inputaddr  = (uint32_t)pInputData;
        /* Enter the last block made of a 128-bit value formatted
           from the original B0 packet. */
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
      }
      else
      {
        /* Unspecified Chaining Mode */
        return  HAL_ERROR;
      }
#endif
    }

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}




/**
  * @brief  Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering
  *         operation according to hcryp->Init structure fields.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @param  pInputData
  *         - pointer to payload data in GCM or CCM payload phase,
  *         - pointer to B0 block in CMAC header phase,
  *         - pointer to C block in CMAC final phase.
  *         - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
  * @param  Size
  *         - length of the input payload data buffer in bytes in GCM or CCM payload phase,
  *         - length of B0 block (in bytes) in CMAC header phase,
  *         - length of C block (in bytes) in CMAC final phase.
  *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  *         - Parameter is meaningless in case of CCM final phase.
  *         - Parameter is message length in bytes in case of GCM final phase.
  *         - Parameter must be set to zero in case of GMAC final phase.
  * @param  pOutputData
  *         - pointer to plain or cipher text in GCM/CCM payload phase,
  *         - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
  *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  *         - Parameter is meaningless in case of CMAC header phase.
  * @note   Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
  * @note   Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
  *         can be skipped by the user if so required.
  * @note   pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
{
  uint32_t inputaddr      ;
  uint32_t outputaddr     ;
  uint32_t tagaddr        ;
  uint64_t headerlength   ;
  uint64_t inputlength    ;
  uint64_t payloadlength  ;


  if (hcryp->State == HAL_CRYP_STATE_READY)
  {
    /* input/output parameters check */
    if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
    {
       /* No processing required */
    }
    else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
    {
      if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
      {
        return  HAL_ERROR;
      }
#if defined(AES_CR_NPBLB)
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
      {
        /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and  Size = 0 */
        if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
        {
          return  HAL_ERROR;
        }
      }
#else
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
      {
        if ((pInputData == NULL) || (Size == 0U))
        {
          return  HAL_ERROR;
        }
      }
#endif
    }
    else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
    {
      if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
      {
        return  HAL_ERROR;
      }
    }
    else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
    {
      if (pOutputData == NULL)
      {
        return  HAL_ERROR;
      }
#if !defined(AES_CR_NPBLB)
      if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
      {
        return  HAL_ERROR;
      }
#endif
    }
    else
    {
      /* Unspecified Phase */
      return  HAL_ERROR;
    }


    /* Process Locked */
    __HAL_LOCK(hcryp);

    /* Change the CRYP state */
    hcryp->State = HAL_CRYP_STATE_BUSY;

    /*==============================================*/
    /* GCM/GMAC (or CCM when applicable) init phase */
    /*==============================================*/
    /* In case of init phase, the input data (Key and Initialization Vector) have
       already been entered during the initialization process. No DMA transfer is
       required at that point therefore, the software just waits for the CCF flag
       to be raised. */
    if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
    {
      /* just wait for hash computation */
      if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
      {
        hcryp->State = HAL_CRYP_STATE_READY;
        __HAL_UNLOCK(hcryp);
        return HAL_TIMEOUT;
      }

      /* Clear CCF Flag */
      __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
      /* Mark that the initialization phase is over */
      hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
      hcryp->State = HAL_CRYP_STATE_READY;
    }
    /*====================================*/
    /* GCM/GMAC/ CCM or CMAC header phase */
    /*====================================*/
    else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
    {
#if !defined(AES_CR_NPBLB)
      /* Set header phase; for GCM or GMAC, set data-byte at this point */
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
      {
        MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
      }
      else
#endif
      {
        MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
      }

      /* Enable the CRYP peripheral */
      __HAL_CRYP_ENABLE(hcryp);

#if !defined(AES_CR_NPBLB)
      /* enter first B0 block in polling mode (no DMA transfer for B0) */
      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
      {
        inputaddr  = (uint32_t)pInputData;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);

        if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
        {
          hcryp->State = HAL_CRYP_STATE_READY;
          __HAL_UNLOCK(hcryp);
          return HAL_TIMEOUT;
        }
        /* Clear CCF Flag */
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
      }
#endif

      /* No header case */
      if (hcryp->Init.Header == NULL)
      {
        hcryp->State = HAL_CRYP_STATE_READY;
        /* Mark that the header phase is over */
        hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
        /* Process Unlocked */
        __HAL_UNLOCK(hcryp);

        return HAL_OK;
      }

      inputaddr = (uint32_t)hcryp->Init.Header;
      if ((hcryp->Init.HeaderSize % 16U) != 0U)
      {

        if (hcryp->Init.HeaderSize < 16U)
        {
          hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
          CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF);

          hcryp->State = HAL_CRYP_STATE_READY;
          /* Mark that the header phase is over */
          hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;

          /* CCF flag indicating header phase AES processing completion
             will be checked at the start of the next phase:
            - payload phase (GCM / CCM when applicable)
            - final phase (GMAC or CMAC when applicable).  */
        }
        else
        {
          /* Local variable headerlength is a number of bytes multiple of 128 bits,
            remaining header data (if any) are handled after this loop */
          headerlength =  (((hcryp->Init.HeaderSize)/16U)*16U) ;
          /* Store the ending transfer point */
          hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength;
          hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */

          /* Set the input and output addresses and start DMA transfer */
          /* (incomplete DMA transfer, will be wrapped up after completion of
             the first one (initiated here) with data padding */
          CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)headerlength, 0);
        }
      }
      else
      {
        hcryp->CrypInCount = 0;
        /* Set the input address and start DMA transfer */
        CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)hcryp->Init.HeaderSize, 0);
      }
    }
    /*============================================*/
    /* GCM (or CCM when applicable) payload phase */
    /*============================================*/
    else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
    {
      /* Coming from header phase, wait for CCF flag to be raised
          if header present and fed to the IP in the previous phase */
      if (hcryp->Init.Header != NULL)
      {
        if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
        {
          hcryp->State = HAL_CRYP_STATE_READY;
          __HAL_UNLOCK(hcryp);
          return HAL_TIMEOUT;
        }
      }
      else
      {
        /* Enable the Peripheral since wasn't in header phase (no header case) */
        __HAL_CRYP_ENABLE(hcryp);
      }
      /* Clear CCF Flag */
      __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);

      MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);

      /* No payload case */
      if (pInputData == NULL)
      {
        hcryp->State = HAL_CRYP_STATE_READY;
        /* Mark that the header phase is over */
        hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
        /* Process Unlocked */
        __HAL_UNLOCK(hcryp);

        return HAL_OK;
      }


      /* Specific handling to manage payload size less than 128 bits */
      if ((Size % 16U) != 0U)
      {
        inputaddr  = (uint32_t)pInputData;
        outputaddr = (uint32_t)pOutputData;
        if (Size < 16U)
        {
          /* Block is now entered in polling mode, no actual gain in resorting to DMA */
          hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
          hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;

          CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON);

          /* Change the CRYP state to ready */
          hcryp->State = HAL_CRYP_STATE_READY;
          /* Mark that the payload phase is over */
          hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;

          /* Call output data transfer complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
          hcryp->OutCpltCallback(hcryp);
#else
          HAL_CRYP_OutCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
        }
        else
        {
          payloadlength = (Size/16U) * 16U;

          /* Store the ending transfer points */
          hcryp->pCrypInBuffPtr = pInputData;
          hcryp->pCrypInBuffPtr += payloadlength;
          hcryp->pCrypOutBuffPtr = pOutputData;
          hcryp->pCrypOutBuffPtr += payloadlength;
          hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */

          /* Set the input and output addresses and start DMA transfer */
          /* (incomplete DMA transfer, will be wrapped up with data padding
             after completion of the one initiated here) */
          CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)payloadlength, outputaddr);
        }
      }
      else
      {
        hcryp->CrypInCount = 0;
        inputaddr  = (uint32_t)pInputData;
        outputaddr = (uint32_t)pOutputData;

        /* Set the input and output addresses and start DMA transfer */
        CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)Size, outputaddr);
      }
    }
    /*==================================*/
    /* GCM/GMAC/CCM or CMAC final phase */
    /*==================================*/
    else
    {
      /* If coming from header phase (GMAC or CMAC case when applicable),
         wait for CCF flag to be raised */
      if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE)
      {
        if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
        {
          hcryp->State = HAL_CRYP_STATE_READY;
          __HAL_UNLOCK(hcryp);
          return HAL_TIMEOUT;
        }
        /* Clear CCF Flag */
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
      }

      tagaddr = (uint32_t)pOutputData;

#if defined(AES_CR_NPBLB)
     /* By default, clear NPBLB field */
      CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
#endif
      MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);

      /* if the header and payload phases have been bypassed, AES must be enabled again */
      if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
      {
        __HAL_CRYP_ENABLE(hcryp);
      }

      if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
      {
        headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
        inputlength = Size * 8U;  /* input length in bits */
        /* Write the number of bits in the header on 64 bits followed by the number
           of bits in the payload on 64 bits as well */
#if !defined(AES_CR_NPBLB)
        if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
        {
          hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
          hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
          hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
          hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
        }
        else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
        {
          hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
          hcryp->Instance->DINR = __REV((uint32_t)headerlength);
          hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
          hcryp->Instance->DINR = __REV((uint32_t)inputlength);
        }
        else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
        {
          hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
          hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
          hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
          hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
        }
        else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
        {
          hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
          hcryp->Instance->DINR = (uint32_t)(headerlength);
          hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
          hcryp->Instance->DINR = (uint32_t)(inputlength);
        }
        else
        {
          /* Unspecified Data Type */
          return  HAL_ERROR;
        }
#else
        hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
        hcryp->Instance->DINR = (uint32_t)(headerlength);
        hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
        hcryp->Instance->DINR = (uint32_t)(inputlength);
#endif
      }
#if !defined(AES_CR_NPBLB)
      else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
      {
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);

        inputaddr  = (uint32_t)pInputData;
        /* Enter the last block made of a 128-bit value formatted
           from the original B0 packet. */
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
        inputaddr+=4U;
        hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
      }
      else
      {
        /* Unspecified Chaining Mode */
        return  HAL_ERROR;
      }
#endif

      /* No DMA transfer is required at that point therefore, the software
         just waits for the CCF flag to be raised. */
      if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
      {
          hcryp->State = HAL_CRYP_STATE_READY;
          __HAL_UNLOCK(hcryp);
          return HAL_TIMEOUT;
      }

      /* Read the Auth TAG in the IN 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;

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

      /* Mark that the final phase is over */
      hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
      hcryp->State = HAL_CRYP_STATE_READY;
      /* Disable the Peripheral */
      __HAL_CRYP_DISABLE(hcryp);

    }

    /* Process Unlocked */
    __HAL_UNLOCK(hcryp);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

/**
  * @}
  */

/** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions
 *  @brief   Extended processing functions.
 *
@verbatim
  ==============================================================================
                    ##### AES extended suspension and resumption functions #####
  ==============================================================================
    [..]  This section provides functions allowing to:
      (+) save in memory the Initialization Vector, the Key registers, the Control register or
          the Suspend registers when a process is suspended by a higher priority message
      (+) write back in CRYP hardware block the saved values listed above when the suspended
          lower priority message processing is resumed.

@endverbatim
  * @{
  */


/**
  * @brief  In case of message processing suspension, read the Initialization Vector.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Output Pointer to the buffer containing the saved Initialization Vector.
  * @note   This value has to be stored for reuse by writing the AES_IVRx registers
  *         as soon as the interrupted processing has to be resumed.
  *         Applicable to all chaining modes.
  * @note   AES must be disabled when reading or resetting the IV values.
  * @retval None
  */
void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
{
  uint32_t outputaddr = (uint32_t)Output;

  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0);
}

/**
  * @brief  In case of message processing resumption, rewrite the Initialization
  *         Vector in the AES_IVRx registers.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Input Pointer to the buffer containing the saved Initialization Vector to
  *         write back in the CRYP hardware block.
  * @note   Applicable to all chaining modes.
  * @note   AES must be disabled when reading or resetting the IV values.
  * @retval None
  */
void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
{
  uint32_t ivaddr = (uint32_t)Input;

  hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr));
}


/**
  * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension,
  *         read the Suspend Registers.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Output Pointer to the buffer containing the saved Suspend Registers.
  * @note   These values have to be stored for reuse by writing back the AES_SUSPxR registers
  *         as soon as the interrupted processing has to be resumed.
  * @retval None
  */
void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
{
  uint32_t outputaddr = (uint32_t)Output;

  /* In case of GCM payload phase encryption, check that suspension can be carried out */
  if (READ_BIT(hcryp->Instance->CR, (AES_CR_CHMOD|AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT))
  {
    /* Ensure that Busy flag is reset */
    if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
    {
      hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR;
      hcryp->State = HAL_CRYP_STATE_ERROR;

      /* Process Unlocked */
      __HAL_UNLOCK(hcryp);

#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
      hcryp->ErrorCallback(hcryp);
#else
      HAL_CRYP_ErrorCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
      return ;
    }
  }

  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R);
  outputaddr+=4U;
  *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R);
}

/**
  * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Suspend
  *         Registers in the AES_SUSPxR registers.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Input Pointer to the buffer containing the saved suspend registers to
  *         write back in the CRYP hardware block.
  * @retval None
  */
void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
{
  uint32_t ivaddr = (uint32_t)Input;

  hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr));
  ivaddr+=4U;
  hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr));
}


/**
  * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Key Registers.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Output Pointer to the buffer containing the saved Key Registers.
  * @param  KeySize Indicates the key size (128 or 256 bits).
  * @note   These values have to be stored for reuse by writing back the AES_KEYRx registers
  *         as soon as the interrupted processing has to be resumed.
  * @retval None
  */
void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize)
{
  uint32_t keyaddr = (uint32_t)Output;

  if (KeySize == CRYP_KEYSIZE_256B)
  {
    *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7);
    keyaddr+=4U;
    *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6);
    keyaddr+=4U;
    *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5);
    keyaddr+=4U;
    *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4);
    keyaddr+=4U;
  }

  *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3);
  keyaddr+=4U;
  *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2);
  keyaddr+=4U;
  *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1);
  keyaddr+=4U;
  *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0);
}

/**
  * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key
  *         Registers in the AES_KEYRx registers.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Input Pointer to the buffer containing the saved key registers to
  *         write back in the CRYP hardware block.
  * @param  KeySize Indicates the key size (128 or 256 bits)
  * @retval None
  */
void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize)
{
  uint32_t keyaddr = (uint32_t)Input;

  if (KeySize == CRYP_KEYSIZE_256B)
  {
    hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr));
    keyaddr+=4U;
    hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr));
    keyaddr+=4U;
    hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr));
    keyaddr+=4U;
    hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr));
    keyaddr+=4U;
  }

    hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr));
    keyaddr+=4U;
    hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr));
    keyaddr+=4U;
    hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr));
    keyaddr+=4U;
    hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr));
}


/**
  * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Control Register.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Output Pointer to the buffer containing the saved Control Register.
  * @note   This values has to be stored for reuse by writing back the AES_CR register
  *         as soon as the interrupted processing has to be resumed.
  * @retval None
  */
void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
{
  *(uint32_t*)(void *)(Output) = hcryp->Instance->CR;                           /* Derogation MisraC2012 R.11.5 */
}

/**
  * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Control
  *         Registers in the AES_CR register.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Input Pointer to the buffer containing the saved Control Register to
  *         write back in the CRYP hardware block.
  * @retval None
  */
void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
{
  hcryp->Instance->CR = *(uint32_t*)(void *)(Input);                            /* Derogation MisraC2012 R.11.5 */
  /* At the same time, set handle state back to READY to be able to resume the AES calculations
     without the processing APIs returning HAL_BUSY when called. */
  hcryp->State        = HAL_CRYP_STATE_READY;
}

/**
  * @brief  Request CRYP processing suspension when in polling or interruption mode.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @note   Set the handle field SuspendRequest to the appropriate value so that
  *         the on-going CRYP processing is suspended as soon as the required
  *         conditions are met.
  * @note   It is advised not to suspend the CRYP processing when the DMA controller
  *         is managing the data transfer
  * @retval None
  */
void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
{
  /* Set Handle Suspend Request field */
  hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
}

/**
  * @}
  */

/**
  * @}
  */

/** @addtogroup CRYPEx_Private_Functions
  * @{
  */

/**
  * @brief  DMA CRYP Input Data process complete callback
  *         for GCM, GMAC, CCM or CMAC chaining modes.
  * @note   Specific setting of hcryp fields are required only
  *         in the case of header phase where no output data DMA
  *         transfer is on-going (only input data transfer is enabled
  *         in such a case).
  * @param  hdma DMA handle.
  * @retval None
  */
static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma)
{
  uint32_t difflength;
  CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */

  /* Disable the DMA transfer for input request  */
  CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);

  if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
  {

    if (hcryp->CrypInCount != 0U)
    {
      /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
      difflength = hcryp->CrypInCount;
      hcryp->CrypInCount = 0;

      CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF);
    }
    hcryp->State = HAL_CRYP_STATE_READY;
    /* Mark that the header phase is over */
    hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
  }
  /* CCF flag indicating header phase AES processing completion
     will be checked at the start of the next phase:
     - payload phase (GCM or CCM when applicable)
     - final phase (GMAC or CMAC).
    This allows to avoid the Wait on Flag within the IRQ handling.  */

  /* Call input data transfer complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  hcryp->InCpltCallback(hcryp);
#else
  HAL_CRYP_InCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
}

/**
  * @brief  DMA CRYP Output Data process complete callback
  *         for GCM, GMAC, CCM or CMAC chaining modes.
  * @note   This callback is called only in the payload phase.
  * @param  hdma DMA handle.
  * @retval None
  */
static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma)
{
  uint32_t difflength;
  CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */

  /* Disable the DMA transfer for output request */
  CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);

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

  /* Initiate additional transfer to wrap-up data feeding to the IP */
  if (hcryp->CrypInCount != 0U)
  {
    /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
    difflength = hcryp->CrypInCount;
    hcryp->CrypInCount = 0;

    CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
  }

  /* Change the CRYP state to ready */
  hcryp->State = HAL_CRYP_STATE_READY;
  /* Mark that the payload phase is over */
  hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;

  /* Call output data transfer complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  hcryp->OutCpltCallback(hcryp);
#else
  HAL_CRYP_OutCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
}

/**
  * @brief  DMA CRYP communication error callback
  *         for GCM, GMAC, CCM or CMAC chaining modes.
  * @param  hdma DMA handle
  * @retval None
  */
static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma)
{
  CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */

  hcryp->State= HAL_CRYP_STATE_ERROR;
  hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  hcryp->ErrorCallback(hcryp);
#else
  HAL_CRYP_ErrorCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  /* Clear Error Flag */
  __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
}



/**
  * @brief  Handle CRYP block input/output data handling under interruption
  *         for GCM, GMAC, CCM  or CMAC chaining modes.
  * @note   The function is called under interruption only, once
  *         interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT().
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @retval HAL status
  */
HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp)
{
  uint32_t inputaddr         ;
  uint32_t outputaddr        ;
  uint32_t index             ;
  uint32_t addhoc_process = 0;
  uint32_t difflength     = 0;
  uint32_t difflengthmod4 = 0;
  uint32_t mask[4][3]        ;
  uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
  uint32_t intermediate_data[4] = {0};

  mask[0][0] = 0xFF000000U;  mask[0][1] = 0xFFFF0000U;  mask[0][2] = 0xFFFFFF00U;  /* 32-bit data */
  mask[1][0] = 0x0000FF00U;  mask[1][1] = 0x0000FFFFU;  mask[1][2] = 0xFF00FFFFU;  /* 16-bit data */
  mask[2][0] = 0x000000FFU;  mask[2][1] = 0x0000FFFFU;  mask[2][2] = 0x00FFFFFFU;  /* 8-bit data  */
  mask[3][0] = 0x000000FFU;  mask[3][1] = 0x0000FFFFU;  mask[3][2] = 0x00FFFFFFU;  /* Bit data    */

  if(hcryp->State == HAL_CRYP_STATE_BUSY)
  {
    /*===========================*/
    /* GCM/GMAC(/CCM) init phase */
    /*===========================*/
    if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
    {
      /* Clear Computation Complete Flag */
      __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
      /* Disable Computation Complete Flag and Errors Interrupts */
      __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
      /* Change the CRYP state */
      hcryp->State = HAL_CRYP_STATE_READY;

      /* Mark that the initialization phase is over */
      hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;

      /* Process Unlocked */
      __HAL_UNLOCK(hcryp);
      /* Call computation complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
      hcryp->CompCpltCallback(hcryp);
#else
      HAL_CRYPEx_ComputationCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
      return HAL_OK;
    }
    /*========================================*/
    /* GCM/GMAC (or CCM or CMAC) header phase */
    /*========================================*/
    else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
    {
      /* Check if all input header data have been entered */
      if (hcryp->CrypInCount == 0U)
      {
        /* Clear Computation Complete Flag */
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
        /* Disable Computation Complete Flag and Errors Interrupts */
        __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
        /* Change the CRYP state */
        hcryp->State = HAL_CRYP_STATE_READY;
       /* Mark that the header phase is over */
        hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;

       /* Process Unlocked */
        __HAL_UNLOCK(hcryp);

        /* Call computation complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
        hcryp->CompCpltCallback(hcryp);
#else
        HAL_CRYPEx_ComputationCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */

        return HAL_OK;
      }
      /* If suspension flag has been raised, suspend processing */
      else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
      {
        /* Clear CCF Flag */
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);

        /* reset SuspendRequest */
        hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
        /* Disable Computation Complete Flag and Errors Interrupts */
        __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
        /* Change the CRYP state */
        hcryp->State = HAL_CRYP_STATE_SUSPENDED;
        /* Mark that the header phase is suspended */
        hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;

       /* Process Unlocked */
        __HAL_UNLOCK(hcryp);

        return HAL_OK;
      }
      else /* Carry on feeding input data to the CRYP hardware block */
      {
        /* Clear Computation Complete Flag */
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
        /* Get the last Input data address */
        inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;

        /* Increment/decrement instance pointer/counter */
        if (hcryp->CrypInCount < 16U)
        {
          difflength = hcryp->CrypInCount;
          hcryp->CrypInCount = 0;
          addhoc_process = 1;
          difflengthmod4 = difflength%4U;
        }
        else
        {
          hcryp->pCrypInBuffPtr += 16;
          hcryp->CrypInCount -= 16U;
        }

#if defined(AES_CR_NPBLB)
        if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
#else
        if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
#endif
        {
          if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
          {
            /* All B blocks will have been entered after the next
              four DINR writing, so point at header buffer for
              the next iteration */
            hcryp->pCrypInBuffPtr = hcryp->Init.Header;
          }
        }

        /* Write the Input block in the Data Input register */
        if (addhoc_process == 0U)
        {
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
          hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        }
        else
        {
          /* Header remainder has size less than 128 bits */
          /* Enter complete words when possible */
          for(index=0U ; index < (difflength/4U); index ++)
          {
            /* Write the Input block in the Data Input register */
            hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
            inputaddr+=4U;
          }
          /* Enter incomplete word padded with zeroes if applicable
            (case of header length not a multiple of 32-bits) */
          if (difflengthmod4 != 0U)
          {
            hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
          }
          /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
          for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
          {
            hcryp->Instance->DINR = 0;
          }
        }

        return HAL_OK;
      }
    }
    /*=======================*/
    /* GCM/CCM payload phase */
    /*=======================*/
    else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
    {
      /* Get the last output data address */
      outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;

     /* Specific handling to manage payload size less than 128 bits
        when GCM (or CCM when applicable) encryption or decryption is selected.
        Check here if the last block output data are read */
#if defined(AES_CR_NPBLB)
      if ((hcryp->CrypOutCount < 16U)                                && \
          (hcryp->CrypOutCount > 0U))
#else
      if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
          (hcryp->CrypOutCount < 16U)                                && \
          (hcryp->CrypOutCount > 0U))
#endif
      {
        difflength = hcryp->CrypOutCount;
        difflengthmod4 = difflength%4U;
        hcryp->CrypOutCount = 0;   /* mark that no more output data will be needed */
        /* Retrieve intermediate data */
        for(index=0U ; index < 4U; index ++)
        {
          intermediate_data[index] = hcryp->Instance->DOUTR;
        }
        /* Retrieve last words of cyphered data */
        /* First, retrieve complete output words */
        for(index=0U ; index < (difflength/4U); index ++)
        {
          *(uint32_t*)(outputaddr) = intermediate_data[index];
          outputaddr+=4U;
        }
        /* Next, retrieve partial output word if applicable;
           at the same time, start masking intermediate data
           with a mask of zeros of same size than the padding
           applied to the last block of payload */
        if (difflengthmod4 != 0U)
        {
          intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
          *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
        }

#if !defined(AES_CR_NPBLB)
        if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
        {
          /* Change again CHMOD configuration to GCM mode */
          __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);

          /* Select FINAL phase */
          MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);

          /* Before inserting the intermediate data, carry on masking operation
             with a mask of zeros of same size than the padding applied to the last block of payload */
          for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
          {
            intermediate_data[((difflength+3U)/4U)+index] = 0;
          }

          /* Insert intermediate data to trigger an additional Data Output register reading round */
          /* Clear Computation Complete Flag before entering new block */
          __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
          for(index=0U ; index < 4U; index ++)
          {
            hcryp->Instance->DINR = intermediate_data[index];
          }
        }
        else
#endif
        {
          /* Payload phase is now over */
          /* Clear Computation Complete Flag */
          __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
          /* Disable Computation Complete Flag and Errors Interrupts */
          __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
          /* Change the CRYP state */
          hcryp->State = HAL_CRYP_STATE_READY;
          /* Mark that the payload phase is over */
          hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;

          /* Process Unlocked */
          __HAL_UNLOCK(hcryp);

          /* Call computation complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
          hcryp->CompCpltCallback(hcryp);
#else
          HAL_CRYPEx_ComputationCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
        }
        return HAL_OK;
      }
      else
      {
        if (hcryp->CrypOutCount != 0U)
        {
          /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */
          /* Retrieve the last block available from the CRYP hardware block:
            read the output block from the Data Output Register */
          *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
          outputaddr+=4U;
          *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
          outputaddr+=4U;
          *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
          outputaddr+=4U;
          *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;

          /* Increment/decrement instance pointer/counter */
          hcryp->pCrypOutBuffPtr += 16;
          hcryp->CrypOutCount -= 16U;
        }
#if !defined(AES_CR_NPBLB)
        else
        {
          /* Software work-around: additional Data Output Register reading round to discard the data */
          for(index=0U ; index < 4U; index ++)
          {
            intermediate_data[index] = hcryp->Instance->DOUTR;
          }
        }
#endif
      }

      /* Check if all output text has been retrieved */
      if (hcryp->CrypOutCount == 0U)
      {
        /* Clear Computation Complete Flag */
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
        /* Disable Computation Complete Flag and Errors Interrupts */
        __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
        /* Change the CRYP state */
        hcryp->State = HAL_CRYP_STATE_READY;
       /* Mark that the payload phase is over */
        hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;

       /* Process Unlocked */
        __HAL_UNLOCK(hcryp);

        /* Call computation complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
        hcryp->CompCpltCallback(hcryp);
#else
        HAL_CRYPEx_ComputationCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */

        return HAL_OK;
      }
      /* If suspension flag has been raised, suspend processing */
      else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
      {
        /* Clear CCF Flag */
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);

        /* reset SuspendRequest */
        hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
        /* Disable Computation Complete Flag and Errors Interrupts */
        __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
        /* Change the CRYP state */
        hcryp->State = HAL_CRYP_STATE_SUSPENDED;
        /* Mark that the payload phase is suspended */
        hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_SUSPENDED;

       /* Process Unlocked */
        __HAL_UNLOCK(hcryp);

        return HAL_OK;
      }
      else /* Output data are still expected, carry on feeding the CRYP
               hardware block with input data */
      {
        /* Clear Computation Complete Flag */
        __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
        /* Get the last Input data address */
        inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;

        /* Usual input data feeding case */
        if (hcryp->CrypInCount < 16U)
        {
          difflength = (uint32_t) (hcryp->CrypInCount);
          difflengthmod4 = difflength%4U;
          hcryp->CrypInCount = 0;

#if defined(AES_CR_NPBLB)
          /* In case of GCM encryption or CCM decryption, specify the number of padding
             bytes in last block of payload */
          {
            uint32_t cr_temp = hcryp->Instance->CR;

            if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
             ||  ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
            {
              /* Set NPBLB field in writing the number of padding bytes
              for the last block of payload */
              MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
             }
          }
#else
          /* Software workaround applied to GCM encryption only */
          if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
          {
            /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
            __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
          }
#endif

          /*  Insert the last block (which size is inferior to 128 bits) padded with zeroes
              to have a complete block of 128 bits */
          for(index=0U ; index < (difflength/4U); index ++)
          {
            /* Write the Input block in the Data Input register */
            hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
            inputaddr+=4U;
          }
          /* If required, manage input data size not multiple of 32 bits */
          if (difflengthmod4 != 0U)
          {
            hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
          }
          /* Wrap-up in padding with zero-words if applicable */
          for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
          {
            hcryp->Instance->DINR = 0;
          }

        }
        else
        {
          hcryp->pCrypInBuffPtr += 16;
          hcryp->CrypInCount -= 16U;

          /* Write the Input block in the Data Input register */
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
          hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
          inputaddr+=4U;
          hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
        }


        return HAL_OK;
      }
    }
    /*=======================================*/
    /* GCM/GMAC (or CCM or CMAC) final phase */
    /*=======================================*/
    else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
    {
      /* Clear Computation Complete Flag */
      __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);

      /* Get the last output data address */
      outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;

      /* Retrieve the last expected data from the CRYP hardware block:
         read the output block from the Data Output Register */
      *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
      outputaddr+=4U;
      *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
      outputaddr+=4U;
      *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
      outputaddr+=4U;
      *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;

      /* Disable Computation Complete Flag and Errors Interrupts */
      __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
      /* Change the CRYP state */
      hcryp->State = HAL_CRYP_STATE_READY;
      /* Mark that the header phase is over */
      hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;

      /* Disable the Peripheral */
      __HAL_CRYP_DISABLE(hcryp);
      /* Process Unlocked */
       __HAL_UNLOCK(hcryp);

      /* Call computation complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
      hcryp->CompCpltCallback(hcryp);
#else
      HAL_CRYPEx_ComputationCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */

      return HAL_OK;
    }
    else
    {
      /* Clear Computation Complete Flag */
      __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
      hcryp->State = HAL_CRYP_STATE_ERROR;
      __HAL_UNLOCK(hcryp);
      return HAL_ERROR;
    }
  }
  else
  {
    return HAL_BUSY;
  }
}



/**
  * @brief  Set the DMA configuration and start the DMA transfer
  *         for GCM, GMAC, CCM  or CMAC chaining modes.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  inputaddr Address of the Input buffer.
  * @param  Size Size of the Input buffer un bytes, must be a multiple of 16.
  * @param  outputaddr Address of the Output buffer, null pointer when no output DMA stream
  *         has to be configured.
  * @retval None
  */
static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
{

  /* Set the input CRYP DMA transfer complete callback */
  hcryp->hdmain->XferCpltCallback = CRYP_Authentication_DMAInCplt;
  /* Set the DMA error callback */
  hcryp->hdmain->XferErrorCallback = CRYP_Authentication_DMAError;

  if (outputaddr != 0U)
  {
    /* Set the output CRYP DMA transfer complete callback */
    hcryp->hdmaout->XferCpltCallback = CRYP_Authentication_DMAOutCplt;
    /* Set the DMA error callback */
    hcryp->hdmaout->XferErrorCallback = CRYP_Authentication_DMAError;
  }

  /* Enable the CRYP peripheral */
  __HAL_CRYP_ENABLE(hcryp);

  /* Enable the DMA input stream */
  if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
  {
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
    hcryp->ErrorCallback(hcryp);
#else
    HAL_CRYP_ErrorCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  }

  /* Enable the DMA input request */
  SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);


  if (outputaddr != 0U)
  {
    /* Enable the DMA output stream */
    if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
    {
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
      hcryp->ErrorCallback(hcryp);
#else
      HAL_CRYP_ErrorCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
    }

    /* Enable the DMA output request */
    SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
  }
}



/**
  * @brief  Write/read input/output data in polling mode.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Input Pointer to the Input buffer.
  * @param  Ilength Length of the Input buffer in bytes, must be a multiple of 16.
  * @param  Output Pointer to the returned buffer.
  * @param  Timeout Specify Timeout value.
  * @retval HAL status
  */
static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout)
{
  uint32_t index;
  uint32_t inputaddr  = (uint32_t)Input;
  uint32_t outputaddr = (uint32_t)Output;


  for(index=0U ; (index < Ilength); index += 16U)
  {
    /* Write the Input block in the Data Input register */
    hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
    inputaddr+=4U;
    hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
    inputaddr+=4U;
    hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
    inputaddr+=4U;
    hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
    inputaddr+=4U;

    /* Wait for CCF flag to be raised */
    if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
    {
      hcryp->State = HAL_CRYP_STATE_READY;
      __HAL_UNLOCK(hcryp);
      return HAL_TIMEOUT;
    }

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

    /* Read the Output block from the Data Output Register */
    *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
    outputaddr+=4U;
    *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
    outputaddr+=4U;
    *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
    outputaddr+=4U;
    *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
    outputaddr+=4U;

    /* If the suspension flag has been raised and if the processing is not about
       to end, suspend processing */
    if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength))
    {
      /* Reset SuspendRequest */
      hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;

      /* Save current reading and writing locations of Input and Output buffers */
      hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
      hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
      /* Save the number of bytes that remain to be processed at this point */
      hcryp->CrypInCount     =  Ilength - (index+16U);

      /* Change the CRYP state */
      hcryp->State = HAL_CRYP_STATE_SUSPENDED;

      return HAL_OK;
    }


  }
  /* Return function status */
  return HAL_OK;

}





/**
  * @brief  Read derivative key in polling mode when CRYP hardware block is set
  *         in key derivation operating mode (mode 2).
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Output Pointer to the returned buffer.
  * @param  Timeout Specify Timeout value.
  * @retval HAL status
  */
static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout)
{
  uint32_t outputaddr = (uint32_t)Output;

  /* Wait for CCF flag to be raised */
  if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
  {
    hcryp->State = HAL_CRYP_STATE_READY;
    __HAL_UNLOCK(hcryp);
    return HAL_TIMEOUT;
  }
  /* Clear CCF Flag */
  __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);

    /* Read the derivative key from the AES_KEYRx registers */
  if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B)
  {
    *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7);
    outputaddr+=4U;
    *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6);
    outputaddr+=4U;
    *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5);
    outputaddr+=4U;
    *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4);
    outputaddr+=4U;
  }

    *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3);
    outputaddr+=4U;
    *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2);
    outputaddr+=4U;
    *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1);
    outputaddr+=4U;
    *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0);


  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Set the DMA configuration and start the DMA transfer.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  inputaddr Address of the Input buffer.
  * @param  Size Size of the Input buffer in bytes, must be a multiple of 16.
  * @param  outputaddr Address of the Output buffer.
  * @retval None
  */
static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
{
  /* Set the CRYP DMA transfer complete callback */
  hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
  /* Set the DMA error callback */
  hcryp->hdmain->XferErrorCallback = CRYP_DMAError;

  /* Set the CRYP DMA transfer complete callback */
  hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
  /* Set the DMA error callback */
  hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;

  /* Enable the DMA input stream */
  if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
  {
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
    hcryp->ErrorCallback(hcryp);
#else
    HAL_CRYP_ErrorCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  }

  /* Enable the DMA output stream */
  if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
  {
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
    hcryp->ErrorCallback(hcryp);
#else
    HAL_CRYP_ErrorCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  }

  /* Enable In and Out DMA requests */
  SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));

  /* Enable the CRYP peripheral */
  __HAL_CRYP_ENABLE(hcryp);
}


/**
  * @brief  Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Timeout Timeout duration.
  * @retval HAL status
  */
static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
{
  uint32_t tickstart;

  /* Get timeout */
  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)
      {
        return HAL_TIMEOUT;
      }
    }
  }
  return HAL_OK;
}

/**
  * @brief  Wait for Busy Flag to be reset during a GCM payload encryption process suspension.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  Timeout Timeout duration.
  * @retval HAL status
  */
static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
{
  uint32_t tickstart;

  /* Get timeout */
  tickstart = HAL_GetTick();

  while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((HAL_GetTick() - tickstart ) > Timeout)
      {
        return HAL_TIMEOUT;
      }
    }
  }
  return HAL_OK;
}


/**
  * @brief  DMA CRYP Input Data process complete callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
{
  CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */

  /* Disable the DMA transfer for input request  */
  CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);

  /* Call input data transfer complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  hcryp->InCpltCallback(hcryp);
#else
  HAL_CRYP_InCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
}

/**
  * @brief  DMA CRYP Output Data process complete callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
{
  CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */

  /* Disable the DMA transfer for output request */
  CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);

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

  /* Disable CRYP */
  __HAL_CRYP_DISABLE(hcryp);

  /* Change the CRYP state to ready */
  hcryp->State = HAL_CRYP_STATE_READY;

  /* Call output data transfer complete callback */
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  hcryp->OutCpltCallback(hcryp);
#else
  HAL_CRYP_OutCpltCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
}

/**
  * @brief  DMA CRYP communication error callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
{
  CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */

  hcryp->State= HAL_CRYP_STATE_ERROR;
  hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  hcryp->ErrorCallback(hcryp);
#else
  HAL_CRYP_ErrorCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  /* Clear Error Flag */
  __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
}

/**
  * @brief  Last header or payload block padding when size is not a multiple of 128 bits.
  * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module.
  * @param  difflength size remainder after having fed all complete 128-bit blocks.
  * @param  polling specifies whether or not polling on CCF must be done after having
  *                  entered a complete block.
  * @retval None
  */
static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling)
{
  uint32_t index;
  uint32_t difflengthmod4 = difflength%4U;
  uint32_t inputaddr      = (uint32_t)hcryp->pCrypInBuffPtr;
  uint32_t outputaddr     = (uint32_t)hcryp->pCrypOutBuffPtr;
  uint32_t mask[4][3];
  uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;

  uint32_t intermediate_data[4] = {0};

  mask[0][0] = 0xFF000000U;  mask[0][1] = 0xFFFF0000U;  mask[0][2] = 0xFFFFFF00U;  /* 32-bit data */
  mask[1][0] = 0x0000FF00U;  mask[1][1] = 0x0000FFFFU;  mask[1][2] = 0xFF00FFFFU;  /* 16-bit data */
  mask[2][0] = 0x000000FFU;  mask[2][1] = 0x0000FFFFU;  mask[2][2] = 0x00FFFFFFU;  /* 8-bit data  */
  mask[3][0] = 0x000000FFU;  mask[3][1] = 0x0000FFFFU;  mask[3][2] = 0x00FFFFFFU;  /* Bit data    */

#if defined(AES_CR_NPBLB)
  /* In case of GCM encryption or CCM decryption, specify the number of padding
     bytes in last block of payload */
     if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
     {
       uint32_t cr_temp = hcryp->Instance->CR;

       if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
       ||  ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
       {
         /* Set NPBLB field in writing the number of padding bytes
            for the last block of payload */
         MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
       }
     }
#else
  /* Software workaround applied to GCM encryption only */
  if ((hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) &&
      (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT))
  {
    /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
    __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
  }
#endif

  /* Wrap-up entering header or payload data */
  /* Enter complete words when possible */
  for(index=0U ; index < (difflength/4U); index ++)
  {
    /* Write the Input block in the Data Input register */
    hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
    inputaddr+=4U;
  }
  /* Enter incomplete word padded with zeroes if applicable
    (case of header length not a multiple of 32-bits) */
  if (difflengthmod4 != 0U)
  {
    hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
  }
  /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
  for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
  {
    hcryp->Instance->DINR = 0;
  }

  if (polling == (uint32_t)CRYP_POLLING_ON)
  {
    if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
    {
        hcryp->State = HAL_CRYP_STATE_READY;
        __HAL_UNLOCK(hcryp);
#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
        hcryp->ErrorCallback(hcryp);
#else
       HAL_CRYP_ErrorCallback(hcryp);
#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
      }

    /* Clear CCF Flag */
    __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  }

  /* if payload */
  if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
  {

    /* Retrieve intermediate data */
    for(index=0U ; index < 4U; index ++)
    {
      intermediate_data[index] = hcryp->Instance->DOUTR;
    }
    /* Retrieve last words of cyphered data */
    /* First, retrieve complete output words */
    for(index=0U ; index < (difflength/4U); index ++)
    {
      *(uint32_t*)(outputaddr) = intermediate_data[index];
      outputaddr+=4U;
    }
    /* Next, retrieve partial output word if applicable;
       at the same time, start masking intermediate data
       with a mask of zeros of same size than the padding
       applied to the last block of payload */
    if (difflengthmod4 != 0U)
    {
      intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
      *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
    }


#if !defined(AES_CR_NPBLB)
    /* Software workaround applied to GCM encryption only,
       applicable for AES IP v2 version (where NPBLB is not defined) */
    if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
    {
      /* Change again CHMOD configuration to GCM mode */
      __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);

      /* Select FINAL phase */
      MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);

      /* Before inserting the intermediate data, carry on masking operation
         with a mask of zeros of same size than the padding applied to the last block of payload */
      for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
      {
        intermediate_data[((difflength+3U)/4U)+index] = 0;
      }
      /* Insert intermediate data */
      for(index=0U ; index < 4U; index ++)
      {
        hcryp->Instance->DINR = intermediate_data[index];
      }

      /*  Wait for completion, and read data on Data Output Register. This data is to discard. */
      if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
      {
        hcryp->State = HAL_CRYP_STATE_READY;
        __HAL_UNLOCK(hcryp);
        HAL_CRYP_ErrorCallback(hcryp);
      }

      /* Read data to discard */
      /* Clear CCF Flag */
      __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
      for(index=0U ; index < 4U; index ++)
      {
        intermediate_data[index] = hcryp->Instance->DOUTR;
      }

    } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */
#endif  /* !defined(AES_CR_NPBLB) */
  }   /* if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) */

}

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

#endif /* AES */

#endif /* HAL_CRYP_MODULE_ENABLED */
