STM32G474xx HAL用户手册
stm32g4xx_hal_cryp_ex.c 源文件
转到此文件的文档。
00001 /**
00002   ******************************************************************************
00003   * @file    stm32g4xx_hal_cryp_ex.c
00004   * @author  MCD Application Team
00005   * @brief   CRYPEx HAL module driver.
00006   *          This file provides firmware functions to manage the extended
00007   *          functionalities of the Cryptography (CRYP) peripheral.
00008   *
00009   ******************************************************************************
00010   * @attention
00011   *
00012   * Copyright (c) 2019 STMicroelectronics.
00013   * All rights reserved.
00014   *
00015   * This software is licensed under terms that can be found in the LICENSE file
00016   * in the root directory of this software component.
00017   * If no LICENSE file comes with this software, it is provided AS-IS.
00018   *
00020   ******************************************************************************
00021   */
00022 
00023 /* Includes ------------------------------------------------------------------*/
00024 #include "stm32g4xx_hal.h"
00025 
00026 /** @addtogroup STM32G4xx_HAL_Driver
00027   * @{
00028   */
00029 
00030 /** @addtogroup CRYPEx
00031   * @{
00032   */
00033 
00034 #if defined(AES)
00035 
00036 #ifdef HAL_CRYP_MODULE_ENABLED
00036 
00037 /* Private typedef -----------------------------------------------------------*/
00038 /* Private define ------------------------------------------------------------*/
00039 /** @addtogroup CRYPEx_Private_Defines
00040   * @{
00042   */
00043 
00044 #define CRYP_PHASE_INIT                              0x00000000U             /*!< GCM/GMAC (or CCM) init phase */
00045 #define CRYP_PHASE_HEADER                            AES_CR_GCMPH_0          /*!< GCM/GMAC or CCM header phase */
00046 #define CRYP_PHASE_PAYLOAD                           AES_CR_GCMPH_1          /*!< GCM(/CCM) payload phase   */
00047 #define CRYP_PHASE_FINAL                             AES_CR_GCMPH            /*!< GCM/GMAC or CCM  final phase  */
00048 
00049 #define CRYP_OPERATINGMODE_ENCRYPT                   0x00000000U             /*!< Encryption mode   */
00050 #define CRYP_OPERATINGMODE_KEYDERIVATION             AES_CR_MODE_0           /*!< Key derivation mode  only used when performing ECB and CBC decryptions  */
00051 #define CRYP_OPERATINGMODE_DECRYPT                   AES_CR_MODE_1           /*!< Decryption       */
00052 #define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT     AES_CR_MODE             /*!< Key derivation and decryption only used when performing ECB and CBC decryptions  */
00053 
00054 #define  CRYPEx_PHASE_PROCESS       0x02U     /*!< CRYP peripheral is in processing phase */
00055 #define  CRYPEx_PHASE_FINAL         0x03U     /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
00056 
00057 /*  CTR0 information to use in CCM algorithm */
00058 #define CRYP_CCM_CTR0_0            0x07FFFFFFU
00059 #define CRYP_CCM_CTR0_3            0xFFFFFF00U
00060 
00061 /**
00062   * @}
00063   */
00064 
00065 /* Private macro -------------------------------------------------------------*/
00066 /* Private variables ---------------------------------------------------------*/
00067 /* Private function prototypes -----------------------------------------------*/
00068 
00069 /* Exported functions---------------------------------------------------------*/
00070 /** @addtogroup CRYPEx_Exported_Functions
00071   * @{
00072   */
00073 
00074 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
00075   *  @brief   Extended processing functions.
00076   *
00077 @verbatim
00078   ==============================================================================
00079               ##### Extended AES processing functions #####
00080   ==============================================================================
00081     [..]  This section provides functions allowing to generate the authentication
00082           TAG in Polling mode
00083       (#)HAL_CRYPEx_AESGCM_GenerateAuthTAG
00084       (#)HAL_CRYPEx_AESCCM_GenerateAuthTAG
00085          they should be used after Encrypt/Decrypt operation.
00087 
00088 @endverbatim
00089   * @{
00090   */
00091 
00092 /**
00093   * @brief  generate the GCM authentication TAG.
00094   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00095   *         the configuration information for CRYP module
00096   * @param  AuthTag Pointer to the authentication buffer
00097   * @param  Timeout Timeout duration
00098   * @retval HAL status
00099   */
00100 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *AuthTag,
00101                                                     uint32_t Timeout)
00102 {
00103   uint32_t tickstart;
00104   /* Assume first Init.HeaderSize is in words */
00105   uint64_t headerlength = (uint64_t)hcryp->Init.HeaderSize * 32U; /* Header length in bits */
00106   uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
00107   uint32_t tagaddr = (uint32_t)AuthTag;
00108 
00109   /* Correct headerlength if Init.HeaderSize is actually in bytes */
00111   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
00111   {
00112     headerlength /= 4U;
00113   }
00114 
00115   if (hcryp->State == HAL_CRYP_STATE_READY)
00116   {
00117     /* Process locked */
00118     __HAL_LOCK(hcryp);
00119 
00120     /* Change the CRYP peripheral state */
00121     hcryp->State = HAL_CRYP_STATE_BUSY;
00122 
00123     /* Check if initialization phase has already been performed */
00125     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
00125     {
00126       /* Change the CRYP phase */
00127       hcryp->Phase = CRYPEx_PHASE_FINAL;
00128     }
00129     else /* Initialization phase has not been performed*/
00130     {
00131       /* Disable the Peripheral */
00132       __HAL_CRYP_DISABLE(hcryp);
00133 
00134       /* Sequence error code field */
00135       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
00137 
00138       /* Change the CRYP peripheral state */
00139       hcryp->State = HAL_CRYP_STATE_READY;
00141 
00143       /* Process unlocked */
00144       __HAL_UNLOCK(hcryp);
00146       return HAL_ERROR;
00148     }
00149 
00150     /* Select final phase */
00151     MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
00153 
00154     /* Set the encrypt operating mode*/
00155     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
00157 
00158     /*TinyAES peripheral from V3.1.1 : data has to be inserted normally (no swapping)*/
00159     /* Write into the AES_DINR register the number of bits in header (64 bits)
00160     followed by the number of bits in the payload */
00161 
00162     hcryp->Instance->DINR = 0U;
00163     hcryp->Instance->DINR = (uint32_t)(headerlength);
00164     hcryp->Instance->DINR = 0U;
00165     hcryp->Instance->DINR = (uint32_t)(inputlength);
00166 
00168     /* Wait for CCF flag to be raised */
00169     tickstart = HAL_GetTick();
00170     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
00171     {
00172       /* Check for the Timeout */
00173       if (Timeout != HAL_MAX_DELAY)
00174       {
00175         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
00176         {
00177           /* Disable the CRYP peripheral clock */
00178           __HAL_CRYP_DISABLE(hcryp);
00180 
00181           /* Change state */
00183           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
00184           hcryp->State = HAL_CRYP_STATE_READY;
00186 
00187           /* Process unlocked */
00188           __HAL_UNLOCK(hcryp);
00190           return HAL_ERROR;
00191         }
00192       }
00193     }
00195 
00196     /* Read the authentication TAG in the output FIFO */
00197     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
00198     tagaddr += 4U;
00199     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
00200     tagaddr += 4U;
00201     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
00202     tagaddr += 4U;
00203     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
00204 
00205     /* Clear CCF flag */
00206     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
00207 
00209     /* Disable the peripheral */
00210     __HAL_CRYP_DISABLE(hcryp);
00211 
00212     /* Change the CRYP peripheral state */
00213     hcryp->State = HAL_CRYP_STATE_READY;
00214 
00215     /* Process unlocked */
00216     __HAL_UNLOCK(hcryp);
00217   }
00218   else
00219   {
00220     /* Busy error code field */
00221     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
00223     return HAL_ERROR;
00225   }
00226   /* Return function status */
00228   return HAL_OK;
00229 }
00230 
00231 /**
00232   * @brief  AES CCM Authentication TAG generation.
00233   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00234   *         the configuration information for CRYP module
00235   * @param  AuthTag Pointer to the authentication buffer
00236   * @param  Timeout Timeout duration
00237   * @retval HAL status
00238   */
00239 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *AuthTag,
00240                                                     uint32_t Timeout)
00241 {
00242   uint32_t tagaddr = (uint32_t)AuthTag;
00243   uint32_t tickstart;
00244 
00245   if (hcryp->State == HAL_CRYP_STATE_READY)
00246   {
00247     /* Process locked */
00248     __HAL_LOCK(hcryp);
00249 
00250     /* Disable interrupts in case they were kept enabled to proceed
00251        a single message in several iterations */
00252     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
00253 
00254     /* Change the CRYP peripheral state */
00255     hcryp->State = HAL_CRYP_STATE_BUSY;
00257 
00258     /* Check if initialization phase has already been performed */
00259     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
00260     {
00261       /* Change the CRYP phase */
00262       hcryp->Phase = CRYPEx_PHASE_FINAL;
00264     }
00265     else /* Initialization phase has not been performed*/
00266     {
00267       /* Disable the peripheral */
00268       __HAL_CRYP_DISABLE(hcryp);
00269 
00270       /* Sequence error code field */
00272       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
00274 
00275       /* Change the CRYP peripheral state */
00276       hcryp->State = HAL_CRYP_STATE_READY;
00278 
00280       /* Process unlocked */
00281       __HAL_UNLOCK(hcryp);
00283       return HAL_ERROR;
00285     }
00286     /* Select final phase */
00287     MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
00289 
00290     /* Set encrypt  operating mode*/
00291     MODIFY_REG(hcryp->