STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_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) 2017 STMicroelectronics. 00013 * All rights reserved. 00014 * 00015 * This software is licensed under terms that can be found in the LICENSE file in 00016 * the root directory of this software component. 00017 * If no LICENSE file comes with this software, it is provided AS-IS. 00018 ****************************************************************************** 00019 */ 00020 00021 /* Includes ------------------------------------------------------------------*/ 00022 #include "stm32l4xx_hal.h" 00023 00024 #ifdef HAL_CRYP_MODULE_ENABLED 00025 00026 #if defined(AES) 00027 00028 /** @addtogroup STM32L4xx_HAL_Driver 00029 * @{ 00030 */ 00031 00032 /** @defgroup CRYPEx CRYPEx 00033 * @brief CRYP Extended HAL module driver 00034 * @{ 00035 */ 00036 00037 /* Private typedef -----------------------------------------------------------*/ 00038 /* Private define ------------------------------------------------------------*/ 00039 /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants 00040 * @{ 00041 */ 00042 #define CRYP_CCF_TIMEOUTVALUE 22000 /*!< CCF flag raising time-out value */ 00043 #define CRYP_BUSY_TIMEOUTVALUE 22000 /*!< BUSY flag reset time-out value */ 00044 00045 #define CRYP_POLLING_OFF 0x0 /*!< No polling when padding */ 00046 #define CRYP_POLLING_ON 0x1 /*!< Polling when padding */ 00047 00048 #if defined(AES_CR_NPBLB) 00049 #define AES_POSITION_CR_NPBLB (uint32_t)POSITION_VAL(AES_CR_NPBLB) /*!< Required left shift to set background CLUT size */ 00050 #endif 00051 /** 00052 * @} 00053 */ 00054 00055 /* Private macro -------------------------------------------------------------*/ 00056 /* Private variables ---------------------------------------------------------*/ 00057 /* Private function prototypes -----------------------------------------------*/ 00058 /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions 00059 * @{ 00060 */ 00061 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout); 00062 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout); 00063 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr); 00064 static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr); 00065 static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma); 00066 static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma); 00067 static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma); 00068 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout); 00069 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout); 00070 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma); 00071 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma); 00072 static void CRYP_DMAError(DMA_HandleTypeDef *hdma); 00073 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling); 00074 /** 00075 * @} 00076 */ 00077 00078 /* Exported functions ---------------------------------------------------------*/ 00079 00080 /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions 00081 * @{ 00082 */ 00083 00084 00085 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function 00086 * @brief Extended callback functions. 00087 * 00088 @verbatim 00089 =============================================================================== 00090 ##### Extended callback functions ##### 00091 =============================================================================== 00092 [..] This section provides callback function: 00093 (+) Computation completed. 00094 00095 @endverbatim 00096 * @{ 00097 */ 00098 00099 00100 /** 00101 * @brief Computation completed callbacks. 00102 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00103 * the configuration information for CRYP module 00104 * @retval None 00105 */ 00106 __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp) 00107 { 00108 /* Prevent unused argument(s) compilation warning */ 00109 UNUSED(hcryp); 00110 00111 /* NOTE : This function should not be modified; when the callback is needed, 00112 the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file 00113 */ 00114 } 00115 00116 /** 00117 * @} 00118 */ 00119 00120 /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions 00121 * @brief Extended processing functions. 00122 * 00123 @verbatim 00124 ============================================================================== 00125 ##### AES extended processing functions ##### 00126 ============================================================================== 00127 [..] This section provides functions allowing to: 00128 (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes. 00129 Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated 00130 based on the processing type. Three processing types are available: 00131 (++) Polling mode 00132 (++) Interrupt mode 00133 (++) DMA mode 00134 (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES 00135 algorithm in different chaining modes. 00136 Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase 00137 so that steps can be skipped if so required. Functions are only differentiated based on the processing type. 00138 Three processing types are available: 00139 (++) Polling mode 00140 (++) Interrupt mode 00141 (++) DMA mode 00142 00143 @endverbatim 00144 * @{ 00145 */ 00146 00147 /** 00148 * @brief Carry out in polling mode the ciphering or deciphering operation according to 00149 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and 00150 * chaining modes ECB, CBC and CTR are managed by this function in polling mode. 00151 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00152 * the configuration information for CRYP module 00153 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption 00154 * or key derivation+decryption. 00155 * Parameter is meaningless in case of key derivation. 00156 * @param Size Length of the input data buffer in bytes, must be a multiple of 16. 00157 * Parameter is meaningless in case of key derivation. 00158 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of 00159 * decryption/key derivation+decryption, or pointer to the derivative keys in 00160 * case of key derivation only. 00161 * @param Timeout Specify Timeout value 00162 * @retval HAL status 00163 */ 00164 HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout) 00165 { 00166 00167 if (hcryp->State == HAL_CRYP_STATE_READY) 00168 { 00169 /* Check parameters setting */ 00170 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION) 00171 { 00172 if (pOutputData == NULL) 00173 { 00174 return HAL_ERROR; 00175 } 00176 } 00177 else 00178 { 00179 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U)) 00180 { 00181 return HAL_ERROR; 00182 } 00183 } 00184 00185 /* Process Locked */ 00186 __HAL_LOCK(hcryp); 00187 00188 /* Change the CRYP state */ 00189 hcryp->State = HAL_CRYP_STATE_BUSY; 00190 00191 /* Call CRYP_ReadKey() API if the operating mode is set to 00192 key derivation, CRYP_ProcessData() otherwise */ 00193 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION) 00194 { 00195 if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK) 00196 { 00197 return HAL_TIMEOUT; 00198 } 00199 } 00200 else 00201 { 00202 if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK) 00203 { 00204 return HAL_TIMEOUT; 00205 } 00206 } 00207 00208 /* If the state has not been set to SUSPENDED, set it to 00209 READY, otherwise keep it as it is */ 00210 if (hcryp->State != HAL_CRYP_STATE_SUSPENDED) 00211 { 00212 hcryp->State = HAL_CRYP_STATE_READY; 00213 } 00214 00215 /* Process Unlocked */ 00216 __HAL_UNLOCK(hcryp); 00217 00218 return HAL_OK; 00219 } 00220 else 00221 { 00222 return HAL_BUSY; 00223 } 00224 } 00225 00226 00227 00228 /** 00229 * @brief Carry out in interrupt mode the ciphering or deciphering operation according to 00230 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and 00231 * chaining modes ECB, CBC and CTR are managed by this function in interrupt mode. 00232 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00233 * the configuration information for CRYP module 00234 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption 00235 * or key derivation+decryption. 00236 * Parameter is meaningless in case of key derivation. 00237 * @param Size Length of the input data buffer in bytes, must be a multiple of 16. 00238 * Parameter is meaningless in case of key derivation. 00239 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of 00240 * decryption/key derivation+decryption, or pointer to the derivative keys in 00241 * case of key derivation only. 00242 * @retval HAL status 00243 */ 00244 HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData) 00245 { 00246 uint32_t inputaddr; 00247 00248 if(hcryp->State == HAL_CRYP_STATE_READY) 00249 { 00250 /* Check parameters setting */ 00251 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION) 00252 { 00253 if (pOutputData == NULL) 00254 { 00255 return HAL_ERROR; 00256 } 00257 } 00258 else 00259 { 00260 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U)) 00261 { 00262 return HAL_ERROR; 00263 } 00264 } 00265 /* Process Locked */ 00266 __HAL_LOCK(hcryp); 00267 00268 /* If operating mode is not limited to key derivation only, 00269 get the buffers addresses and sizes */ 00270 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION) 00271 { 00272 00273 hcryp->CrypInCount = Size; 00274 hcryp->pCrypInBuffPtr = pInputData; 00275 hcryp->pCrypOutBuffPtr = pOutputData; 00276 hcryp->CrypOutCount = Size; 00277 } 00278 else 00279 { 00280 /* For key derivation, set output buffer only 00281 (will point at derivated key) */ 00282 hcryp->pCrypOutBuffPtr = pOutputData; 00283 } 00284 00285 /* Change the CRYP state */ 00286 hcryp->State = HAL_CRYP_STATE_BUSY; 00287 00288 /* Process Unlocked */ 00289 __HAL_UNLOCK(hcryp); 00290 00291 /* Enable Computation Complete Flag and Error Interrupts */ 00292 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE); 00293 00294 00295 /* If operating mode is key derivation only, the input data have 00296 already been entered during the initialization process. For 00297 the other operating modes, they are fed to the CRYP hardware 00298 block at this point. */ 00299 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION) 00300 { 00301 /* Initiate the processing under interrupt in entering 00302 the first input data */ 00303 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 00304 /* Increment/decrement instance pointer/counter */ 00305 hcryp->pCrypInBuffPtr += 16; 00306 hcryp->CrypInCount -= 16U; 00307 /* Write the first input block in the Data Input register */ 00308 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00309 inputaddr+=4U; 00310 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00311 inputaddr+=4U; 00312 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00313 inputaddr+=4U; 00314 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00315 } 00316 00317 /* Return function status */ 00318 return HAL_OK; 00319 } 00320 else 00321 { 00322 return HAL_BUSY; 00323 } 00324 } 00325 00326 00327 00328 00329 00330 /** 00331 * @brief Carry out in DMA mode the ciphering or deciphering operation according to 00332 * hcryp->Init structure fields. 00333 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00334 * the configuration information for CRYP module 00335 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption 00336 * or key derivation+decryption. 00337 * @param Size Length of the input data buffer in bytes, must be a multiple of 16. 00338 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of 00339 * decryption/key derivation+decryption. 00340 * @note Chaining modes ECB, CBC and CTR are managed by this function in DMA mode. 00341 * @note Supported operating modes are encryption, decryption and key derivation with decryption. 00342 * @note No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx 00343 * registers must be done by software. 00344 * @note This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx 00345 * registers must be done by software thru HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs. 00346 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP. 00347 * @retval HAL status 00348 */ 00349 HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData) 00350 { 00351 uint32_t inputaddr; 00352 uint32_t outputaddr; 00353 00354 if (hcryp->State == HAL_CRYP_STATE_READY) 00355 { 00356 /* Check parameters setting */ 00357 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION) 00358 { 00359 /* no DMA channel is provided for key derivation operating mode, 00360 access to AES_KEYRx registers must be done by software */ 00361 return HAL_ERROR; 00362 } 00363 else 00364 { 00365 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U)) 00366 { 00367 return HAL_ERROR; 00368 } 00369 } 00370 00371 00372 /* Process Locked */ 00373 __HAL_LOCK(hcryp); 00374 00375 inputaddr = (uint32_t)pInputData; 00376 outputaddr = (uint32_t)pOutputData; 00377 00378 /* Change the CRYP state */ 00379 hcryp->State = HAL_CRYP_STATE_BUSY; 00380 00381 /* Set the input and output addresses and start DMA transfer */ 00382 CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); 00383 00384 /* Process Unlocked */ 00385 __HAL_UNLOCK(hcryp); 00386 00387 /* Return function status */ 00388 return HAL_OK; 00389 } 00390 else 00391 { 00392 return HAL_BUSY; 00393 } 00394 } 00395 00396 00397 00398 00399 00400 00401 /** 00402 * @brief Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering 00403 * operation according to hcryp->Init structure fields. 00404 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00405 * the configuration information for CRYP module 00406 * @param pInputData 00407 * - pointer to payload data in GCM or CCM payload phase, 00408 * - pointer to B0 block in CMAC header phase, 00409 * - pointer to C block in CMAC final phase. 00410 * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases. 00411 * @param Size 00412 * - length of the input payload data buffer in bytes in GCM or CCM payload phase, 00413 * - length of B0 block (in bytes) in CMAC header phase, 00414 * - length of C block (in bytes) in CMAC final phase. 00415 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases. 00416 * - Parameter is meaningless in case of CCM final phase. 00417 * - Parameter is message length in bytes in case of GCM final phase. 00418 * - Parameter must be set to zero in case of GMAC final phase. 00419 * @param pOutputData 00420 * - pointer to plain or cipher text in GCM/CCM payload phase, 00421 * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase. 00422 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases. 00423 * - Parameter is meaningless in case of CMAC header phase. 00424 * @param Timeout Specify Timeout value 00425 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable. 00426 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes 00427 * can be skipped by the user if so required. 00428 * @retval HAL status 00429 */ 00430 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout) 00431 { 00432 uint32_t index ; 00433 uint32_t inputaddr ; 00434 uint32_t outputaddr ; 00435 uint32_t tagaddr ; 00436 uint64_t headerlength ; 00437 uint64_t inputlength ; 00438 uint64_t payloadlength ; 00439 uint32_t difflength = 0; 00440 uint32_t addhoc_process = 0; 00441 00442 if (hcryp->State == HAL_CRYP_STATE_READY) 00443 { 00444 /* input/output parameters check */ 00445 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 00446 { 00447 /* No processing required */ 00448 } 00449 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 00450 { 00451 if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) || 00452 ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U))) 00453 { 00454 return HAL_ERROR; 00455 } 00456 #if defined(AES_CR_NPBLB) 00457 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM) 00458 #else 00459 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 00460 #endif 00461 { 00462 /* In case of CMAC or CCM (when applicable) header phase resumption, we can have pInputData = NULL and Size = 0 */ 00463 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U))) 00464 { 00465 return HAL_ERROR; 00466 } 00467 } 00468 } 00469 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 00470 { 00471 if (((pInputData == NULL) && (Size != 0U)) || \ 00472 ((pInputData != NULL) && (Size == 0U)) || \ 00473 ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))) 00474 { 00475 return HAL_ERROR; 00476 } 00477 } 00478 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 00479 { 00480 if (pOutputData == NULL) 00481 { 00482 return HAL_ERROR; 00483 } 00484 #if !defined(AES_CR_NPBLB) 00485 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL)) 00486 { 00487 return HAL_ERROR; 00488 } 00489 #endif 00490 } 00491 else 00492 { 00493 /* Unspecified Phase */ 00494 return HAL_ERROR; 00495 } 00496 00497 00498 /* Process Locked */ 00499 __HAL_LOCK(hcryp); 00500 00501 /* Change the CRYP state */ 00502 hcryp->State = HAL_CRYP_STATE_BUSY; 00503 00504 /*==============================================*/ 00505 /* GCM/GMAC (or CCM when applicable) init phase */ 00506 /*==============================================*/ 00507 /* In case of init phase, the input data (Key and Initialization Vector) have 00508 already been entered during the initialization process. Therefore, the 00509 API just waits for the CCF flag to be set. */ 00510 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 00511 { 00512 /* just wait for hash computation */ 00513 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 00514 { 00515 hcryp->State = HAL_CRYP_STATE_READY; 00516 __HAL_UNLOCK(hcryp); 00517 return HAL_TIMEOUT; 00518 } 00519 00520 /* Clear CCF Flag */ 00521 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 00522 /* Mark that the initialization phase is over */ 00523 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER; 00524 } 00525 /*=======================================================*/ 00526 /* GCM/GMAC or (CCM / CMAC when applicable) header phase */ 00527 /*=======================================================*/ 00528 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 00529 { 00530 #if !defined(AES_CR_NPBLB) 00531 /* Set header phase; for GCM or GMAC, set data-byte at this point */ 00532 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 00533 { 00534 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType); 00535 } 00536 else 00537 #endif 00538 { 00539 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE); 00540 } 00541 00542 /* Enable the Peripheral */ 00543 __HAL_CRYP_ENABLE(hcryp); 00544 00545 #if !defined(AES_CR_NPBLB) 00546 /* in case of CMAC, enter B0 block in header phase, before the header itself. */ 00547 /* If Size = 0 (possible case of resumption after CMAC header phase suspension), 00548 skip these steps and go directly to header buffer feeding to the HW */ 00549 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U)) 00550 { 00551 uint64_t index_test; 00552 inputaddr = (uint32_t)pInputData; 00553 00554 for(index=0U ; (index < Size); index += 16U) 00555 { 00556 /* Write the Input block in the Data Input register */ 00557 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00558 inputaddr+=4U; 00559 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00560 inputaddr+=4U; 00561 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00562 inputaddr+=4U; 00563 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00564 inputaddr+=4U; 00565 00566 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 00567 { 00568 hcryp->State = HAL_CRYP_STATE_READY; 00569 __HAL_UNLOCK(hcryp); 00570 return HAL_TIMEOUT; 00571 } 00572 /* Clear CCF Flag */ 00573 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 00574 00575 /* If the suspension flag has been raised and if the processing is not about 00576 to end, suspend processing */ 00577 index_test = (uint64_t)index + 16U; 00578 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_test < Size)) 00579 { 00580 /* reset SuspendRequest */ 00581 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 00582 /* Change the CRYP state */ 00583 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 00584 /* Mark that the header phase is over */ 00585 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED; 00586 00587 /* Save current reading and writing locations of Input and Output buffers */ 00588 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 00589 /* Save the total number of bytes (B blocks + header) that remain to be 00590 processed at this point */ 00591 hcryp->CrypInCount = (uint32_t) (hcryp->Init.HeaderSize + Size - index_test); 00592 00593 /* Process Unlocked */ 00594 __HAL_UNLOCK(hcryp); 00595 00596 return HAL_OK; 00597 } 00598 } /* for(index=0; (index < Size); index += 16) */ 00599 } 00600 #endif /* !defined(AES_CR_NPBLB) */ 00601 00602 /* Enter header */ 00603 inputaddr = (uint32_t)hcryp->Init.Header; 00604 /* Local variable headerlength is a number of bytes multiple of 128 bits, 00605 remaining header data (if any) are handled after this loop */ 00606 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ; 00607 if ((hcryp->Init.HeaderSize % 16U) != 0U) 00608 { 00609 difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength); 00610 } 00611 for(index=0U ; index < headerlength; index += 16U) 00612 { 00613 uint64_t index_temp; 00614 /* Write the Input block in the Data Input register */ 00615 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00616 inputaddr+=4U; 00617 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00618 inputaddr+=4U; 00619 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00620 inputaddr+=4U; 00621 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00622 inputaddr+=4U; 00623 00624 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 00625 { 00626 hcryp->State = HAL_CRYP_STATE_READY; 00627 __HAL_UNLOCK(hcryp); 00628 return HAL_TIMEOUT; 00629 } 00630 /* Clear CCF Flag */ 00631 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 00632 00633 /* If the suspension flag has been raised and if the processing is not about 00634 to end, suspend processing */ 00635 index_temp = (uint64_t)index + 16U; 00636 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < headerlength)) 00637 { 00638 /* reset SuspendRequest */ 00639 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 00640 /* Change the CRYP state */ 00641 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 00642 /* Mark that the header phase is over */ 00643 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED; 00644 00645 /* Save current reading and writing locations of Input and Output buffers */ 00646 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 00647 /* Save the total number of bytes that remain to be processed at this point */ 00648 hcryp->CrypInCount = (uint32_t) (hcryp->Init.HeaderSize - index_temp); 00649 00650 /* Process Unlocked */ 00651 __HAL_UNLOCK(hcryp); 00652 00653 return HAL_OK; 00654 } 00655 } 00656 00657 /* Case header length is not a multiple of 16 bytes */ 00658 if (difflength != 0U) 00659 { 00660 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 00661 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON); 00662 } 00663 00664 /* Mark that the header phase is over */ 00665 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 00666 } 00667 /*============================================*/ 00668 /* GCM (or CCM when applicable) payload phase */ 00669 /*============================================*/ 00670 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 00671 { 00672 00673 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE); 00674 00675 /* if the header phase has been bypassed, AES must be enabled again */ 00676 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 00677 { 00678 __HAL_CRYP_ENABLE(hcryp); 00679 } 00680 00681 inputaddr = (uint32_t)pInputData; 00682 outputaddr = (uint32_t)pOutputData; 00683 00684 /* Enter payload */ 00685 /* Specific handling to manage payload last block size less than 128 bits */ 00686 if ((Size % 16U) != 0U) 00687 { 00688 payloadlength = (Size/16U) * 16U; 00689 difflength = (uint32_t) (Size - payloadlength); 00690 addhoc_process = 1; 00691 } 00692 else 00693 { 00694 payloadlength = Size; 00695 } 00696 00697 /* Feed payload */ 00698 for(index=0U ; index < payloadlength; index += 16U) 00699 { 00700 uint64_t index_temp; 00701 /* Write the Input block in the Data Input register */ 00702 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00703 inputaddr+=4U; 00704 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00705 inputaddr+=4U; 00706 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00707 inputaddr+=4U; 00708 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00709 inputaddr+=4U; 00710 00711 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 00712 { 00713 hcryp->State = HAL_CRYP_STATE_READY; 00714 __HAL_UNLOCK(hcryp); 00715 return HAL_TIMEOUT; 00716 } 00717 00718 /* Clear CCF Flag */ 00719 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 00720 00721 /* Retrieve output data: read the output block 00722 from the Data Output Register */ 00723 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 00724 outputaddr+=4U; 00725 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 00726 outputaddr+=4U; 00727 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 00728 outputaddr+=4U; 00729 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 00730 outputaddr+=4U; 00731 00732 /* If the suspension flag has been raised and if the processing is not about 00733 to end, suspend processing */ 00734 index_temp = (uint64_t)index + 16U; 00735 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < payloadlength)) 00736 { 00737 /* no flag waiting under IRQ handling */ 00738 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 00739 { 00740 /* Ensure that Busy flag is reset */ 00741 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK) 00742 { 00743 hcryp->State = HAL_CRYP_STATE_READY; 00744 __HAL_UNLOCK(hcryp); 00745 return HAL_TIMEOUT; 00746 } 00747 } 00748 /* reset SuspendRequest */ 00749 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 00750 /* Change the CRYP state */ 00751 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 00752 /* Mark that the header phase is over */ 00753 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED; 00754 00755 /* Save current reading and writing locations of Input and Output buffers */ 00756 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr; 00757 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 00758 /* Save the number of bytes that remain to be processed at this point */ 00759 hcryp->CrypInCount = (uint32_t) (Size - index_temp); 00760 00761 /* Process Unlocked */ 00762 __HAL_UNLOCK(hcryp); 00763 00764 return HAL_OK; 00765 } 00766 00767 } 00768 00769 /* Additional processing to manage GCM(/CCM) encryption and decryption cases when 00770 payload last block size less than 128 bits */ 00771 if (addhoc_process == 1U) 00772 { 00773 00774 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 00775 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr; 00776 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON); 00777 00778 } /* (addhoc_process == 1) */ 00779 00780 /* Mark that the payload phase is over */ 00781 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 00782 } 00783 /*==================================*/ 00784 /* GCM/GMAC/CCM or CMAC final phase */ 00785 /*==================================*/ 00786 else 00787 { 00788 tagaddr = (uint32_t)pOutputData; 00789 00790 #if defined(AES_CR_NPBLB) 00791 /* By default, clear NPBLB field */ 00792 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB); 00793 #endif 00794 00795 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE); 00796 00797 /* if the header and payload phases have been bypassed, AES must be enabled again */ 00798 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 00799 { 00800 __HAL_CRYP_ENABLE(hcryp); 00801 } 00802 00803 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 00804 { 00805 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */ 00806 inputlength = Size * 8U; /* input length in bits */ 00807 00808 #if !defined(AES_CR_NPBLB) 00809 if(hcryp->Init.DataType == CRYP_DATATYPE_1B) 00810 { 00811 hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32)); 00812 hcryp->Instance->DINR = __RBIT((uint32_t)headerlength); 00813 hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32)); 00814 hcryp->Instance->DINR = __RBIT((uint32_t)inputlength); 00815 } 00816 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B) 00817 { 00818 hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32)); 00819 hcryp->Instance->DINR = __REV((uint32_t)headerlength); 00820 hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32)); 00821 hcryp->Instance->DINR = __REV((uint32_t)inputlength); 00822 } 00823 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B) 00824 { 00825 hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16); 00826 hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16); 00827 hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16); 00828 hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16); 00829 } 00830 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B) 00831 { 00832 hcryp->Instance->DINR = (uint32_t)(headerlength>>32); 00833 hcryp->Instance->DINR = (uint32_t)(headerlength); 00834 hcryp->Instance->DINR = (uint32_t)(inputlength>>32); 00835 hcryp->Instance->DINR = (uint32_t)(inputlength); 00836 } 00837 else 00838 { 00839 /* Unspecified Data Type */ 00840 return HAL_ERROR; 00841 } 00842 #else 00843 hcryp->Instance->DINR = (uint32_t)(headerlength>>32); 00844 hcryp->Instance->DINR = (uint32_t)(headerlength); 00845 hcryp->Instance->DINR = (uint32_t)(inputlength>>32); 00846 hcryp->Instance->DINR = (uint32_t)(inputlength); 00847 #endif 00848 } 00849 #if !defined(AES_CR_NPBLB) 00850 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 00851 { 00852 inputaddr = (uint32_t)pInputData; 00853 /* Enter the last block made of a 128-bit value formatted 00854 from the original B0 packet. */ 00855 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00856 inputaddr+=4U; 00857 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00858 inputaddr+=4U; 00859 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00860 inputaddr+=4U; 00861 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 00862 } 00863 else 00864 { 00865 /* Unspecified Chaining Mode */ 00866 return HAL_ERROR; 00867 } 00868 #endif 00869 00870 00871 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 00872 { 00873 hcryp->State = HAL_CRYP_STATE_READY; 00874 __HAL_UNLOCK(hcryp); 00875 return HAL_TIMEOUT; 00876 } 00877 00878 /* Read the Auth TAG in the Data Out register */ 00879 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 00880 tagaddr+=4U; 00881 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 00882 tagaddr+=4U; 00883 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 00884 tagaddr+=4U; 00885 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 00886 00887 00888 /* Clear CCF Flag */ 00889 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 00890 /* Mark that the final phase is over */ 00891 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER; 00892 /* Disable the Peripheral */ 00893 __HAL_CRYP_DISABLE(hcryp); 00894 } 00895 00896 /* Change the CRYP state */ 00897 hcryp->State = HAL_CRYP_STATE_READY; 00898 00899 /* Process Unlocked */ 00900 __HAL_UNLOCK(hcryp); 00901 00902 return HAL_OK; 00903 } 00904 else 00905 { 00906 return HAL_BUSY; 00907 } 00908 } 00909 00910 00911 00912 00913 /** 00914 * @brief Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering 00915 * operation according to hcryp->Init structure fields. 00916 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00917 * the configuration information for CRYP module 00918 * @param pInputData 00919 * - pointer to payload data in GCM or CCM payload phase, 00920 * - pointer to B0 block in CMAC header phase, 00921 * - pointer to C block in CMAC final phase. 00922 * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases. 00923 * @param Size 00924 * - length of the input payload data buffer in bytes in GCM or CCM payload phase, 00925 * - length of B0 block (in bytes) in CMAC header phase, 00926 * - length of C block (in bytes) in CMAC final phase. 00927 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases. 00928 * - Parameter is meaningless in case of CCM final phase. 00929 * - Parameter is message length in bytes in case of GCM final phase. 00930 * - Parameter must be set to zero in case of GMAC final phase. 00931 * @param pOutputData 00932 * - pointer to plain or cipher text in GCM/CCM payload phase, 00933 * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase. 00934 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases. 00935 * - Parameter is meaningless in case of CMAC header phase. 00936 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC. 00937 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes 00938 * can be skipped by the user if so required. 00939 * @retval HAL status 00940 */ 00941 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData) 00942 { 00943 00944 uint32_t inputaddr ; 00945 uint64_t headerlength ; 00946 uint64_t inputlength ; 00947 uint32_t index ; 00948 uint32_t addhoc_process = 0; 00949 uint32_t difflength = 0; 00950 uint32_t difflengthmod4 = 0; 00951 uint32_t mask[4][3]; 00952 00953 uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos; 00954 00955 mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */ 00956 mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */ 00957 mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */ 00958 mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */ 00959 00960 if (hcryp->State == HAL_CRYP_STATE_READY) 00961 { 00962 /* input/output parameters check */ 00963 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 00964 { 00965 /* No processing required */ 00966 } 00967 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 00968 { 00969 if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) || 00970 ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U))) 00971 { 00972 return HAL_ERROR; 00973 } 00974 #if defined(AES_CR_NPBLB) 00975 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM) 00976 #else 00977 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 00978 #endif 00979 { 00980 /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and Size = 0 */ 00981 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U))) 00982 { 00983 return HAL_ERROR; 00984 } 00985 } 00986 } 00987 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 00988 { 00989 if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL)) 00990 { 00991 return HAL_ERROR; 00992 } 00993 } 00994 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 00995 { 00996 if (pOutputData == NULL) 00997 { 00998 return HAL_ERROR; 00999 } 01000 #if !defined(AES_CR_NPBLB) 01001 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL)) 01002 { 01003 return HAL_ERROR; 01004 } 01005 #endif 01006 } 01007 else 01008 { 01009 /* Unspecified Phase */ 01010 return HAL_ERROR; 01011 } 01012 01013 01014 /* Process Locked */ 01015 __HAL_LOCK(hcryp); 01016 01017 /* Change the CRYP state */ 01018 hcryp->State = HAL_CRYP_STATE_BUSY; 01019 01020 /* Process Unlocked */ 01021 __HAL_UNLOCK(hcryp); 01022 01023 /* Enable Computation Complete Flag and Error Interrupts */ 01024 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE); 01025 01026 01027 01028 /*==============================================*/ 01029 /* GCM/GMAC (or CCM when applicable) init phase */ 01030 /*==============================================*/ 01031 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 01032 { 01033 /* In case of init phase, the input data (Key and Initialization Vector) have 01034 already been entered during the initialization process. Therefore, the 01035 software just waits for the CCF interrupt to be raised and which will 01036 be handled by CRYP_AES_Auth_IT() API. */ 01037 } 01038 /*===================================*/ 01039 /* GCM/GMAC/CCM or CMAC header phase */ 01040 /*===================================*/ 01041 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 01042 { 01043 01044 #if defined(AES_CR_NPBLB) 01045 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM) 01046 #else 01047 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 01048 #endif 01049 { 01050 /* In case of CMAC, B blocks are first entered, before the header. 01051 Therefore, B blocks and the header are entered back-to-back 01052 as if it was only one single block. 01053 However, in case of resumption after suspension, if all the 01054 B blocks have been entered (in that case, Size = 0), only the 01055 remainder of the non-processed header bytes are entered. */ 01056 if (Size != 0U) 01057 { 01058 hcryp->CrypInCount = (uint32_t)(Size + hcryp->Init.HeaderSize); 01059 hcryp->pCrypInBuffPtr = pInputData; 01060 } 01061 else 01062 { 01063 hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize; 01064 hcryp->pCrypInBuffPtr = hcryp->Init.Header; 01065 } 01066 } 01067 else 01068 { 01069 /* Get the header addresses and sizes */ 01070 hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize; 01071 hcryp->pCrypInBuffPtr = hcryp->Init.Header; 01072 } 01073 01074 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 01075 01076 01077 #if !defined(AES_CR_NPBLB) 01078 /* Set header phase; for GCM or GMAC, set data-byte at this point */ 01079 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 01080 { 01081 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType); 01082 } 01083 else 01084 #endif 01085 { 01086 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE); 01087 } 01088 01089 /* Enable the Peripheral */ 01090 __HAL_CRYP_ENABLE(hcryp); 01091 01092 /* Increment/decrement instance pointer/counter */ 01093 if (hcryp->CrypInCount == 0U) 01094 { 01095 /* Case of no header */ 01096 hcryp->State = HAL_CRYP_STATE_READY; 01097 /* Mark that the header phase is over */ 01098 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 01099 return HAL_OK; 01100 } 01101 else if (hcryp->CrypInCount < 16U) 01102 { 01103 hcryp->CrypInCount = 0; 01104 addhoc_process = 1; 01105 difflength = (uint32_t) (hcryp->Init.HeaderSize); 01106 difflengthmod4 = difflength%4U; 01107 } 01108 else 01109 { 01110 hcryp->pCrypInBuffPtr += 16; 01111 hcryp->CrypInCount -= 16U; 01112 } 01113 01114 01115 #if defined(AES_CR_NPBLB) 01116 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM) 01117 #else 01118 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 01119 #endif 01120 { 01121 if (hcryp->CrypInCount == hcryp->Init.HeaderSize) 01122 { 01123 /* All B blocks will have been entered after the next 01124 four DINR writing, so point at header buffer for 01125 the next iteration */ 01126 hcryp->pCrypInBuffPtr = hcryp->Init.Header; 01127 } 01128 } 01129 01130 /* Enter header first block to initiate the process 01131 in the Data Input register */ 01132 if (addhoc_process == 0U) 01133 { 01134 /* Header has size equal or larger than 128 bits */ 01135 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01136 inputaddr+=4U; 01137 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01138 inputaddr+=4U; 01139 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01140 inputaddr+=4U; 01141 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01142 } 01143 else 01144 { 01145 /* Header has size less than 128 bits */ 01146 /* Enter complete words when possible */ 01147 for(index=0U ; index < (difflength/4U); index ++) 01148 { 01149 /* Write the Input block in the Data Input register */ 01150 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01151 inputaddr+=4U; 01152 } 01153 /* Enter incomplete word padded with zeroes if applicable 01154 (case of header length not a multiple of 32-bits) */ 01155 if (difflengthmod4 != 0U) 01156 { 01157 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]); 01158 } 01159 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */ 01160 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 01161 { 01162 hcryp->Instance->DINR = 0; 01163 } 01164 01165 } 01166 } 01167 /*============================================*/ 01168 /* GCM (or CCM when applicable) payload phase */ 01169 /*============================================*/ 01170 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 01171 { 01172 /* Get the buffer addresses and sizes */ 01173 hcryp->CrypInCount = (uint32_t)Size; 01174 hcryp->pCrypInBuffPtr = pInputData; 01175 hcryp->pCrypOutBuffPtr = pOutputData; 01176 hcryp->CrypOutCount = (uint32_t)Size; 01177 01178 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 01179 01180 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE); 01181 01182 /* if the header phase has been bypassed, AES must be enabled again */ 01183 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 01184 { 01185 __HAL_CRYP_ENABLE(hcryp); 01186 } 01187 01188 /* No payload case */ 01189 if (pInputData == NULL) 01190 { 01191 hcryp->State = HAL_CRYP_STATE_READY; 01192 /* Mark that the header phase is over */ 01193 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 01194 /* Process Unlocked */ 01195 __HAL_UNLOCK(hcryp); 01196 01197 return HAL_OK; 01198 } 01199 01200 /* Specific handling to manage payload size less than 128 bits */ 01201 if (Size < 16U) 01202 { 01203 difflength = (uint32_t) (Size); 01204 #if defined(AES_CR_NPBLB) 01205 /* In case of GCM encryption or CCM decryption, specify the number of padding 01206 bytes in last block of payload */ 01207 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE) 01208 { 01209 uint32_t cr_temp = hcryp->Instance->CR; 01210 01211 if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT)) 01212 || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT))) 01213 { 01214 /* Set NPBLB field in writing the number of padding bytes 01215 for the last block of payload */ 01216 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB); 01217 } 01218 } 01219 #else 01220 /* Software workaround applied to GCM encryption only */ 01221 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 01222 { 01223 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */ 01224 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR); 01225 } 01226 #endif 01227 01228 01229 /* Set hcryp->CrypInCount to 0 (no more data to enter) */ 01230 hcryp->CrypInCount = 0; 01231 01232 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes, 01233 to have a complete block of 128 bits */ 01234 difflengthmod4 = difflength%4U; 01235 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes 01236 to have a complete block of 128 bits */ 01237 for(index=0U; index < (difflength/4U); index ++) 01238 { 01239 /* Write the Input block in the Data Input register */ 01240 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01241 inputaddr+=4U; 01242 } 01243 /* If required, manage input data size not multiple of 32 bits */ 01244 if (difflengthmod4 != 0U) 01245 { 01246 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]); 01247 } 01248 /* Wrap-up in padding with zero-words if applicable */ 01249 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 01250 { 01251 hcryp->Instance->DINR = 0; 01252 } 01253 } 01254 else 01255 { 01256 /* Increment/decrement instance pointer/counter */ 01257 hcryp->pCrypInBuffPtr += 16; 01258 hcryp->CrypInCount -= 16U; 01259 01260 /* Enter payload first block to initiate the process 01261 in the Data Input register */ 01262 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01263 inputaddr+=4U; 01264 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01265 inputaddr+=4U; 01266 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01267 inputaddr+=4U; 01268 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01269 } 01270 } 01271 /*==================================*/ 01272 /* GCM/GMAC/CCM or CMAC final phase */ 01273 /*==================================*/ 01274 else 01275 { 01276 hcryp->pCrypOutBuffPtr = pOutputData; 01277 01278 #if defined(AES_CR_NPBLB) 01279 /* By default, clear NPBLB field */ 01280 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB); 01281 #endif 01282 01283 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE); 01284 01285 /* if the header and payload phases have been bypassed, AES must be enabled again */ 01286 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 01287 { 01288 __HAL_CRYP_ENABLE(hcryp); 01289 } 01290 01291 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 01292 { 01293 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */ 01294 inputlength = Size * 8U; /* Input length in bits */ 01295 /* Write the number of bits in the header on 64 bits followed by the number 01296 of bits in the payload on 64 bits as well */ 01297 01298 #if !defined(AES_CR_NPBLB) 01299 if(hcryp->Init.DataType == CRYP_DATATYPE_1B) 01300 { 01301 hcryp->Instance->DINR = __RBIT((uint32_t)((headerlength)>>32)); 01302 hcryp->Instance->DINR = __RBIT((uint32_t)headerlength); 01303 hcryp->Instance->DINR = __RBIT((uint32_t)((inputlength)>>32)); 01304 hcryp->Instance->DINR = __RBIT((uint32_t)inputlength); 01305 } 01306 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B) 01307 { 01308 hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32)); 01309 hcryp->Instance->DINR = __REV((uint32_t)headerlength); 01310 hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32)); 01311 hcryp->Instance->DINR = __REV((uint32_t)inputlength); 01312 } 01313 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B) 01314 { 01315 hcryp->Instance->DINR = __ROR((uint32_t)((headerlength)>>32), 16); 01316 hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16); 01317 hcryp->Instance->DINR = __ROR((uint32_t)((inputlength)>>32), 16); 01318 hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16); 01319 } 01320 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B) 01321 { 01322 hcryp->Instance->DINR = (uint32_t)(headerlength>>32); 01323 hcryp->Instance->DINR = (uint32_t)(headerlength); 01324 hcryp->Instance->DINR = (uint32_t)(inputlength>>32); 01325 hcryp->Instance->DINR = (uint32_t)(inputlength); 01326 } 01327 else 01328 { 01329 /* Unspecified Data Type */ 01330 return HAL_ERROR; 01331 } 01332 #else 01333 hcryp->Instance->DINR = (uint32_t)(headerlength>>32); 01334 hcryp->Instance->DINR = (uint32_t)(headerlength); 01335 hcryp->Instance->DINR = (uint32_t)(inputlength>>32); 01336 hcryp->Instance->DINR = (uint32_t)(inputlength); 01337 #endif 01338 } 01339 #if !defined(AES_CR_NPBLB) 01340 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 01341 { 01342 inputaddr = (uint32_t)pInputData; 01343 /* Enter the last block made of a 128-bit value formatted 01344 from the original B0 packet. */ 01345 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01346 inputaddr+=4U; 01347 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01348 inputaddr+=4U; 01349 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01350 inputaddr+=4U; 01351 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01352 } 01353 else 01354 { 01355 /* Unspecified Chaining Mode */ 01356 return HAL_ERROR; 01357 } 01358 #endif 01359 } 01360 01361 return HAL_OK; 01362 } 01363 else 01364 { 01365 return HAL_BUSY; 01366 } 01367 } 01368 01369 01370 01371 01372 /** 01373 * @brief Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering 01374 * operation according to hcryp->Init structure fields. 01375 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01376 * the configuration information for CRYP module 01377 * @param pInputData 01378 * - pointer to payload data in GCM or CCM payload phase, 01379 * - pointer to B0 block in CMAC header phase, 01380 * - pointer to C block in CMAC final phase. 01381 * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases. 01382 * @param Size 01383 * - length of the input payload data buffer in bytes in GCM or CCM payload phase, 01384 * - length of B0 block (in bytes) in CMAC header phase, 01385 * - length of C block (in bytes) in CMAC final phase. 01386 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases. 01387 * - Parameter is meaningless in case of CCM final phase. 01388 * - Parameter is message length in bytes in case of GCM final phase. 01389 * - Parameter must be set to zero in case of GMAC final phase. 01390 * @param pOutputData 01391 * - pointer to plain or cipher text in GCM/CCM payload phase, 01392 * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase. 01393 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases. 01394 * - Parameter is meaningless in case of CMAC header phase. 01395 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC. 01396 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes 01397 * can be skipped by the user if so required. 01398 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP. 01399 * @retval HAL status 01400 */ 01401 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData) 01402 { 01403 uint32_t inputaddr ; 01404 uint32_t outputaddr ; 01405 uint32_t tagaddr ; 01406 uint64_t headerlength ; 01407 uint64_t inputlength ; 01408 uint64_t payloadlength ; 01409 01410 01411 if (hcryp->State == HAL_CRYP_STATE_READY) 01412 { 01413 /* input/output parameters check */ 01414 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 01415 { 01416 /* No processing required */ 01417 } 01418 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 01419 { 01420 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) 01421 { 01422 return HAL_ERROR; 01423 } 01424 #if defined(AES_CR_NPBLB) 01425 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM) 01426 { 01427 /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and Size = 0 */ 01428 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U))) 01429 { 01430 return HAL_ERROR; 01431 } 01432 } 01433 #else 01434 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 01435 { 01436 if ((pInputData == NULL) || (Size == 0U)) 01437 { 01438 return HAL_ERROR; 01439 } 01440 } 01441 #endif 01442 } 01443 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 01444 { 01445 if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL)) 01446 { 01447 return HAL_ERROR; 01448 } 01449 } 01450 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 01451 { 01452 if (pOutputData == NULL) 01453 { 01454 return HAL_ERROR; 01455 } 01456 #if !defined(AES_CR_NPBLB) 01457 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL)) 01458 { 01459 return HAL_ERROR; 01460 } 01461 #endif 01462 } 01463 else 01464 { 01465 /* Unspecified Phase */ 01466 return HAL_ERROR; 01467 } 01468 01469 01470 /* Process Locked */ 01471 __HAL_LOCK(hcryp); 01472 01473 /* Change the CRYP state */ 01474 hcryp->State = HAL_CRYP_STATE_BUSY; 01475 01476 /*==============================================*/ 01477 /* GCM/GMAC (or CCM when applicable) init phase */ 01478 /*==============================================*/ 01479 /* In case of init phase, the input data (Key and Initialization Vector) have 01480 already been entered during the initialization process. No DMA transfer is 01481 required at that point therefore, the software just waits for the CCF flag 01482 to be raised. */ 01483 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 01484 { 01485 /* just wait for hash computation */ 01486 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 01487 { 01488 hcryp->State = HAL_CRYP_STATE_READY; 01489 __HAL_UNLOCK(hcryp); 01490 return HAL_TIMEOUT; 01491 } 01492 01493 /* Clear CCF Flag */ 01494 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 01495 /* Mark that the initialization phase is over */ 01496 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER; 01497 hcryp->State = HAL_CRYP_STATE_READY; 01498 } 01499 /*====================================*/ 01500 /* GCM/GMAC/ CCM or CMAC header phase */ 01501 /*====================================*/ 01502 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 01503 { 01504 #if !defined(AES_CR_NPBLB) 01505 /* Set header phase; for GCM or GMAC, set data-byte at this point */ 01506 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 01507 { 01508 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType); 01509 } 01510 else 01511 #endif 01512 { 01513 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE); 01514 } 01515 01516 /* Enable the CRYP peripheral */ 01517 __HAL_CRYP_ENABLE(hcryp); 01518 01519 #if !defined(AES_CR_NPBLB) 01520 /* enter first B0 block in polling mode (no DMA transfer for B0) */ 01521 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 01522 { 01523 inputaddr = (uint32_t)pInputData; 01524 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01525 inputaddr+=4U; 01526 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01527 inputaddr+=4U; 01528 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01529 inputaddr+=4U; 01530 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01531 01532 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 01533 { 01534 hcryp->State = HAL_CRYP_STATE_READY; 01535 __HAL_UNLOCK(hcryp); 01536 return HAL_TIMEOUT; 01537 } 01538 /* Clear CCF Flag */ 01539 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 01540 } 01541 #endif 01542 01543 /* No header case */ 01544 if (hcryp->Init.Header == NULL) 01545 { 01546 hcryp->State = HAL_CRYP_STATE_READY; 01547 /* Mark that the header phase is over */ 01548 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 01549 /* Process Unlocked */ 01550 __HAL_UNLOCK(hcryp); 01551 01552 return HAL_OK; 01553 } 01554 01555 inputaddr = (uint32_t)hcryp->Init.Header; 01556 if ((hcryp->Init.HeaderSize % 16U) != 0U) 01557 { 01558 01559 if (hcryp->Init.HeaderSize < 16U) 01560 { 01561 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 01562 CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF); 01563 01564 hcryp->State = HAL_CRYP_STATE_READY; 01565 /* Mark that the header phase is over */ 01566 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 01567 01568 /* CCF flag indicating header phase AES processing completion 01569 will be checked at the start of the next phase: 01570 - payload phase (GCM / CCM when applicable) 01571 - final phase (GMAC or CMAC when applicable). */ 01572 } 01573 else 01574 { 01575 /* Local variable headerlength is a number of bytes multiple of 128 bits, 01576 remaining header data (if any) are handled after this loop */ 01577 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ; 01578 /* Store the ending transfer point */ 01579 hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength; 01580 hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */ 01581 01582 /* Set the input and output addresses and start DMA transfer */ 01583 /* (incomplete DMA transfer, will be wrapped up after completion of 01584 the first one (initiated here) with data padding */ 01585 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)headerlength, 0); 01586 } 01587 } 01588 else 01589 { 01590 hcryp->CrypInCount = 0; 01591 /* Set the input address and start DMA transfer */ 01592 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)hcryp->Init.HeaderSize, 0); 01593 } 01594 } 01595 /*============================================*/ 01596 /* GCM (or CCM when applicable) payload phase */ 01597 /*============================================*/ 01598 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 01599 { 01600 /* Coming from header phase, wait for CCF flag to be raised 01601 if header present and fed to the IP in the previous phase */ 01602 if (hcryp->Init.Header != NULL) 01603 { 01604 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 01605 { 01606 hcryp->State = HAL_CRYP_STATE_READY; 01607 __HAL_UNLOCK(hcryp); 01608 return HAL_TIMEOUT; 01609 } 01610 } 01611 else 01612 { 01613 /* Enable the Peripheral since wasn't in header phase (no header case) */ 01614 __HAL_CRYP_ENABLE(hcryp); 01615 } 01616 /* Clear CCF Flag */ 01617 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 01618 01619 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE); 01620 01621 /* No payload case */ 01622 if (pInputData == NULL) 01623 { 01624 hcryp->State = HAL_CRYP_STATE_READY; 01625 /* Mark that the header phase is over */ 01626 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 01627 /* Process Unlocked */ 01628 __HAL_UNLOCK(hcryp); 01629 01630 return HAL_OK; 01631 } 01632 01633 01634 /* Specific handling to manage payload size less than 128 bits */ 01635 if ((Size % 16U) != 0U) 01636 { 01637 inputaddr = (uint32_t)pInputData; 01638 outputaddr = (uint32_t)pOutputData; 01639 if (Size < 16U) 01640 { 01641 /* Block is now entered in polling mode, no actual gain in resorting to DMA */ 01642 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 01643 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr; 01644 01645 CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON); 01646 01647 /* Change the CRYP state to ready */ 01648 hcryp->State = HAL_CRYP_STATE_READY; 01649 /* Mark that the payload phase is over */ 01650 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 01651 01652 /* Call output data transfer complete callback */ 01653 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 01654 hcryp->OutCpltCallback(hcryp); 01655 #else 01656 HAL_CRYP_OutCpltCallback(hcryp); 01657 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 01658 } 01659 else 01660 { 01661 payloadlength = (Size/16U) * 16U; 01662 01663 /* Store the ending transfer points */ 01664 hcryp->pCrypInBuffPtr = pInputData; 01665 hcryp->pCrypInBuffPtr += payloadlength; 01666 hcryp->pCrypOutBuffPtr = pOutputData; 01667 hcryp->pCrypOutBuffPtr += payloadlength; 01668 hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */ 01669 01670 /* Set the input and output addresses and start DMA transfer */ 01671 /* (incomplete DMA transfer, will be wrapped up with data padding 01672 after completion of the one initiated here) */ 01673 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)payloadlength, outputaddr); 01674 } 01675 } 01676 else 01677 { 01678 hcryp->CrypInCount = 0; 01679 inputaddr = (uint32_t)pInputData; 01680 outputaddr = (uint32_t)pOutputData; 01681 01682 /* Set the input and output addresses and start DMA transfer */ 01683 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)Size, outputaddr); 01684 } 01685 } 01686 /*==================================*/ 01687 /* GCM/GMAC/CCM or CMAC final phase */ 01688 /*==================================*/ 01689 else 01690 { 01691 /* If coming from header phase (GMAC or CMAC case when applicable), 01692 wait for CCF flag to be raised */ 01693 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE) 01694 { 01695 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 01696 { 01697 hcryp->State = HAL_CRYP_STATE_READY; 01698 __HAL_UNLOCK(hcryp); 01699 return HAL_TIMEOUT; 01700 } 01701 /* Clear CCF Flag */ 01702 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 01703 } 01704 01705 tagaddr = (uint32_t)pOutputData; 01706 01707 #if defined(AES_CR_NPBLB) 01708 /* By default, clear NPBLB field */ 01709 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB); 01710 #endif 01711 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE); 01712 01713 /* if the header and payload phases have been bypassed, AES must be enabled again */ 01714 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 01715 { 01716 __HAL_CRYP_ENABLE(hcryp); 01717 } 01718 01719 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 01720 { 01721 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */ 01722 inputlength = Size * 8U; /* input length in bits */ 01723 /* Write the number of bits in the header on 64 bits followed by the number 01724 of bits in the payload on 64 bits as well */ 01725 #if !defined(AES_CR_NPBLB) 01726 if(hcryp->Init.DataType == CRYP_DATATYPE_1B) 01727 { 01728 hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32)); 01729 hcryp->Instance->DINR = __RBIT((uint32_t)headerlength); 01730 hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32)); 01731 hcryp->Instance->DINR = __RBIT((uint32_t)inputlength); 01732 } 01733 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B) 01734 { 01735 hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32)); 01736 hcryp->Instance->DINR = __REV((uint32_t)headerlength); 01737 hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32)); 01738 hcryp->Instance->DINR = __REV((uint32_t)inputlength); 01739 } 01740 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B) 01741 { 01742 hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16); 01743 hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16); 01744 hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16); 01745 hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16); 01746 } 01747 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B) 01748 { 01749 hcryp->Instance->DINR = (uint32_t)(headerlength>>32); 01750 hcryp->Instance->DINR = (uint32_t)(headerlength); 01751 hcryp->Instance->DINR = (uint32_t)(inputlength>>32); 01752 hcryp->Instance->DINR = (uint32_t)(inputlength); 01753 } 01754 else 01755 { 01756 /* Unspecified Data Type */ 01757 return HAL_ERROR; 01758 } 01759 #else 01760 hcryp->Instance->DINR = (uint32_t)(headerlength>>32); 01761 hcryp->Instance->DINR = (uint32_t)(headerlength); 01762 hcryp->Instance->DINR = (uint32_t)(inputlength>>32); 01763 hcryp->Instance->DINR = (uint32_t)(inputlength); 01764 #endif 01765 } 01766 #if !defined(AES_CR_NPBLB) 01767 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 01768 { 01769 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 01770 01771 inputaddr = (uint32_t)pInputData; 01772 /* Enter the last block made of a 128-bit value formatted 01773 from the original B0 packet. */ 01774 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01775 inputaddr+=4U; 01776 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01777 inputaddr+=4U; 01778 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01779 inputaddr+=4U; 01780 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 01781 } 01782 else 01783 { 01784 /* Unspecified Chaining Mode */ 01785 return HAL_ERROR; 01786 } 01787 #endif 01788 01789 /* No DMA transfer is required at that point therefore, the software 01790 just waits for the CCF flag to be raised. */ 01791 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 01792 { 01793 hcryp->State = HAL_CRYP_STATE_READY; 01794 __HAL_UNLOCK(hcryp); 01795 return HAL_TIMEOUT; 01796 } 01797 01798 /* Read the Auth TAG in the IN FIFO */ 01799 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 01800 tagaddr+=4U; 01801 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 01802 tagaddr+=4U; 01803 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 01804 tagaddr+=4U; 01805 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 01806 01807 /* Clear CCF Flag */ 01808 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 01809 01810 /* Mark that the final phase is over */ 01811 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER; 01812 hcryp->State = HAL_CRYP_STATE_READY; 01813 /* Disable the Peripheral */ 01814 __HAL_CRYP_DISABLE(hcryp); 01815 01816 } 01817 01818 /* Process Unlocked */ 01819 __HAL_UNLOCK(hcryp); 01820 01821 return HAL_OK; 01822 } 01823 else 01824 { 01825 return HAL_BUSY; 01826 } 01827 } 01828 01829 /** 01830 * @} 01831 */ 01832 01833 /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions 01834 * @brief Extended processing functions. 01835 * 01836 @verbatim 01837 ============================================================================== 01838 ##### AES extended suspension and resumption functions ##### 01839 ============================================================================== 01840 [..] This section provides functions allowing to: 01841 (+) save in memory the Initialization Vector, the Key registers, the Control register or 01842 the Suspend registers when a process is suspended by a higher priority message 01843 (+) write back in CRYP hardware block the saved values listed above when the suspended 01844 lower priority message processing is resumed. 01845 01846 @endverbatim 01847 * @{ 01848 */ 01849 01850 01851 /** 01852 * @brief In case of message processing suspension, read the Initialization Vector. 01853 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01854 * the configuration information for CRYP module. 01855 * @param Output Pointer to the buffer containing the saved Initialization Vector. 01856 * @note This value has to be stored for reuse by writing the AES_IVRx registers 01857 * as soon as the interrupted processing has to be resumed. 01858 * Applicable to all chaining modes. 01859 * @note AES must be disabled when reading or resetting the IV values. 01860 * @retval None 01861 */ 01862 void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output) 01863 { 01864 uint32_t outputaddr = (uint32_t)Output; 01865 01866 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3); 01867 outputaddr+=4U; 01868 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2); 01869 outputaddr+=4U; 01870 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1); 01871 outputaddr+=4U; 01872 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0); 01873 } 01874 01875 /** 01876 * @brief In case of message processing resumption, rewrite the Initialization 01877 * Vector in the AES_IVRx registers. 01878 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01879 * the configuration information for CRYP module. 01880 * @param Input Pointer to the buffer containing the saved Initialization Vector to 01881 * write back in the CRYP hardware block. 01882 * @note Applicable to all chaining modes. 01883 * @note AES must be disabled when reading or resetting the IV values. 01884 * @retval None 01885 */ 01886 void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input) 01887 { 01888 uint32_t ivaddr = (uint32_t)Input; 01889 01890 hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr)); 01891 ivaddr+=4U; 01892 hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr)); 01893 ivaddr+=4U; 01894 hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr)); 01895 ivaddr+=4U; 01896 hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr)); 01897 } 01898 01899 01900 /** 01901 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, 01902 * read the Suspend Registers. 01903 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01904 * the configuration information for CRYP module. 01905 * @param Output Pointer to the buffer containing the saved Suspend Registers. 01906 * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers 01907 * as soon as the interrupted processing has to be resumed. 01908 * @retval None 01909 */ 01910 void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output) 01911 { 01912 uint32_t outputaddr = (uint32_t)Output; 01913 01914 /* In case of GCM payload phase encryption, check that suspension can be carried out */ 01915 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)) 01916 { 01917 /* Ensure that Busy flag is reset */ 01918 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK) 01919 { 01920 hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR; 01921 hcryp->State = HAL_CRYP_STATE_ERROR; 01922 01923 /* Process Unlocked */ 01924 __HAL_UNLOCK(hcryp); 01925 01926 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 01927 hcryp->ErrorCallback(hcryp); 01928 #else 01929 HAL_CRYP_ErrorCallback(hcryp); 01930 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 01931 return ; 01932 } 01933 } 01934 01935 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R); 01936 outputaddr+=4U; 01937 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R); 01938 outputaddr+=4U; 01939 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R); 01940 outputaddr+=4U; 01941 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R); 01942 outputaddr+=4U; 01943 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R); 01944 outputaddr+=4U; 01945 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R); 01946 outputaddr+=4U; 01947 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R); 01948 outputaddr+=4U; 01949 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R); 01950 } 01951 01952 /** 01953 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Suspend 01954 * Registers in the AES_SUSPxR registers. 01955 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01956 * the configuration information for CRYP module. 01957 * @param Input Pointer to the buffer containing the saved suspend registers to 01958 * write back in the CRYP hardware block. 01959 * @retval None 01960 */ 01961 void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input) 01962 { 01963 uint32_t ivaddr = (uint32_t)Input; 01964 01965 hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr)); 01966 ivaddr+=4U; 01967 hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr)); 01968 ivaddr+=4U; 01969 hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr)); 01970 ivaddr+=4U; 01971 hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr)); 01972 ivaddr+=4U; 01973 hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr)); 01974 ivaddr+=4U; 01975 hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr)); 01976 ivaddr+=4U; 01977 hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr)); 01978 ivaddr+=4U; 01979 hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr)); 01980 } 01981 01982 01983 /** 01984 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Key Registers. 01985 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01986 * the configuration information for CRYP module. 01987 * @param Output Pointer to the buffer containing the saved Key Registers. 01988 * @param KeySize Indicates the key size (128 or 256 bits). 01989 * @note These values have to be stored for reuse by writing back the AES_KEYRx registers 01990 * as soon as the interrupted processing has to be resumed. 01991 * @retval None 01992 */ 01993 void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize) 01994 { 01995 uint32_t keyaddr = (uint32_t)Output; 01996 01997 if (KeySize == CRYP_KEYSIZE_256B) 01998 { 01999 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7); 02000 keyaddr+=4U; 02001 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6); 02002 keyaddr+=4U; 02003 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5); 02004 keyaddr+=4U; 02005 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4); 02006 keyaddr+=4U; 02007 } 02008 02009 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3); 02010 keyaddr+=4U; 02011 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2); 02012 keyaddr+=4U; 02013 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1); 02014 keyaddr+=4U; 02015 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0); 02016 } 02017 02018 /** 02019 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key 02020 * Registers in the AES_KEYRx registers. 02021 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02022 * the configuration information for CRYP module. 02023 * @param Input Pointer to the buffer containing the saved key registers to 02024 * write back in the CRYP hardware block. 02025 * @param KeySize Indicates the key size (128 or 256 bits) 02026 * @retval None 02027 */ 02028 void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize) 02029 { 02030 uint32_t keyaddr = (uint32_t)Input; 02031 02032 if (KeySize == CRYP_KEYSIZE_256B) 02033 { 02034 hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr)); 02035 keyaddr+=4U; 02036 hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr)); 02037 keyaddr+=4U; 02038 hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr)); 02039 keyaddr+=4U; 02040 hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr)); 02041 keyaddr+=4U; 02042 } 02043 02044 hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr)); 02045 keyaddr+=4U; 02046 hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr)); 02047 keyaddr+=4U; 02048 hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr)); 02049 keyaddr+=4U; 02050 hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr)); 02051 } 02052 02053 02054 /** 02055 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Control Register. 02056 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02057 * the configuration information for CRYP module. 02058 * @param Output Pointer to the buffer containing the saved Control Register. 02059 * @note This values has to be stored for reuse by writing back the AES_CR register 02060 * as soon as the interrupted processing has to be resumed. 02061 * @retval None 02062 */ 02063 void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output) 02064 { 02065 *(uint32_t*)(void *)(Output) = hcryp->Instance->CR; /* Derogation MisraC2012 R.11.5 */ 02066 } 02067 02068 /** 02069 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Control 02070 * Registers in the AES_CR register. 02071 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02072 * the configuration information for CRYP module. 02073 * @param Input Pointer to the buffer containing the saved Control Register to 02074 * write back in the CRYP hardware block. 02075 * @retval None 02076 */ 02077 void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input) 02078 { 02079 hcryp->Instance->CR = *(uint32_t*)(void *)(Input); /* Derogation MisraC2012 R.11.5 */ 02080 /* At the same time, set handle state back to READY to be able to resume the AES calculations 02081 without the processing APIs returning HAL_BUSY when called. */ 02082 hcryp->State = HAL_CRYP_STATE_READY; 02083 } 02084 02085 /** 02086 * @brief Request CRYP processing suspension when in polling or interruption mode. 02087 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02088 * the configuration information for CRYP module. 02089 * @note Set the handle field SuspendRequest to the appropriate value so that 02090 * the on-going CRYP processing is suspended as soon as the required 02091 * conditions are met. 02092 * @note It is advised not to suspend the CRYP processing when the DMA controller 02093 * is managing the data transfer 02094 * @retval None 02095 */ 02096 void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp) 02097 { 02098 /* Set Handle Suspend Request field */ 02099 hcryp->SuspendRequest = HAL_CRYP_SUSPEND; 02100 } 02101 02102 /** 02103 * @} 02104 */ 02105 02106 /** 02107 * @} 02108 */ 02109 02110 /** @addtogroup CRYPEx_Private_Functions 02111 * @{ 02112 */ 02113 02114 /** 02115 * @brief DMA CRYP Input Data process complete callback 02116 * for GCM, GMAC, CCM or CMAC chaining modes. 02117 * @note Specific setting of hcryp fields are required only 02118 * in the case of header phase where no output data DMA 02119 * transfer is on-going (only input data transfer is enabled 02120 * in such a case). 02121 * @param hdma DMA handle. 02122 * @retval None 02123 */ 02124 static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma) 02125 { 02126 uint32_t difflength; 02127 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */ 02128 02129 /* Disable the DMA transfer for input request */ 02130 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN); 02131 02132 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 02133 { 02134 02135 if (hcryp->CrypInCount != 0U) 02136 { 02137 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */ 02138 difflength = hcryp->CrypInCount; 02139 hcryp->CrypInCount = 0; 02140 02141 CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF); 02142 } 02143 hcryp->State = HAL_CRYP_STATE_READY; 02144 /* Mark that the header phase is over */ 02145 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 02146 } 02147 /* CCF flag indicating header phase AES processing completion 02148 will be checked at the start of the next phase: 02149 - payload phase (GCM or CCM when applicable) 02150 - final phase (GMAC or CMAC). 02151 This allows to avoid the Wait on Flag within the IRQ handling. */ 02152 02153 /* Call input data transfer complete callback */ 02154 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02155 hcryp->InCpltCallback(hcryp); 02156 #else 02157 HAL_CRYP_InCpltCallback(hcryp); 02158 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02159 } 02160 02161 /** 02162 * @brief DMA CRYP Output Data process complete callback 02163 * for GCM, GMAC, CCM or CMAC chaining modes. 02164 * @note This callback is called only in the payload phase. 02165 * @param hdma DMA handle. 02166 * @retval None 02167 */ 02168 static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma) 02169 { 02170 uint32_t difflength; 02171 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */ 02172 02173 /* Disable the DMA transfer for output request */ 02174 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN); 02175 02176 /* Clear CCF Flag */ 02177 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02178 02179 /* Initiate additional transfer to wrap-up data feeding to the IP */ 02180 if (hcryp->CrypInCount != 0U) 02181 { 02182 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */ 02183 difflength = hcryp->CrypInCount; 02184 hcryp->CrypInCount = 0; 02185 02186 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON); 02187 } 02188 02189 /* Change the CRYP state to ready */ 02190 hcryp->State = HAL_CRYP_STATE_READY; 02191 /* Mark that the payload phase is over */ 02192 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 02193 02194 /* Call output data transfer complete callback */ 02195 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02196 hcryp->OutCpltCallback(hcryp); 02197 #else 02198 HAL_CRYP_OutCpltCallback(hcryp); 02199 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02200 } 02201 02202 /** 02203 * @brief DMA CRYP communication error callback 02204 * for GCM, GMAC, CCM or CMAC chaining modes. 02205 * @param hdma DMA handle 02206 * @retval None 02207 */ 02208 static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma) 02209 { 02210 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */ 02211 02212 hcryp->State= HAL_CRYP_STATE_ERROR; 02213 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR; 02214 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02215 hcryp->ErrorCallback(hcryp); 02216 #else 02217 HAL_CRYP_ErrorCallback(hcryp); 02218 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02219 /* Clear Error Flag */ 02220 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR); 02221 } 02222 02223 02224 02225 /** 02226 * @brief Handle CRYP block input/output data handling under interruption 02227 * for GCM, GMAC, CCM or CMAC chaining modes. 02228 * @note The function is called under interruption only, once 02229 * interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT(). 02230 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02231 * the configuration information for CRYP module 02232 * @retval HAL status 02233 */ 02234 HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp) 02235 { 02236 uint32_t inputaddr ; 02237 uint32_t outputaddr ; 02238 uint32_t index ; 02239 uint32_t addhoc_process = 0; 02240 uint32_t difflength = 0; 02241 uint32_t difflengthmod4 = 0; 02242 uint32_t mask[4][3] ; 02243 uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos; 02244 uint32_t intermediate_data[4] = {0}; 02245 02246 mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */ 02247 mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */ 02248 mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */ 02249 mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */ 02250 02251 if(hcryp->State == HAL_CRYP_STATE_BUSY) 02252 { 02253 /*===========================*/ 02254 /* GCM/GMAC(/CCM) init phase */ 02255 /*===========================*/ 02256 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 02257 { 02258 /* Clear Computation Complete Flag */ 02259 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02260 /* Disable Computation Complete Flag and Errors Interrupts */ 02261 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE); 02262 /* Change the CRYP state */ 02263 hcryp->State = HAL_CRYP_STATE_READY; 02264 02265 /* Mark that the initialization phase is over */ 02266 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER; 02267 02268 /* Process Unlocked */ 02269 __HAL_UNLOCK(hcryp); 02270 /* Call computation complete callback */ 02271 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02272 hcryp->CompCpltCallback(hcryp); 02273 #else 02274 HAL_CRYPEx_ComputationCpltCallback(hcryp); 02275 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02276 return HAL_OK; 02277 } 02278 /*========================================*/ 02279 /* GCM/GMAC (or CCM or CMAC) header phase */ 02280 /*========================================*/ 02281 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 02282 { 02283 /* Check if all input header data have been entered */ 02284 if (hcryp->CrypInCount == 0U) 02285 { 02286 /* Clear Computation Complete Flag */ 02287 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02288 /* Disable Computation Complete Flag and Errors Interrupts */ 02289 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE); 02290 /* Change the CRYP state */ 02291 hcryp->State = HAL_CRYP_STATE_READY; 02292 /* Mark that the header phase is over */ 02293 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 02294 02295 /* Process Unlocked */ 02296 __HAL_UNLOCK(hcryp); 02297 02298 /* Call computation complete callback */ 02299 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02300 hcryp->CompCpltCallback(hcryp); 02301 #else 02302 HAL_CRYPEx_ComputationCpltCallback(hcryp); 02303 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02304 02305 return HAL_OK; 02306 } 02307 /* If suspension flag has been raised, suspend processing */ 02308 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND) 02309 { 02310 /* Clear CCF Flag */ 02311 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02312 02313 /* reset SuspendRequest */ 02314 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 02315 /* Disable Computation Complete Flag and Errors Interrupts */ 02316 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE); 02317 /* Change the CRYP state */ 02318 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 02319 /* Mark that the header phase is suspended */ 02320 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED; 02321 02322 /* Process Unlocked */ 02323 __HAL_UNLOCK(hcryp); 02324 02325 return HAL_OK; 02326 } 02327 else /* Carry on feeding input data to the CRYP hardware block */ 02328 { 02329 /* Clear Computation Complete Flag */ 02330 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02331 /* Get the last Input data address */ 02332 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 02333 02334 /* Increment/decrement instance pointer/counter */ 02335 if (hcryp->CrypInCount < 16U) 02336 { 02337 difflength = hcryp->CrypInCount; 02338 hcryp->CrypInCount = 0; 02339 addhoc_process = 1; 02340 difflengthmod4 = difflength%4U; 02341 } 02342 else 02343 { 02344 hcryp->pCrypInBuffPtr += 16; 02345 hcryp->CrypInCount -= 16U; 02346 } 02347 02348 #if defined(AES_CR_NPBLB) 02349 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM) 02350 #else 02351 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 02352 #endif 02353 { 02354 if (hcryp->CrypInCount == hcryp->Init.HeaderSize) 02355 { 02356 /* All B blocks will have been entered after the next 02357 four DINR writing, so point at header buffer for 02358 the next iteration */ 02359 hcryp->pCrypInBuffPtr = hcryp->Init.Header; 02360 } 02361 } 02362 02363 /* Write the Input block in the Data Input register */ 02364 if (addhoc_process == 0U) 02365 { 02366 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02367 inputaddr+=4U; 02368 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02369 inputaddr+=4U; 02370 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02371 inputaddr+=4U; 02372 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02373 } 02374 else 02375 { 02376 /* Header remainder has size less than 128 bits */ 02377 /* Enter complete words when possible */ 02378 for(index=0U ; index < (difflength/4U); index ++) 02379 { 02380 /* Write the Input block in the Data Input register */ 02381 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02382 inputaddr+=4U; 02383 } 02384 /* Enter incomplete word padded with zeroes if applicable 02385 (case of header length not a multiple of 32-bits) */ 02386 if (difflengthmod4 != 0U) 02387 { 02388 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]); 02389 } 02390 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */ 02391 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 02392 { 02393 hcryp->Instance->DINR = 0; 02394 } 02395 } 02396 02397 return HAL_OK; 02398 } 02399 } 02400 /*=======================*/ 02401 /* GCM/CCM payload phase */ 02402 /*=======================*/ 02403 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 02404 { 02405 /* Get the last output data address */ 02406 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 02407 02408 /* Specific handling to manage payload size less than 128 bits 02409 when GCM (or CCM when applicable) encryption or decryption is selected. 02410 Check here if the last block output data are read */ 02411 #if defined(AES_CR_NPBLB) 02412 if ((hcryp->CrypOutCount < 16U) && \ 02413 (hcryp->CrypOutCount > 0U)) 02414 #else 02415 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \ 02416 (hcryp->CrypOutCount < 16U) && \ 02417 (hcryp->CrypOutCount > 0U)) 02418 #endif 02419 { 02420 difflength = hcryp->CrypOutCount; 02421 difflengthmod4 = difflength%4U; 02422 hcryp->CrypOutCount = 0; /* mark that no more output data will be needed */ 02423 /* Retrieve intermediate data */ 02424 for(index=0U ; index < 4U; index ++) 02425 { 02426 intermediate_data[index] = hcryp->Instance->DOUTR; 02427 } 02428 /* Retrieve last words of cyphered data */ 02429 /* First, retrieve complete output words */ 02430 for(index=0U ; index < (difflength/4U); index ++) 02431 { 02432 *(uint32_t*)(outputaddr) = intermediate_data[index]; 02433 outputaddr+=4U; 02434 } 02435 /* Next, retrieve partial output word if applicable; 02436 at the same time, start masking intermediate data 02437 with a mask of zeros of same size than the padding 02438 applied to the last block of payload */ 02439 if (difflengthmod4 != 0U) 02440 { 02441 intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U]; 02442 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U]; 02443 } 02444 02445 #if !defined(AES_CR_NPBLB) 02446 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 02447 { 02448 /* Change again CHMOD configuration to GCM mode */ 02449 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC); 02450 02451 /* Select FINAL phase */ 02452 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE); 02453 02454 /* Before inserting the intermediate data, carry on masking operation 02455 with a mask of zeros of same size than the padding applied to the last block of payload */ 02456 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++) 02457 { 02458 intermediate_data[((difflength+3U)/4U)+index] = 0; 02459 } 02460 02461 /* Insert intermediate data to trigger an additional DOUTR reading round */ 02462 /* Clear Computation Complete Flag before entering new block */ 02463 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02464 for(index=0U ; index < 4U; index ++) 02465 { 02466 hcryp->Instance->DINR = intermediate_data[index]; 02467 } 02468 } 02469 else 02470 #endif 02471 { 02472 /* Payload phase is now over */ 02473 /* Clear Computation Complete Flag */ 02474 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02475 /* Disable Computation Complete Flag and Errors Interrupts */ 02476 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE); 02477 /* Change the CRYP state */ 02478 hcryp->State = HAL_CRYP_STATE_READY; 02479 /* Mark that the payload phase is over */ 02480 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 02481 02482 /* Process Unlocked */ 02483 __HAL_UNLOCK(hcryp); 02484 02485 /* Call computation complete callback */ 02486 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02487 hcryp->CompCpltCallback(hcryp); 02488 #else 02489 HAL_CRYPEx_ComputationCpltCallback(hcryp); 02490 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02491 } 02492 return HAL_OK; 02493 } 02494 else 02495 { 02496 if (hcryp->CrypOutCount != 0U) 02497 { 02498 /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */ 02499 /* Retrieve the last block available from the CRYP hardware block: 02500 read the output block from the Data Output Register */ 02501 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02502 outputaddr+=4U; 02503 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02504 outputaddr+=4U; 02505 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02506 outputaddr+=4U; 02507 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02508 02509 /* Increment/decrement instance pointer/counter */ 02510 hcryp->pCrypOutBuffPtr += 16; 02511 hcryp->CrypOutCount -= 16U; 02512 } 02513 #if !defined(AES_CR_NPBLB) 02514 else 02515 { 02516 /* Software work-around: additional DOUTR reading round to discard the data */ 02517 for(index=0U ; index < 4U; index ++) 02518 { 02519 intermediate_data[index] = hcryp->Instance->DOUTR; 02520 } 02521 } 02522 #endif 02523 } 02524 02525 /* Check if all output text has been retrieved */ 02526 if (hcryp->CrypOutCount == 0U) 02527 { 02528 /* Clear Computation Complete Flag */ 02529 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02530 /* Disable Computation Complete Flag and Errors Interrupts */ 02531 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE); 02532 /* Change the CRYP state */ 02533 hcryp->State = HAL_CRYP_STATE_READY; 02534 /* Mark that the payload phase is over */ 02535 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 02536 02537 /* Process Unlocked */ 02538 __HAL_UNLOCK(hcryp); 02539 02540 /* Call computation complete callback */ 02541 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02542 hcryp->CompCpltCallback(hcryp); 02543 #else 02544 HAL_CRYPEx_ComputationCpltCallback(hcryp); 02545 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02546 02547 return HAL_OK; 02548 } 02549 /* If suspension flag has been raised, suspend processing */ 02550 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND) 02551 { 02552 /* Clear CCF Flag */ 02553 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02554 02555 /* reset SuspendRequest */ 02556 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 02557 /* Disable Computation Complete Flag and Errors Interrupts */ 02558 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE); 02559 /* Change the CRYP state */ 02560 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 02561 /* Mark that the payload phase is suspended */ 02562 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_SUSPENDED; 02563 02564 /* Process Unlocked */ 02565 __HAL_UNLOCK(hcryp); 02566 02567 return HAL_OK; 02568 } 02569 else /* Output data are still expected, carry on feeding the CRYP 02570 hardware block with input data */ 02571 { 02572 /* Clear Computation Complete Flag */ 02573 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02574 /* Get the last Input data address */ 02575 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 02576 02577 /* Usual input data feeding case */ 02578 if (hcryp->CrypInCount < 16U) 02579 { 02580 difflength = (uint32_t) (hcryp->CrypInCount); 02581 difflengthmod4 = difflength%4U; 02582 hcryp->CrypInCount = 0; 02583 02584 #if defined(AES_CR_NPBLB) 02585 /* In case of GCM encryption or CCM decryption, specify the number of padding 02586 bytes in last block of payload */ 02587 { 02588 uint32_t cr_temp = hcryp->Instance->CR; 02589 02590 if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT)) 02591 || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT))) 02592 { 02593 /* Set NPBLB field in writing the number of padding bytes 02594 for the last block of payload */ 02595 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB); 02596 } 02597 } 02598 #else 02599 /* Software workaround applied to GCM encryption only */ 02600 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 02601 { 02602 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */ 02603 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR); 02604 } 02605 #endif 02606 02607 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes 02608 to have a complete block of 128 bits */ 02609 for(index=0U ; index < (difflength/4U); index ++) 02610 { 02611 /* Write the Input block in the Data Input register */ 02612 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02613 inputaddr+=4U; 02614 } 02615 /* If required, manage input data size not multiple of 32 bits */ 02616 if (difflengthmod4 != 0U) 02617 { 02618 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]); 02619 } 02620 /* Wrap-up in padding with zero-words if applicable */ 02621 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++) 02622 { 02623 hcryp->Instance->DINR = 0; 02624 } 02625 02626 } 02627 else 02628 { 02629 hcryp->pCrypInBuffPtr += 16; 02630 hcryp->CrypInCount -= 16U; 02631 02632 /* Write the Input block in the Data Input register */ 02633 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02634 inputaddr+=4U; 02635 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02636 inputaddr+=4U; 02637 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02638 inputaddr+=4U; 02639 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02640 } 02641 02642 02643 return HAL_OK; 02644 } 02645 } 02646 /*=======================================*/ 02647 /* GCM/GMAC (or CCM or CMAC) final phase */ 02648 /*=======================================*/ 02649 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 02650 { 02651 /* Clear Computation Complete Flag */ 02652 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02653 02654 /* Get the last output data address */ 02655 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 02656 02657 /* Retrieve the last expected data from the CRYP hardware block: 02658 read the output block from the Data Output Register */ 02659 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02660 outputaddr+=4U; 02661 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02662 outputaddr+=4U; 02663 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02664 outputaddr+=4U; 02665 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02666 02667 /* Disable Computation Complete Flag and Errors Interrupts */ 02668 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE); 02669 /* Change the CRYP state */ 02670 hcryp->State = HAL_CRYP_STATE_READY; 02671 /* Mark that the header phase is over */ 02672 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER; 02673 02674 /* Disable the Peripheral */ 02675 __HAL_CRYP_DISABLE(hcryp); 02676 /* Process Unlocked */ 02677 __HAL_UNLOCK(hcryp); 02678 02679 /* Call computation complete callback */ 02680 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02681 hcryp->CompCpltCallback(hcryp); 02682 #else 02683 HAL_CRYPEx_ComputationCpltCallback(hcryp); 02684 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02685 02686 return HAL_OK; 02687 } 02688 else 02689 { 02690 /* Clear Computation Complete Flag */ 02691 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02692 hcryp->State = HAL_CRYP_STATE_ERROR; 02693 __HAL_UNLOCK(hcryp); 02694 return HAL_ERROR; 02695 } 02696 } 02697 else 02698 { 02699 return HAL_BUSY; 02700 } 02701 } 02702 02703 02704 02705 /** 02706 * @brief Set the DMA configuration and start the DMA transfer 02707 * for GCM, GMAC, CCM or CMAC chaining modes. 02708 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02709 * the configuration information for CRYP module. 02710 * @param inputaddr Address of the Input buffer. 02711 * @param Size Size of the Input buffer un bytes, must be a multiple of 16. 02712 * @param outputaddr Address of the Output buffer, null pointer when no output DMA stream 02713 * has to be configured. 02714 * @retval None 02715 */ 02716 static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr) 02717 { 02718 02719 /* Set the input CRYP DMA transfer complete callback */ 02720 hcryp->hdmain->XferCpltCallback = CRYP_Authentication_DMAInCplt; 02721 /* Set the DMA error callback */ 02722 hcryp->hdmain->XferErrorCallback = CRYP_Authentication_DMAError; 02723 02724 if (outputaddr != 0U) 02725 { 02726 /* Set the output CRYP DMA transfer complete callback */ 02727 hcryp->hdmaout->XferCpltCallback = CRYP_Authentication_DMAOutCplt; 02728 /* Set the DMA error callback */ 02729 hcryp->hdmaout->XferErrorCallback = CRYP_Authentication_DMAError; 02730 } 02731 02732 /* Enable the CRYP peripheral */ 02733 __HAL_CRYP_ENABLE(hcryp); 02734 02735 /* Enable the DMA input stream */ 02736 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK) 02737 { 02738 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02739 hcryp->ErrorCallback(hcryp); 02740 #else 02741 HAL_CRYP_ErrorCallback(hcryp); 02742 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02743 } 02744 02745 /* Enable the DMA input request */ 02746 SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN); 02747 02748 02749 if (outputaddr != 0U) 02750 { 02751 /* Enable the DMA output stream */ 02752 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK) 02753 { 02754 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02755 hcryp->ErrorCallback(hcryp); 02756 #else 02757 HAL_CRYP_ErrorCallback(hcryp); 02758 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02759 } 02760 02761 /* Enable the DMA output request */ 02762 SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN); 02763 } 02764 } 02765 02766 02767 02768 /** 02769 * @brief Write/read input/output data in polling mode. 02770 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02771 * the configuration information for CRYP module. 02772 * @param Input Pointer to the Input buffer. 02773 * @param Ilength Length of the Input buffer in bytes, must be a multiple of 16. 02774 * @param Output Pointer to the returned buffer. 02775 * @param Timeout Specify Timeout value. 02776 * @retval HAL status 02777 */ 02778 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout) 02779 { 02780 uint32_t index; 02781 uint32_t inputaddr = (uint32_t)Input; 02782 uint32_t outputaddr = (uint32_t)Output; 02783 02784 02785 for(index=0U ; (index < Ilength); index += 16U) 02786 { 02787 /* Write the Input block in the Data Input register */ 02788 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02789 inputaddr+=4U; 02790 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02791 inputaddr+=4U; 02792 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02793 inputaddr+=4U; 02794 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 02795 inputaddr+=4U; 02796 02797 /* Wait for CCF flag to be raised */ 02798 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 02799 { 02800 hcryp->State = HAL_CRYP_STATE_READY; 02801 __HAL_UNLOCK(hcryp); 02802 return HAL_TIMEOUT; 02803 } 02804 02805 /* Clear CCF Flag */ 02806 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02807 02808 /* Read the Output block from the Data Output Register */ 02809 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02810 outputaddr+=4U; 02811 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02812 outputaddr+=4U; 02813 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02814 outputaddr+=4U; 02815 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 02816 outputaddr+=4U; 02817 02818 /* If the suspension flag has been raised and if the processing is not about 02819 to end, suspend processing */ 02820 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength)) 02821 { 02822 /* Reset SuspendRequest */ 02823 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 02824 02825 /* Save current reading and writing locations of Input and Output buffers */ 02826 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr; 02827 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 02828 /* Save the number of bytes that remain to be processed at this point */ 02829 hcryp->CrypInCount = Ilength - (index+16U); 02830 02831 /* Change the CRYP state */ 02832 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 02833 02834 return HAL_OK; 02835 } 02836 02837 02838 } 02839 /* Return function status */ 02840 return HAL_OK; 02841 02842 } 02843 02844 02845 02846 02847 02848 /** 02849 * @brief Read derivative key in polling mode when CRYP hardware block is set 02850 * in key derivation operating mode (mode 2). 02851 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02852 * the configuration information for CRYP module. 02853 * @param Output Pointer to the returned buffer. 02854 * @param Timeout Specify Timeout value. 02855 * @retval HAL status 02856 */ 02857 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout) 02858 { 02859 uint32_t outputaddr = (uint32_t)Output; 02860 02861 /* Wait for CCF flag to be raised */ 02862 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 02863 { 02864 hcryp->State = HAL_CRYP_STATE_READY; 02865 __HAL_UNLOCK(hcryp); 02866 return HAL_TIMEOUT; 02867 } 02868 /* Clear CCF Flag */ 02869 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 02870 02871 /* Read the derivative key from the AES_KEYRx registers */ 02872 if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B) 02873 { 02874 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7); 02875 outputaddr+=4U; 02876 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6); 02877 outputaddr+=4U; 02878 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5); 02879 outputaddr+=4U; 02880 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4); 02881 outputaddr+=4U; 02882 } 02883 02884 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3); 02885 outputaddr+=4U; 02886 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2); 02887 outputaddr+=4U; 02888 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1); 02889 outputaddr+=4U; 02890 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0); 02891 02892 02893 /* Return function status */ 02894 return HAL_OK; 02895 } 02896 02897 /** 02898 * @brief Set the DMA configuration and start the DMA transfer. 02899 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02900 * the configuration information for CRYP module. 02901 * @param inputaddr Address of the Input buffer. 02902 * @param Size Size of the Input buffer in bytes, must be a multiple of 16. 02903 * @param outputaddr Address of the Output buffer. 02904 * @retval None 02905 */ 02906 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr) 02907 { 02908 /* Set the CRYP DMA transfer complete callback */ 02909 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt; 02910 /* Set the DMA error callback */ 02911 hcryp->hdmain->XferErrorCallback = CRYP_DMAError; 02912 02913 /* Set the CRYP DMA transfer complete callback */ 02914 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt; 02915 /* Set the DMA error callback */ 02916 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError; 02917 02918 /* Enable the DMA input stream */ 02919 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK) 02920 { 02921 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02922 hcryp->ErrorCallback(hcryp); 02923 #else 02924 HAL_CRYP_ErrorCallback(hcryp); 02925 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02926 } 02927 02928 /* Enable the DMA output stream */ 02929 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK) 02930 { 02931 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02932 hcryp->ErrorCallback(hcryp); 02933 #else 02934 HAL_CRYP_ErrorCallback(hcryp); 02935 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02936 } 02937 02938 /* Enable In and Out DMA requests */ 02939 SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN)); 02940 02941 /* Enable the CRYP peripheral */ 02942 __HAL_CRYP_ENABLE(hcryp); 02943 } 02944 02945 02946 /** 02947 * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised. 02948 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02949 * the configuration information for CRYP module. 02950 * @param Timeout Timeout duration. 02951 * @retval HAL status 02952 */ 02953 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout) 02954 { 02955 uint32_t tickstart; 02956 02957 /* Get timeout */ 02958 tickstart = HAL_GetTick(); 02959 02960 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF)) 02961 { 02962 /* Check for the Timeout */ 02963 if(Timeout != HAL_MAX_DELAY) 02964 { 02965 if((HAL_GetTick() - tickstart ) > Timeout) 02966 { 02967 return HAL_TIMEOUT; 02968 } 02969 } 02970 } 02971 return HAL_OK; 02972 } 02973 02974 /** 02975 * @brief Wait for Busy Flag to be reset during a GCM payload encryption process suspension. 02976 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02977 * the configuration information for CRYP module. 02978 * @param Timeout Timeout duration. 02979 * @retval HAL status 02980 */ 02981 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout) 02982 { 02983 uint32_t tickstart; 02984 02985 /* Get timeout */ 02986 tickstart = HAL_GetTick(); 02987 02988 while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY)) 02989 { 02990 /* Check for the Timeout */ 02991 if(Timeout != HAL_MAX_DELAY) 02992 { 02993 if((HAL_GetTick() - tickstart ) > Timeout) 02994 { 02995 return HAL_TIMEOUT; 02996 } 02997 } 02998 } 02999 return HAL_OK; 03000 } 03001 03002 03003 /** 03004 * @brief DMA CRYP Input Data process complete callback. 03005 * @param hdma DMA handle. 03006 * @retval None 03007 */ 03008 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma) 03009 { 03010 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */ 03011 03012 /* Disable the DMA transfer for input request */ 03013 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN); 03014 03015 /* Call input data transfer complete callback */ 03016 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 03017 hcryp->InCpltCallback(hcryp); 03018 #else 03019 HAL_CRYP_InCpltCallback(hcryp); 03020 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 03021 } 03022 03023 /** 03024 * @brief DMA CRYP Output Data process complete callback. 03025 * @param hdma DMA handle. 03026 * @retval None 03027 */ 03028 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma) 03029 { 03030 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */ 03031 03032 /* Disable the DMA transfer for output request */ 03033 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN); 03034 03035 /* Clear CCF Flag */ 03036 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 03037 03038 /* Disable CRYP */ 03039 __HAL_CRYP_DISABLE(hcryp); 03040 03041 /* Change the CRYP state to ready */ 03042 hcryp->State = HAL_CRYP_STATE_READY; 03043 03044 /* Call output data transfer complete callback */ 03045 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 03046 hcryp->OutCpltCallback(hcryp); 03047 #else 03048 HAL_CRYP_OutCpltCallback(hcryp); 03049 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 03050 } 03051 03052 /** 03053 * @brief DMA CRYP communication error callback. 03054 * @param hdma DMA handle. 03055 * @retval None 03056 */ 03057 static void CRYP_DMAError(DMA_HandleTypeDef *hdma) 03058 { 03059 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */ 03060 03061 hcryp->State= HAL_CRYP_STATE_ERROR; 03062 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR; 03063 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 03064 hcryp->ErrorCallback(hcryp); 03065 #else 03066 HAL_CRYP_ErrorCallback(hcryp); 03067 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 03068 /* Clear Error Flag */ 03069 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR); 03070 } 03071 03072 /** 03073 * @brief Last header or payload block padding when size is not a multiple of 128 bits. 03074 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 03075 * the configuration information for CRYP module. 03076 * @param difflength size remainder after having fed all complete 128-bit blocks. 03077 * @param polling specifies whether or not polling on CCF must be done after having 03078 * entered a complete block. 03079 * @retval None 03080 */ 03081 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling) 03082 { 03083 uint32_t index; 03084 uint32_t difflengthmod4 = difflength%4U; 03085 uint32_t inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 03086 uint32_t outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 03087 uint32_t mask[4][3]; 03088 uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos; 03089 03090 uint32_t intermediate_data[4] = {0}; 03091 03092 mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */ 03093 mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */ 03094 mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */ 03095 mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */ 03096 03097 #if defined(AES_CR_NPBLB) 03098 /* In case of GCM encryption or CCM decryption, specify the number of padding 03099 bytes in last block of payload */ 03100 if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE) 03101 { 03102 uint32_t cr_temp = hcryp->Instance->CR; 03103 03104 if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT)) 03105 || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT))) 03106 { 03107 /* Set NPBLB field in writing the number of padding bytes 03108 for the last block of payload */ 03109 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB); 03110 } 03111 } 03112 #else 03113 /* Software workaround applied to GCM encryption only */ 03114 if ((hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) && 03115 (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)) 03116 { 03117 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */ 03118 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR); 03119 } 03120 #endif 03121 03122 /* Wrap-up entering header or payload data */ 03123 /* Enter complete words when possible */ 03124 for(index=0U ; index < (difflength/4U); index ++) 03125 { 03126 /* Write the Input block in the Data Input register */ 03127 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03128 inputaddr+=4U; 03129 } 03130 /* Enter incomplete word padded with zeroes if applicable 03131 (case of header length not a multiple of 32-bits) */ 03132 if (difflengthmod4 != 0U) 03133 { 03134 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]); 03135 } 03136 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */ 03137 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++) 03138 { 03139 hcryp->Instance->DINR = 0; 03140 } 03141 03142 if (polling == (uint32_t)CRYP_POLLING_ON) 03143 { 03144 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 03145 { 03146 hcryp->State = HAL_CRYP_STATE_READY; 03147 __HAL_UNLOCK(hcryp); 03148 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 03149 hcryp->ErrorCallback(hcryp); 03150 #else 03151 HAL_CRYP_ErrorCallback(hcryp); 03152 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 03153 } 03154 03155 /* Clear CCF Flag */ 03156 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 03157 } 03158 03159 /* if payload */ 03160 if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 03161 { 03162 03163 /* Retrieve intermediate data */ 03164 for(index=0U ; index < 4U; index ++) 03165 { 03166 intermediate_data[index] = hcryp->Instance->DOUTR; 03167 } 03168 /* Retrieve last words of cyphered data */ 03169 /* First, retrieve complete output words */ 03170 for(index=0U ; index < (difflength/4U); index ++) 03171 { 03172 *(uint32_t*)(outputaddr) = intermediate_data[index]; 03173 outputaddr+=4U; 03174 } 03175 /* Next, retrieve partial output word if applicable; 03176 at the same time, start masking intermediate data 03177 with a mask of zeros of same size than the padding 03178 applied to the last block of payload */ 03179 if (difflengthmod4 != 0U) 03180 { 03181 intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U]; 03182 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U]; 03183 } 03184 03185 03186 #if !defined(AES_CR_NPBLB) 03187 /* Software workaround applied to GCM encryption only, 03188 applicable for AES IP v2 version (where NPBLB is not defined) */ 03189 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 03190 { 03191 /* Change again CHMOD configuration to GCM mode */ 03192 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC); 03193 03194 /* Select FINAL phase */ 03195 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE); 03196 03197 /* Before inserting the intermediate data, carry on masking operation 03198 with a mask of zeros of same size than the padding applied to the last block of payload */ 03199 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++) 03200 { 03201 intermediate_data[((difflength+3U)/4U)+index] = 0; 03202 } 03203 /* Insert intermediate data */ 03204 for(index=0U ; index < 4U; index ++) 03205 { 03206 hcryp->Instance->DINR = intermediate_data[index]; 03207 } 03208 03209 /* Wait for completion, and read data on DOUT. This data is to discard. */ 03210 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 03211 { 03212 hcryp->State = HAL_CRYP_STATE_READY; 03213 __HAL_UNLOCK(hcryp); 03214 HAL_CRYP_ErrorCallback(hcryp); 03215 } 03216 03217 /* Read data to discard */ 03218 /* Clear CCF Flag */ 03219 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR); 03220 for(index=0U ; index < 4U; index ++) 03221 { 03222 intermediate_data[index] = hcryp->Instance->DOUTR; 03223 } 03224 03225 } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */ 03226 #endif /* !defined(AES_CR_NPBLB) */ 03227 } /* if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) */ 03228 03229 } 03230 03231 /** 03232 * @} 03233 */ 03234 03235 /** 03236 * @} 03237 */ 03238 03239 /** 03240 * @} 03241 */ 03242 03243 #endif /* AES */ 03244 03245 #endif /* HAL_CRYP_MODULE_ENABLED */