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