123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- /**
- ******************************************************************************
- * @file stm32g0xx_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) 2018 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 "stm32g0xx_hal.h"
- /** @addtogroup STM32G0xx_HAL_Driver
- * @{
- */
- /** @addtogroup CRYPEx
- * @{
- */
- #if defined(AES)
- #ifdef HAL_CRYP_MODULE_ENABLED
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /** @addtogroup CRYPEx_Private_Defines
- * @{
- */
- #define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */
- #define CRYP_PHASE_HEADER AES_CR_GCMPH_0 /*!< GCM/GMAC or CCM header phase */
- #define CRYP_PHASE_PAYLOAD AES_CR_GCMPH_1 /*!< GCM(/CCM) payload phase */
- #define CRYP_PHASE_FINAL AES_CR_GCMPH /*!< GCM/GMAC or CCM final phase */
- #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */
- #define CRYP_OPERATINGMODE_KEYDERIVATION AES_CR_MODE_0 /*!< Key derivation mode only used when performing ECB and CBC decryptions */
- #define CRYP_OPERATINGMODE_DECRYPT AES_CR_MODE_1 /*!< Decryption */
- #define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT AES_CR_MODE /*!< Key derivation and decryption only used when performing ECB and CBC decryptions */
- #define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */
- #define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
- /* CTR0 information to use in CCM algorithm */
- #define CRYP_CCM_CTR0_0 0x07FFFFFFU
- #define CRYP_CCM_CTR0_3 0xFFFFFF00U
- /**
- * @}
- */
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- /* Private function prototypes -----------------------------------------------*/
- /* Exported functions---------------------------------------------------------*/
- /** @addtogroup CRYPEx_Exported_Functions
- * @{
- */
- /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
- * @brief Extended processing functions.
- *
- @verbatim
- ==============================================================================
- ##### Extended AES processing functions #####
- ==============================================================================
- [..] This section provides functions allowing to generate the authentication
- TAG in Polling mode
- (#)HAL_CRYPEx_AESGCM_GenerateAuthTAG
- (#)HAL_CRYPEx_AESCCM_GenerateAuthTAG
- they should be used after Encrypt/Decrypt operation.
- @endverbatim
- * @{
- */
- /**
- * @brief generate the GCM authentication TAG.
- * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
- * the configuration information for CRYP module
- * @param AuthTag Pointer to the authentication buffer
- * @param Timeout Timeout duration
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
- {
- uint32_t tickstart;
- /* Assume first Init.HeaderSize is in words */
- uint64_t headerlength = (uint64_t)hcryp->Init.HeaderSize * 32U; /* Header length in bits */
- uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
- uint32_t tagaddr = (uint32_t)AuthTag;
- /* Correct headerlength if Init.HeaderSize is actually in bytes */
- if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
- {
- headerlength /= 4U;
- }
- if (hcryp->State == HAL_CRYP_STATE_READY)
- {
- /* Process locked */
- __HAL_LOCK(hcryp);
- /* Change the CRYP peripheral state */
- hcryp->State = HAL_CRYP_STATE_BUSY;
- /* Check if initialization phase has already been performed */
- if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
- {
- /* Change the CRYP phase */
- hcryp->Phase = CRYPEx_PHASE_FINAL;
- }
- else /* Initialization phase has not been performed*/
- {
- /* Disable the Peripheral */
- __HAL_CRYP_DISABLE(hcryp);
- /* Sequence error code field */
- hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
- /* Change the CRYP peripheral state */
- hcryp->State = HAL_CRYP_STATE_READY;
- /* Process unlocked */
- __HAL_UNLOCK(hcryp);
- return HAL_ERROR;
- }
- /* Select final phase */
- MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
- /* Set the encrypt operating mode*/
- MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
- /*TinyAES peripheral from V3.1.1 : data has to be inserted normally (no swapping)*/
- /* Write into the AES_DINR register the number of bits in header (64 bits)
- followed by the number of bits in the payload */
- hcryp->Instance->DINR = 0U;
- hcryp->Instance->DINR = (uint32_t)(headerlength);
- hcryp->Instance->DINR = 0U;
- hcryp->Instance->DINR = (uint32_t)(inputlength);
- /* Wait for CCF flag to be raised */
- tickstart = HAL_GetTick();
- while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
- {
- /* Check for the Timeout */
- if (Timeout != HAL_MAX_DELAY)
- {
- if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
- {
- /* Disable the CRYP peripheral clock */
- __HAL_CRYP_DISABLE(hcryp);
- /* Change state */
- hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
- hcryp->State = HAL_CRYP_STATE_READY;
- /* Process unlocked */
- __HAL_UNLOCK(hcryp);
- return HAL_ERROR;
- }
- }
- }
- /* Read the authentication TAG in the output FIFO */
- *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
- tagaddr += 4U;
- *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
- tagaddr += 4U;
- *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
- tagaddr += 4U;
- *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
- /* Clear CCF flag */
- __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
- /* Disable the peripheral */
- __HAL_CRYP_DISABLE(hcryp);
- /* Change the CRYP peripheral state */
- hcryp->State = HAL_CRYP_STATE_READY;
- /* Process unlocked */
- __HAL_UNLOCK(hcryp);
- }
- else
- {
- /* Busy error code field */
- hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
- return HAL_ERROR;
- }
- /* Return function status */
- return HAL_OK;
- }
- /**
- * @brief AES CCM Authentication TAG generation.
- * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
- * the configuration information for CRYP module
- * @param AuthTag Pointer to the authentication buffer
- * @param Timeout Timeout duration
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
- {
- uint32_t tagaddr = (uint32_t)AuthTag;
- uint32_t tickstart;
- if (hcryp->State == HAL_CRYP_STATE_READY)
- {
- /* Process locked */
- __HAL_LOCK(hcryp);
- /* Disable interrupts in case they were kept enabled to proceed
- a single message in several iterations */
- __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
- /* Change the CRYP peripheral state */
- hcryp->State = HAL_CRYP_STATE_BUSY;
- /* Check if initialization phase has already been performed */
- if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
- {
- /* Change the CRYP phase */
- hcryp->Phase = CRYPEx_PHASE_FINAL;
- }
- else /* Initialization phase has not been performed*/
- {
- /* Disable the peripheral */
- __HAL_CRYP_DISABLE(hcryp);
- /* Sequence error code field */
- hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
- /* Change the CRYP peripheral state */
- hcryp->State = HAL_CRYP_STATE_READY;
- /* Process unlocked */
- __HAL_UNLOCK(hcryp);
- return HAL_ERROR;
- }
- /* Select final phase */
- MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
- /* Set encrypt operating mode*/
- MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
- /* Wait for CCF flag to be raised */
- tickstart = HAL_GetTick();
- while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
- {
- /* Check for the Timeout */
- if (Timeout != HAL_MAX_DELAY)
- {
- if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
- {
- /* Disable the CRYP peripheral Clock */
- __HAL_CRYP_DISABLE(hcryp);
- /* Change state */
- hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
- hcryp->State = HAL_CRYP_STATE_READY;
- /* Process unlocked */
- __HAL_UNLOCK(hcryp);
- return HAL_ERROR;
- }
- }
- }
- /* Read the authentication TAG in the output FIFO */
- *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
- tagaddr += 4U;
- *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
- tagaddr += 4U;
- *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
- tagaddr += 4U;
- *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
- /* Clear CCF Flag */
- __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
- /* Change the CRYP peripheral state */
- hcryp->State = HAL_CRYP_STATE_READY;
- /* Process unlocked */
- __HAL_UNLOCK(hcryp);
- /* Disable CRYP */
- __HAL_CRYP_DISABLE(hcryp);
- }
- else
- {
- /* Busy error code field */
- hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
- return HAL_ERROR;
- }
- /* Return function status */
- return HAL_OK;
- }
- /**
- * @}
- */
- /** @defgroup CRYPEx_Exported_Functions_Group2 Extended AES Key Derivations functions
- * @brief Extended Key Derivations functions.
- *
- @verbatim
- ==============================================================================
- ##### Key Derivation functions #####
- ==============================================================================
- [..] This section provides functions allowing to Enable or Disable the
- the AutoKeyDerivation parameter in CRYP_HandleTypeDef structure
- These function are allowed only in TinyAES peripheral.
- @endverbatim
- * @{
- */
- /**
- * @brief AES enable key derivation functions
- * @param hcryp pointer to a CRYP_HandleTypeDef structure.
- */
- void HAL_CRYPEx_EnableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
- {
- if (hcryp->State == HAL_CRYP_STATE_READY)
- {
- hcryp->AutoKeyDerivation = ENABLE;
- }
- else
- {
- /* Busy error code field */
- hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
- }
- }
- /**
- * @brief AES disable key derivation functions
- * @param hcryp pointer to a CRYP_HandleTypeDef structure.
- */
- void HAL_CRYPEx_DisableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
- {
- if (hcryp->State == HAL_CRYP_STATE_READY)
- {
- hcryp->AutoKeyDerivation = DISABLE;
- }
- else
- {
- /* Busy error code field */
- hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
- }
- }
- /**
- * @}
- */
- /**
- * @}
- */
- #endif /* HAL_CRYP_MODULE_ENABLED */
- #endif /* AES */
- /**
- * @}
- */
- /**
- * @}
- */
|