|
STM32G474xx HAL用户手册
|
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->