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