STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_hal_cryp_ex.c 00004 * @author MCD Application Team 00005 * @brief Extended CRYP HAL module driver 00006 * This file provides firmware functions to manage the following 00007 * functionalities of CRYP extension peripheral: 00008 * + Extended AES processing functions 00009 * 00010 ****************************************************************************** 00011 * @attention 00012 * 00013 * Copyright (c) 2017 STMicroelectronics. 00014 * All rights reserved. 00015 * 00016 * This software is licensed under terms that can be found in the LICENSE file 00017 * in the root directory of this software component. 00018 * If no LICENSE file comes with this software, it is provided AS-IS. 00019 * 00020 ****************************************************************************** 00021 @verbatim 00022 ============================================================================== 00023 ##### How to use this driver ##### 00024 ============================================================================== 00025 [..] 00026 The CRYP extension HAL driver can be used after AES-GCM or AES-CCM 00027 Encryption/Decryption to get the authentication messages. 00028 00029 @endverbatim 00030 */ 00031 00032 /* Includes ------------------------------------------------------------------*/ 00033 #include "stm32h7xx_hal.h" 00034 00035 /** @addtogroup STM32H7xx_HAL_Driver 00036 * @{ 00037 */ 00038 #if defined (CRYP) 00039 /** @defgroup CRYPEx CRYPEx 00040 * @brief CRYP Extension HAL module driver. 00041 * @{ 00042 */ 00043 00044 #ifdef HAL_CRYP_MODULE_ENABLED 00045 00046 /* Private typedef -----------------------------------------------------------*/ 00047 /* Private define ------------------------------------------------------------*/ 00048 /** @addtogroup CRYPEx_Private_Defines 00049 * @{ 00050 */ 00051 00052 #define CRYP_PHASE_INIT 0x00000000U 00053 #define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0 00054 #define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1 00055 #define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH 00056 00057 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U 00058 #define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR 00059 00060 #define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */ 00061 #define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */ 00062 00063 /* CTR0 information to use in CCM algorithm */ 00064 #define CRYP_CCM_CTR0_0 0x07FFFFFFU 00065 #define CRYP_CCM_CTR0_3 0xFFFFFF00U 00066 00067 /** 00068 * @} 00069 */ 00070 00071 /* Private macro -------------------------------------------------------------*/ 00072 /* Private variables ---------------------------------------------------------*/ 00073 /* Private function prototypes -----------------------------------------------*/ 00074 00075 00076 00077 /* Exported functions---------------------------------------------------------*/ 00078 /** @addtogroup CRYPEx_Exported_Functions 00079 * @{ 00080 */ 00081 00082 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions 00083 * @brief CRYPEx Extended processing functions. 00084 * 00085 @verbatim 00086 ============================================================================== 00087 ##### Extended AES processing functions ##### 00088 ============================================================================== 00089 [..] This section provides functions allowing to generate the authentication 00090 TAG in Polling mode 00091 (+)HAL_CRYPEx_AESGCM_GenerateAuthTAG 00092 (+)HAL_CRYPEx_AESCCM_GenerateAuthTAG 00093 they should be used after Encrypt/Decrypt operation. 00094 00095 @endverbatim 00096 * @{ 00097 */ 00098 00099 00100 /** 00101 * @brief generate the GCM authentication TAG. 00102 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 00103 * the configuration information for CRYP module 00104 * @param AuthTag: Pointer to the authentication buffer 00105 * the AuthTag generated here is 128bits length, if the TAG length is 00106 * less than 128bits, user should consider only the valid part of AuthTag 00107 * buffer which correspond exactly to TAG length. 00108 * @param Timeout: Timeout duration 00109 * @retval HAL status 00110 */ 00111 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout) 00112 { 00113 uint32_t tickstart; 00114 uint64_t headerlength = (uint64_t)(hcryp->Init.HeaderSize) * 32U; /* Header length in bits */ 00115 uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */ 00116 uint32_t tagaddr = (uint32_t)AuthTag; 00117 00118 /* Correct header length if Init.HeaderSize is actually in bytes */ 00119 if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE) 00120 { 00121 headerlength /= 4U; 00122 } 00123 00124 if (hcryp->State == HAL_CRYP_STATE_READY) 00125 { 00126 /* Process locked */ 00127 __HAL_LOCK(hcryp); 00128 00129 /* Change the CRYP peripheral state */ 00130 hcryp->State = HAL_CRYP_STATE_BUSY; 00131 00132 /* Check if initialization phase has already been performed */ 00133 if (hcryp->Phase == CRYPEx_PHASE_PROCESS) 00134 { 00135 /* Change the CRYP phase */ 00136 hcryp->Phase = CRYPEx_PHASE_FINAL; 00137 } 00138 else /* Initialization phase has not been performed*/ 00139 { 00140 /* Disable the Peripheral */ 00141 __HAL_CRYP_DISABLE(hcryp); 00142 00143 /* Sequence error code field */ 00144 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE; 00145 00146 /* Change the CRYP peripheral state */ 00147 hcryp->State = HAL_CRYP_STATE_READY; 00148 00149 /* Process unlocked */ 00150 __HAL_UNLOCK(hcryp); 00151 return HAL_ERROR; 00152 } 00153 00154 /* Disable CRYP to start the final phase */ 00155 __HAL_CRYP_DISABLE(hcryp); 00156 00157 /* Select final phase */ 00158 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL); 00159 00160 /*ALGODIR bit must be set to '0'.*/ 00161 hcryp->Instance->CR &= ~CRYP_CR_ALGODIR; 00162 00163 /* Enable the CRYP peripheral */ 00164 __HAL_CRYP_ENABLE(hcryp); 00165 00166 /* Write the number of bits in header (64 bits) followed by the number of bits 00167 in the payload */ 00168 #if !defined (CRYP_VER_2_2) 00169 /* STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/ 00170 if (hcryp->Version >= REV_ID_B) 00171 #endif /*End of not defined CRYP_VER_2_2*/ 00172 { 00173 hcryp->Instance->DIN = 0U; 00174 hcryp->Instance->DIN = (uint32_t)(headerlength); 00175 hcryp->Instance->DIN = 0U; 00176 hcryp->Instance->DIN = (uint32_t)(inputlength); 00177 } 00178 #if !defined (CRYP_VER_2_2) 00179 else/* data has to be swapped according to the DATATYPE */ 00180 { 00181 if (hcryp->Init.DataType == CRYP_DATATYPE_1B) 00182 { 00183 hcryp->Instance->DIN = 0U; 00184 hcryp->Instance->DIN = __RBIT((uint32_t)(headerlength)); 00185 hcryp->Instance->DIN = 0U; 00186 hcryp->Instance->DIN = __RBIT((uint32_t)(inputlength)); 00187 } 00188 else if (hcryp->Init.DataType == CRYP_DATATYPE_8B) 00189 { 00190 hcryp->Instance->DIN = 0U; 00191 hcryp->Instance->DIN = __REV((uint32_t)(headerlength)); 00192 hcryp->Instance->DIN = 0U; 00193 hcryp->Instance->DIN = __REV((uint32_t)(inputlength)); 00194 } 00195 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B) 00196 { 00197 hcryp->Instance->DIN = 0U; 00198 hcryp->Instance->DIN = __ROR((uint32_t)headerlength, 16U); 00199 hcryp->Instance->DIN = 0U; 00200 hcryp->Instance->DIN = __ROR((uint32_t)inputlength, 16U); 00201 } 00202 else if (hcryp->Init.DataType == CRYP_DATATYPE_32B) 00203 { 00204 hcryp->Instance->DIN = 0U; 00205 hcryp->Instance->DIN = (uint32_t)(headerlength); 00206 hcryp->Instance->DIN = 0U; 00207 hcryp->Instance->DIN = (uint32_t)(inputlength); 00208 } 00209 else 00210 { 00211 /* Nothing to do */ 00212 } 00213 } 00214 #endif /*End of not defined CRYP_VER_2_2*/ 00215 /* Wait for OFNE flag to be raised */ 00216 tickstart = HAL_GetTick(); 00217 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) 00218 { 00219 /* Check for the Timeout */ 00220 if (Timeout != HAL_MAX_DELAY) 00221 { 00222 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 00223 { 00224 /* Disable the CRYP Peripheral Clock */ 00225 __HAL_CRYP_DISABLE(hcryp); 00226 00227 /* Change state */ 00228 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 00229 hcryp->State = HAL_CRYP_STATE_READY; 00230 00231 /* Process unlocked */ 00232 __HAL_UNLOCK(hcryp); 00233 return HAL_ERROR; 00234 } 00235 } 00236 } 00237 00238 /* Read the authentication TAG in the output FIFO */ 00239 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT; 00240 tagaddr += 4U; 00241 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT; 00242 tagaddr += 4U; 00243 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT; 00244 tagaddr += 4U; 00245 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT; 00246 00247 /* Disable the peripheral */ 00248 __HAL_CRYP_DISABLE(hcryp); 00249 00250 /* Change the CRYP peripheral state */ 00251 hcryp->State = HAL_CRYP_STATE_READY; 00252 00253 /* Process unlocked */ 00254 __HAL_UNLOCK(hcryp); 00255 } 00256 else 00257 { 00258 /* Busy error code field */ 00259 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 00260 return HAL_ERROR; 00261 } 00262 /* Return function status */ 00263 return HAL_OK; 00264 } 00265 00266 /** 00267 * @brief AES CCM Authentication TAG generation. 00268 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 00269 * the configuration information for CRYP module 00270 * @param AuthTag: Pointer to the authentication buffer 00271 * the AuthTag generated here is 128bits length, if the TAG length is 00272 * less than 128bits, user should consider only the valid part of AuthTag 00273 * buffer which correspond exactly to TAG length. 00274 * @param Timeout: Timeout duration 00275 * @retval HAL status 00276 */ 00277 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout) 00278 { 00279 uint32_t tagaddr = (uint32_t)AuthTag; 00280 uint32_t ctr0 [4] = {0}; 00281 uint32_t ctr0addr = (uint32_t)ctr0; 00282 uint32_t tickstart; 00283 00284 if (hcryp->State == HAL_CRYP_STATE_READY) 00285 { 00286 /* Process locked */ 00287 __HAL_LOCK(hcryp); 00288 00289 /* Change the CRYP peripheral state */ 00290 hcryp->State = HAL_CRYP_STATE_BUSY; 00291 00292 /* Check if initialization phase has already been performed */ 00293 if (hcryp->Phase == CRYPEx_PHASE_PROCESS) 00294 { 00295 /* Change the CRYP phase */ 00296 hcryp->Phase = CRYPEx_PHASE_FINAL; 00297 } 00298 else /* Initialization phase has not been performed*/ 00299 { 00300 /* Disable the peripheral */ 00301 __HAL_CRYP_DISABLE(hcryp); 00302 00303 /* Sequence error code field */ 00304 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE; 00305 00306 /* Change the CRYP peripheral state */ 00307 hcryp->State = HAL_CRYP_STATE_READY; 00308 00309 /* Process unlocked */ 00310 __HAL_UNLOCK(hcryp); 00311 return HAL_ERROR; 00312 } 00313 00314 /* Disable CRYP to start the final phase */ 00315 __HAL_CRYP_DISABLE(hcryp); 00316 00317 /* Select final phase & ALGODIR bit must be set to '0'. */ 00318 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH | CRYP_CR_ALGODIR, CRYP_PHASE_FINAL | CRYP_OPERATINGMODE_ENCRYPT); 00319 00320 /* Enable the CRYP peripheral */ 00321 __HAL_CRYP_ENABLE(hcryp); 00322 00323 /* Write the counter block in the IN FIFO, CTR0 information from B0 00324 data has to be swapped according to the DATATYPE*/ 00325 ctr0[0] = (hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0; 00326 ctr0[1] = hcryp->Init.B0[1]; 00327 ctr0[2] = hcryp->Init.B0[2]; 00328 ctr0[3] = hcryp->Init.B0[3] & CRYP_CCM_CTR0_3; 00329 00330 #if !defined (CRYP_VER_2_2) 00331 /*STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/ 00332 if (hcryp->Version >= REV_ID_B) 00333 #endif /*End of not defined CRYP_VER_2_2*/ 00334 { 00335 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr); 00336 ctr0addr += 4U; 00337 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr); 00338 ctr0addr += 4U; 00339 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr); 00340 ctr0addr += 4U; 00341 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr); 00342 } 00343 #if !defined (CRYP_VER_2_2) 00344 else /* data has to be swapped according to the DATATYPE */ 00345 { 00346 if (hcryp->Init.DataType == CRYP_DATATYPE_8B) 00347 { 00348 hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr)); 00349 ctr0addr += 4U; 00350 hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr)); 00351 ctr0addr += 4U; 00352 hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr)); 00353 ctr0addr += 4U; 00354 hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr)); 00355 } 00356 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B) 00357 { 00358 hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U); 00359 ctr0addr += 4U; 00360 hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U); 00361 ctr0addr += 4U; 00362 hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U); 00363 ctr0addr += 4U; 00364 hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U); 00365 } 00366 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B) 00367 { 00368 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr)); 00369 ctr0addr += 4U; 00370 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr)); 00371 ctr0addr += 4U; 00372 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr)); 00373 ctr0addr += 4U; 00374 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr)); 00375 } 00376 else 00377 { 00378 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr); 00379 ctr0addr += 4U; 00380 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr); 00381 ctr0addr += 4U; 00382 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr); 00383 ctr0addr += 4U; 00384 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr); 00385 } 00386 } 00387 #endif /*End of not defined CRYP_VER_2_2*/ 00388 /* Wait for OFNE flag to be raised */ 00389 tickstart = HAL_GetTick(); 00390 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) 00391 { 00392 /* Check for the Timeout */ 00393 if (Timeout != HAL_MAX_DELAY) 00394 { 00395 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 00396 { 00397 /* Disable the CRYP peripheral Clock */ 00398 __HAL_CRYP_DISABLE(hcryp); 00399 00400 /* Change state */ 00401 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 00402 hcryp->State = HAL_CRYP_STATE_READY; 00403 00404 /* Process unlocked */ 00405 __HAL_UNLOCK(hcryp); 00406 return HAL_ERROR; 00407 } 00408 } 00409 } 00410 00411 /* Read the Auth TAG in the IN FIFO */ 00412 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT; 00413 tagaddr += 4U; 00414 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT; 00415 tagaddr += 4U; 00416 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT; 00417 tagaddr += 4U; 00418 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT; 00419 00420 /* Change the CRYP peripheral state */ 00421 hcryp->State = HAL_CRYP_STATE_READY; 00422 00423 /* Process unlocked */ 00424 __HAL_UNLOCK(hcryp); 00425 00426 /* Disable CRYP */ 00427 __HAL_CRYP_DISABLE(hcryp); 00428 } 00429 else 00430 { 00431 /* Busy error code field */ 00432 hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY; 00433 return HAL_ERROR; 00434 } 00435 /* Return function status */ 00436 return HAL_OK; 00437 } 00438 00439 /** 00440 * @} 00441 */ 00442 00443 00444 #endif /* HAL_CRYP_MODULE_ENABLED */ 00445 00446 /** 00447 * @} 00448 */ 00449 #endif /* CRYP */ 00450 /** 00451 * @} 00452 */ 00453 00454 /** 00455 * @} 00456 */