STM32F439xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_cryp_ex.c 00004 * @author MCD Application Team 00005 * @brief Extended CRYP HAL module driver 00006 * This file provides firmware functions to manage the following 00007 * functionalities of CRYP extension peripheral: 00008 * + Extended AES processing functions 00009 * 00010 @verbatim 00011 ============================================================================== 00012 ##### How to use this driver ##### 00013 ============================================================================== 00014 [..] 00015 The CRYP Extension HAL driver can be used as follows: 00016 (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit(): 00017 (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE() 00018 (##) In case of using interrupts (e.g. HAL_CRYPEx_AESGCM_Encrypt_IT()) 00019 (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority() 00020 (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ() 00021 (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler() 00022 (##) In case of using DMA to control data transfer (e.g. HAL_AES_ECB_Encrypt_DMA()) 00023 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE() 00024 (+++) Configure and enable two DMA streams one for managing data transfer from 00025 memory to peripheral (input stream) and another stream for managing data 00026 transfer from peripheral to memory (output stream) 00027 (+++) Associate the initialized DMA handle to the CRYP DMA handle 00028 using __HAL_LINKDMA() 00029 (+++) Configure the priority and enable the NVIC for the transfer complete 00030 interrupt on the two DMA Streams. The output stream should have higher 00031 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ() 00032 (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly: 00033 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit 00034 (##) The key size: 128, 192 and 256. This parameter is relevant only for AES 00035 (##) The encryption/decryption key. Its size depends on the algorithm 00036 used for encryption/decryption 00037 (##) The initialization vector (counter). It is not used ECB mode. 00038 (#)Three processing (encryption/decryption) functions are available: 00039 (##) Polling mode: encryption and decryption APIs are blocking functions 00040 i.e. they process the data and wait till the processing is finished 00041 e.g. HAL_CRYPEx_AESGCM_Encrypt() 00042 (##) Interrupt mode: encryption and decryption APIs are not blocking functions 00043 i.e. they process the data under interrupt 00044 e.g. HAL_CRYPEx_AESGCM_Encrypt_IT() 00045 (##) DMA mode: encryption and decryption APIs are not blocking functions 00046 i.e. the data transfer is ensured by DMA 00047 e.g. HAL_CRYPEx_AESGCM_Encrypt_DMA() 00048 (#)When the processing function is called at first time after HAL_CRYP_Init() 00049 the CRYP peripheral is initialized and processes the buffer in input. 00050 At second call, the processing function performs an append of the already 00051 processed buffer. 00052 When a new data block is to be processed, call HAL_CRYP_Init() then the 00053 processing function. 00054 (#)In AES-GCM and AES-CCM modes are an authenticated encryption algorithms 00055 which provide authentication messages. 00056 HAL_AES_GCM_Finish() and HAL_AES_CCM_Finish() are used to provide those 00057 authentication messages. 00058 Call those functions after the processing ones (polling, interrupt or DMA). 00059 e.g. in AES-CCM mode call HAL_CRYPEx_AESCCM_Encrypt() to encrypt the plain data 00060 then call HAL_CRYPEx_AESCCM_Finish() to get the authentication message 00061 -@- For CCM Encrypt/Decrypt API's, only DataType = 8-bit is supported by this version. 00062 -@- The HAL_CRYPEx_AESGCM_xxxx() implementation is limited to 32bits inputs data length 00063 (Plain/Cyphertext, Header) compared with GCM standards specifications (800-38D). 00064 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral. 00065 00066 @endverbatim 00067 ****************************************************************************** 00068 * @attention 00069 * 00070 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00071 * 00072 * Redistribution and use in source and binary forms, with or without modification, 00073 * are permitted provided that the following conditions are met: 00074 * 1. Redistributions of source code must retain the above copyright notice, 00075 * this list of conditions and the following disclaimer. 00076 * 2. Redistributions in binary form must reproduce the above copyright notice, 00077 * this list of conditions and the following disclaimer in the documentation 00078 * and/or other materials provided with the distribution. 00079 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00080 * may be used to endorse or promote products derived from this software 00081 * without specific prior written permission. 00082 * 00083 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00084 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00085 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00086 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00087 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00088 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00089 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00090 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00091 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00092 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00093 * 00094 ****************************************************************************** 00095 */ 00096 00097 /* Includes ------------------------------------------------------------------*/ 00098 #include "stm32f4xx_hal.h" 00099 00100 /** @addtogroup STM32F4xx_HAL_Driver 00101 * @{ 00102 */ 00103 00104 /** @defgroup CRYPEx CRYPEx 00105 * @brief CRYP Extension HAL module driver. 00106 * @{ 00107 */ 00108 00109 #ifdef HAL_CRYP_MODULE_ENABLED 00110 00111 #if defined(CRYP) 00112 00113 /* Private typedef -----------------------------------------------------------*/ 00114 /* Private define ------------------------------------------------------------*/ 00115 /** @addtogroup CRYPEx_Private_define 00116 * @{ 00117 */ 00118 #define CRYPEx_TIMEOUT_VALUE 1U 00119 /** 00120 * @} 00121 */ 00122 00123 /* Private macro -------------------------------------------------------------*/ 00124 /* Private variables ---------------------------------------------------------*/ 00125 /* Private function prototypes -----------------------------------------------*/ 00126 /** @defgroup CRYPEx_Private_Functions_prototypes CRYP Private Functions Prototypes 00127 * @{ 00128 */ 00129 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector); 00130 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize); 00131 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout); 00132 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout); 00133 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma); 00134 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma); 00135 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma); 00136 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr); 00137 /** 00138 * @} 00139 */ 00140 00141 /* Private functions ---------------------------------------------------------*/ 00142 /** @addtogroup CRYPEx_Private_Functions 00143 * @{ 00144 */ 00145 00146 /** 00147 * @brief DMA CRYP Input Data process complete callback. 00148 * @param hdma DMA handle 00149 * @retval None 00150 */ 00151 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma) 00152 { 00153 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 00154 00155 /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit 00156 in the DMACR register */ 00157 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN); 00158 00159 /* Call input data transfer complete callback */ 00160 HAL_CRYP_InCpltCallback(hcryp); 00161 } 00162 00163 /** 00164 * @brief DMA CRYP Output Data process complete callback. 00165 * @param hdma DMA handle 00166 * @retval None 00167 */ 00168 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma) 00169 { 00170 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 00171 00172 /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit 00173 in the DMACR register */ 00174 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN); 00175 00176 /* Enable the CRYP peripheral */ 00177 __HAL_CRYP_DISABLE(hcryp); 00178 00179 /* Change the CRYP peripheral state */ 00180 hcryp->State = HAL_CRYP_STATE_READY; 00181 00182 /* Call output data transfer complete callback */ 00183 HAL_CRYP_OutCpltCallback(hcryp); 00184 } 00185 00186 /** 00187 * @brief DMA CRYP communication error callback. 00188 * @param hdma DMA handle 00189 * @retval None 00190 */ 00191 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma) 00192 { 00193 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 00194 hcryp->State= HAL_CRYP_STATE_READY; 00195 HAL_CRYP_ErrorCallback(hcryp); 00196 } 00197 00198 /** 00199 * @brief Writes the Key in Key registers. 00200 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00201 * the configuration information for CRYP module 00202 * @param Key Pointer to Key buffer 00203 * @param KeySize Size of Key 00204 * @retval None 00205 */ 00206 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize) 00207 { 00208 uint32_t keyaddr = (uint32_t)Key; 00209 00210 switch(KeySize) 00211 { 00212 case CRYP_KEYSIZE_256B: 00213 /* Key Initialisation */ 00214 hcryp->Instance->K0LR = __REV(*(uint32_t*)(keyaddr)); 00215 keyaddr+=4U; 00216 hcryp->Instance->K0RR = __REV(*(uint32_t*)(keyaddr)); 00217 keyaddr+=4U; 00218 hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr)); 00219 keyaddr+=4U; 00220 hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr)); 00221 keyaddr+=4U; 00222 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr)); 00223 keyaddr+=4U; 00224 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr)); 00225 keyaddr+=4U; 00226 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr)); 00227 keyaddr+=4U; 00228 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr)); 00229 break; 00230 case CRYP_KEYSIZE_192B: 00231 hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr)); 00232 keyaddr+=4U; 00233 hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr)); 00234 keyaddr+=4U; 00235 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr)); 00236 keyaddr+=4U; 00237 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr)); 00238 keyaddr+=4U; 00239 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr)); 00240 keyaddr+=4U; 00241 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr)); 00242 break; 00243 case CRYP_KEYSIZE_128B: 00244 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr)); 00245 keyaddr+=4U; 00246 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr)); 00247 keyaddr+=4U; 00248 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr)); 00249 keyaddr+=4U; 00250 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr)); 00251 break; 00252 default: 00253 break; 00254 } 00255 } 00256 00257 /** 00258 * @brief Writes the InitVector/InitCounter in IV registers. 00259 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00260 * the configuration information for CRYP module 00261 * @param InitVector Pointer to InitVector/InitCounter buffer 00262 * @retval None 00263 */ 00264 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector) 00265 { 00266 uint32_t ivaddr = (uint32_t)InitVector; 00267 00268 hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr)); 00269 ivaddr+=4U; 00270 hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr)); 00271 ivaddr+=4U; 00272 hcryp->Instance->IV1LR = __REV(*(uint32_t*)(ivaddr)); 00273 ivaddr+=4U; 00274 hcryp->Instance->IV1RR = __REV(*(uint32_t*)(ivaddr)); 00275 } 00276 00277 /** 00278 * @brief Process Data: Writes Input data in polling mode and read the Output data. 00279 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00280 * the configuration information for CRYP module 00281 * @param Input Pointer to the Input buffer. 00282 * @param Ilength Length of the Input buffer, must be a multiple of 16 00283 * @param Output Pointer to the returned buffer 00284 * @param Timeout Timeout value 00285 * @retval None 00286 */ 00287 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout) 00288 { 00289 uint32_t tickstart = 0U; 00290 uint32_t i = 0U; 00291 uint32_t inputaddr = (uint32_t)Input; 00292 uint32_t outputaddr = (uint32_t)Output; 00293 00294 for(i=0U; (i < Ilength); i+=16U) 00295 { 00296 /* Write the Input block in the IN FIFO */ 00297 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 00298 inputaddr+=4U; 00299 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 00300 inputaddr+=4U; 00301 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 00302 inputaddr+=4U; 00303 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 00304 inputaddr+=4U; 00305 00306 /* Get tick */ 00307 tickstart = HAL_GetTick(); 00308 00309 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) 00310 { 00311 /* Check for the Timeout */ 00312 if(Timeout != HAL_MAX_DELAY) 00313 { 00314 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 00315 { 00316 /* Change state */ 00317 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 00318 00319 /* Process Unlocked */ 00320 __HAL_UNLOCK(hcryp); 00321 00322 return HAL_TIMEOUT; 00323 } 00324 } 00325 } 00326 /* Read the Output block from the OUT FIFO */ 00327 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 00328 outputaddr+=4U; 00329 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 00330 outputaddr+=4U; 00331 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 00332 outputaddr+=4U; 00333 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 00334 outputaddr+=4U; 00335 } 00336 /* Return function status */ 00337 return HAL_OK; 00338 } 00339 00340 /** 00341 * @brief Sets the header phase 00342 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00343 * the configuration information for CRYP module 00344 * @param Input Pointer to the Input buffer. 00345 * @param Ilength Length of the Input buffer, must be a multiple of 16 00346 * @param Timeout Timeout value 00347 * @retval None 00348 */ 00349 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout) 00350 { 00351 uint32_t tickstart = 0U; 00352 uint32_t loopcounter = 0U; 00353 uint32_t headeraddr = (uint32_t)Input; 00354 00355 /* Prevent unused argument(s) compilation warning */ 00356 UNUSED(Ilength); 00357 00358 /***************************** Header phase *********************************/ 00359 if(hcryp->Init.HeaderSize != 0U) 00360 { 00361 /* Select header phase */ 00362 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 00363 /* Enable the CRYP peripheral */ 00364 __HAL_CRYP_ENABLE(hcryp); 00365 00366 for(loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter+=16U) 00367 { 00368 /* Get tick */ 00369 tickstart = HAL_GetTick(); 00370 00371 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) 00372 { 00373 /* Check for the Timeout */ 00374 if(Timeout != HAL_MAX_DELAY) 00375 { 00376 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00377 { 00378 /* Change state */ 00379 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 00380 00381 /* Process Unlocked */ 00382 __HAL_UNLOCK(hcryp); 00383 00384 return HAL_TIMEOUT; 00385 } 00386 } 00387 } 00388 /* Write the Input block in the IN FIFO */ 00389 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 00390 headeraddr+=4U; 00391 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 00392 headeraddr+=4U; 00393 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 00394 headeraddr+=4U; 00395 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 00396 headeraddr+=4U; 00397 } 00398 00399 /* Wait until the complete message has been processed */ 00400 00401 /* Get tick */ 00402 tickstart = HAL_GetTick(); 00403 00404 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) 00405 { 00406 /* Check for the Timeout */ 00407 if(Timeout != HAL_MAX_DELAY) 00408 { 00409 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00410 { 00411 /* Change state */ 00412 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 00413 00414 /* Process Unlocked */ 00415 __HAL_UNLOCK(hcryp); 00416 00417 return HAL_TIMEOUT; 00418 } 00419 } 00420 } 00421 } 00422 /* Return function status */ 00423 return HAL_OK; 00424 } 00425 00426 /** 00427 * @brief Sets the DMA configuration and start the DMA transfer. 00428 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00429 * the configuration information for CRYP module 00430 * @param inputaddr Address of the Input buffer 00431 * @param Size Size of the Input buffer, must be a multiple of 16 00432 * @param outputaddr Address of the Output buffer 00433 * @retval None 00434 */ 00435 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr) 00436 { 00437 /* Set the CRYP DMA transfer complete callback */ 00438 hcryp->hdmain->XferCpltCallback = CRYPEx_GCMCCM_DMAInCplt; 00439 /* Set the DMA error callback */ 00440 hcryp->hdmain->XferErrorCallback = CRYPEx_GCMCCM_DMAError; 00441 00442 /* Set the CRYP DMA transfer complete callback */ 00443 hcryp->hdmaout->XferCpltCallback = CRYPEx_GCMCCM_DMAOutCplt; 00444 /* Set the DMA error callback */ 00445 hcryp->hdmaout->XferErrorCallback = CRYPEx_GCMCCM_DMAError; 00446 00447 /* Enable the CRYP peripheral */ 00448 __HAL_CRYP_ENABLE(hcryp); 00449 00450 /* Enable the DMA In DMA Stream */ 00451 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DR, Size/4U); 00452 00453 /* Enable In DMA request */ 00454 hcryp->Instance->DMACR = CRYP_DMACR_DIEN; 00455 00456 /* Enable the DMA Out DMA Stream */ 00457 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size/4U); 00458 00459 /* Enable Out DMA request */ 00460 hcryp->Instance->DMACR |= CRYP_DMACR_DOEN; 00461 } 00462 00463 /** 00464 * @} 00465 */ 00466 00467 /* Exported functions---------------------------------------------------------*/ 00468 /** @addtogroup CRYPEx_Exported_Functions 00469 * @{ 00470 */ 00471 00472 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions 00473 * @brief Extended processing functions. 00474 * 00475 @verbatim 00476 ============================================================================== 00477 ##### Extended AES processing functions ##### 00478 ============================================================================== 00479 [..] This section provides functions allowing to: 00480 (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes 00481 (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes 00482 (+) Finish the processing. This function is available only for GCM and CCM 00483 [..] Three processing methods are available: 00484 (+) Polling mode 00485 (+) Interrupt mode 00486 (+) DMA mode 00487 00488 @endverbatim 00489 * @{ 00490 */ 00491 00492 00493 /** 00494 * @brief Initializes the CRYP peripheral in AES CCM encryption mode then 00495 * encrypt pPlainData. The cypher data are available in pCypherData. 00496 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00497 * the configuration information for CRYP module 00498 * @param pPlainData Pointer to the plaintext buffer 00499 * @param Size Length of the plaintext buffer, must be a multiple of 16 00500 * @param pCypherData Pointer to the cyphertext buffer 00501 * @param Timeout Timeout duration 00502 * @retval HAL status 00503 */ 00504 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) 00505 { 00506 uint32_t tickstart = 0U; 00507 uint32_t headersize = hcryp->Init.HeaderSize; 00508 uint32_t headeraddr = (uint32_t)hcryp->Init.Header; 00509 uint32_t loopcounter = 0U; 00510 uint32_t bufferidx = 0U; 00511 uint8_t blockb0[16U] = {0};/* Block B0 */ 00512 uint8_t ctr[16U] = {0}; /* Counter */ 00513 uint32_t b0addr = (uint32_t)blockb0; 00514 00515 /* Process Locked */ 00516 __HAL_LOCK(hcryp); 00517 00518 /* Change the CRYP peripheral state */ 00519 hcryp->State = HAL_CRYP_STATE_BUSY; 00520 00521 /* Check if initialization phase has already been performed */ 00522 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 00523 { 00524 /************************ Formatting the header block *********************/ 00525 if(headersize != 0U) 00526 { 00527 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ 00528 if(headersize < 65280U) 00529 { 00530 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); 00531 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); 00532 headersize += 2U; 00533 } 00534 else 00535 { 00536 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ 00537 hcryp->Init.pScratch[bufferidx++] = 0xFFU; 00538 hcryp->Init.pScratch[bufferidx++] = 0xFEU; 00539 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U; 00540 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U; 00541 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U; 00542 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU; 00543 headersize += 6U; 00544 } 00545 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ 00546 for(loopcounter = 0U; loopcounter < headersize; loopcounter++) 00547 { 00548 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; 00549 } 00550 /* Check if the header size is modulo 16 */ 00551 if ((headersize % 16U) != 0U) 00552 { 00553 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ 00554 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++) 00555 { 00556 hcryp->Init.pScratch[loopcounter] = 0U; 00557 } 00558 /* Set the header size to modulo 16 */ 00559 headersize = ((headersize/16U) + 1U) * 16U; 00560 } 00561 /* Set the pointer headeraddr to hcryp->Init.pScratch */ 00562 headeraddr = (uint32_t)hcryp->Init.pScratch; 00563 } 00564 /*********************** Formatting the block B0 **************************/ 00565 if(headersize != 0U) 00566 { 00567 blockb0[0U] = 0x40U; 00568 } 00569 /* Flags byte */ 00570 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */ 00571 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U); 00572 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); 00573 00574 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++) 00575 { 00576 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter]; 00577 } 00578 for ( ; loopcounter < 13U; loopcounter++) 00579 { 00580 blockb0[loopcounter+1U] = 0U; 00581 } 00582 00583 blockb0[14U] = (Size >> 8U); 00584 blockb0[15U] = (Size & 0xFFU); 00585 00586 /************************* Formatting the initial counter *****************/ 00587 /* Byte 0: 00588 Bits 7 and 6 are reserved and shall be set to 0 00589 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks 00590 are distinct from B0 00591 Bits 0, 1, and 2 contain the same encoding of q as in B0 00592 */ 00593 ctr[0U] = blockb0[0U] & 0x07U; 00594 /* byte 1 to NonceSize is the IV (Nonce) */ 00595 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++) 00596 { 00597 ctr[loopcounter] = blockb0[loopcounter]; 00598 } 00599 /* Set the LSB to 1 */ 00600 ctr[15U] |= 0x01U; 00601 00602 /* Set the key */ 00603 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 00604 00605 /* Set the CRYP peripheral in AES CCM mode */ 00606 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT); 00607 00608 /* Set the Initialization Vector */ 00609 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); 00610 00611 /* Select init phase */ 00612 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 00613 00614 b0addr = (uint32_t)blockb0; 00615 /* Write the blockb0 block in the IN FIFO */ 00616 hcryp->Instance->DR = *(uint32_t*)(b0addr); 00617 b0addr+=4U; 00618 hcryp->Instance->DR = *(uint32_t*)(b0addr); 00619 b0addr+=4U; 00620 hcryp->Instance->DR = *(uint32_t*)(b0addr); 00621 b0addr+=4U; 00622 hcryp->Instance->DR = *(uint32_t*)(b0addr); 00623 00624 /* Enable the CRYP peripheral */ 00625 __HAL_CRYP_ENABLE(hcryp); 00626 00627 /* Get tick */ 00628 tickstart = HAL_GetTick(); 00629 00630 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 00631 { 00632 /* Check for the Timeout */ 00633 if(Timeout != HAL_MAX_DELAY) 00634 { 00635 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00636 { 00637 /* Change state */ 00638 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 00639 00640 /* Process Unlocked */ 00641 __HAL_UNLOCK(hcryp); 00642 00643 return HAL_TIMEOUT; 00644 } 00645 } 00646 } 00647 /***************************** Header phase *******************************/ 00648 if(headersize != 0U) 00649 { 00650 /* Select header phase */ 00651 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 00652 00653 /* Enable the CRYP peripheral */ 00654 __HAL_CRYP_ENABLE(hcryp); 00655 00656 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U) 00657 { 00658 /* Get tick */ 00659 tickstart = HAL_GetTick(); 00660 00661 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) 00662 { 00663 { 00664 /* Check for the Timeout */ 00665 if(Timeout != HAL_MAX_DELAY) 00666 { 00667 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00668 { 00669 /* Change state */ 00670 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 00671 00672 /* Process Unlocked */ 00673 __HAL_UNLOCK(hcryp); 00674 00675 return HAL_TIMEOUT; 00676 } 00677 } 00678 } 00679 } 00680 /* Write the header block in the IN FIFO */ 00681 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 00682 headeraddr+=4U; 00683 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 00684 headeraddr+=4U; 00685 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 00686 headeraddr+=4U; 00687 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 00688 headeraddr+=4U; 00689 } 00690 00691 /* Get tick */ 00692 tickstart = HAL_GetTick(); 00693 00694 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) 00695 { 00696 /* Check for the Timeout */ 00697 if(Timeout != HAL_MAX_DELAY) 00698 { 00699 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00700 { 00701 /* Change state */ 00702 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 00703 00704 /* Process Unlocked */ 00705 __HAL_UNLOCK(hcryp); 00706 00707 return HAL_TIMEOUT; 00708 } 00709 } 00710 } 00711 } 00712 /* Save formatted counter into the scratch buffer pScratch */ 00713 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++) 00714 { 00715 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; 00716 } 00717 /* Reset bit 0 */ 00718 hcryp->Init.pScratch[15U] &= 0xFEU; 00719 00720 /* Select payload phase once the header phase is performed */ 00721 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 00722 00723 /* Flush FIFO */ 00724 __HAL_CRYP_FIFO_FLUSH(hcryp); 00725 00726 /* Enable the CRYP peripheral */ 00727 __HAL_CRYP_ENABLE(hcryp); 00728 00729 /* Set the phase */ 00730 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 00731 } 00732 00733 /* Write Plain Data and Get Cypher Data */ 00734 if(CRYPEx_GCMCCM_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK) 00735 { 00736 return HAL_TIMEOUT; 00737 } 00738 00739 /* Change the CRYP peripheral state */ 00740 hcryp->State = HAL_CRYP_STATE_READY; 00741 00742 /* Process Unlocked */ 00743 __HAL_UNLOCK(hcryp); 00744 00745 /* Return function status */ 00746 return HAL_OK; 00747 } 00748 00749 /** 00750 * @brief Initializes the CRYP peripheral in AES GCM encryption mode then 00751 * encrypt pPlainData. The cypher data are available in pCypherData. 00752 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00753 * the configuration information for CRYP module 00754 * @param pPlainData Pointer to the plaintext buffer 00755 * @param Size Length of the plaintext buffer, must be a multiple of 16 00756 * @param pCypherData Pointer to the cyphertext buffer 00757 * @param Timeout Timeout duration 00758 * @retval HAL status 00759 */ 00760 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) 00761 { 00762 uint32_t tickstart = 0U; 00763 00764 /* Process Locked */ 00765 __HAL_LOCK(hcryp); 00766 00767 /* Change the CRYP peripheral state */ 00768 hcryp->State = HAL_CRYP_STATE_BUSY; 00769 00770 /* Check if initialization phase has already been performed */ 00771 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 00772 { 00773 /* Set the key */ 00774 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 00775 00776 /* Set the CRYP peripheral in AES GCM mode */ 00777 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT); 00778 00779 /* Set the Initialization Vector */ 00780 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); 00781 00782 /* Flush FIFO */ 00783 __HAL_CRYP_FIFO_FLUSH(hcryp); 00784 00785 /* Enable the CRYP peripheral */ 00786 __HAL_CRYP_ENABLE(hcryp); 00787 00788 /* Get tick */ 00789 tickstart = HAL_GetTick(); 00790 00791 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 00792 { 00793 /* Check for the Timeout */ 00794 if(Timeout != HAL_MAX_DELAY) 00795 { 00796 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00797 { 00798 /* Change state */ 00799 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 00800 00801 /* Process Unlocked */ 00802 __HAL_UNLOCK(hcryp); 00803 00804 return HAL_TIMEOUT; 00805 } 00806 } 00807 } 00808 00809 /* Set the header phase */ 00810 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK) 00811 { 00812 return HAL_TIMEOUT; 00813 } 00814 00815 /* Disable the CRYP peripheral */ 00816 __HAL_CRYP_DISABLE(hcryp); 00817 00818 /* Select payload phase once the header phase is performed */ 00819 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 00820 00821 /* Flush FIFO */ 00822 __HAL_CRYP_FIFO_FLUSH(hcryp); 00823 00824 /* Enable the CRYP peripheral */ 00825 __HAL_CRYP_ENABLE(hcryp); 00826 00827 /* Set the phase */ 00828 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 00829 } 00830 00831 /* Write Plain Data and Get Cypher Data */ 00832 if(CRYPEx_GCMCCM_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) 00833 { 00834 return HAL_TIMEOUT; 00835 } 00836 00837 /* Change the CRYP peripheral state */ 00838 hcryp->State = HAL_CRYP_STATE_READY; 00839 00840 /* Process Unlocked */ 00841 __HAL_UNLOCK(hcryp); 00842 00843 /* Return function status */ 00844 return HAL_OK; 00845 } 00846 00847 /** 00848 * @brief Initializes the CRYP peripheral in AES GCM decryption mode then 00849 * decrypted pCypherData. The cypher data are available in pPlainData. 00850 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00851 * the configuration information for CRYP module 00852 * @param pCypherData Pointer to the cyphertext buffer 00853 * @param Size Length of the cyphertext buffer, must be a multiple of 16 00854 * @param pPlainData Pointer to the plaintext buffer 00855 * @param Timeout Timeout duration 00856 * @retval HAL status 00857 */ 00858 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout) 00859 { 00860 uint32_t tickstart = 0U; 00861 00862 /* Process Locked */ 00863 __HAL_LOCK(hcryp); 00864 00865 /* Change the CRYP peripheral state */ 00866 hcryp->State = HAL_CRYP_STATE_BUSY; 00867 00868 /* Check if initialization phase has already been performed */ 00869 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 00870 { 00871 /* Set the key */ 00872 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 00873 00874 /* Set the CRYP peripheral in AES GCM decryption mode */ 00875 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT); 00876 00877 /* Set the Initialization Vector */ 00878 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); 00879 00880 /* Flush FIFO */ 00881 __HAL_CRYP_FIFO_FLUSH(hcryp); 00882 00883 /* Enable the CRYP peripheral */ 00884 __HAL_CRYP_ENABLE(hcryp); 00885 00886 /* Get tick */ 00887 tickstart = HAL_GetTick(); 00888 00889 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 00890 { 00891 /* Check for the Timeout */ 00892 if(Timeout != HAL_MAX_DELAY) 00893 { 00894 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00895 { 00896 /* Change state */ 00897 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 00898 00899 /* Process Unlocked */ 00900 __HAL_UNLOCK(hcryp); 00901 00902 return HAL_TIMEOUT; 00903 } 00904 } 00905 } 00906 00907 /* Set the header phase */ 00908 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK) 00909 { 00910 return HAL_TIMEOUT; 00911 } 00912 /* Disable the CRYP peripheral */ 00913 __HAL_CRYP_DISABLE(hcryp); 00914 00915 /* Select payload phase once the header phase is performed */ 00916 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 00917 00918 /* Enable the CRYP peripheral */ 00919 __HAL_CRYP_ENABLE(hcryp); 00920 00921 /* Set the phase */ 00922 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 00923 } 00924 00925 /* Write Plain Data and Get Cypher Data */ 00926 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK) 00927 { 00928 return HAL_TIMEOUT; 00929 } 00930 00931 /* Change the CRYP peripheral state */ 00932 hcryp->State = HAL_CRYP_STATE_READY; 00933 00934 /* Process Unlocked */ 00935 __HAL_UNLOCK(hcryp); 00936 00937 /* Return function status */ 00938 return HAL_OK; 00939 } 00940 00941 /** 00942 * @brief Computes the authentication TAG. 00943 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 00944 * the configuration information for CRYP module 00945 * @param Size Total length of the plain/cyphertext buffer 00946 * @param AuthTag Pointer to the authentication buffer 00947 * @param Timeout Timeout duration 00948 * @retval HAL status 00949 */ 00950 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint32_t Size, uint8_t *AuthTag, uint32_t Timeout) 00951 { 00952 uint32_t tickstart = 0U; 00953 uint64_t headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */ 00954 uint64_t inputlength = Size * 8U; /* input length in bits */ 00955 uint32_t tagaddr = (uint32_t)AuthTag; 00956 00957 /* Process Locked */ 00958 __HAL_LOCK(hcryp); 00959 00960 /* Change the CRYP peripheral state */ 00961 hcryp->State = HAL_CRYP_STATE_BUSY; 00962 00963 /* Check if initialization phase has already been performed */ 00964 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS) 00965 { 00966 /* Change the CRYP phase */ 00967 hcryp->Phase = HAL_CRYP_PHASE_FINAL; 00968 00969 /* Disable CRYP to start the final phase */ 00970 __HAL_CRYP_DISABLE(hcryp); 00971 00972 /* Select final phase */ 00973 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL); 00974 00975 /* Enable the CRYP peripheral */ 00976 __HAL_CRYP_ENABLE(hcryp); 00977 00978 /* Write the number of bits in header (64 bits) followed by the number of bits 00979 in the payload */ 00980 if(hcryp->Init.DataType == CRYP_DATATYPE_1B) 00981 { 00982 hcryp->Instance->DR = __RBIT(headerlength >> 32U); 00983 hcryp->Instance->DR = __RBIT(headerlength); 00984 hcryp->Instance->DR = __RBIT(inputlength >> 32U); 00985 hcryp->Instance->DR = __RBIT(inputlength); 00986 } 00987 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B) 00988 { 00989 hcryp->Instance->DR = __REV(headerlength >> 32U); 00990 hcryp->Instance->DR = __REV(headerlength); 00991 hcryp->Instance->DR = __REV(inputlength >> 32U); 00992 hcryp->Instance->DR = __REV(inputlength); 00993 } 00994 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B) 00995 { 00996 hcryp->Instance->DR = __ROR((uint32_t)(headerlength >> 32U), 16U); 00997 hcryp->Instance->DR = __ROR((uint32_t)headerlength, 16U); 00998 hcryp->Instance->DR = __ROR((uint32_t)(inputlength >> 32U), 16U); 00999 hcryp->Instance->DR = __ROR((uint32_t)inputlength, 16U); 01000 } 01001 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B) 01002 { 01003 hcryp->Instance->DR = (uint32_t)(headerlength >> 32U); 01004 hcryp->Instance->DR = (uint32_t)(headerlength); 01005 hcryp->Instance->DR = (uint32_t)(inputlength >> 32U); 01006 hcryp->Instance->DR = (uint32_t)(inputlength); 01007 } 01008 /* Get tick */ 01009 tickstart = HAL_GetTick(); 01010 01011 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) 01012 { 01013 /* Check for the Timeout */ 01014 if(Timeout != HAL_MAX_DELAY) 01015 { 01016 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 01017 { 01018 /* Change state */ 01019 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01020 01021 /* Process Unlocked */ 01022 __HAL_UNLOCK(hcryp); 01023 01024 return HAL_TIMEOUT; 01025 } 01026 } 01027 } 01028 01029 /* Read the Auth TAG in the IN FIFO */ 01030 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; 01031 tagaddr+=4U; 01032 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; 01033 tagaddr+=4U; 01034 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; 01035 tagaddr+=4U; 01036 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; 01037 } 01038 01039 /* Change the CRYP peripheral state */ 01040 hcryp->State = HAL_CRYP_STATE_READY; 01041 01042 /* Process Unlocked */ 01043 __HAL_UNLOCK(hcryp); 01044 01045 /* Return function status */ 01046 return HAL_OK; 01047 } 01048 01049 /** 01050 * @brief Computes the authentication TAG for AES CCM mode. 01051 * @note This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt() 01052 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01053 * the configuration information for CRYP module 01054 * @param AuthTag Pointer to the authentication buffer 01055 * @param Timeout Timeout duration 01056 * @retval HAL status 01057 */ 01058 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout) 01059 { 01060 uint32_t tickstart = 0U; 01061 uint32_t tagaddr = (uint32_t)AuthTag; 01062 uint32_t ctraddr = (uint32_t)hcryp->Init.pScratch; 01063 uint32_t temptag[4U] = {0U}; /* Temporary TAG (MAC) */ 01064 uint32_t loopcounter; 01065 01066 /* Process Locked */ 01067 __HAL_LOCK(hcryp); 01068 01069 /* Change the CRYP peripheral state */ 01070 hcryp->State = HAL_CRYP_STATE_BUSY; 01071 01072 /* Check if initialization phase has already been performed */ 01073 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS) 01074 { 01075 /* Change the CRYP phase */ 01076 hcryp->Phase = HAL_CRYP_PHASE_FINAL; 01077 01078 /* Disable CRYP to start the final phase */ 01079 __HAL_CRYP_DISABLE(hcryp); 01080 01081 /* Select final phase */ 01082 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL); 01083 01084 /* Enable the CRYP peripheral */ 01085 __HAL_CRYP_ENABLE(hcryp); 01086 01087 /* Write the counter block in the IN FIFO */ 01088 hcryp->Instance->DR = *(uint32_t*)ctraddr; 01089 ctraddr+=4U; 01090 hcryp->Instance->DR = *(uint32_t*)ctraddr; 01091 ctraddr+=4U; 01092 hcryp->Instance->DR = *(uint32_t*)ctraddr; 01093 ctraddr+=4U; 01094 hcryp->Instance->DR = *(uint32_t*)ctraddr; 01095 01096 /* Get tick */ 01097 tickstart = HAL_GetTick(); 01098 01099 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) 01100 { 01101 /* Check for the Timeout */ 01102 if(Timeout != HAL_MAX_DELAY) 01103 { 01104 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 01105 { 01106 /* Change state */ 01107 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01108 01109 /* Process Unlocked */ 01110 __HAL_UNLOCK(hcryp); 01111 01112 return HAL_TIMEOUT; 01113 } 01114 } 01115 } 01116 01117 /* Read the Auth TAG in the IN FIFO */ 01118 temptag[0U] = hcryp->Instance->DOUT; 01119 temptag[1U] = hcryp->Instance->DOUT; 01120 temptag[2U] = hcryp->Instance->DOUT; 01121 temptag[3U] = hcryp->Instance->DOUT; 01122 } 01123 01124 /* Copy temporary authentication TAG in user TAG buffer */ 01125 for(loopcounter = 0U; loopcounter < hcryp->Init.TagSize ; loopcounter++) 01126 { 01127 /* Set the authentication TAG buffer */ 01128 *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter); 01129 } 01130 01131 /* Change the CRYP peripheral state */ 01132 hcryp->State = HAL_CRYP_STATE_READY; 01133 01134 /* Process Unlocked */ 01135 __HAL_UNLOCK(hcryp); 01136 01137 /* Return function status */ 01138 return HAL_OK; 01139 } 01140 01141 /** 01142 * @brief Initializes the CRYP peripheral in AES CCM decryption mode then 01143 * decrypted pCypherData. The cypher data are available in pPlainData. 01144 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01145 * the configuration information for CRYP module 01146 * @param pPlainData Pointer to the plaintext buffer 01147 * @param Size Length of the plaintext buffer, must be a multiple of 16 01148 * @param pCypherData Pointer to the cyphertext buffer 01149 * @param Timeout Timeout duration 01150 * @retval HAL status 01151 */ 01152 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout) 01153 { 01154 uint32_t tickstart = 0U; 01155 uint32_t headersize = hcryp->Init.HeaderSize; 01156 uint32_t headeraddr = (uint32_t)hcryp->Init.Header; 01157 uint32_t loopcounter = 0U; 01158 uint32_t bufferidx = 0U; 01159 uint8_t blockb0[16U] = {0};/* Block B0 */ 01160 uint8_t ctr[16U] = {0}; /* Counter */ 01161 uint32_t b0addr = (uint32_t)blockb0; 01162 01163 /* Process Locked */ 01164 __HAL_LOCK(hcryp); 01165 01166 /* Change the CRYP peripheral state */ 01167 hcryp->State = HAL_CRYP_STATE_BUSY; 01168 01169 /* Check if initialization phase has already been performed */ 01170 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 01171 { 01172 /************************ Formatting the header block *********************/ 01173 if(headersize != 0U) 01174 { 01175 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ 01176 if(headersize < 65280U) 01177 { 01178 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); 01179 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); 01180 headersize += 2U; 01181 } 01182 else 01183 { 01184 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ 01185 hcryp->Init.pScratch[bufferidx++] = 0xFFU; 01186 hcryp->Init.pScratch[bufferidx++] = 0xFEU; 01187 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U; 01188 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U; 01189 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U; 01190 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU; 01191 headersize += 6U; 01192 } 01193 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ 01194 for(loopcounter = 0U; loopcounter < headersize; loopcounter++) 01195 { 01196 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; 01197 } 01198 /* Check if the header size is modulo 16 */ 01199 if ((headersize % 16U) != 0U) 01200 { 01201 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ 01202 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++) 01203 { 01204 hcryp->Init.pScratch[loopcounter] = 0U; 01205 } 01206 /* Set the header size to modulo 16 */ 01207 headersize = ((headersize/16U) + 1U) * 16U; 01208 } 01209 /* Set the pointer headeraddr to hcryp->Init.pScratch */ 01210 headeraddr = (uint32_t)hcryp->Init.pScratch; 01211 } 01212 /*********************** Formatting the block B0 **************************/ 01213 if(headersize != 0U) 01214 { 01215 blockb0[0U] = 0x40U; 01216 } 01217 /* Flags byte */ 01218 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */ 01219 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2U))) >> 1U) & (uint8_t)0x07U) << 3U); 01220 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15U) - hcryp->Init.IVSize) - (uint8_t)1U) & (uint8_t)0x07U); 01221 01222 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++) 01223 { 01224 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter]; 01225 } 01226 for ( ; loopcounter < 13U; loopcounter++) 01227 { 01228 blockb0[loopcounter+1U] = 0U; 01229 } 01230 01231 blockb0[14U] = (Size >> 8U); 01232 blockb0[15U] = (Size & 0xFFU); 01233 01234 /************************* Formatting the initial counter *****************/ 01235 /* Byte 0: 01236 Bits 7 and 6 are reserved and shall be set to 0 01237 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 01238 blocks are distinct from B0 01239 Bits 0, 1, and 2 contain the same encoding of q as in B0 01240 */ 01241 ctr[0U] = blockb0[0U] & 0x07U; 01242 /* byte 1 to NonceSize is the IV (Nonce) */ 01243 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++) 01244 { 01245 ctr[loopcounter] = blockb0[loopcounter]; 01246 } 01247 /* Set the LSB to 1 */ 01248 ctr[15U] |= 0x01U; 01249 01250 /* Set the key */ 01251 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 01252 01253 /* Set the CRYP peripheral in AES CCM mode */ 01254 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT); 01255 01256 /* Set the Initialization Vector */ 01257 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); 01258 01259 /* Select init phase */ 01260 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 01261 01262 b0addr = (uint32_t)blockb0; 01263 /* Write the blockb0 block in the IN FIFO */ 01264 hcryp->Instance->DR = *(uint32_t*)(b0addr); 01265 b0addr+=4U; 01266 hcryp->Instance->DR = *(uint32_t*)(b0addr); 01267 b0addr+=4U; 01268 hcryp->Instance->DR = *(uint32_t*)(b0addr); 01269 b0addr+=4U; 01270 hcryp->Instance->DR = *(uint32_t*)(b0addr); 01271 01272 /* Enable the CRYP peripheral */ 01273 __HAL_CRYP_ENABLE(hcryp); 01274 01275 /* Get tick */ 01276 tickstart = HAL_GetTick(); 01277 01278 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 01279 { 01280 /* Check for the Timeout */ 01281 if(Timeout != HAL_MAX_DELAY) 01282 { 01283 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 01284 { 01285 /* Change state */ 01286 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01287 01288 /* Process Unlocked */ 01289 __HAL_UNLOCK(hcryp); 01290 01291 return HAL_TIMEOUT; 01292 } 01293 } 01294 } 01295 /***************************** Header phase *******************************/ 01296 if(headersize != 0U) 01297 { 01298 /* Select header phase */ 01299 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 01300 01301 /* Enable Crypto processor */ 01302 __HAL_CRYP_ENABLE(hcryp); 01303 01304 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U) 01305 { 01306 /* Get tick */ 01307 tickstart = HAL_GetTick(); 01308 01309 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) 01310 { 01311 /* Check for the Timeout */ 01312 if(Timeout != HAL_MAX_DELAY) 01313 { 01314 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 01315 { 01316 /* Change state */ 01317 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01318 01319 /* Process Unlocked */ 01320 __HAL_UNLOCK(hcryp); 01321 01322 return HAL_TIMEOUT; 01323 } 01324 } 01325 } 01326 /* Write the header block in the IN FIFO */ 01327 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 01328 headeraddr+=4U; 01329 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 01330 headeraddr+=4U; 01331 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 01332 headeraddr+=4U; 01333 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 01334 headeraddr+=4U; 01335 } 01336 01337 /* Get tick */ 01338 tickstart = HAL_GetTick(); 01339 01340 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) 01341 { 01342 /* Check for the Timeout */ 01343 if(Timeout != HAL_MAX_DELAY) 01344 { 01345 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 01346 { 01347 /* Change state */ 01348 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01349 01350 /* Process Unlocked */ 01351 __HAL_UNLOCK(hcryp); 01352 01353 return HAL_TIMEOUT; 01354 } 01355 } 01356 } 01357 } 01358 /* Save formatted counter into the scratch buffer pScratch */ 01359 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++) 01360 { 01361 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; 01362 } 01363 /* Reset bit 0 */ 01364 hcryp->Init.pScratch[15U] &= 0xFEU; 01365 /* Select payload phase once the header phase is performed */ 01366 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 01367 01368 /* Flush FIFO */ 01369 __HAL_CRYP_FIFO_FLUSH(hcryp); 01370 01371 /* Enable the CRYP peripheral */ 01372 __HAL_CRYP_ENABLE(hcryp); 01373 01374 /* Set the phase */ 01375 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 01376 } 01377 01378 /* Write Plain Data and Get Cypher Data */ 01379 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK) 01380 { 01381 return HAL_TIMEOUT; 01382 } 01383 01384 /* Change the CRYP peripheral state */ 01385 hcryp->State = HAL_CRYP_STATE_READY; 01386 01387 /* Process Unlocked */ 01388 __HAL_UNLOCK(hcryp); 01389 01390 /* Return function status */ 01391 return HAL_OK; 01392 } 01393 01394 /** 01395 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using IT. 01396 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01397 * the configuration information for CRYP module 01398 * @param pPlainData Pointer to the plaintext buffer 01399 * @param Size Length of the plaintext buffer, must be a multiple of 16 01400 * @param pCypherData Pointer to the cyphertext buffer 01401 * @retval HAL status 01402 */ 01403 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) 01404 { 01405 uint32_t tickstart = 0U; 01406 uint32_t inputaddr; 01407 uint32_t outputaddr; 01408 01409 if(hcryp->State == HAL_CRYP_STATE_READY) 01410 { 01411 /* Process Locked */ 01412 __HAL_LOCK(hcryp); 01413 01414 /* Get the buffer addresses and sizes */ 01415 hcryp->CrypInCount = Size; 01416 hcryp->pCrypInBuffPtr = pPlainData; 01417 hcryp->pCrypOutBuffPtr = pCypherData; 01418 hcryp->CrypOutCount = Size; 01419 01420 /* Change the CRYP peripheral state */ 01421 hcryp->State = HAL_CRYP_STATE_BUSY; 01422 01423 /* Check if initialization phase has already been performed */ 01424 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 01425 { 01426 /* Set the key */ 01427 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 01428 01429 /* Set the CRYP peripheral in AES GCM mode */ 01430 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT); 01431 01432 /* Set the Initialization Vector */ 01433 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); 01434 01435 /* Flush FIFO */ 01436 __HAL_CRYP_FIFO_FLUSH(hcryp); 01437 01438 /* Enable CRYP to start the init phase */ 01439 __HAL_CRYP_ENABLE(hcryp); 01440 01441 /* Get tick */ 01442 tickstart = HAL_GetTick(); 01443 01444 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 01445 { 01446 /* Check for the Timeout */ 01447 01448 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 01449 { 01450 /* Change state */ 01451 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01452 01453 /* Process Unlocked */ 01454 __HAL_UNLOCK(hcryp); 01455 01456 return HAL_TIMEOUT; 01457 01458 } 01459 } 01460 01461 /* Set the header phase */ 01462 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK) 01463 { 01464 return HAL_TIMEOUT; 01465 } 01466 /* Disable the CRYP peripheral */ 01467 __HAL_CRYP_DISABLE(hcryp); 01468 01469 /* Select payload phase once the header phase is performed */ 01470 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 01471 01472 /* Flush FIFO */ 01473 __HAL_CRYP_FIFO_FLUSH(hcryp); 01474 01475 /* Set the phase */ 01476 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 01477 } 01478 01479 if(Size != 0U) 01480 { 01481 /* Enable Interrupts */ 01482 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 01483 /* Enable the CRYP peripheral */ 01484 __HAL_CRYP_ENABLE(hcryp); 01485 } 01486 else 01487 { 01488 /* Process Locked */ 01489 __HAL_UNLOCK(hcryp); 01490 /* Change the CRYP state and phase */ 01491 hcryp->State = HAL_CRYP_STATE_READY; 01492 } 01493 /* Return function status */ 01494 return HAL_OK; 01495 } 01496 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) 01497 { 01498 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 01499 /* Write the Input block in the IN FIFO */ 01500 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01501 inputaddr+=4U; 01502 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01503 inputaddr+=4U; 01504 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01505 inputaddr+=4U; 01506 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01507 hcryp->pCrypInBuffPtr += 16U; 01508 hcryp->CrypInCount -= 16U; 01509 if(hcryp->CrypInCount == 0U) 01510 { 01511 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); 01512 /* Call the Input data transfer complete callback */ 01513 HAL_CRYP_InCpltCallback(hcryp); 01514 } 01515 } 01516 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) 01517 { 01518 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 01519 /* Read the Output block from the Output FIFO */ 01520 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01521 outputaddr+=4U; 01522 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01523 outputaddr+=4U; 01524 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01525 outputaddr+=4U; 01526 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01527 hcryp->pCrypOutBuffPtr += 16U; 01528 hcryp->CrypOutCount -= 16U; 01529 if(hcryp->CrypOutCount == 0U) 01530 { 01531 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); 01532 /* Process Unlocked */ 01533 __HAL_UNLOCK(hcryp); 01534 /* Change the CRYP peripheral state */ 01535 hcryp->State = HAL_CRYP_STATE_READY; 01536 /* Call Input transfer complete callback */ 01537 HAL_CRYP_OutCpltCallback(hcryp); 01538 } 01539 } 01540 01541 /* Return function status */ 01542 return HAL_OK; 01543 } 01544 01545 /** 01546 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt. 01547 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01548 * the configuration information for CRYP module 01549 * @param pPlainData Pointer to the plaintext buffer 01550 * @param Size Length of the plaintext buffer, must be a multiple of 16 01551 * @param pCypherData Pointer to the cyphertext buffer 01552 * @retval HAL status 01553 */ 01554 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) 01555 { 01556 uint32_t tickstart = 0U; 01557 uint32_t inputaddr; 01558 uint32_t outputaddr; 01559 01560 uint32_t headersize = hcryp->Init.HeaderSize; 01561 uint32_t headeraddr = (uint32_t)hcryp->Init.Header; 01562 uint32_t loopcounter = 0U; 01563 uint32_t bufferidx = 0U; 01564 uint8_t blockb0[16U] = {0};/* Block B0 */ 01565 uint8_t ctr[16U] = {0}; /* Counter */ 01566 uint32_t b0addr = (uint32_t)blockb0; 01567 01568 if(hcryp->State == HAL_CRYP_STATE_READY) 01569 { 01570 /* Process Locked */ 01571 __HAL_LOCK(hcryp); 01572 01573 hcryp->CrypInCount = Size; 01574 hcryp->pCrypInBuffPtr = pPlainData; 01575 hcryp->pCrypOutBuffPtr = pCypherData; 01576 hcryp->CrypOutCount = Size; 01577 01578 /* Change the CRYP peripheral state */ 01579 hcryp->State = HAL_CRYP_STATE_BUSY; 01580 01581 /* Check if initialization phase has already been performed */ 01582 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 01583 { 01584 /************************ Formatting the header block *******************/ 01585 if(headersize != 0U) 01586 { 01587 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ 01588 if(headersize < 65280U) 01589 { 01590 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); 01591 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); 01592 headersize += 2U; 01593 } 01594 else 01595 { 01596 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ 01597 hcryp->Init.pScratch[bufferidx++] = 0xFFU; 01598 hcryp->Init.pScratch[bufferidx++] = 0xFEU; 01599 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U; 01600 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U; 01601 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U; 01602 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU; 01603 headersize += 6U; 01604 } 01605 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ 01606 for(loopcounter = 0U; loopcounter < headersize; loopcounter++) 01607 { 01608 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; 01609 } 01610 /* Check if the header size is modulo 16 */ 01611 if ((headersize % 16U) != 0U) 01612 { 01613 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ 01614 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++) 01615 { 01616 hcryp->Init.pScratch[loopcounter] = 0U; 01617 } 01618 /* Set the header size to modulo 16 */ 01619 headersize = ((headersize/16U) + 1U) * 16U; 01620 } 01621 /* Set the pointer headeraddr to hcryp->Init.pScratch */ 01622 headeraddr = (uint32_t)hcryp->Init.pScratch; 01623 } 01624 /*********************** Formatting the block B0 ************************/ 01625 if(headersize != 0U) 01626 { 01627 blockb0[0U] = 0x40U; 01628 } 01629 /* Flags byte */ 01630 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */ 01631 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U); 01632 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); 01633 01634 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++) 01635 { 01636 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter]; 01637 } 01638 for ( ; loopcounter < 13U; loopcounter++) 01639 { 01640 blockb0[loopcounter+1U] = 0U; 01641 } 01642 01643 blockb0[14U] = (Size >> 8U); 01644 blockb0[15U] = (Size & 0xFFU); 01645 01646 /************************* Formatting the initial counter ***************/ 01647 /* Byte 0: 01648 Bits 7 and 6 are reserved and shall be set to 0 01649 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 01650 blocks are distinct from B0 01651 Bits 0, 1, and 2 contain the same encoding of q as in B0 01652 */ 01653 ctr[0U] = blockb0[0U] & 0x07U; 01654 /* byte 1 to NonceSize is the IV (Nonce) */ 01655 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++) 01656 { 01657 ctr[loopcounter] = blockb0[loopcounter]; 01658 } 01659 /* Set the LSB to 1 */ 01660 ctr[15U] |= 0x01U; 01661 01662 /* Set the key */ 01663 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 01664 01665 /* Set the CRYP peripheral in AES CCM mode */ 01666 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT); 01667 01668 /* Set the Initialization Vector */ 01669 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); 01670 01671 /* Select init phase */ 01672 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 01673 01674 b0addr = (uint32_t)blockb0; 01675 /* Write the blockb0 block in the IN FIFO */ 01676 hcryp->Instance->DR = *(uint32_t*)(b0addr); 01677 b0addr+=4U; 01678 hcryp->Instance->DR = *(uint32_t*)(b0addr); 01679 b0addr+=4U; 01680 hcryp->Instance->DR = *(uint32_t*)(b0addr); 01681 b0addr+=4U; 01682 hcryp->Instance->DR = *(uint32_t*)(b0addr); 01683 01684 /* Enable the CRYP peripheral */ 01685 __HAL_CRYP_ENABLE(hcryp); 01686 01687 /* Get tick */ 01688 tickstart = HAL_GetTick(); 01689 01690 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 01691 { 01692 /* Check for the Timeout */ 01693 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 01694 { 01695 /* Change state */ 01696 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01697 01698 /* Process Unlocked */ 01699 __HAL_UNLOCK(hcryp); 01700 01701 return HAL_TIMEOUT; 01702 } 01703 } 01704 /***************************** Header phase *****************************/ 01705 if(headersize != 0U) 01706 { 01707 /* Select header phase */ 01708 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 01709 01710 /* Enable Crypto processor */ 01711 __HAL_CRYP_ENABLE(hcryp); 01712 01713 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U) 01714 { 01715 /* Get tick */ 01716 tickstart = HAL_GetTick(); 01717 01718 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) 01719 { 01720 /* Check for the Timeout */ 01721 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 01722 { 01723 /* Change state */ 01724 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01725 01726 /* Process Unlocked */ 01727 __HAL_UNLOCK(hcryp); 01728 01729 return HAL_TIMEOUT; 01730 } 01731 } 01732 /* Write the header block in the IN FIFO */ 01733 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 01734 headeraddr+=4U; 01735 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 01736 headeraddr+=4U; 01737 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 01738 headeraddr+=4U; 01739 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 01740 headeraddr+=4U; 01741 } 01742 01743 /* Get tick */ 01744 tickstart = HAL_GetTick(); 01745 01746 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) 01747 { 01748 /* Check for the Timeout */ 01749 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 01750 { 01751 /* Change state */ 01752 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01753 01754 /* Process Unlocked */ 01755 __HAL_UNLOCK(hcryp); 01756 01757 return HAL_TIMEOUT; 01758 } 01759 } 01760 } 01761 /* Save formatted counter into the scratch buffer pScratch */ 01762 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++) 01763 { 01764 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; 01765 } 01766 /* Reset bit 0 */ 01767 hcryp->Init.pScratch[15U] &= 0xFEU; 01768 01769 /* Select payload phase once the header phase is performed */ 01770 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 01771 01772 /* Flush FIFO */ 01773 __HAL_CRYP_FIFO_FLUSH(hcryp); 01774 01775 /* Set the phase */ 01776 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 01777 } 01778 01779 if(Size != 0U) 01780 { 01781 /* Enable Interrupts */ 01782 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 01783 /* Enable the CRYP peripheral */ 01784 __HAL_CRYP_ENABLE(hcryp); 01785 } 01786 else 01787 { 01788 /* Change the CRYP state and phase */ 01789 hcryp->State = HAL_CRYP_STATE_READY; 01790 } 01791 01792 /* Return function status */ 01793 return HAL_OK; 01794 } 01795 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) 01796 { 01797 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 01798 /* Write the Input block in the IN FIFO */ 01799 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01800 inputaddr+=4U; 01801 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01802 inputaddr+=4U; 01803 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01804 inputaddr+=4U; 01805 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01806 hcryp->pCrypInBuffPtr += 16U; 01807 hcryp->CrypInCount -= 16U; 01808 if(hcryp->CrypInCount == 0U) 01809 { 01810 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); 01811 /* Call Input transfer complete callback */ 01812 HAL_CRYP_InCpltCallback(hcryp); 01813 } 01814 } 01815 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) 01816 { 01817 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 01818 /* Read the Output block from the Output FIFO */ 01819 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01820 outputaddr+=4U; 01821 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01822 outputaddr+=4U; 01823 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01824 outputaddr+=4U; 01825 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01826 hcryp->pCrypOutBuffPtr += 16U; 01827 hcryp->CrypOutCount -= 16U; 01828 if(hcryp->CrypOutCount == 0U) 01829 { 01830 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); 01831 /* Process Unlocked */ 01832 __HAL_UNLOCK(hcryp); 01833 /* Change the CRYP peripheral state */ 01834 hcryp->State = HAL_CRYP_STATE_READY; 01835 /* Call Input transfer complete callback */ 01836 HAL_CRYP_OutCpltCallback(hcryp); 01837 } 01838 } 01839 01840 /* Return function status */ 01841 return HAL_OK; 01842 } 01843 01844 /** 01845 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using IT. 01846 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01847 * the configuration information for CRYP module 01848 * @param pCypherData Pointer to the cyphertext buffer 01849 * @param Size Length of the cyphertext buffer, must be a multiple of 16 01850 * @param pPlainData Pointer to the plaintext buffer 01851 * @retval HAL status 01852 */ 01853 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) 01854 { 01855 uint32_t tickstart = 0U; 01856 uint32_t inputaddr; 01857 uint32_t outputaddr; 01858 01859 if(hcryp->State == HAL_CRYP_STATE_READY) 01860 { 01861 /* Process Locked */ 01862 __HAL_LOCK(hcryp); 01863 01864 /* Get the buffer addresses and sizes */ 01865 hcryp->CrypInCount = Size; 01866 hcryp->pCrypInBuffPtr = pCypherData; 01867 hcryp->pCrypOutBuffPtr = pPlainData; 01868 hcryp->CrypOutCount = Size; 01869 01870 /* Change the CRYP peripheral state */ 01871 hcryp->State = HAL_CRYP_STATE_BUSY; 01872 01873 /* Check if initialization phase has already been performed */ 01874 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 01875 { 01876 /* Set the key */ 01877 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 01878 01879 /* Set the CRYP peripheral in AES GCM decryption mode */ 01880 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT); 01881 01882 /* Set the Initialization Vector */ 01883 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); 01884 01885 /* Flush FIFO */ 01886 __HAL_CRYP_FIFO_FLUSH(hcryp); 01887 01888 /* Enable CRYP to start the init phase */ 01889 __HAL_CRYP_ENABLE(hcryp); 01890 01891 /* Get tick */ 01892 tickstart = HAL_GetTick(); 01893 01894 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 01895 { 01896 /* Check for the Timeout */ 01897 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 01898 { 01899 /* Change state */ 01900 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 01901 01902 /* Process Unlocked */ 01903 __HAL_UNLOCK(hcryp); 01904 01905 return HAL_TIMEOUT; 01906 } 01907 } 01908 01909 /* Set the header phase */ 01910 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK) 01911 { 01912 return HAL_TIMEOUT; 01913 } 01914 /* Disable the CRYP peripheral */ 01915 __HAL_CRYP_DISABLE(hcryp); 01916 01917 /* Select payload phase once the header phase is performed */ 01918 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 01919 01920 /* Set the phase */ 01921 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 01922 } 01923 01924 if(Size != 0U) 01925 { 01926 /* Enable Interrupts */ 01927 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 01928 /* Enable the CRYP peripheral */ 01929 __HAL_CRYP_ENABLE(hcryp); 01930 } 01931 else 01932 { 01933 /* Process Locked */ 01934 __HAL_UNLOCK(hcryp); 01935 /* Change the CRYP state and phase */ 01936 hcryp->State = HAL_CRYP_STATE_READY; 01937 } 01938 01939 /* Return function status */ 01940 return HAL_OK; 01941 } 01942 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) 01943 { 01944 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 01945 /* Write the Input block in the IN FIFO */ 01946 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01947 inputaddr+=4U; 01948 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01949 inputaddr+=4U; 01950 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01951 inputaddr+=4U; 01952 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 01953 hcryp->pCrypInBuffPtr += 16U; 01954 hcryp->CrypInCount -= 16U; 01955 if(hcryp->CrypInCount == 0U) 01956 { 01957 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); 01958 /* Call the Input data transfer complete callback */ 01959 HAL_CRYP_InCpltCallback(hcryp); 01960 } 01961 } 01962 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) 01963 { 01964 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 01965 /* Read the Output block from the Output FIFO */ 01966 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01967 outputaddr+=4U; 01968 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01969 outputaddr+=4U; 01970 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01971 outputaddr+=4U; 01972 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 01973 hcryp->pCrypOutBuffPtr += 16U; 01974 hcryp->CrypOutCount -= 16U; 01975 if(hcryp->CrypOutCount == 0U) 01976 { 01977 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); 01978 /* Process Unlocked */ 01979 __HAL_UNLOCK(hcryp); 01980 /* Change the CRYP peripheral state */ 01981 hcryp->State = HAL_CRYP_STATE_READY; 01982 /* Call Input transfer complete callback */ 01983 HAL_CRYP_OutCpltCallback(hcryp); 01984 } 01985 } 01986 01987 /* Return function status */ 01988 return HAL_OK; 01989 } 01990 01991 /** 01992 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using interrupt 01993 * then decrypted pCypherData. The cypher data are available in pPlainData. 01994 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 01995 * the configuration information for CRYP module 01996 * @param pCypherData Pointer to the cyphertext buffer 01997 * @param Size Length of the plaintext buffer, must be a multiple of 16 01998 * @param pPlainData Pointer to the plaintext buffer 01999 * @retval HAL status 02000 */ 02001 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) 02002 { 02003 uint32_t inputaddr; 02004 uint32_t outputaddr; 02005 uint32_t tickstart = 0U; 02006 uint32_t headersize = hcryp->Init.HeaderSize; 02007 uint32_t headeraddr = (uint32_t)hcryp->Init.Header; 02008 uint32_t loopcounter = 0U; 02009 uint32_t bufferidx = 0U; 02010 uint8_t blockb0[16U] = {0};/* Block B0 */ 02011 uint8_t ctr[16U] = {0}; /* Counter */ 02012 uint32_t b0addr = (uint32_t)blockb0; 02013 02014 if(hcryp->State == HAL_CRYP_STATE_READY) 02015 { 02016 /* Process Locked */ 02017 __HAL_LOCK(hcryp); 02018 02019 hcryp->CrypInCount = Size; 02020 hcryp->pCrypInBuffPtr = pCypherData; 02021 hcryp->pCrypOutBuffPtr = pPlainData; 02022 hcryp->CrypOutCount = Size; 02023 02024 /* Change the CRYP peripheral state */ 02025 hcryp->State = HAL_CRYP_STATE_BUSY; 02026 02027 /* Check if initialization phase has already been performed */ 02028 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 02029 { 02030 /************************ Formatting the header block *******************/ 02031 if(headersize != 0U) 02032 { 02033 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ 02034 if(headersize < 65280U) 02035 { 02036 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); 02037 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); 02038 headersize += 2U; 02039 } 02040 else 02041 { 02042 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ 02043 hcryp->Init.pScratch[bufferidx++] = 0xFFU; 02044 hcryp->Init.pScratch[bufferidx++] = 0xFEU; 02045 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U; 02046 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U; 02047 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U; 02048 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU; 02049 headersize += 6U; 02050 } 02051 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ 02052 for(loopcounter = 0U; loopcounter < headersize; loopcounter++) 02053 { 02054 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; 02055 } 02056 /* Check if the header size is modulo 16 */ 02057 if ((headersize % 16U) != 0U) 02058 { 02059 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ 02060 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++) 02061 { 02062 hcryp->Init.pScratch[loopcounter] = 0U; 02063 } 02064 /* Set the header size to modulo 16 */ 02065 headersize = ((headersize/16U) + 1U) * 16U; 02066 } 02067 /* Set the pointer headeraddr to hcryp->Init.pScratch */ 02068 headeraddr = (uint32_t)hcryp->Init.pScratch; 02069 } 02070 /*********************** Formatting the block B0 ************************/ 02071 if(headersize != 0U) 02072 { 02073 blockb0[0U] = 0x40U; 02074 } 02075 /* Flags byte */ 02076 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */ 02077 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U); 02078 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); 02079 02080 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++) 02081 { 02082 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter]; 02083 } 02084 for ( ; loopcounter < 13U; loopcounter++) 02085 { 02086 blockb0[loopcounter+1U] = 0U; 02087 } 02088 02089 blockb0[14U] = (Size >> 8U); 02090 blockb0[15U] = (Size & 0xFFU); 02091 02092 /************************* Formatting the initial counter ***************/ 02093 /* Byte 0: 02094 Bits 7 and 6 are reserved and shall be set to 0 02095 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 02096 blocks are distinct from B0 02097 Bits 0, 1, and 2 contain the same encoding of q as in B0 02098 */ 02099 ctr[0U] = blockb0[0U] & 0x07U; 02100 /* byte 1 to NonceSize is the IV (Nonce) */ 02101 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++) 02102 { 02103 ctr[loopcounter] = blockb0[loopcounter]; 02104 } 02105 /* Set the LSB to 1 */ 02106 ctr[15U] |= 0x01U; 02107 02108 /* Set the key */ 02109 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 02110 02111 /* Set the CRYP peripheral in AES CCM mode */ 02112 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT); 02113 02114 /* Set the Initialization Vector */ 02115 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); 02116 02117 /* Select init phase */ 02118 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 02119 02120 b0addr = (uint32_t)blockb0; 02121 /* Write the blockb0 block in the IN FIFO */ 02122 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02123 b0addr+=4U; 02124 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02125 b0addr+=4U; 02126 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02127 b0addr+=4U; 02128 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02129 02130 /* Enable the CRYP peripheral */ 02131 __HAL_CRYP_ENABLE(hcryp); 02132 02133 /* Get tick */ 02134 tickstart = HAL_GetTick(); 02135 02136 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 02137 { 02138 /* Check for the Timeout */ 02139 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02140 { 02141 /* Change state */ 02142 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02143 02144 /* Process Unlocked */ 02145 __HAL_UNLOCK(hcryp); 02146 02147 return HAL_TIMEOUT; 02148 } 02149 } 02150 /***************************** Header phase *****************************/ 02151 if(headersize != 0U) 02152 { 02153 /* Select header phase */ 02154 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 02155 02156 /* Enable Crypto processor */ 02157 __HAL_CRYP_ENABLE(hcryp); 02158 02159 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U) 02160 { 02161 /* Get tick */ 02162 tickstart = HAL_GetTick(); 02163 02164 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) 02165 { 02166 /* Check for the Timeout */ 02167 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02168 { 02169 /* Change state */ 02170 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02171 02172 /* Process Unlocked */ 02173 __HAL_UNLOCK(hcryp); 02174 02175 return HAL_TIMEOUT; 02176 } 02177 } 02178 /* Write the header block in the IN FIFO */ 02179 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02180 headeraddr+=4U; 02181 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02182 headeraddr+=4U; 02183 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02184 headeraddr+=4U; 02185 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02186 headeraddr+=4U; 02187 } 02188 02189 /* Get tick */ 02190 tickstart = HAL_GetTick(); 02191 02192 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) 02193 { 02194 /* Check for the Timeout */ 02195 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02196 { 02197 /* Change state */ 02198 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02199 02200 /* Process Unlocked */ 02201 __HAL_UNLOCK(hcryp); 02202 02203 return HAL_TIMEOUT; 02204 } 02205 } 02206 } 02207 /* Save formatted counter into the scratch buffer pScratch */ 02208 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++) 02209 { 02210 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; 02211 } 02212 /* Reset bit 0 */ 02213 hcryp->Init.pScratch[15U] &= 0xFEU; 02214 /* Select payload phase once the header phase is performed */ 02215 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 02216 02217 /* Flush FIFO */ 02218 __HAL_CRYP_FIFO_FLUSH(hcryp); 02219 02220 /* Set the phase */ 02221 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 02222 } 02223 02224 /* Enable Interrupts */ 02225 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 02226 02227 /* Enable the CRYP peripheral */ 02228 __HAL_CRYP_ENABLE(hcryp); 02229 02230 /* Return function status */ 02231 return HAL_OK; 02232 } 02233 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) 02234 { 02235 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 02236 /* Write the Input block in the IN FIFO */ 02237 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 02238 inputaddr+=4U; 02239 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 02240 inputaddr+=4U; 02241 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 02242 inputaddr+=4U; 02243 hcryp->Instance->DR = *(uint32_t*)(inputaddr); 02244 hcryp->pCrypInBuffPtr += 16U; 02245 hcryp->CrypInCount -= 16U; 02246 if(hcryp->CrypInCount == 0U) 02247 { 02248 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); 02249 /* Call the Input data transfer complete callback */ 02250 HAL_CRYP_InCpltCallback(hcryp); 02251 } 02252 } 02253 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) 02254 { 02255 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 02256 /* Read the Output block from the Output FIFO */ 02257 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 02258 outputaddr+=4U; 02259 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 02260 outputaddr+=4U; 02261 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 02262 outputaddr+=4U; 02263 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; 02264 hcryp->pCrypOutBuffPtr += 16U; 02265 hcryp->CrypOutCount -= 16U; 02266 if(hcryp->CrypOutCount == 0U) 02267 { 02268 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); 02269 /* Process Unlocked */ 02270 __HAL_UNLOCK(hcryp); 02271 /* Change the CRYP peripheral state */ 02272 hcryp->State = HAL_CRYP_STATE_READY; 02273 /* Call Input transfer complete callback */ 02274 HAL_CRYP_OutCpltCallback(hcryp); 02275 } 02276 } 02277 02278 /* Return function status */ 02279 return HAL_OK; 02280 } 02281 02282 /** 02283 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using DMA. 02284 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02285 * the configuration information for CRYP module 02286 * @param pPlainData Pointer to the plaintext buffer 02287 * @param Size Length of the plaintext buffer, must be a multiple of 16 02288 * @param pCypherData Pointer to the cyphertext buffer 02289 * @retval HAL status 02290 */ 02291 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) 02292 { 02293 uint32_t tickstart = 0U; 02294 uint32_t inputaddr; 02295 uint32_t outputaddr; 02296 02297 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) 02298 { 02299 /* Process Locked */ 02300 __HAL_LOCK(hcryp); 02301 02302 inputaddr = (uint32_t)pPlainData; 02303 outputaddr = (uint32_t)pCypherData; 02304 02305 /* Change the CRYP peripheral state */ 02306 hcryp->State = HAL_CRYP_STATE_BUSY; 02307 02308 /* Check if initialization phase has already been performed */ 02309 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 02310 { 02311 /* Set the key */ 02312 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 02313 02314 /* Set the CRYP peripheral in AES GCM mode */ 02315 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT); 02316 02317 /* Set the Initialization Vector */ 02318 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); 02319 02320 /* Flush FIFO */ 02321 __HAL_CRYP_FIFO_FLUSH(hcryp); 02322 02323 /* Enable CRYP to start the init phase */ 02324 __HAL_CRYP_ENABLE(hcryp); 02325 02326 /* Get tick */ 02327 tickstart = HAL_GetTick(); 02328 02329 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 02330 { 02331 /* Check for the Timeout */ 02332 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02333 { 02334 /* Change state */ 02335 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02336 02337 /* Process Unlocked */ 02338 __HAL_UNLOCK(hcryp); 02339 02340 return HAL_TIMEOUT; 02341 } 02342 } 02343 /* Flush FIFO */ 02344 __HAL_CRYP_FIFO_FLUSH(hcryp); 02345 02346 /* Set the header phase */ 02347 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK) 02348 { 02349 return HAL_TIMEOUT; 02350 } 02351 /* Disable the CRYP peripheral */ 02352 __HAL_CRYP_DISABLE(hcryp); 02353 02354 /* Select payload phase once the header phase is performed */ 02355 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 02356 02357 /* Flush FIFO */ 02358 __HAL_CRYP_FIFO_FLUSH(hcryp); 02359 02360 /* Set the phase */ 02361 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 02362 } 02363 02364 /* Set the input and output addresses and start DMA transfer */ 02365 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); 02366 02367 /* Unlock process */ 02368 __HAL_UNLOCK(hcryp); 02369 02370 /* Return function status */ 02371 return HAL_OK; 02372 } 02373 else 02374 { 02375 return HAL_ERROR; 02376 } 02377 } 02378 02379 /** 02380 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt. 02381 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02382 * the configuration information for CRYP module 02383 * @param pPlainData Pointer to the plaintext buffer 02384 * @param Size Length of the plaintext buffer, must be a multiple of 16 02385 * @param pCypherData Pointer to the cyphertext buffer 02386 * @retval HAL status 02387 */ 02388 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) 02389 { 02390 uint32_t tickstart = 0U; 02391 uint32_t inputaddr; 02392 uint32_t outputaddr; 02393 uint32_t headersize; 02394 uint32_t headeraddr; 02395 uint32_t loopcounter = 0U; 02396 uint32_t bufferidx = 0U; 02397 uint8_t blockb0[16U] = {0};/* Block B0 */ 02398 uint8_t ctr[16U] = {0}; /* Counter */ 02399 uint32_t b0addr = (uint32_t)blockb0; 02400 02401 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) 02402 { 02403 /* Process Locked */ 02404 __HAL_LOCK(hcryp); 02405 02406 inputaddr = (uint32_t)pPlainData; 02407 outputaddr = (uint32_t)pCypherData; 02408 02409 headersize = hcryp->Init.HeaderSize; 02410 headeraddr = (uint32_t)hcryp->Init.Header; 02411 02412 hcryp->CrypInCount = Size; 02413 hcryp->pCrypInBuffPtr = pPlainData; 02414 hcryp->pCrypOutBuffPtr = pCypherData; 02415 hcryp->CrypOutCount = Size; 02416 02417 /* Change the CRYP peripheral state */ 02418 hcryp->State = HAL_CRYP_STATE_BUSY; 02419 02420 /* Check if initialization phase has already been performed */ 02421 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 02422 { 02423 /************************ Formatting the header block *******************/ 02424 if(headersize != 0U) 02425 { 02426 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ 02427 if(headersize < 65280U) 02428 { 02429 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); 02430 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); 02431 headersize += 2U; 02432 } 02433 else 02434 { 02435 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ 02436 hcryp->Init.pScratch[bufferidx++] = 0xFFU; 02437 hcryp->Init.pScratch[bufferidx++] = 0xFEU; 02438 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U; 02439 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U; 02440 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U; 02441 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU; 02442 headersize += 6U; 02443 } 02444 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ 02445 for(loopcounter = 0U; loopcounter < headersize; loopcounter++) 02446 { 02447 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; 02448 } 02449 /* Check if the header size is modulo 16 */ 02450 if ((headersize % 16U) != 0U) 02451 { 02452 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ 02453 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++) 02454 { 02455 hcryp->Init.pScratch[loopcounter] = 0U; 02456 } 02457 /* Set the header size to modulo 16 */ 02458 headersize = ((headersize/16U) + 1U) * 16U; 02459 } 02460 /* Set the pointer headeraddr to hcryp->Init.pScratch */ 02461 headeraddr = (uint32_t)hcryp->Init.pScratch; 02462 } 02463 /*********************** Formatting the block B0 ************************/ 02464 if(headersize != 0U) 02465 { 02466 blockb0[0U] = 0x40U; 02467 } 02468 /* Flags byte */ 02469 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */ 02470 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07) << 3); 02471 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); 02472 02473 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++) 02474 { 02475 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter]; 02476 } 02477 for ( ; loopcounter < 13U; loopcounter++) 02478 { 02479 blockb0[loopcounter+1U] = 0U; 02480 } 02481 02482 blockb0[14U] = (Size >> 8U); 02483 blockb0[15U] = (Size & 0xFFU); 02484 02485 /************************* Formatting the initial counter ***************/ 02486 /* Byte 0: 02487 Bits 7 and 6 are reserved and shall be set to 0 02488 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 02489 blocks are distinct from B0 02490 Bits 0, 1, and 2 contain the same encoding of q as in B0 02491 */ 02492 ctr[0U] = blockb0[0U] & 0x07U; 02493 /* byte 1 to NonceSize is the IV (Nonce) */ 02494 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++) 02495 { 02496 ctr[loopcounter] = blockb0[loopcounter]; 02497 } 02498 /* Set the LSB to 1 */ 02499 ctr[15U] |= 0x01U; 02500 02501 /* Set the key */ 02502 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 02503 02504 /* Set the CRYP peripheral in AES CCM mode */ 02505 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT); 02506 02507 /* Set the Initialization Vector */ 02508 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); 02509 02510 /* Select init phase */ 02511 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 02512 02513 b0addr = (uint32_t)blockb0; 02514 /* Write the blockb0 block in the IN FIFO */ 02515 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02516 b0addr+=4U; 02517 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02518 b0addr+=4U; 02519 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02520 b0addr+=4U; 02521 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02522 02523 /* Enable the CRYP peripheral */ 02524 __HAL_CRYP_ENABLE(hcryp); 02525 02526 /* Get tick */ 02527 tickstart = HAL_GetTick(); 02528 02529 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 02530 { 02531 /* Check for the Timeout */ 02532 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02533 { 02534 /* Change state */ 02535 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02536 02537 /* Process Unlocked */ 02538 __HAL_UNLOCK(hcryp); 02539 02540 return HAL_TIMEOUT; 02541 } 02542 } 02543 /***************************** Header phase *****************************/ 02544 if(headersize != 0U) 02545 { 02546 /* Select header phase */ 02547 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 02548 02549 /* Enable Crypto processor */ 02550 __HAL_CRYP_ENABLE(hcryp); 02551 02552 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U) 02553 { 02554 /* Get tick */ 02555 tickstart = HAL_GetTick(); 02556 02557 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) 02558 { 02559 /* Check for the Timeout */ 02560 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02561 { 02562 /* Change state */ 02563 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02564 02565 /* Process Unlocked */ 02566 __HAL_UNLOCK(hcryp); 02567 02568 return HAL_TIMEOUT; 02569 } 02570 } 02571 /* Write the header block in the IN FIFO */ 02572 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02573 headeraddr+=4U; 02574 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02575 headeraddr+=4U; 02576 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02577 headeraddr+=4U; 02578 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02579 headeraddr+=4U; 02580 } 02581 02582 /* Get tick */ 02583 tickstart = HAL_GetTick(); 02584 02585 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) 02586 { 02587 /* Check for the Timeout */ 02588 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02589 { 02590 /* Change state */ 02591 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02592 02593 /* Process Unlocked */ 02594 __HAL_UNLOCK(hcryp); 02595 02596 return HAL_TIMEOUT; 02597 } 02598 } 02599 } 02600 /* Save formatted counter into the scratch buffer pScratch */ 02601 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++) 02602 { 02603 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; 02604 } 02605 /* Reset bit 0 */ 02606 hcryp->Init.pScratch[15U] &= 0xFEU; 02607 02608 /* Select payload phase once the header phase is performed */ 02609 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 02610 02611 /* Flush FIFO */ 02612 __HAL_CRYP_FIFO_FLUSH(hcryp); 02613 02614 /* Set the phase */ 02615 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 02616 } 02617 02618 /* Set the input and output addresses and start DMA transfer */ 02619 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); 02620 02621 /* Unlock process */ 02622 __HAL_UNLOCK(hcryp); 02623 02624 /* Return function status */ 02625 return HAL_OK; 02626 } 02627 else 02628 { 02629 return HAL_ERROR; 02630 } 02631 } 02632 02633 /** 02634 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using DMA. 02635 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02636 * the configuration information for CRYP module 02637 * @param pCypherData Pointer to the cyphertext buffer. 02638 * @param Size Length of the cyphertext buffer, must be a multiple of 16 02639 * @param pPlainData Pointer to the plaintext buffer 02640 * @retval HAL status 02641 */ 02642 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) 02643 { 02644 uint32_t tickstart = 0U; 02645 uint32_t inputaddr; 02646 uint32_t outputaddr; 02647 02648 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) 02649 { 02650 /* Process Locked */ 02651 __HAL_LOCK(hcryp); 02652 02653 inputaddr = (uint32_t)pCypherData; 02654 outputaddr = (uint32_t)pPlainData; 02655 02656 /* Change the CRYP peripheral state */ 02657 hcryp->State = HAL_CRYP_STATE_BUSY; 02658 02659 /* Check if initialization phase has already been performed */ 02660 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 02661 { 02662 /* Set the key */ 02663 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 02664 02665 /* Set the CRYP peripheral in AES GCM decryption mode */ 02666 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT); 02667 02668 /* Set the Initialization Vector */ 02669 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); 02670 02671 /* Enable CRYP to start the init phase */ 02672 __HAL_CRYP_ENABLE(hcryp); 02673 02674 /* Get tick */ 02675 tickstart = HAL_GetTick(); 02676 02677 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 02678 { 02679 /* Check for the Timeout */ 02680 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02681 { 02682 /* Change state */ 02683 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02684 02685 /* Process Unlocked */ 02686 __HAL_UNLOCK(hcryp); 02687 02688 return HAL_TIMEOUT; 02689 } 02690 } 02691 02692 /* Set the header phase */ 02693 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK) 02694 { 02695 return HAL_TIMEOUT; 02696 } 02697 /* Disable the CRYP peripheral */ 02698 __HAL_CRYP_DISABLE(hcryp); 02699 02700 /* Select payload phase once the header phase is performed */ 02701 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 02702 02703 /* Set the phase */ 02704 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 02705 } 02706 02707 /* Set the input and output addresses and start DMA transfer */ 02708 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); 02709 02710 /* Unlock process */ 02711 __HAL_UNLOCK(hcryp); 02712 02713 /* Return function status */ 02714 return HAL_OK; 02715 } 02716 else 02717 { 02718 return HAL_ERROR; 02719 } 02720 } 02721 02722 /** 02723 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using DMA 02724 * then decrypted pCypherData. The cypher data are available in pPlainData. 02725 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 02726 * the configuration information for CRYP module 02727 * @param pCypherData Pointer to the cyphertext buffer 02728 * @param Size Length of the plaintext buffer, must be a multiple of 16 02729 * @param pPlainData Pointer to the plaintext buffer 02730 * @retval HAL status 02731 */ 02732 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) 02733 { 02734 uint32_t tickstart = 0U; 02735 uint32_t inputaddr; 02736 uint32_t outputaddr; 02737 uint32_t headersize; 02738 uint32_t headeraddr; 02739 uint32_t loopcounter = 0U; 02740 uint32_t bufferidx = 0U; 02741 uint8_t blockb0[16U] = {0};/* Block B0 */ 02742 uint8_t ctr[16U] = {0}; /* Counter */ 02743 uint32_t b0addr = (uint32_t)blockb0; 02744 02745 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) 02746 { 02747 /* Process Locked */ 02748 __HAL_LOCK(hcryp); 02749 02750 inputaddr = (uint32_t)pCypherData; 02751 outputaddr = (uint32_t)pPlainData; 02752 02753 headersize = hcryp->Init.HeaderSize; 02754 headeraddr = (uint32_t)hcryp->Init.Header; 02755 02756 hcryp->CrypInCount = Size; 02757 hcryp->pCrypInBuffPtr = pCypherData; 02758 hcryp->pCrypOutBuffPtr = pPlainData; 02759 hcryp->CrypOutCount = Size; 02760 02761 /* Change the CRYP peripheral state */ 02762 hcryp->State = HAL_CRYP_STATE_BUSY; 02763 02764 /* Check if initialization phase has already been performed */ 02765 if(hcryp->Phase == HAL_CRYP_PHASE_READY) 02766 { 02767 /************************ Formatting the header block *******************/ 02768 if(headersize != 0U) 02769 { 02770 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ 02771 if(headersize < 65280U) 02772 { 02773 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); 02774 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); 02775 headersize += 2U; 02776 } 02777 else 02778 { 02779 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ 02780 hcryp->Init.pScratch[bufferidx++] = 0xFFU; 02781 hcryp->Init.pScratch[bufferidx++] = 0xFEU; 02782 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U; 02783 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U; 02784 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U; 02785 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU; 02786 headersize += 6U; 02787 } 02788 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ 02789 for(loopcounter = 0U; loopcounter < headersize; loopcounter++) 02790 { 02791 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; 02792 } 02793 /* Check if the header size is modulo 16 */ 02794 if ((headersize % 16U) != 0U) 02795 { 02796 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ 02797 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++) 02798 { 02799 hcryp->Init.pScratch[loopcounter] = 0U; 02800 } 02801 /* Set the header size to modulo 16 */ 02802 headersize = ((headersize/16U) + 1U) * 16U; 02803 } 02804 /* Set the pointer headeraddr to hcryp->Init.pScratch */ 02805 headeraddr = (uint32_t)hcryp->Init.pScratch; 02806 } 02807 /*********************** Formatting the block B0 ************************/ 02808 if(headersize != 0U) 02809 { 02810 blockb0[0U] = 0x40U; 02811 } 02812 /* Flags byte */ 02813 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */ 02814 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07) << 3); 02815 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); 02816 02817 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++) 02818 { 02819 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter]; 02820 } 02821 for ( ; loopcounter < 13U; loopcounter++) 02822 { 02823 blockb0[loopcounter+1U] = 0U; 02824 } 02825 02826 blockb0[14U] = (Size >> 8U); 02827 blockb0[15U] = (Size & 0xFFU); 02828 02829 /************************* Formatting the initial counter ***************/ 02830 /* Byte 0: 02831 Bits 7 and 6 are reserved and shall be set to 0 02832 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 02833 blocks are distinct from B0 02834 Bits 0, 1, and 2 contain the same encoding of q as in B0 02835 */ 02836 ctr[0U] = blockb0[0U] & 0x07U; 02837 /* byte 1 to NonceSize is the IV (Nonce) */ 02838 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++) 02839 { 02840 ctr[loopcounter] = blockb0[loopcounter]; 02841 } 02842 /* Set the LSB to 1 */ 02843 ctr[15U] |= 0x01U; 02844 02845 /* Set the key */ 02846 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); 02847 02848 /* Set the CRYP peripheral in AES CCM mode */ 02849 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT); 02850 02851 /* Set the Initialization Vector */ 02852 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); 02853 02854 /* Select init phase */ 02855 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 02856 02857 b0addr = (uint32_t)blockb0; 02858 /* Write the blockb0 block in the IN FIFO */ 02859 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02860 b0addr+=4U; 02861 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02862 b0addr+=4U; 02863 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02864 b0addr+=4U; 02865 hcryp->Instance->DR = *(uint32_t*)(b0addr); 02866 02867 /* Enable the CRYP peripheral */ 02868 __HAL_CRYP_ENABLE(hcryp); 02869 02870 /* Get tick */ 02871 tickstart = HAL_GetTick(); 02872 02873 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 02874 { 02875 /* Check for the Timeout */ 02876 02877 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02878 { 02879 /* Change state */ 02880 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02881 02882 /* Process Unlocked */ 02883 __HAL_UNLOCK(hcryp); 02884 02885 return HAL_TIMEOUT; 02886 02887 } 02888 } 02889 /***************************** Header phase *****************************/ 02890 if(headersize != 0U) 02891 { 02892 /* Select header phase */ 02893 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 02894 02895 /* Enable Crypto processor */ 02896 __HAL_CRYP_ENABLE(hcryp); 02897 02898 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U) 02899 { 02900 /* Get tick */ 02901 tickstart = HAL_GetTick(); 02902 02903 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) 02904 { 02905 /* Check for the Timeout */ 02906 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02907 { 02908 /* Change state */ 02909 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02910 02911 /* Process Unlocked */ 02912 __HAL_UNLOCK(hcryp); 02913 02914 return HAL_TIMEOUT; 02915 } 02916 } 02917 /* Write the header block in the IN FIFO */ 02918 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02919 headeraddr+=4U; 02920 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02921 headeraddr+=4U; 02922 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02923 headeraddr+=4U; 02924 hcryp->Instance->DR = *(uint32_t*)(headeraddr); 02925 headeraddr+=4U; 02926 } 02927 02928 /* Get tick */ 02929 tickstart = HAL_GetTick(); 02930 02931 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) 02932 { 02933 /* Check for the Timeout */ 02934 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) 02935 { 02936 /* Change state */ 02937 hcryp->State = HAL_CRYP_STATE_TIMEOUT; 02938 02939 /* Process Unlocked */ 02940 __HAL_UNLOCK(hcryp); 02941 02942 return HAL_TIMEOUT; 02943 } 02944 } 02945 } 02946 /* Save formatted counter into the scratch buffer pScratch */ 02947 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++) 02948 { 02949 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; 02950 } 02951 /* Reset bit 0 */ 02952 hcryp->Init.pScratch[15U] &= 0xFEU; 02953 /* Select payload phase once the header phase is performed */ 02954 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 02955 02956 /* Flush FIFO */ 02957 __HAL_CRYP_FIFO_FLUSH(hcryp); 02958 02959 /* Set the phase */ 02960 hcryp->Phase = HAL_CRYP_PHASE_PROCESS; 02961 } 02962 /* Set the input and output addresses and start DMA transfer */ 02963 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); 02964 02965 /* Unlock process */ 02966 __HAL_UNLOCK(hcryp); 02967 02968 /* Return function status */ 02969 return HAL_OK; 02970 } 02971 else 02972 { 02973 return HAL_ERROR; 02974 } 02975 } 02976 02977 /** 02978 * @} 02979 */ 02980 02981 /** @defgroup CRYPEx_Exported_Functions_Group2 CRYPEx IRQ handler management 02982 * @brief CRYPEx IRQ handler. 02983 * 02984 @verbatim 02985 ============================================================================== 02986 ##### CRYPEx IRQ handler management ##### 02987 ============================================================================== 02988 [..] This section provides CRYPEx IRQ handler function. 02989 02990 @endverbatim 02991 * @{ 02992 */ 02993 02994 /** 02995 * @brief This function handles CRYPEx interrupt request. 02996 * @param hcryp pointer to a CRYPEx_HandleTypeDef structure that contains 02997 * the configuration information for CRYP module 02998 * @retval None 02999 */ 03000 03001 void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp) 03002 { 03003 switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION) 03004 { 03005 case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT: 03006 HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp, NULL, 0U, NULL); 03007 break; 03008 03009 case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT: 03010 HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp, NULL, 0U, NULL); 03011 break; 03012 03013 case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT: 03014 HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp, NULL, 0U, NULL); 03015 break; 03016 03017 case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT: 03018 HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp, NULL, 0U, NULL); 03019 break; 03020 03021 default: 03022 break; 03023 } 03024 } 03025 03026 /** 03027 * @} 03028 */ 03029 03030 /** 03031 * @} 03032 */ 03033 #endif /* CRYP */ 03034 03035 #if defined (AES) 03036 03037 /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants 03038 * @{ 03039 */ 03040 #define CRYP_CCF_TIMEOUTVALUE 22000U /*!< CCF flag raising time-out value */ 03041 #define CRYP_BUSY_TIMEOUTVALUE 22000U /*!< BUSY flag reset time-out value */ 03042 03043 #define CRYP_POLLING_OFF 0x0U /*!< No polling when padding */ 03044 #define CRYP_POLLING_ON 0x1U /*!< Polling when padding */ 03045 /** 03046 * @} 03047 */ 03048 03049 /* Private macro -------------------------------------------------------------*/ 03050 /* Private variables ---------------------------------------------------------*/ 03051 /* Private function prototypes -----------------------------------------------*/ 03052 /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions 03053 * @{ 03054 */ 03055 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout); 03056 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout); 03057 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr); 03058 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr); 03059 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma); 03060 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma); 03061 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma); 03062 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 03063 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 03064 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma); 03065 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma); 03066 static void CRYP_DMAError(DMA_HandleTypeDef *hdma); 03067 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling); 03068 /** 03069 * @} 03070 */ 03071 03072 /* Exported functions ---------------------------------------------------------*/ 03073 03074 /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions 03075 * @{ 03076 */ 03077 03078 03079 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function 03080 * @brief Extended callback functions. 03081 * 03082 @verbatim 03083 =============================================================================== 03084 ##### Extended callback functions ##### 03085 =============================================================================== 03086 [..] This section provides callback function: 03087 (+) Computation completed. 03088 03089 @endverbatim 03090 * @{ 03091 */ 03092 03093 03094 /** 03095 * @brief Computation completed callbacks. 03096 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 03097 * the configuration information for CRYP module 03098 * @retval None 03099 */ 03100 __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp) 03101 { 03102 /* Prevent unused argument(s) compilation warning */ 03103 UNUSED(hcryp); 03104 03105 /* NOTE : This function should not be modified; when the callback is needed, 03106 the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file 03107 */ 03108 } 03109 03110 /** 03111 * @} 03112 */ 03113 03114 /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions 03115 * @brief Extended processing functions. 03116 * 03117 @verbatim 03118 ============================================================================== 03119 ##### AES extended processing functions ##### 03120 ============================================================================== 03121 [..] This section provides functions allowing to: 03122 (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes. 03123 Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated 03124 based on the processing type. Three processing types are available: 03125 (++) Polling mode 03126 (++) Interrupt mode 03127 (++) DMA mode 03128 (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES 03129 algorithm in different chaining modes. 03130 Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase 03131 so that steps can be skipped if so required. Functions are only differentiated based on the processing type. 03132 Three processing types are available: 03133 (++) Polling mode 03134 (++) Interrupt mode 03135 (++) DMA mode 03136 03137 @endverbatim 03138 * @{ 03139 */ 03140 03141 /** 03142 * @brief Carry out in polling mode the ciphering or deciphering operation according to 03143 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and 03144 * chaining modes ECB, CBC and CTR are managed by this function in polling mode. 03145 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 03146 * the configuration information for CRYP module 03147 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption 03148 * or key derivation+decryption. 03149 * Parameter is meaningless in case of key derivation. 03150 * @param Size Length of the input data buffer in bytes, must be a multiple of 16. 03151 * Parameter is meaningless in case of key derivation. 03152 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of 03153 * decryption/key derivation+decryption, or pointer to the derivative keys in 03154 * case of key derivation only. 03155 * @param Timeout Specify Timeout value 03156 * @retval HAL status 03157 */ 03158 HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout) 03159 { 03160 03161 if (hcryp->State == HAL_CRYP_STATE_READY) 03162 { 03163 /* Check parameters setting */ 03164 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION) 03165 { 03166 if (pOutputData == NULL) 03167 { 03168 return HAL_ERROR; 03169 } 03170 } 03171 else 03172 { 03173 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U)) 03174 { 03175 return HAL_ERROR; 03176 } 03177 } 03178 03179 /* Process Locked */ 03180 __HAL_LOCK(hcryp); 03181 03182 /* Change the CRYP state */ 03183 hcryp->State = HAL_CRYP_STATE_BUSY; 03184 03185 /* Call CRYP_ReadKey() API if the operating mode is set to 03186 key derivation, CRYP_ProcessData() otherwise */ 03187 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION) 03188 { 03189 if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK) 03190 { 03191 return HAL_TIMEOUT; 03192 } 03193 } 03194 else 03195 { 03196 if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK) 03197 { 03198 return HAL_TIMEOUT; 03199 } 03200 } 03201 03202 /* If the state has not been set to SUSPENDED, set it to 03203 READY, otherwise keep it as it is */ 03204 if (hcryp->State != HAL_CRYP_STATE_SUSPENDED) 03205 { 03206 hcryp->State = HAL_CRYP_STATE_READY; 03207 } 03208 03209 /* Process Unlocked */ 03210 __HAL_UNLOCK(hcryp); 03211 03212 return HAL_OK; 03213 } 03214 else 03215 { 03216 return HAL_BUSY; 03217 } 03218 } 03219 03220 /** 03221 * @brief Carry out in interrupt mode the ciphering or deciphering operation according to 03222 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and 03223 * chaining modes ECB, CBC and CTR are managed by this function in interrupt mode. 03224 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 03225 * the configuration information for CRYP module 03226 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption 03227 * or key derivation+decryption. 03228 * Parameter is meaningless in case of key derivation. 03229 * @param Size Length of the input data buffer in bytes, must be a multiple of 16. 03230 * Parameter is meaningless in case of key derivation. 03231 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of 03232 * decryption/key derivation+decryption, or pointer to the derivative keys in 03233 * case of key derivation only. 03234 * @retval HAL status 03235 */ 03236 HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData) 03237 { 03238 uint32_t inputaddr = 0U; 03239 03240 if(hcryp->State == HAL_CRYP_STATE_READY) 03241 { 03242 /* Check parameters setting */ 03243 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION) 03244 { 03245 if (pOutputData == NULL) 03246 { 03247 return HAL_ERROR; 03248 } 03249 } 03250 else 03251 { 03252 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U)) 03253 { 03254 return HAL_ERROR; 03255 } 03256 } 03257 /* Process Locked */ 03258 __HAL_LOCK(hcryp); 03259 03260 /* If operating mode is not limited to key derivation only, 03261 get the buffers addresses and sizes */ 03262 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION) 03263 { 03264 03265 hcryp->CrypInCount = Size; 03266 hcryp->pCrypInBuffPtr = pInputData; 03267 hcryp->pCrypOutBuffPtr = pOutputData; 03268 hcryp->CrypOutCount = Size; 03269 } 03270 03271 /* Change the CRYP state */ 03272 hcryp->State = HAL_CRYP_STATE_BUSY; 03273 03274 /* Process Unlocked */ 03275 __HAL_UNLOCK(hcryp); 03276 03277 /* Enable Computation Complete Flag and Error Interrupts */ 03278 __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE); 03279 03280 /* If operating mode is key derivation only, the input data have 03281 already been entered during the initialization process. For 03282 the other operating modes, they are fed to the CRYP hardware 03283 block at this point. */ 03284 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION) 03285 { 03286 /* Initiate the processing under interrupt in entering 03287 the first input data */ 03288 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 03289 /* Increment/decrement instance pointer/counter */ 03290 hcryp->pCrypInBuffPtr += 16U; 03291 hcryp->CrypInCount -= 16U; 03292 /* Write the first input block in the Data Input register */ 03293 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03294 inputaddr+=4U; 03295 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03296 inputaddr+=4U; 03297 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03298 inputaddr+=4U; 03299 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03300 } 03301 03302 /* Return function status */ 03303 return HAL_OK; 03304 } 03305 else 03306 { 03307 return HAL_BUSY; 03308 } 03309 } 03310 03311 /** 03312 * @brief Carry out in DMA mode the ciphering or deciphering operation according to 03313 * hcryp->Init structure fields. 03314 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 03315 * the configuration information for CRYP module 03316 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption 03317 * or key derivation+decryption. 03318 * @param Size Length of the input data buffer in bytes, must be a multiple of 16. 03319 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of 03320 * decryption/key derivation+decryption. 03321 * @note Chaining modes ECB, CBC and CTR are managed by this function in DMA mode. 03322 * @note Supported operating modes are encryption, decryption and key derivation with decryption. 03323 * @note No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx 03324 * registers must be done by software. 03325 * @note This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx 03326 * registers must be done by software thru HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs. 03327 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP. 03328 * @retval HAL status 03329 */ 03330 HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData) 03331 { 03332 uint32_t inputaddr = 0U; 03333 uint32_t outputaddr = 0U; 03334 03335 if (hcryp->State == HAL_CRYP_STATE_READY) 03336 { 03337 /* Check parameters setting */ 03338 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION) 03339 { 03340 /* no DMA channel is provided for key derivation operating mode, 03341 access to AES_KEYRx registers must be done by software */ 03342 return HAL_ERROR; 03343 } 03344 else 03345 { 03346 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U)) 03347 { 03348 return HAL_ERROR; 03349 } 03350 } 03351 03352 /* Process Locked */ 03353 __HAL_LOCK(hcryp); 03354 03355 inputaddr = (uint32_t)pInputData; 03356 outputaddr = (uint32_t)pOutputData; 03357 03358 /* Change the CRYP state */ 03359 hcryp->State = HAL_CRYP_STATE_BUSY; 03360 03361 /* Set the input and output addresses and start DMA transfer */ 03362 CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); 03363 03364 /* Process Unlocked */ 03365 __HAL_UNLOCK(hcryp); 03366 03367 /* Return function status */ 03368 return HAL_OK; 03369 } 03370 else 03371 { 03372 return HAL_BUSY; 03373 } 03374 } 03375 03376 /** 03377 * @brief Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering 03378 * operation according to hcryp->Init structure fields. 03379 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 03380 * the configuration information for CRYP module 03381 * @param pInputData 03382 * - pointer to payload data in GCM payload phase, 03383 * - pointer to B0 block in CMAC header phase, 03384 * - pointer to C block in CMAC final phase. 03385 * - Parameter is meaningless in case of GCM/GMAC init, header and final phases. 03386 * @param Size 03387 * - length of the input payload data buffer in bytes, 03388 * - length of B0 block (in bytes) in CMAC header phase, 03389 * - length of C block (in bytes) in CMAC final phase. 03390 * - Parameter is meaningless in case of GCM/GMAC init and header phases. 03391 * @param pOutputData 03392 * - pointer to plain or cipher text in GCM payload phase, 03393 * - pointer to authentication tag in GCM/GMAC and CMAC final phases. 03394 * - Parameter is meaningless in case of GCM/GMAC init and header phases 03395 * and in case of CMAC header phase. 03396 * @param Timeout Specify Timeout value 03397 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable. 03398 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes 03399 * can be skipped by the user if so required. 03400 * @retval HAL status 03401 */ 03402 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout) 03403 { 03404 uint32_t index = 0U; 03405 uint32_t inputaddr = 0U; 03406 uint32_t outputaddr = 0U; 03407 uint32_t tagaddr = 0U; 03408 uint64_t headerlength = 0U; 03409 uint64_t inputlength = 0U; 03410 uint64_t payloadlength = 0U; 03411 uint32_t difflength = 0U; 03412 uint32_t addhoc_process = 0U; 03413 03414 if (hcryp->State == HAL_CRYP_STATE_READY) 03415 { 03416 /* input/output parameters check */ 03417 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 03418 { 03419 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) 03420 { 03421 return HAL_ERROR; 03422 } 03423 #if defined(AES_CR_NPBLB) 03424 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) 03425 #else 03426 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 03427 #endif 03428 { 03429 /* In case of CMAC (or CCM) header phase resumption, we can have pInputData = NULL and Size = 0 */ 03430 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U))) 03431 { 03432 return HAL_ERROR; 03433 } 03434 } 03435 } 03436 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 03437 { 03438 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U)) 03439 { 03440 return HAL_ERROR; 03441 } 03442 } 03443 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 03444 { 03445 if (pOutputData == NULL) 03446 { 03447 return HAL_ERROR; 03448 } 03449 #if defined(AES_CR_NPBLB) 03450 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL)) 03451 #else 03452 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL)) 03453 #endif 03454 { 03455 return HAL_ERROR; 03456 } 03457 } 03458 03459 /* Process Locked */ 03460 __HAL_LOCK(hcryp); 03461 03462 /* Change the CRYP state */ 03463 hcryp->State = HAL_CRYP_STATE_BUSY; 03464 03465 /*==============================================*/ 03466 /* GCM/GMAC (or CCM when applicable) init phase */ 03467 /*==============================================*/ 03468 /* In case of init phase, the input data (Key and Initialization Vector) have 03469 already been entered during the initialization process. Therefore, the 03470 API just waits for the CCF flag to be set. */ 03471 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 03472 { 03473 /* just wait for hash computation */ 03474 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 03475 { 03476 hcryp->State = HAL_CRYP_STATE_READY; 03477 __HAL_UNLOCK(hcryp); 03478 return HAL_TIMEOUT; 03479 } 03480 03481 /* Clear CCF Flag */ 03482 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 03483 /* Mark that the initialization phase is over */ 03484 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER; 03485 } 03486 /*=====================================*/ 03487 /* GCM/GMAC or (CCM/)CMAC header phase */ 03488 /*=====================================*/ 03489 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 03490 { 03491 /* Set header phase; for GCM or GMAC, set data-byte at this point */ 03492 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 03493 { 03494 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType); 03495 } 03496 else 03497 { 03498 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE); 03499 } 03500 03501 /* Enable the Peripheral */ 03502 __HAL_CRYP_ENABLE(); 03503 03504 #if !defined(AES_CR_NPBLB) 03505 /* in case of CMAC, enter B0 block in header phase, before the header itself. */ 03506 /* If Size = 0 (possible case of resumption after CMAC header phase suspension), 03507 skip these steps and go directly to header buffer feeding to the HW */ 03508 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U)) 03509 { 03510 inputaddr = (uint32_t)pInputData; 03511 03512 for(index=0U; (index < Size); index += 16U) 03513 { 03514 /* Write the Input block in the Data Input register */ 03515 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03516 inputaddr+=4U; 03517 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03518 inputaddr+=4U; 03519 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03520 inputaddr+=4U; 03521 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03522 inputaddr+=4U; 03523 03524 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 03525 { 03526 hcryp->State = HAL_CRYP_STATE_READY; 03527 __HAL_UNLOCK(hcryp); 03528 return HAL_TIMEOUT; 03529 } 03530 /* Clear CCF Flag */ 03531 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 03532 03533 /* If the suspension flag has been raised and if the processing is not about 03534 to end, suspend processing */ 03535 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Size)) 03536 { 03537 /* reset SuspendRequest */ 03538 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 03539 /* Change the CRYP state */ 03540 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 03541 /* Mark that the header phase is over */ 03542 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED; 03543 03544 /* Save current reading and writing locations of Input and Output buffers */ 03545 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 03546 /* Save the total number of bytes (B blocks + header) that remain to be 03547 processed at this point */ 03548 hcryp->CrypInCount = hcryp->Init.HeaderSize + Size - (index+16U); 03549 03550 /* Process Unlocked */ 03551 __HAL_UNLOCK(hcryp); 03552 03553 return HAL_OK; 03554 } 03555 } /* for(index=0; (index < Size); index += 16) */ 03556 } 03557 #endif /* !defined(AES_CR_NPBLB) */ 03558 03559 /* Enter header */ 03560 inputaddr = (uint32_t)hcryp->Init.Header; 03561 /* Local variable headerlength is a number of bytes multiple of 128 bits, 03562 remaining header data (if any) are handled after this loop */ 03563 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ; 03564 if ((hcryp->Init.HeaderSize % 16U) != 0U) 03565 { 03566 difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength); 03567 } 03568 for(index=0U; index < headerlength; index += 16U) 03569 { 03570 /* Write the Input block in the Data Input register */ 03571 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03572 inputaddr+=4U; 03573 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03574 inputaddr+=4U; 03575 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03576 inputaddr+=4U; 03577 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03578 inputaddr+=4U; 03579 03580 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 03581 { 03582 hcryp->State = HAL_CRYP_STATE_READY; 03583 __HAL_UNLOCK(hcryp); 03584 return HAL_TIMEOUT; 03585 } 03586 /* Clear CCF Flag */ 03587 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 03588 03589 /* If the suspension flag has been raised and if the processing is not about 03590 to end, suspend processing */ 03591 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < headerlength)) 03592 { 03593 /* reset SuspendRequest */ 03594 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 03595 /* Change the CRYP state */ 03596 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 03597 /* Mark that the header phase is over */ 03598 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED; 03599 03600 /* Save current reading and writing locations of Input and Output buffers */ 03601 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 03602 /* Save the total number of bytes that remain to be processed at this point */ 03603 hcryp->CrypInCount = hcryp->Init.HeaderSize - (index+16U); 03604 03605 /* Process Unlocked */ 03606 __HAL_UNLOCK(hcryp); 03607 03608 return HAL_OK; 03609 } 03610 } 03611 03612 /* Case header length is not a multiple of 16 bytes */ 03613 if (difflength != 0U) 03614 { 03615 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 03616 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON); 03617 } 03618 03619 /* Mark that the header phase is over */ 03620 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 03621 } 03622 /*============================================*/ 03623 /* GCM (or CCM when applicable) payload phase */ 03624 /*============================================*/ 03625 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 03626 { 03627 03628 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE); 03629 03630 /* if the header phase has been bypassed, AES must be enabled again */ 03631 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 03632 { 03633 __HAL_CRYP_ENABLE(); 03634 } 03635 03636 inputaddr = (uint32_t)pInputData; 03637 outputaddr = (uint32_t)pOutputData; 03638 03639 /* Enter payload */ 03640 /* Specific handling to manage payload last block size less than 128 bits */ 03641 if ((Size % 16U) != 0U) 03642 { 03643 payloadlength = (Size/16U) * 16U; 03644 difflength = (uint32_t) (Size - payloadlength); 03645 addhoc_process = 1U; 03646 } 03647 else 03648 { 03649 payloadlength = Size; 03650 addhoc_process = 0U; 03651 } 03652 03653 /* Feed payload */ 03654 for(index=0U; index < payloadlength; index += 16U) 03655 { 03656 /* Write the Input block in the Data Input register */ 03657 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03658 inputaddr+=4U; 03659 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03660 inputaddr+=4U; 03661 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03662 inputaddr+=4U; 03663 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03664 inputaddr+=4U; 03665 03666 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 03667 { 03668 hcryp->State = HAL_CRYP_STATE_READY; 03669 __HAL_UNLOCK(hcryp); 03670 return HAL_TIMEOUT; 03671 } 03672 03673 /* Clear CCF Flag */ 03674 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 03675 03676 /* Retrieve output data: read the output block 03677 from the Data Output Register */ 03678 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 03679 outputaddr+=4U; 03680 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 03681 outputaddr+=4U; 03682 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 03683 outputaddr+=4U; 03684 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 03685 outputaddr+=4U; 03686 03687 /* If the suspension flag has been raised and if the processing is not about 03688 to end, suspend processing */ 03689 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < payloadlength)) 03690 { 03691 /* no flag waiting under IRQ handling */ 03692 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 03693 { 03694 /* Ensure that Busy flag is reset */ 03695 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK) 03696 { 03697 hcryp->State = HAL_CRYP_STATE_READY; 03698 __HAL_UNLOCK(hcryp); 03699 return HAL_TIMEOUT; 03700 } 03701 } 03702 /* reset SuspendRequest */ 03703 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 03704 /* Change the CRYP state */ 03705 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 03706 /* Mark that the header phase is over */ 03707 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED; 03708 03709 /* Save current reading and writing locations of Input and Output buffers */ 03710 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr; 03711 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 03712 /* Save the number of bytes that remain to be processed at this point */ 03713 hcryp->CrypInCount = Size - (index+16U); 03714 03715 /* Process Unlocked */ 03716 __HAL_UNLOCK(hcryp); 03717 03718 return HAL_OK; 03719 } 03720 03721 } 03722 03723 /* Additional processing to manage GCM(/CCM) encryption and decryption cases when 03724 payload last block size less than 128 bits */ 03725 if (addhoc_process == 1U) 03726 { 03727 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 03728 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr; 03729 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON); 03730 } /* (addhoc_process == 1) */ 03731 03732 /* Mark that the payload phase is over */ 03733 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 03734 } 03735 /*====================================*/ 03736 /* GCM/GMAC or (CCM/)CMAC final phase */ 03737 /*====================================*/ 03738 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 03739 { 03740 tagaddr = (uint32_t)pOutputData; 03741 03742 #if defined(AES_CR_NPBLB) 03743 /* By default, clear NPBLB field */ 03744 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB); 03745 #endif 03746 03747 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE); 03748 03749 /* if the header and payload phases have been bypassed, AES must be enabled again */ 03750 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 03751 { 03752 __HAL_CRYP_ENABLE(); 03753 } 03754 03755 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 03756 { 03757 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */ 03758 inputlength = Size * 8U; /* input length in bits */ 03759 03760 03761 if(hcryp->Init.DataType == CRYP_DATATYPE_1B) 03762 { 03763 hcryp->Instance->DINR = __RBIT((headerlength)>>32U); 03764 hcryp->Instance->DINR = __RBIT(headerlength); 03765 hcryp->Instance->DINR = __RBIT((inputlength)>>32U); 03766 hcryp->Instance->DINR = __RBIT(inputlength); 03767 } 03768 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B) 03769 { 03770 hcryp->Instance->DINR = __REV((headerlength)>>32U); 03771 hcryp->Instance->DINR = __REV(headerlength); 03772 hcryp->Instance->DINR = __REV((inputlength)>>32U); 03773 hcryp->Instance->DINR = __REV(inputlength); 03774 } 03775 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B) 03776 { 03777 hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U); 03778 hcryp->Instance->DINR = __ROR(headerlength, 16U); 03779 hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U); 03780 hcryp->Instance->DINR = __ROR(inputlength, 16U); 03781 } 03782 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B) 03783 { 03784 hcryp->Instance->DINR = (uint32_t)(headerlength>>32U); 03785 hcryp->Instance->DINR = (uint32_t)(headerlength); 03786 hcryp->Instance->DINR = (uint32_t)(inputlength>>32U); 03787 hcryp->Instance->DINR = (uint32_t)(inputlength); 03788 } 03789 } 03790 #if !defined(AES_CR_NPBLB) 03791 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 03792 { 03793 inputaddr = (uint32_t)pInputData; 03794 /* Enter the last block made of a 128-bit value formatted 03795 from the original B0 packet. */ 03796 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03797 inputaddr+=4U; 03798 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03799 inputaddr+=4U; 03800 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03801 inputaddr+=4U; 03802 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 03803 } 03804 #endif 03805 03806 03807 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 03808 { 03809 hcryp->State = HAL_CRYP_STATE_READY; 03810 __HAL_UNLOCK(hcryp); 03811 return HAL_TIMEOUT; 03812 } 03813 03814 /* Read the Auth TAG in the Data Out register */ 03815 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 03816 tagaddr+=4U; 03817 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 03818 tagaddr+=4U; 03819 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 03820 tagaddr+=4U; 03821 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 03822 03823 03824 /* Clear CCF Flag */ 03825 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 03826 /* Mark that the final phase is over */ 03827 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER; 03828 /* Disable the Peripheral */ 03829 __HAL_CRYP_DISABLE(); 03830 } 03831 /*=================================================*/ 03832 /* case incorrect hcryp->Init.GCMCMACPhase setting */ 03833 /*=================================================*/ 03834 else 03835 { 03836 hcryp->State = HAL_CRYP_STATE_ERROR; 03837 __HAL_UNLOCK(hcryp); 03838 return HAL_ERROR; 03839 } 03840 03841 /* Change the CRYP state */ 03842 hcryp->State = HAL_CRYP_STATE_READY; 03843 03844 /* Process Unlocked */ 03845 __HAL_UNLOCK(hcryp); 03846 03847 return HAL_OK; 03848 } 03849 else 03850 { 03851 return HAL_BUSY; 03852 } 03853 } 03854 03855 03856 03857 03858 /** 03859 * @brief Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering 03860 * operation according to hcryp->Init structure fields. 03861 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 03862 * the configuration information for CRYP module 03863 * @param pInputData 03864 * - pointer to payload data in GCM payload phase, 03865 * - pointer to B0 block in CMAC header phase, 03866 * - pointer to C block in CMAC final phase. 03867 * Parameter is meaningless in case of GCM/GMAC init, header and final phases. 03868 * @param Size 03869 * - length of the input payload data buffer in bytes, 03870 * - length of B0 block (in bytes) in CMAC header phase, 03871 * - length of C block (in bytes) in CMAC final phase. 03872 * - Parameter is meaningless in case of GCM/GMAC init and header phases. 03873 * @param pOutputData 03874 * - pointer to plain or cipher text in GCM payload phase, 03875 * - pointer to authentication tag in GCM/GMAC and CMAC final phases. 03876 * - Parameter is meaningless in case of GCM/GMAC init and header phases 03877 * and in case of CMAC header phase. 03878 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC. 03879 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes 03880 * can be skipped by the user if so required. 03881 * @retval HAL status 03882 */ 03883 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData) 03884 { 03885 03886 uint32_t inputaddr = 0U; 03887 uint64_t headerlength = 0U; 03888 uint64_t inputlength = 0U; 03889 uint32_t index = 0U; 03890 uint32_t addhoc_process = 0U; 03891 uint32_t difflength = 0U; 03892 uint32_t difflengthmod4 = 0U; 03893 uint32_t mask[3U] = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU}; 03894 03895 03896 if (hcryp->State == HAL_CRYP_STATE_READY) 03897 { 03898 /* input/output parameters check */ 03899 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 03900 { 03901 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) 03902 { 03903 return HAL_ERROR; 03904 } 03905 #if defined(AES_CR_NPBLB) 03906 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) 03907 #else 03908 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 03909 #endif 03910 { 03911 /* In case of CMAC header phase resumption, we can have pInputData = NULL and Size = 0 */ 03912 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U))) 03913 { 03914 return HAL_ERROR; 03915 } 03916 } 03917 } 03918 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 03919 { 03920 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U)) 03921 { 03922 return HAL_ERROR; 03923 } 03924 } 03925 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 03926 { 03927 if (pOutputData == NULL) 03928 { 03929 return HAL_ERROR; 03930 } 03931 #if defined(AES_CR_NPBLB) 03932 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL)) 03933 #else 03934 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL)) 03935 #endif 03936 { 03937 return HAL_ERROR; 03938 } 03939 } 03940 03941 /* Process Locked */ 03942 __HAL_LOCK(hcryp); 03943 03944 /* Change the CRYP state */ 03945 hcryp->State = HAL_CRYP_STATE_BUSY; 03946 03947 /* Process Unlocked */ 03948 __HAL_UNLOCK(hcryp); 03949 03950 /* Enable Computation Complete Flag and Error Interrupts */ 03951 __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE); 03952 03953 /*==============================================*/ 03954 /* GCM/GMAC (or CCM when applicable) init phase */ 03955 /*==============================================*/ 03956 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 03957 { 03958 /* In case of init phase, the input data (Key and Initialization Vector) have 03959 already been entered during the initialization process. Therefore, the 03960 software just waits for the CCF interrupt to be raised and which will 03961 be handled by CRYP_AES_Auth_IT() API. */ 03962 } 03963 /*=====================================*/ 03964 /* GCM/GMAC or (CCM/)CMAC header phase */ 03965 /*=====================================*/ 03966 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 03967 { 03968 03969 #if defined(AES_CR_NPBLB) 03970 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) 03971 #else 03972 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 03973 #endif 03974 { 03975 /* In case of CMAC, B blocks are first entered, before the header. 03976 Therefore, B blocks and the header are entered back-to-back 03977 as if it was only one single block. 03978 However, in case of resumption after suspension, if all the 03979 B blocks have been entered (in that case, Size = 0), only the 03980 remainder of the non-processed header bytes are entered. */ 03981 if (Size != 0U) 03982 { 03983 hcryp->CrypInCount = Size + hcryp->Init.HeaderSize; 03984 hcryp->pCrypInBuffPtr = pInputData; 03985 } 03986 else 03987 { 03988 hcryp->CrypInCount = hcryp->Init.HeaderSize; 03989 hcryp->pCrypInBuffPtr = hcryp->Init.Header; 03990 } 03991 } 03992 else 03993 { 03994 /* Get the header addresses and sizes */ 03995 hcryp->CrypInCount = hcryp->Init.HeaderSize; 03996 hcryp->pCrypInBuffPtr = hcryp->Init.Header; 03997 } 03998 03999 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 04000 04001 /* Set header phase; for GCM or GMAC, set data-byte at this point */ 04002 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 04003 { 04004 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType); 04005 } 04006 else 04007 { 04008 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE); 04009 } 04010 04011 /* Enable the Peripheral */ 04012 __HAL_CRYP_ENABLE(); 04013 04014 /* Increment/decrement instance pointer/counter */ 04015 if (hcryp->CrypInCount == 0U) 04016 { 04017 /* Case of no header */ 04018 hcryp->State = HAL_CRYP_STATE_READY; 04019 return HAL_OK; 04020 } 04021 else if (hcryp->CrypInCount < 16U) 04022 { 04023 hcryp->CrypInCount = 0U; 04024 addhoc_process = 1U; 04025 difflength = (uint32_t) (hcryp->Init.HeaderSize); 04026 difflengthmod4 = difflength%4U; 04027 } 04028 else 04029 { 04030 hcryp->pCrypInBuffPtr += 16U; 04031 hcryp->CrypInCount -= 16U; 04032 } 04033 04034 #if defined(AES_CR_NPBLB) 04035 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) 04036 #else 04037 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 04038 #endif 04039 { 04040 if (hcryp->CrypInCount == hcryp->Init.HeaderSize) 04041 { 04042 /* All B blocks will have been entered after the next 04043 four DINR writing, so point at header buffer for 04044 the next iteration */ 04045 hcryp->pCrypInBuffPtr = hcryp->Init.Header; 04046 } 04047 } 04048 04049 /* Enter header first block to initiate the process 04050 in the Data Input register */ 04051 if (addhoc_process == 0U) 04052 { 04053 /* Header has size equal or larger than 128 bits */ 04054 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04055 inputaddr+=4U; 04056 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04057 inputaddr+=4U; 04058 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04059 inputaddr+=4U; 04060 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04061 } 04062 else 04063 { 04064 /* Header has size less than 128 bits */ 04065 /* Enter complete words when possible */ 04066 for(index=0U; index < (difflength/4U); index ++) 04067 { 04068 /* Write the Input block in the Data Input register */ 04069 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04070 inputaddr+=4U; 04071 } 04072 /* Enter incomplete word padded with zeroes if applicable 04073 (case of header length not a multiple of 32-bits) */ 04074 if (difflengthmod4 != 0U) 04075 { 04076 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]); 04077 } 04078 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */ 04079 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 04080 { 04081 hcryp->Instance->DINR = 0U; 04082 } 04083 04084 } 04085 } 04086 /*============================================*/ 04087 /* GCM (or CCM when applicable) payload phase */ 04088 /*============================================*/ 04089 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 04090 { 04091 /* Get the buffer addresses and sizes */ 04092 hcryp->CrypInCount = Size; 04093 hcryp->pCrypInBuffPtr = pInputData; 04094 hcryp->pCrypOutBuffPtr = pOutputData; 04095 hcryp->CrypOutCount = Size; 04096 04097 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 04098 04099 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCM_PAYLOAD_PHASE); 04100 04101 /* if the header phase has been bypassed, AES must be enabled again */ 04102 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 04103 { 04104 __HAL_CRYP_ENABLE(); 04105 } 04106 04107 /* Specific handling to manage payload size less than 128 bits */ 04108 if (Size < 16U) 04109 { 04110 #if defined(AES_CR_NPBLB) 04111 /* In case of GCM encryption or CCM decryption, specify the number of padding 04112 bytes in last block of payload */ 04113 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE) 04114 { 04115 if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC) 04116 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT)) 04117 || ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC) 04118 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT))) 04119 { 04120 /* Set NPBLB field in writing the number of padding bytes 04121 for the last block of payload */ 04122 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength); 04123 } 04124 } 04125 #else 04126 /* Software workaround applied to GCM encryption only */ 04127 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 04128 { 04129 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */ 04130 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR); 04131 } 04132 #endif 04133 04134 /* Set hcryp->CrypInCount to 0 (no more data to enter) */ 04135 hcryp->CrypInCount = 0U; 04136 04137 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes, 04138 to have a complete block of 128 bits */ 04139 difflength = (uint32_t) (Size); 04140 difflengthmod4 = difflength%4U; 04141 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes 04142 to have a complete block of 128 bits */ 04143 for(index=0U; index < (difflength/4U); index ++) 04144 { 04145 /* Write the Input block in the Data Input register */ 04146 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04147 inputaddr+=4U; 04148 } 04149 /* If required, manage input data size not multiple of 32 bits */ 04150 if (difflengthmod4 != 0U) 04151 { 04152 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]); 04153 } 04154 /* Wrap-up in padding with zero-words if applicable */ 04155 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 04156 { 04157 hcryp->Instance->DINR = 0U; 04158 } 04159 } 04160 else 04161 { 04162 /* Increment/decrement instance pointer/counter */ 04163 hcryp->pCrypInBuffPtr += 16U; 04164 hcryp->CrypInCount -= 16U; 04165 04166 /* Enter payload first block to initiate the process 04167 in the Data Input register */ 04168 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04169 inputaddr+=4U; 04170 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04171 inputaddr+=4U; 04172 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04173 inputaddr+=4U; 04174 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04175 } 04176 } 04177 /*====================================*/ 04178 /* GCM/GMAC or (CCM/)CMAC final phase */ 04179 /*====================================*/ 04180 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 04181 { 04182 hcryp->pCrypOutBuffPtr = pOutputData; 04183 04184 #if defined(AES_CR_NPBLB) 04185 /* By default, clear NPBLB field */ 04186 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB); 04187 #endif 04188 04189 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE); 04190 04191 /* if the header and payload phases have been bypassed, AES must be enabled again */ 04192 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 04193 { 04194 __HAL_CRYP_ENABLE(); 04195 } 04196 04197 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 04198 { 04199 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */ 04200 inputlength = Size * 8U; /* Input length in bits */ 04201 /* Write the number of bits in the header on 64 bits followed by the number 04202 of bits in the payload on 64 bits as well */ 04203 if(hcryp->Init.DataType == CRYP_DATATYPE_1B) 04204 { 04205 hcryp->Instance->DINR = __RBIT((headerlength)>>32U); 04206 hcryp->Instance->DINR = __RBIT(headerlength); 04207 hcryp->Instance->DINR = __RBIT((inputlength)>>32U); 04208 hcryp->Instance->DINR = __RBIT(inputlength); 04209 } 04210 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B) 04211 { 04212 hcryp->Instance->DINR = __REV((headerlength)>>32U); 04213 hcryp->Instance->DINR = __REV(headerlength); 04214 hcryp->Instance->DINR = __REV((inputlength)>>32U); 04215 hcryp->Instance->DINR = __REV(inputlength); 04216 } 04217 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B) 04218 { 04219 hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U); 04220 hcryp->Instance->DINR = __ROR(headerlength, 16U); 04221 hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U); 04222 hcryp->Instance->DINR = __ROR(inputlength, 16U); 04223 } 04224 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B) 04225 { 04226 hcryp->Instance->DINR = (uint32_t)(headerlength>>32U); 04227 hcryp->Instance->DINR = (uint32_t)(headerlength); 04228 hcryp->Instance->DINR = (uint32_t)(inputlength>>32U); 04229 hcryp->Instance->DINR = (uint32_t)(inputlength); 04230 } 04231 } 04232 #if !defined(AES_CR_NPBLB) 04233 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 04234 { 04235 inputaddr = (uint32_t)pInputData; 04236 /* Enter the last block made of a 128-bit value formatted 04237 from the original B0 packet. */ 04238 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04239 inputaddr+=4U; 04240 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04241 inputaddr+=4U; 04242 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04243 inputaddr+=4U; 04244 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04245 inputaddr+=4U; 04246 } 04247 #endif 04248 } 04249 /*=================================================*/ 04250 /* case incorrect hcryp->Init.GCMCMACPhase setting */ 04251 /*=================================================*/ 04252 else 04253 { 04254 hcryp->State = HAL_CRYP_STATE_ERROR; 04255 return HAL_ERROR; 04256 } 04257 04258 return HAL_OK; 04259 } 04260 else 04261 { 04262 return HAL_BUSY; 04263 } 04264 } 04265 04266 04267 04268 04269 /** 04270 * @brief Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering 04271 * operation according to hcryp->Init structure fields. 04272 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04273 * the configuration information for CRYP module 04274 * @param pInputData 04275 * - pointer to payload data in GCM payload phase, 04276 * - pointer to B0 block in CMAC header phase, 04277 * - pointer to C block in CMAC final phase. 04278 * - Parameter is meaningless in case of GCM/GMAC init, header and final phases. 04279 * @param Size 04280 * - length of the input payload data buffer in bytes, 04281 * - length of B block (in bytes) in CMAC header phase, 04282 * - length of C block (in bytes) in CMAC final phase. 04283 * - Parameter is meaningless in case of GCM/GMAC init and header phases. 04284 * @param pOutputData 04285 * - pointer to plain or cipher text in GCM payload phase, 04286 * - pointer to authentication tag in GCM/GMAC and CMAC final phases. 04287 * - Parameter is meaningless in case of GCM/GMAC init and header phases 04288 * and in case of CMAC header phase. 04289 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC. 04290 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes 04291 * can be skipped by the user if so required. 04292 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP. 04293 * @retval HAL status 04294 */ 04295 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData) 04296 { 04297 uint32_t inputaddr = 0U; 04298 uint32_t outputaddr = 0U; 04299 uint32_t tagaddr = 0U; 04300 uint64_t headerlength = 0U; 04301 uint64_t inputlength = 0U; 04302 uint64_t payloadlength = 0U; 04303 04304 04305 if (hcryp->State == HAL_CRYP_STATE_READY) 04306 { 04307 /* input/output parameters check */ 04308 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 04309 { 04310 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) 04311 { 04312 return HAL_ERROR; 04313 } 04314 #if defined(AES_CR_NPBLB) 04315 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) 04316 #else 04317 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 04318 #endif 04319 { 04320 if ((pInputData == NULL) || (Size == 0U)) 04321 { 04322 return HAL_ERROR; 04323 } 04324 } 04325 } 04326 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 04327 { 04328 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U)) 04329 { 04330 return HAL_ERROR; 04331 } 04332 } 04333 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 04334 { 04335 if (pOutputData == NULL) 04336 { 04337 return HAL_ERROR; 04338 } 04339 #if defined(AES_CR_NPBLB) 04340 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL)) 04341 #else 04342 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL)) 04343 #endif 04344 { 04345 return HAL_ERROR; 04346 } 04347 } 04348 04349 /* Process Locked */ 04350 __HAL_LOCK(hcryp); 04351 04352 /* Change the CRYP state */ 04353 hcryp->State = HAL_CRYP_STATE_BUSY; 04354 04355 /*==============================================*/ 04356 /* GCM/GMAC (or CCM when applicable) init phase */ 04357 /*==============================================*/ 04358 /* In case of init phase, the input data (Key and Initialization Vector) have 04359 already been entered during the initialization process. No DMA transfer is 04360 required at that point therefore, the software just waits for the CCF flag 04361 to be raised. */ 04362 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 04363 { 04364 /* just wait for hash computation */ 04365 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 04366 { 04367 hcryp->State = HAL_CRYP_STATE_READY; 04368 __HAL_UNLOCK(hcryp); 04369 return HAL_TIMEOUT; 04370 } 04371 04372 /* Clear CCF Flag */ 04373 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 04374 /* Mark that the initialization phase is over */ 04375 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER; 04376 hcryp->State = HAL_CRYP_STATE_READY; 04377 } 04378 /*===============================*/ 04379 /* GCM/GMAC or CMAC header phase */ 04380 /*===============================*/ 04381 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE) 04382 { 04383 /* Set header phase; for GCM or GMAC, set data-byte at this point */ 04384 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 04385 { 04386 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_GCMCMAC_HEADER_PHASE|hcryp->Init.DataType); 04387 } 04388 else 04389 { 04390 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_HEADER_PHASE); 04391 } 04392 04393 #if !defined(AES_CR_NPBLB) 04394 /* enter first B0 block in polling mode (no DMA transfer for B0) */ 04395 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 04396 { 04397 /* Enable the CRYP peripheral */ 04398 __HAL_CRYP_ENABLE(); 04399 04400 inputaddr = (uint32_t)pInputData; 04401 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04402 inputaddr+=4U; 04403 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04404 inputaddr+=4U; 04405 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04406 inputaddr+=4U; 04407 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04408 04409 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 04410 { 04411 hcryp->State = HAL_CRYP_STATE_READY; 04412 __HAL_UNLOCK(hcryp); 04413 return HAL_TIMEOUT; 04414 } 04415 /* Clear CCF Flag */ 04416 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 04417 } 04418 #endif 04419 04420 /* No header case */ 04421 if (hcryp->Init.Header == NULL) 04422 { 04423 hcryp->State = HAL_CRYP_STATE_READY; 04424 /* Mark that the header phase is over */ 04425 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 04426 /* Process Unlocked */ 04427 __HAL_UNLOCK(hcryp); 04428 04429 return HAL_OK; 04430 } 04431 04432 inputaddr = (uint32_t)hcryp->Init.Header; 04433 if ((hcryp->Init.HeaderSize % 16U) != 0U) 04434 { 04435 04436 if (hcryp->Init.HeaderSize < 16U) 04437 { 04438 CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF); 04439 04440 hcryp->State = HAL_CRYP_STATE_READY; 04441 /* Mark that the header phase is over */ 04442 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 04443 04444 /* CCF flag indicating header phase AES processing completion 04445 will be checked at the start of the next phase: 04446 - payload phase (GCM / CCM when applicable) 04447 - final phase (GMAC or CMAC). */ 04448 } 04449 else 04450 { 04451 /* Local variable headerlength is a number of bytes multiple of 128 bits, 04452 remaining header data (if any) are handled after this loop */ 04453 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ; 04454 /* Store the ending transfer point */ 04455 hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength; 04456 hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */ 04457 04458 /* Set the input and output addresses and start DMA transfer */ 04459 /* (incomplete DMA transfer, will be wrapped up after completion of 04460 the first one (initiated here) with data padding */ 04461 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, headerlength, 0U); 04462 } 04463 } 04464 else 04465 { 04466 hcryp->CrypInCount = 0U; 04467 /* Set the input address and start DMA transfer */ 04468 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, hcryp->Init.HeaderSize, 0U); 04469 } 04470 04471 } 04472 /*============================================*/ 04473 /* GCM (or CCM when applicable) payload phase */ 04474 /*============================================*/ 04475 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 04476 { 04477 /* Coming from header phase, wait for CCF flag to be raised 04478 if header present and fed to the IP in the previous phase */ 04479 if (hcryp->Init.Header != NULL) 04480 { 04481 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 04482 { 04483 hcryp->State = HAL_CRYP_STATE_READY; 04484 __HAL_UNLOCK(hcryp); 04485 return HAL_TIMEOUT; 04486 } 04487 } 04488 else 04489 { 04490 /* Enable the Peripheral since wasn't in header phase (no header case) */ 04491 __HAL_CRYP_ENABLE(); 04492 } 04493 /* Clear CCF Flag */ 04494 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 04495 04496 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE); 04497 04498 /* Specific handling to manage payload size less than 128 bits */ 04499 if ((Size % 16U) != 0U) 04500 { 04501 inputaddr = (uint32_t)pInputData; 04502 outputaddr = (uint32_t)pOutputData; 04503 if (Size < 16U) 04504 { 04505 /* Block is now entered in polling mode, no actual gain in resorting to DMA */ 04506 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 04507 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr; 04508 04509 CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON); 04510 04511 /* Change the CRYP state to ready */ 04512 hcryp->State = HAL_CRYP_STATE_READY; 04513 /* Mark that the payload phase is over */ 04514 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 04515 04516 /* Call output data transfer complete callback */ 04517 HAL_CRYP_OutCpltCallback(hcryp); 04518 } 04519 else 04520 { 04521 payloadlength = (Size/16U) * 16U; 04522 04523 /* Store the ending transfer points */ 04524 hcryp->pCrypInBuffPtr = pInputData + payloadlength; 04525 hcryp->pCrypOutBuffPtr = pOutputData + payloadlength; 04526 hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */ 04527 04528 /* Set the input and output addresses and start DMA transfer */ 04529 /* (incomplete DMA transfer, will be wrapped up with data padding 04530 after completion of the one initiated here) */ 04531 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, payloadlength, outputaddr); 04532 } 04533 } 04534 else 04535 { 04536 hcryp->CrypInCount = 0U; 04537 inputaddr = (uint32_t)pInputData; 04538 outputaddr = (uint32_t)pOutputData; 04539 04540 /* Set the input and output addresses and start DMA transfer */ 04541 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); 04542 } 04543 } 04544 /*====================================*/ 04545 /* GCM/GMAC or (CCM/)CMAC final phase */ 04546 /*====================================*/ 04547 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 04548 { 04549 /* If coming from header phase (GMAC or CMAC case), 04550 wait for CCF flag to be raised */ 04551 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE) 04552 { 04553 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 04554 { 04555 hcryp->State = HAL_CRYP_STATE_READY; 04556 __HAL_UNLOCK(hcryp); 04557 return HAL_TIMEOUT; 04558 } 04559 /* Clear CCF Flag */ 04560 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 04561 } 04562 04563 tagaddr = (uint32_t)pOutputData; 04564 04565 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE); 04566 04567 /* if the header and payload phases have been bypassed, AES must be enabled again */ 04568 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER) 04569 { 04570 __HAL_CRYP_ENABLE(); 04571 } 04572 04573 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) 04574 { 04575 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */ 04576 inputlength = Size * 8U; /* input length in bits */ 04577 /* Write the number of bits in the header on 64 bits followed by the number 04578 of bits in the payload on 64 bits as well */ 04579 if(hcryp->Init.DataType == CRYP_DATATYPE_1B) 04580 { 04581 hcryp->Instance->DINR = __RBIT((headerlength)>>32U); 04582 hcryp->Instance->DINR = __RBIT(headerlength); 04583 hcryp->Instance->DINR = __RBIT((inputlength)>>32U); 04584 hcryp->Instance->DINR = __RBIT(inputlength); 04585 } 04586 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B) 04587 { 04588 hcryp->Instance->DINR = __REV((headerlength)>>32U); 04589 hcryp->Instance->DINR = __REV(headerlength); 04590 hcryp->Instance->DINR = __REV((inputlength)>>32U); 04591 hcryp->Instance->DINR = __REV(inputlength); 04592 } 04593 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B) 04594 { 04595 hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U); 04596 hcryp->Instance->DINR = __ROR(headerlength, 16U); 04597 hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U); 04598 hcryp->Instance->DINR = __ROR(inputlength, 16U); 04599 } 04600 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B) 04601 { 04602 hcryp->Instance->DINR = (uint32_t)(headerlength>>32U); 04603 hcryp->Instance->DINR = (uint32_t)(headerlength); 04604 hcryp->Instance->DINR = (uint32_t)(inputlength>>32U); 04605 hcryp->Instance->DINR = (uint32_t)(inputlength); 04606 } 04607 } 04608 #if !defined(AES_CR_NPBLB) 04609 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 04610 { 04611 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 04612 04613 inputaddr = (uint32_t)pInputData; 04614 /* Enter the last block made of a 128-bit value formatted 04615 from the original B0 packet. */ 04616 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04617 inputaddr+=4U; 04618 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04619 inputaddr+=4U; 04620 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04621 inputaddr+=4U; 04622 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 04623 inputaddr+=4U; 04624 } 04625 #endif 04626 04627 /* No DMA transfer is required at that point therefore, the software 04628 just waits for the CCF flag to be raised. */ 04629 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 04630 { 04631 hcryp->State = HAL_CRYP_STATE_READY; 04632 __HAL_UNLOCK(hcryp); 04633 return HAL_TIMEOUT; 04634 } 04635 /* Clear CCF Flag */ 04636 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 04637 /* Read the Auth TAG in the IN FIFO */ 04638 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 04639 tagaddr+=4U; 04640 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 04641 tagaddr+=4U; 04642 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 04643 tagaddr+=4U; 04644 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 04645 04646 /* Mark that the final phase is over */ 04647 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER; 04648 hcryp->State = HAL_CRYP_STATE_READY; 04649 /* Disable the Peripheral */ 04650 __HAL_CRYP_DISABLE(); 04651 } 04652 /*=================================================*/ 04653 /* case incorrect hcryp->Init.GCMCMACPhase setting */ 04654 /*=================================================*/ 04655 else 04656 { 04657 hcryp->State = HAL_CRYP_STATE_ERROR; 04658 __HAL_UNLOCK(hcryp); 04659 return HAL_ERROR; 04660 } 04661 04662 /* Process Unlocked */ 04663 __HAL_UNLOCK(hcryp); 04664 04665 return HAL_OK; 04666 } 04667 else 04668 { 04669 return HAL_BUSY; 04670 } 04671 } 04672 04673 /** 04674 * @} 04675 */ 04676 04677 /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions 04678 * @brief Extended processing functions. 04679 * 04680 @verbatim 04681 ============================================================================== 04682 ##### AES extended suspension and resumption functions ##### 04683 ============================================================================== 04684 [..] This section provides functions allowing to: 04685 (+) save in memory the Initialization Vector, the Key registers, the Control register or 04686 the Suspend registers when a process is suspended by a higher priority message 04687 (+) write back in CRYP hardware block the saved values listed above when the suspended 04688 lower priority message processing is resumed. 04689 04690 @endverbatim 04691 * @{ 04692 */ 04693 04694 04695 /** 04696 * @brief In case of message processing suspension, read the Initialization Vector. 04697 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04698 * the configuration information for CRYP module. 04699 * @param Output Pointer to the buffer containing the saved Initialization Vector. 04700 * @note This value has to be stored for reuse by writing the AES_IVRx registers 04701 * as soon as the interrupted processing has to be resumed. 04702 * Applicable to all chaining modes. 04703 * @note AES must be disabled when reading or resetting the IV values. 04704 * @retval None 04705 */ 04706 void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output) 04707 { 04708 uint32_t outputaddr = (uint32_t)Output; 04709 04710 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3); 04711 outputaddr+=4U; 04712 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2); 04713 outputaddr+=4U; 04714 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1); 04715 outputaddr+=4U; 04716 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0); 04717 } 04718 04719 /** 04720 * @brief In case of message processing resumption, rewrite the Initialization 04721 * Vector in the AES_IVRx registers. 04722 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04723 * the configuration information for CRYP module. 04724 * @param Input Pointer to the buffer containing the saved Initialization Vector to 04725 * write back in the CRYP hardware block. 04726 * @note Applicable to all chaining modes. 04727 * @note AES must be disabled when reading or resetting the IV values. 04728 * @retval None 04729 */ 04730 void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input) 04731 { 04732 uint32_t ivaddr = (uint32_t)Input; 04733 04734 hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr)); 04735 ivaddr+=4U; 04736 hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr)); 04737 ivaddr+=4U; 04738 hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr)); 04739 ivaddr+=4U; 04740 hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr)); 04741 } 04742 04743 04744 /** 04745 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Suspend Registers. 04746 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04747 * the configuration information for CRYP module. 04748 * @param Output Pointer to the buffer containing the saved Suspend Registers. 04749 * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers 04750 * as soon as the interrupted processing has to be resumed. 04751 * @retval None 04752 */ 04753 void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output) 04754 { 04755 uint32_t outputaddr = (uint32_t)Output; 04756 04757 /* In case of GCM payload phase encryption, check that suspension can be carried out */ 04758 if (READ_BIT(hcryp->Instance->CR, (AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_GCM_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT)) 04759 { 04760 /* Ensure that Busy flag is reset */ 04761 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK) 04762 { 04763 hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR; 04764 hcryp->State = HAL_CRYP_STATE_ERROR; 04765 04766 /* Process Unlocked */ 04767 __HAL_UNLOCK(hcryp); 04768 04769 HAL_CRYP_ErrorCallback(hcryp); 04770 return ; 04771 } 04772 } 04773 04774 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R); 04775 outputaddr+=4U; 04776 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R); 04777 outputaddr+=4U; 04778 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R); 04779 outputaddr+=4U; 04780 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R); 04781 outputaddr+=4U; 04782 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R); 04783 outputaddr+=4U; 04784 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R); 04785 outputaddr+=4U; 04786 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R); 04787 outputaddr+=4U; 04788 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R); 04789 } 04790 04791 /** 04792 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Suspend 04793 * Registers in the AES_SUSPxR registers. 04794 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04795 * the configuration information for CRYP module. 04796 * @param Input Pointer to the buffer containing the saved suspend registers to 04797 * write back in the CRYP hardware block. 04798 * @retval None 04799 */ 04800 void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input) 04801 { 04802 uint32_t ivaddr = (uint32_t)Input; 04803 04804 hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr)); 04805 ivaddr+=4U; 04806 hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr)); 04807 ivaddr+=4U; 04808 hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr)); 04809 ivaddr+=4U; 04810 hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr)); 04811 ivaddr+=4U; 04812 hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr)); 04813 ivaddr+=4U; 04814 hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr)); 04815 ivaddr+=4U; 04816 hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr)); 04817 ivaddr+=4U; 04818 hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr)); 04819 } 04820 04821 04822 /** 04823 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Key Registers. 04824 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04825 * the configuration information for CRYP module. 04826 * @param Output Pointer to the buffer containing the saved Key Registers. 04827 * @param KeySize Indicates the key size (128 or 256 bits). 04828 * @note These values have to be stored for reuse by writing back the AES_KEYRx registers 04829 * as soon as the interrupted processing has to be resumed. 04830 * @retval None 04831 */ 04832 void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize) 04833 { 04834 uint32_t keyaddr = (uint32_t)Output; 04835 04836 if (KeySize == CRYP_KEYSIZE_256B) 04837 { 04838 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7); 04839 keyaddr+=4U; 04840 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6); 04841 keyaddr+=4U; 04842 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5); 04843 keyaddr+=4U; 04844 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4); 04845 keyaddr+=4U; 04846 } 04847 04848 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3); 04849 keyaddr+=4U; 04850 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2); 04851 keyaddr+=4U; 04852 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1); 04853 keyaddr+=4U; 04854 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0); 04855 } 04856 04857 /** 04858 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Key 04859 * Registers in the AES_KEYRx registers. 04860 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04861 * the configuration information for CRYP module. 04862 * @param Input Pointer to the buffer containing the saved key registers to 04863 * write back in the CRYP hardware block. 04864 * @param KeySize Indicates the key size (128 or 256 bits) 04865 * @retval None 04866 */ 04867 void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize) 04868 { 04869 uint32_t keyaddr = (uint32_t)Input; 04870 04871 if (KeySize == CRYP_KEYSIZE_256B) 04872 { 04873 hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr)); 04874 keyaddr+=4U; 04875 hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr)); 04876 keyaddr+=4U; 04877 hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr)); 04878 keyaddr+=4U; 04879 hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr)); 04880 keyaddr+=4U; 04881 } 04882 04883 hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr)); 04884 keyaddr+=4U; 04885 hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr)); 04886 keyaddr+=4U; 04887 hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr)); 04888 keyaddr+=4U; 04889 hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr)); 04890 } 04891 04892 04893 /** 04894 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Control Register. 04895 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04896 * the configuration information for CRYP module. 04897 * @param Output Pointer to the buffer containing the saved Control Register. 04898 * @note This values has to be stored for reuse by writing back the AES_CR register 04899 * as soon as the interrupted processing has to be resumed. 04900 * @retval None 04901 */ 04902 void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output) 04903 { 04904 *(uint32_t*)(Output) = hcryp->Instance->CR; 04905 } 04906 04907 /** 04908 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Control 04909 * Registers in the AES_CR register. 04910 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04911 * the configuration information for CRYP module. 04912 * @param Input Pointer to the buffer containing the saved Control Register to 04913 * write back in the CRYP hardware block. 04914 * @retval None 04915 */ 04916 void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input) 04917 { 04918 hcryp->Instance->CR = *(uint32_t*)(Input); 04919 /* At the same time, set handle state back to READY to be able to resume the AES calculations 04920 without the processing APIs returning HAL_BUSY when called. */ 04921 hcryp->State = HAL_CRYP_STATE_READY; 04922 } 04923 04924 /** 04925 * @brief Request CRYP processing suspension when in polling or interruption mode. 04926 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 04927 * the configuration information for CRYP module. 04928 * @note Set the handle field SuspendRequest to the appropriate value so that 04929 * the on-going CRYP processing is suspended as soon as the required 04930 * conditions are met. 04931 * @note It is advised not to suspend the CRYP processing when the DMA controller 04932 * is managing the data transfer 04933 * @retval None 04934 */ 04935 void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp) 04936 { 04937 /* Set Handle Suspend Request field */ 04938 hcryp->SuspendRequest = HAL_CRYP_SUSPEND; 04939 } 04940 04941 /** 04942 * @} 04943 */ 04944 04945 /** 04946 * @} 04947 */ 04948 04949 /** @addtogroup CRYPEx_Private_Functions 04950 * @{ 04951 */ 04952 04953 /** 04954 * @brief DMA CRYP Input Data process complete callback 04955 * for GCM, GMAC or CMAC chainging modes. 04956 * @note Specific setting of hcryp fields are required only 04957 * in the case of header phase where no output data DMA 04958 * transfer is on-going (only input data transfer is enabled 04959 * in such a case). 04960 * @param hdma DMA handle. 04961 * @retval None 04962 */ 04963 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma) 04964 { 04965 uint32_t difflength = 0U; 04966 04967 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 04968 04969 /* Disable the DMA transfer for input request */ 04970 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN); 04971 04972 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 04973 { 04974 04975 if (hcryp->CrypInCount != 0U) 04976 { 04977 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */ 04978 difflength = hcryp->CrypInCount; 04979 hcryp->CrypInCount = 0U; 04980 04981 CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF); 04982 } 04983 hcryp->State = HAL_CRYP_STATE_READY; 04984 /* Mark that the header phase is over */ 04985 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 04986 } 04987 /* CCF flag indicating header phase AES processing completion 04988 will be checked at the start of the next phase: 04989 - payload phase (GCM or CCM when applicable) 04990 - final phase (GMAC or CMAC). 04991 This allows to avoid the Wait on Flag within the IRQ handling. */ 04992 04993 /* Call input data transfer complete callback */ 04994 HAL_CRYP_InCpltCallback(hcryp); 04995 } 04996 04997 /** 04998 * @brief DMA CRYP Output Data process complete callback 04999 * for GCM, GMAC or CMAC chainging modes. 05000 * @note This callback is called only in the payload phase. 05001 * @param hdma DMA handle. 05002 * @retval None 05003 */ 05004 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma) 05005 { 05006 uint32_t difflength = 0U; 05007 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 05008 05009 /* Disable the DMA transfer for output request */ 05010 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN); 05011 05012 /* Clear CCF Flag */ 05013 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05014 05015 /* Initiate additional transfer to wrap-up data feeding to the IP */ 05016 if (hcryp->CrypInCount != 0U) 05017 { 05018 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */ 05019 difflength = hcryp->CrypInCount; 05020 hcryp->CrypInCount = 0U; 05021 05022 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON); 05023 } 05024 05025 /* Change the CRYP state to ready */ 05026 hcryp->State = HAL_CRYP_STATE_READY; 05027 /* Mark that the payload phase is over */ 05028 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 05029 05030 /* Call output data transfer complete callback */ 05031 HAL_CRYP_OutCpltCallback(hcryp); 05032 } 05033 05034 /** 05035 * @brief DMA CRYP communication error callback 05036 * for GCM, GMAC or CMAC chainging modes. 05037 * @param hdma DMA handle 05038 * @retval None 05039 */ 05040 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma) 05041 { 05042 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 05043 05044 hcryp->State= HAL_CRYP_STATE_ERROR; 05045 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR; 05046 HAL_CRYP_ErrorCallback(hcryp); 05047 /* Clear Error Flag */ 05048 __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR); 05049 } 05050 05051 /** 05052 * @brief Handle CRYP block input/output data handling under interruption 05053 * for GCM, GMAC or CMAC chaining modes. 05054 * @note The function is called under interruption only, once 05055 * interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT(). 05056 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 05057 * the configuration information for CRYP module 05058 * @retval HAL status 05059 */ 05060 HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp) 05061 { 05062 uint32_t inputaddr = 0x0U; 05063 uint32_t outputaddr = 0x0U; 05064 uint32_t index = 0x0U; 05065 uint32_t addhoc_process = 0U; 05066 uint32_t difflength = 0U; 05067 uint32_t difflengthmod4 = 0U; 05068 uint32_t mask[3] = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU}; 05069 uint32_t intermediate_data[4U] = {0U}; 05070 05071 if(hcryp->State == HAL_CRYP_STATE_BUSY) 05072 { 05073 /*===========================*/ 05074 /* GCM/GMAC(/CCM) init phase */ 05075 /*===========================*/ 05076 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE) 05077 { 05078 /* Clear Computation Complete Flag */ 05079 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05080 /* Disable Computation Complete Flag and Errors Interrupts */ 05081 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE); 05082 /* Change the CRYP state */ 05083 hcryp->State = HAL_CRYP_STATE_READY; 05084 05085 /* Mark that the initialization phase is over */ 05086 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER; 05087 05088 /* Process Unlocked */ 05089 __HAL_UNLOCK(hcryp); 05090 /* Call computation complete callback */ 05091 HAL_CRYPEx_ComputationCpltCallback(hcryp); 05092 return HAL_OK; 05093 } 05094 /*=====================================*/ 05095 /* GCM/GMAC or (CCM/)CMAC header phase */ 05096 /*=====================================*/ 05097 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE) 05098 { 05099 /* Check if all input header data have been entered */ 05100 if (hcryp->CrypInCount == 0U) 05101 { 05102 /* Clear Computation Complete Flag */ 05103 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05104 /* Disable Computation Complete Flag and Errors Interrupts */ 05105 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE); 05106 /* Change the CRYP state */ 05107 hcryp->State = HAL_CRYP_STATE_READY; 05108 /* Mark that the header phase is over */ 05109 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 05110 05111 /* Process Unlocked */ 05112 __HAL_UNLOCK(hcryp); 05113 05114 /* Call computation complete callback */ 05115 HAL_CRYPEx_ComputationCpltCallback(hcryp); 05116 05117 return HAL_OK; 05118 } 05119 /* If suspension flag has been raised, suspend processing */ 05120 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND) 05121 { 05122 /* Clear CCF Flag */ 05123 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05124 05125 /* reset SuspendRequest */ 05126 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 05127 /* Disable Computation Complete Flag and Errors Interrupts */ 05128 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE); 05129 /* Change the CRYP state */ 05130 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 05131 /* Mark that the header phase is over */ 05132 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED; 05133 05134 /* Process Unlocked */ 05135 __HAL_UNLOCK(hcryp); 05136 05137 return HAL_OK; 05138 } 05139 else /* Carry on feeding input data to the CRYP hardware block */ 05140 { 05141 /* Clear Computation Complete Flag */ 05142 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05143 /* Get the last Input data address */ 05144 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 05145 05146 /* Increment/decrement instance pointer/counter */ 05147 if (hcryp->CrypInCount < 16U) 05148 { 05149 difflength = hcryp->CrypInCount; 05150 hcryp->CrypInCount = 0U; 05151 addhoc_process = 1U; 05152 difflengthmod4 = difflength%4U; 05153 } 05154 else 05155 { 05156 hcryp->pCrypInBuffPtr += 16U; 05157 hcryp->CrypInCount -= 16U; 05158 } 05159 05160 #if defined(AES_CR_NPBLB) 05161 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) 05162 #else 05163 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) 05164 #endif 05165 { 05166 if (hcryp->CrypInCount == hcryp->Init.HeaderSize) 05167 { 05168 /* All B blocks will have been entered after the next 05169 four DINR writing, so point at header buffer for 05170 the next iteration */ 05171 hcryp->pCrypInBuffPtr = hcryp->Init.Header; 05172 } 05173 } 05174 05175 /* Write the Input block in the Data Input register */ 05176 if (addhoc_process == 0U) 05177 { 05178 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05179 inputaddr+=4U; 05180 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05181 inputaddr+=4U; 05182 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05183 inputaddr+=4U; 05184 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05185 } 05186 else 05187 { 05188 /* Header remainder has size less than 128 bits */ 05189 /* Enter complete words when possible */ 05190 for(index=0U; index < (difflength/4U); index ++) 05191 { 05192 /* Write the Input block in the Data Input register */ 05193 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05194 inputaddr+=4U; 05195 } 05196 /* Enter incomplete word padded with zeroes if applicable 05197 (case of header length not a multiple of 32-bits) */ 05198 if (difflengthmod4 != 0U) 05199 { 05200 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]); 05201 } 05202 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */ 05203 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 05204 { 05205 hcryp->Instance->DINR = 0U; 05206 } 05207 } 05208 05209 return HAL_OK; 05210 } 05211 } 05212 /*=======================*/ 05213 /* GCM/CCM payload phase */ 05214 /*=======================*/ 05215 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) 05216 { 05217 /* Get the last output data address */ 05218 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 05219 05220 /* Specific handling to manage payload size less than 128 bits 05221 when GCM (or CCM when applicable) encryption or decryption is selected. 05222 Check here if the last block output data are read */ 05223 #if defined(AES_CR_NPBLB) 05224 if ((hcryp->CrypOutCount < 16U) && \ 05225 (hcryp->CrypOutCount > 0U)) 05226 #else 05227 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \ 05228 (hcryp->CrypOutCount < 16U) && \ 05229 (hcryp->CrypOutCount > 0U)) 05230 #endif 05231 { 05232 addhoc_process = 1U; 05233 difflength = hcryp->CrypOutCount; 05234 difflengthmod4 = difflength%4U; 05235 hcryp->CrypOutCount = 0U; /* mark that no more output data will be needed */ 05236 /* Retrieve intermediate data */ 05237 for(index=0U; index < 4U; index ++) 05238 { 05239 intermediate_data[index] = hcryp->Instance->DOUTR; 05240 } 05241 /* Retrieve last words of cyphered data */ 05242 /* First, retrieve complete output words */ 05243 for(index=0U; index < (difflength/4U); index ++) 05244 { 05245 *(uint32_t*)(outputaddr) = intermediate_data[index]; 05246 outputaddr+=4U; 05247 } 05248 /* Next, retrieve partial output word if applicable; 05249 at the same time, start masking intermediate data 05250 with a mask of zeros of same size than the padding 05251 applied to the last block of payload */ 05252 if (difflengthmod4 != 0U) 05253 { 05254 intermediate_data[difflength/4U] &= mask[difflengthmod4-1U]; 05255 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U]; 05256 } 05257 05258 #if !defined(AES_CR_NPBLB) 05259 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 05260 { 05261 /* Change again CHMOD configuration to GCM mode */ 05262 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC); 05263 05264 /* Select FINAL phase */ 05265 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE); 05266 05267 /* Before inserting the intermediate data, carry on masking operation 05268 with a mask of zeros of same size than the padding applied to the last block of payload */ 05269 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 05270 { 05271 intermediate_data[(difflength+3U)/4U+index] = 0U; 05272 } 05273 05274 /* Insert intermediate data to trigger an additional DOUTR reading round */ 05275 /* Clear Computation Complete Flag before entering new block */ 05276 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05277 for(index=0U; index < 4U; index ++) 05278 { 05279 hcryp->Instance->DINR = intermediate_data[index]; 05280 } 05281 } 05282 else 05283 #endif 05284 { 05285 /* Payload phase is now over */ 05286 /* Clear Computation Complete Flag */ 05287 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05288 /* Disable Computation Complete Flag and Errors Interrupts */ 05289 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE); 05290 /* Change the CRYP state */ 05291 hcryp->State = HAL_CRYP_STATE_READY; 05292 /* Mark that the payload phase is over */ 05293 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 05294 05295 /* Process Unlocked */ 05296 __HAL_UNLOCK(hcryp); 05297 05298 /* Call computation complete callback */ 05299 HAL_CRYPEx_ComputationCpltCallback(hcryp); 05300 } 05301 return HAL_OK; 05302 } 05303 else 05304 { 05305 if (hcryp->CrypOutCount != 0U) 05306 { 05307 /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */ 05308 /* Retrieve the last block available from the CRYP hardware block: 05309 read the output block from the Data Output Register */ 05310 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05311 outputaddr+=4U; 05312 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05313 outputaddr+=4U; 05314 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05315 outputaddr+=4U; 05316 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05317 05318 /* Increment/decrement instance pointer/counter */ 05319 hcryp->pCrypOutBuffPtr += 16U; 05320 hcryp->CrypOutCount -= 16U; 05321 } 05322 #if !defined(AES_CR_NPBLB) 05323 else 05324 { 05325 /* Software work-around: additional DOUTR reading round to discard the data */ 05326 for(index=0U; index < 4U; index ++) 05327 { 05328 intermediate_data[index] = hcryp->Instance->DOUTR; 05329 } 05330 } 05331 #endif 05332 } 05333 05334 /* Check if all output text has been retrieved */ 05335 if (hcryp->CrypOutCount == 0U) 05336 { 05337 #if !defined(AES_CR_NPBLB) 05338 /* Make sure that software-work around is not running before disabling 05339 the interruptions (indeed, if software work-around is running, the 05340 interruptions must not be disabled to allow the additional DOUTR 05341 reading round */ 05342 if (addhoc_process == 0U) 05343 #endif 05344 { 05345 /* Clear Computation Complete Flag */ 05346 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05347 /* Disable Computation Complete Flag and Errors Interrupts */ 05348 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE); 05349 /* Change the CRYP state */ 05350 hcryp->State = HAL_CRYP_STATE_READY; 05351 /* Mark that the payload phase is over */ 05352 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 05353 05354 /* Process Unlocked */ 05355 __HAL_UNLOCK(hcryp); 05356 05357 /* Call computation complete callback */ 05358 HAL_CRYPEx_ComputationCpltCallback(hcryp); 05359 } 05360 05361 return HAL_OK; 05362 } 05363 /* If suspension flag has been raised, suspend processing */ 05364 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND) 05365 { 05366 /* Clear CCF Flag */ 05367 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05368 05369 /* reset SuspendRequest */ 05370 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 05371 /* Disable Computation Complete Flag and Errors Interrupts */ 05372 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE); 05373 /* Change the CRYP state */ 05374 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 05375 /* Mark that the header phase is over */ 05376 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED; 05377 05378 /* Process Unlocked */ 05379 __HAL_UNLOCK(hcryp); 05380 05381 return HAL_OK; 05382 } 05383 else /* Output data are still expected, carry on feeding the CRYP 05384 hardware block with input data */ 05385 { 05386 /* Clear Computation Complete Flag */ 05387 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05388 /* Get the last Input data address */ 05389 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 05390 05391 /* Usual input data feeding case */ 05392 if (hcryp->CrypInCount < 16U) 05393 { 05394 difflength = (uint32_t) (hcryp->CrypInCount); 05395 difflengthmod4 = difflength%4U; 05396 hcryp->CrypInCount = 0U; 05397 05398 #if defined(AES_CR_NPBLB) 05399 /* In case of GCM encryption or CCM decryption, specify the number of padding 05400 bytes in last block of payload */ 05401 if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC) 05402 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT)) 05403 || ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC) 05404 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT))) 05405 { 05406 /* Set NPBLB field in writing the number of padding bytes 05407 for the last block of payload */ 05408 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength); 05409 } 05410 #else 05411 /* Software workaround applied to GCM encryption only */ 05412 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 05413 { 05414 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */ 05415 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR); 05416 } 05417 #endif 05418 05419 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes 05420 to have a complete block of 128 bits */ 05421 for(index=0U; index < (difflength/4U); index ++) 05422 { 05423 /* Write the Input block in the Data Input register */ 05424 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05425 inputaddr+=4U; 05426 } 05427 /* If required, manage input data size not multiple of 32 bits */ 05428 if (difflengthmod4 != 0U) 05429 { 05430 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]); 05431 } 05432 /* Wrap-up in padding with zero-words if applicable */ 05433 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 05434 { 05435 hcryp->Instance->DINR = 0U; 05436 } 05437 } 05438 else 05439 { 05440 hcryp->pCrypInBuffPtr += 16U; 05441 hcryp->CrypInCount -= 16U; 05442 05443 /* Write the Input block in the Data Input register */ 05444 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05445 inputaddr+=4U; 05446 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05447 inputaddr+=4U; 05448 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05449 inputaddr+=4U; 05450 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05451 } 05452 05453 return HAL_OK; 05454 } 05455 } 05456 /*====================================*/ 05457 /* GCM/GMAC or (CCM/)CMAC final phase */ 05458 /*====================================*/ 05459 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE) 05460 { 05461 /* Clear Computation Complete Flag */ 05462 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05463 05464 /* Get the last output data address */ 05465 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 05466 05467 /* Retrieve the last expected data from the CRYP hardware block: 05468 read the output block from the Data Output Register */ 05469 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05470 outputaddr+=4U; 05471 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05472 outputaddr+=4U; 05473 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05474 outputaddr+=4U; 05475 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05476 05477 /* Disable Computation Complete Flag and Errors Interrupts */ 05478 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE); 05479 /* Change the CRYP state */ 05480 hcryp->State = HAL_CRYP_STATE_READY; 05481 /* Mark that the header phase is over */ 05482 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER; 05483 05484 /* Disable the Peripheral */ 05485 __HAL_CRYP_DISABLE(); 05486 /* Process Unlocked */ 05487 __HAL_UNLOCK(hcryp); 05488 05489 /* Call computation complete callback */ 05490 HAL_CRYPEx_ComputationCpltCallback(hcryp); 05491 05492 return HAL_OK; 05493 } 05494 else 05495 { 05496 /* Clear Computation Complete Flag */ 05497 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05498 hcryp->State = HAL_CRYP_STATE_ERROR; 05499 __HAL_UNLOCK(hcryp); 05500 return HAL_ERROR; 05501 } 05502 } 05503 else 05504 { 05505 return HAL_BUSY; 05506 } 05507 } 05508 05509 /** 05510 * @brief Set the DMA configuration and start the DMA transfer 05511 * for GCM, GMAC or CMAC chainging modes. 05512 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 05513 * the configuration information for CRYP module. 05514 * @param inputaddr Address of the Input buffer. 05515 * @param Size Size of the Input buffer un bytes, must be a multiple of 16. 05516 * @param outputaddr Address of the Output buffer, null pointer when no output DMA stream 05517 * has to be configured. 05518 * @retval None 05519 */ 05520 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr) 05521 { 05522 05523 /* Set the input CRYP DMA transfer complete callback */ 05524 hcryp->hdmain->XferCpltCallback = CRYP_GCMCMAC_DMAInCplt; 05525 /* Set the DMA error callback */ 05526 hcryp->hdmain->XferErrorCallback = CRYP_GCMCMAC_DMAError; 05527 05528 if (outputaddr != 0U) 05529 { 05530 /* Set the output CRYP DMA transfer complete callback */ 05531 hcryp->hdmaout->XferCpltCallback = CRYP_GCMCMAC_DMAOutCplt; 05532 /* Set the DMA error callback */ 05533 hcryp->hdmaout->XferErrorCallback = CRYP_GCMCMAC_DMAError; 05534 } 05535 05536 /* Enable the CRYP peripheral */ 05537 __HAL_CRYP_ENABLE(); 05538 05539 /* Enable the DMA input stream */ 05540 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4U); 05541 05542 /* Enable the DMA input request */ 05543 SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN); 05544 05545 05546 if (outputaddr != 0U) 05547 { 05548 /* Enable the DMA output stream */ 05549 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4U); 05550 05551 /* Enable the DMA output request */ 05552 SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN); 05553 } 05554 } 05555 05556 /** 05557 * @brief Write/read input/output data in polling mode. 05558 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 05559 * the configuration information for CRYP module. 05560 * @param Input Pointer to the Input buffer. 05561 * @param Ilength Length of the Input buffer in bytes, must be a multiple of 16. 05562 * @param Output Pointer to the returned buffer. 05563 * @param Timeout Specify Timeout value. 05564 * @retval HAL status 05565 */ 05566 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout) 05567 { 05568 uint32_t index = 0U; 05569 uint32_t inputaddr = (uint32_t)Input; 05570 uint32_t outputaddr = (uint32_t)Output; 05571 05572 05573 for(index=0U; (index < Ilength); index += 16U) 05574 { 05575 /* Write the Input block in the Data Input register */ 05576 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05577 inputaddr+=4U; 05578 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05579 inputaddr+=4U; 05580 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05581 inputaddr+=4U; 05582 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05583 inputaddr+=4U; 05584 05585 /* Wait for CCF flag to be raised */ 05586 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 05587 { 05588 hcryp->State = HAL_CRYP_STATE_READY; 05589 __HAL_UNLOCK(hcryp); 05590 return HAL_TIMEOUT; 05591 } 05592 05593 /* Clear CCF Flag */ 05594 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05595 05596 /* Read the Output block from the Data Output Register */ 05597 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05598 outputaddr+=4U; 05599 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05600 outputaddr+=4U; 05601 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05602 outputaddr+=4U; 05603 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR; 05604 outputaddr+=4U; 05605 05606 /* If the suspension flag has been raised and if the processing is not about 05607 to end, suspend processing */ 05608 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength)) 05609 { 05610 /* Reset SuspendRequest */ 05611 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; 05612 05613 /* Save current reading and writing locations of Input and Output buffers */ 05614 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr; 05615 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr; 05616 /* Save the number of bytes that remain to be processed at this point */ 05617 hcryp->CrypInCount = Ilength - (index+16U); 05618 05619 /* Change the CRYP state */ 05620 hcryp->State = HAL_CRYP_STATE_SUSPENDED; 05621 05622 return HAL_OK; 05623 } 05624 05625 } 05626 /* Return function status */ 05627 return HAL_OK; 05628 05629 } 05630 05631 /** 05632 * @brief Read derivative key in polling mode when CRYP hardware block is set 05633 * in key derivation operating mode (mode 2). 05634 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 05635 * the configuration information for CRYP module. 05636 * @param Output Pointer to the returned buffer. 05637 * @param Timeout Specify Timeout value. 05638 * @retval HAL status 05639 */ 05640 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout) 05641 { 05642 uint32_t outputaddr = (uint32_t)Output; 05643 05644 /* Wait for CCF flag to be raised */ 05645 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) 05646 { 05647 hcryp->State = HAL_CRYP_STATE_READY; 05648 __HAL_UNLOCK(hcryp); 05649 return HAL_TIMEOUT; 05650 } 05651 /* Clear CCF Flag */ 05652 __HAL_CRYP_CLEAR_FLAG( CRYP_CCF_CLEAR); 05653 05654 /* Read the derivative key from the AES_KEYRx registers */ 05655 if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B) 05656 { 05657 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7); 05658 outputaddr+=4U; 05659 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6); 05660 outputaddr+=4U; 05661 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5); 05662 outputaddr+=4U; 05663 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4); 05664 outputaddr+=4U; 05665 } 05666 05667 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3); 05668 outputaddr+=4U; 05669 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2); 05670 outputaddr+=4U; 05671 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1); 05672 outputaddr+=4U; 05673 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0); 05674 05675 /* Return function status */ 05676 return HAL_OK; 05677 } 05678 05679 /** 05680 * @brief Set the DMA configuration and start the DMA transfer. 05681 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 05682 * the configuration information for CRYP module. 05683 * @param inputaddr Address of the Input buffer. 05684 * @param Size Size of the Input buffer in bytes, must be a multiple of 16. 05685 * @param outputaddr Address of the Output buffer. 05686 * @retval None 05687 */ 05688 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr) 05689 { 05690 /* Set the CRYP DMA transfer complete callback */ 05691 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt; 05692 /* Set the DMA error callback */ 05693 hcryp->hdmain->XferErrorCallback = CRYP_DMAError; 05694 05695 /* Set the CRYP DMA transfer complete callback */ 05696 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt; 05697 /* Set the DMA error callback */ 05698 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError; 05699 05700 /* Enable the DMA input stream */ 05701 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4U); 05702 05703 /* Enable the DMA output stream */ 05704 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4U); 05705 05706 /* Enable In and Out DMA requests */ 05707 SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN)); 05708 05709 /* Enable the CRYP peripheral */ 05710 __HAL_CRYP_ENABLE(); 05711 } 05712 05713 /** 05714 * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised. 05715 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 05716 * the configuration information for CRYP module. 05717 * @param Timeout Timeout duration. 05718 * @retval HAL status 05719 */ 05720 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 05721 { 05722 uint32_t tickstart = 0U; 05723 05724 /* Get timeout */ 05725 tickstart = HAL_GetTick(); 05726 05727 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF)) 05728 { 05729 /* Check for the Timeout */ 05730 if(Timeout != HAL_MAX_DELAY) 05731 { 05732 if((HAL_GetTick() - tickstart ) > Timeout) 05733 { 05734 return HAL_TIMEOUT; 05735 } 05736 } 05737 } 05738 return HAL_OK; 05739 } 05740 05741 /** 05742 * @brief Wait for Busy Flag to be reset during a GCM payload encryption process suspension. 05743 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 05744 * the configuration information for CRYP module. 05745 * @param Timeout Timeout duration. 05746 * @retval HAL status 05747 */ 05748 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 05749 { 05750 uint32_t tickstart = 0U; 05751 05752 /* Get timeout */ 05753 tickstart = HAL_GetTick(); 05754 05755 while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY)) 05756 { 05757 /* Check for the Timeout */ 05758 if(Timeout != HAL_MAX_DELAY) 05759 { 05760 if((HAL_GetTick() - tickstart ) > Timeout) 05761 { 05762 return HAL_TIMEOUT; 05763 } 05764 } 05765 } 05766 return HAL_OK; 05767 } 05768 05769 /** 05770 * @brief DMA CRYP Input Data process complete callback. 05771 * @param hdma DMA handle. 05772 * @retval None 05773 */ 05774 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma) 05775 { 05776 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 05777 05778 /* Disable the DMA transfer for input request */ 05779 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN); 05780 05781 /* Call input data transfer complete callback */ 05782 HAL_CRYP_InCpltCallback(hcryp); 05783 } 05784 05785 /** 05786 * @brief DMA CRYP Output Data process complete callback. 05787 * @param hdma DMA handle. 05788 * @retval None 05789 */ 05790 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma) 05791 { 05792 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 05793 05794 /* Disable the DMA transfer for output request */ 05795 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN); 05796 05797 /* Clear CCF Flag */ 05798 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05799 05800 /* Disable CRYP */ 05801 __HAL_CRYP_DISABLE(); 05802 05803 /* Change the CRYP state to ready */ 05804 hcryp->State = HAL_CRYP_STATE_READY; 05805 05806 /* Call output data transfer complete callback */ 05807 HAL_CRYP_OutCpltCallback(hcryp); 05808 } 05809 05810 /** 05811 * @brief DMA CRYP communication error callback. 05812 * @param hdma DMA handle. 05813 * @retval None 05814 */ 05815 static void CRYP_DMAError(DMA_HandleTypeDef *hdma) 05816 { 05817 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 05818 05819 hcryp->State= HAL_CRYP_STATE_ERROR; 05820 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR; 05821 HAL_CRYP_ErrorCallback(hcryp); 05822 /* Clear Error Flag */ 05823 __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR); 05824 } 05825 05826 /** 05827 * @brief Last header or payload block padding when size is not a multiple of 128 bits. 05828 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains 05829 * the configuration information for CRYP module. 05830 * @param difflength size remainder after having fed all complete 128-bit blocks. 05831 * @param polling specifies whether or not polling on CCF must be done after having 05832 * entered a complete block. 05833 * @retval None 05834 */ 05835 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling) 05836 { 05837 uint32_t index = 0U; 05838 uint32_t difflengthmod4 = difflength%4U; 05839 uint32_t inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; 05840 uint32_t outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; 05841 uint32_t mask[3U] = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU}; 05842 uint32_t intermediate_data[4U] = {0U}; 05843 05844 #if defined(AES_CR_NPBLB) 05845 /* In case of GCM encryption or CCM decryption, specify the number of padding 05846 bytes in last block of payload */ 05847 if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE) 05848 { 05849 if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC) 05850 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT)) 05851 || ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC) 05852 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT))) 05853 { 05854 /* Set NPBLB field in writing the number of padding bytes 05855 for the last block of payload */ 05856 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength); 05857 } 05858 } 05859 #else 05860 /* Software workaround applied to GCM encryption only */ 05861 if ((hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) && 05862 (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)) 05863 { 05864 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */ 05865 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR); 05866 } 05867 #endif 05868 05869 /* Wrap-up entering header or payload data */ 05870 /* Enter complete words when possible */ 05871 for(index=0U; index < (difflength/4U); index ++) 05872 { 05873 /* Write the Input block in the Data Input register */ 05874 hcryp->Instance->DINR = *(uint32_t*)(inputaddr); 05875 inputaddr+=4U; 05876 } 05877 /* Enter incomplete word padded with zeroes if applicable 05878 (case of header length not a multiple of 32-bits) */ 05879 if (difflengthmod4 != 0U) 05880 { 05881 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]); 05882 } 05883 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */ 05884 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 05885 { 05886 hcryp->Instance->DINR = 0U; 05887 } 05888 05889 if (polling == CRYP_POLLING_ON) 05890 { 05891 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 05892 { 05893 hcryp->State = HAL_CRYP_STATE_READY; 05894 __HAL_UNLOCK(hcryp); 05895 HAL_CRYP_ErrorCallback(hcryp); 05896 } 05897 05898 /* Clear CCF Flag */ 05899 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05900 } 05901 05902 /* if payload */ 05903 if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) 05904 { 05905 05906 /* Retrieve intermediate data */ 05907 for(index=0U; index < 4U; index ++) 05908 { 05909 intermediate_data[index] = hcryp->Instance->DOUTR; 05910 } 05911 /* Retrieve last words of cyphered data */ 05912 /* First, retrieve complete output words */ 05913 for(index=0U; index < (difflength/4U); index ++) 05914 { 05915 *(uint32_t*)(outputaddr) = intermediate_data[index]; 05916 outputaddr+=4U; 05917 } 05918 /* Next, retrieve partial output word if applicable; 05919 at the same time, start masking intermediate data 05920 with a mask of zeros of same size than the padding 05921 applied to the last block of payload */ 05922 if (difflengthmod4 != 0U) 05923 { 05924 intermediate_data[difflength/4U] &= mask[difflengthmod4-1U]; 05925 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U]; 05926 } 05927 05928 #if !defined(AES_CR_NPBLB) 05929 /* Software workaround applied to GCM encryption only, 05930 applicable for AES IP v2 version (where NPBLB is not defined) */ 05931 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) 05932 { 05933 /* Change again CHMOD configuration to GCM mode */ 05934 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC); 05935 05936 /* Select FINAL phase */ 05937 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE); 05938 05939 /* Before inserting the intermediate data, carry on masking operation 05940 with a mask of zeros of same size than the padding applied to the last block of payload */ 05941 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++) 05942 { 05943 intermediate_data[(difflength+3U)/4U+index] = 0U; 05944 } 05945 /* Insert intermediate data */ 05946 for(index=0U; index < 4U; index ++) 05947 { 05948 hcryp->Instance->DINR = intermediate_data[index]; 05949 } 05950 05951 /* Wait for completion, and read data on DOUT. This data is to discard. */ 05952 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK) 05953 { 05954 hcryp->State = HAL_CRYP_STATE_READY; 05955 __HAL_UNLOCK(hcryp); 05956 HAL_CRYP_ErrorCallback(hcryp); 05957 } 05958 05959 /* Read data to discard */ 05960 /* Clear CCF Flag */ 05961 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 05962 for(index=0U; index < 4U; index ++) 05963 { 05964 intermediate_data[index] = hcryp->Instance->DOUTR; 05965 } 05966 05967 } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */ 05968 #endif /* !defined(AES_CR_NPBLB) */ 05969 } /* if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) */ 05970 05971 } 05972 05973 /** 05974 * @} 05975 */ 05976 05977 #endif /* AES */ 05978 05979 #endif /* HAL_CRYP_MODULE_ENABLED */ 05980 /** 05981 * @} 05982 */ 05983 05984 /** 05985 * @} 05986 */ 05987 05988 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/