STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_hal_cryp.c 00004 * @author MCD Application Team 00005 * @brief CRYP HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Cryptography (CRYP) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + AES processing functions 00010 * + DES processing functions 00011 * + TDES processing functions 00012 * + DMA callback functions 00013 * + CRYP IRQ handler management 00014 * + Peripheral State functions 00015 * 00016 ****************************************************************************** 00017 * @attention 00018 * 00019 * Copyright (c) 2017 STMicroelectronics. 00020 * All rights reserved. 00021 * 00022 * This software is licensed under terms that can be found in the LICENSE file 00023 * in the root directory of this software component. 00024 * If no LICENSE file comes with this software, it is provided AS-IS. 00025 * 00026 ****************************************************************************** 00027 @verbatim 00028 ============================================================================== 00029 ##### How to use this driver ##### 00030 ============================================================================== 00031 [..] 00032 The CRYP HAL driver can be used in CRYP IP as follows: 00033 00034 (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit(): 00035 (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE() 00036 (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT()) 00037 (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority() 00038 (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ() 00039 (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler() 00040 (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA()) 00041 (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE() 00042 (+++) Configure and enable two DMA streams one for managing data transfer from 00043 memory to peripheral (input stream) and another stream for managing data 00044 transfer from peripheral to memory (output stream) 00045 (+++) Associate the initialized DMA handle to the CRYP DMA handle 00046 using __HAL_LINKDMA() 00047 (+++) Configure the priority and enable the NVIC for the transfer complete 00048 interrupt on the two DMA Streams. The output stream should have higher 00049 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ() 00050 00051 (#)Initialize the CRYP according to the specified parameters : 00052 (##) The data type: 1-bit, 8-bit, 16-bit or 32-bit. 00053 (##) The key size: 128, 192 or 256. 00054 (##) The AlgoMode DES/ TDES Algorithm ECB/CBC or AES Algorithm ECB/CBC/CTR/GCM or CCM. 00055 (##) The initialization vector (counter). It is not used in ECB mode. 00056 (##) The key buffer used for encryption/decryption. 00057 (##) The Header used only in AES GCM and CCM Algorithm for authentication. 00058 (##) The HeaderSize The size of header buffer in word. 00059 (##) The B0 block is the first authentication block used only in AES CCM mode. 00060 00061 (#)Three processing (encryption/decryption) functions are available: 00062 (##) Polling mode: encryption and decryption APIs are blocking functions 00063 i.e. they process the data and wait till the processing is finished, 00064 e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt 00065 (##) Interrupt mode: encryption and decryption APIs are not blocking functions 00066 i.e. they process the data under interrupt, 00067 e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT 00068 (##) DMA mode: encryption and decryption APIs are not blocking functions 00069 i.e. the data transfer is ensured by DMA, 00070 e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA 00071 00072 (#)When the processing function is called at first time after HAL_CRYP_Init() 00073 the CRYP peripheral is configured and processes the buffer in input. 00074 At second call, no need to Initialize the CRYP, user have to get current configuration via 00075 HAL_CRYP_GetConfig() API, then only HAL_CRYP_SetConfig() is requested to set 00076 new parametres, finally user can start encryption/decryption. 00077 00078 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral. 00079 00080 (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt() 00081 without having to configure again the Key or the Initialization Vector between each API call, 00082 the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE. 00083 Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA() 00084 or HAL_CRYP_Decrypt_DMA(). 00085 00086 [..] 00087 The cryptographic processor supports following standards: 00088 (#) The data encryption standard (DES) and Triple-DES (TDES) supported only by CRYP1 IP: 00089 (##)64-bit data block processing 00090 (##) chaining modes supported : 00091 (+++) Electronic Code Book(ECB) 00092 (+++) Cipher Block Chaining (CBC) 00093 (##) keys length supported :64-bit, 128-bit and 192-bit. 00094 (#) The advanced encryption standard (AES) supported by CRYP1: 00095 (##)128-bit data block processing 00096 (##) chaining modes supported : 00097 (+++) Electronic Code Book(ECB) 00098 (+++) Cipher Block Chaining (CBC) 00099 (+++) Counter mode (CTR) 00100 (+++) Galois/counter mode (GCM/GMAC) 00101 (+++) Counter with Cipher Block Chaining-Message(CCM) 00102 (##) keys length Supported : 00103 (+++) for CRYP1 IP: 128-bit, 192-bit and 256-bit. 00104 00105 [..] This section describes the AES Galois/counter mode (GCM) supported by both CRYP1 IP: 00106 (#) Algorithm supported : 00107 (##) Galois/counter mode (GCM) 00108 (##) Galois message authentication code (GMAC) :is exactly the same as 00109 GCM algorithm composed only by an header. 00110 (#) Four phases are performed in GCM : 00111 (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing 00112 (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash 00113 computation only. 00114 (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream 00115 encryption + data XORing. It works in a similar way for ciphertext (C). 00116 (##) Final phase: IP generates the authenticated tag (T) using the last block of data. 00117 HAL_CRYPEx_AESGCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond 00118 to the Tag. user should consider only part of this 4 words, if Tag length is less than 128 bits. 00119 (#) structure of message construction in GCM is defined as below : 00120 (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter 00121 (##) The authenticated header A (also knows as Additional Authentication Data AAD) 00122 this part of the message is only authenticated, not encrypted. 00123 (##) The plaintext message P is both authenticated and encrypted as ciphertext. 00124 GCM standard specifies that ciphertext has same bit length as the plaintext. 00125 (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext 00126 (on 64 bits) 00127 00128 [..] This section describe The AES Counter with Cipher Block Chaining-Message 00129 Authentication Code (CCM) supported by both CRYP1 IP: 00130 (#) Specific parameters for CCM : 00131 00132 (##) B0 block : According to NIST Special Publication 800-38C, 00133 The first block B0 is formatted as follows, where l(m) is encoded in 00134 most-significant-byte first order(see below table 3) 00135 00136 (+++) Q: a bit string representation of the octet length of P (plaintext) 00137 (+++) q The octet length of the binary representation of the octet length of the payload 00138 (+++) A nonce (N), n The octet length of the where n+q=15. 00139 (+++) Flags: most significant octet containing four flags for control information, 00140 (+++) t The octet length of the MAC. 00141 (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A) 00142 the associated data length expressed in bytes (a) defined as below: 00143 (+++) If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets 00144 (+++) If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets 00145 (+++) If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets 00146 (##) CTRx block : control blocks 00147 (+++) Generation of CTR1 from first block B0 information : 00148 equal to B0 with first 5 bits zeroed and most significant bits storing octet 00149 length of P also zeroed, then incremented by one ( see below Table 4) 00150 (+++) Generation of CTR0: same as CTR1 with bit[0] set to zero. 00151 00152 (#) Four phases are performed in CCM for CRYP1 IP: 00153 (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing 00154 (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash 00155 computation only. 00156 (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream 00157 encryption + data XORing. It works in a similar way for ciphertext (C). 00158 (##) Final phase: IP generates the authenticated tag (T) using the last block of data. 00159 HAL_CRYPEx_AESCCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond to the Tag. 00160 user should consider only part of this 4 words, if Tag length is less than 128 bits 00161 00162 *** Callback registration *** 00163 ============================= 00164 00165 [..] 00166 The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1 00167 allows the user to configure dynamically the driver callbacks. 00168 Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback() 00169 to register an interrupt callback. 00170 00171 [..] 00172 Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks: 00173 (+) InCpltCallback : Input FIFO transfer completed callback. 00174 (+) OutCpltCallback : Output FIFO transfer completed callback. 00175 (+) ErrorCallback : callback for error detection. 00176 (+) MspInitCallback : CRYP MspInit. 00177 (+) MspDeInitCallback : CRYP MspDeInit. 00178 This function takes as parameters the HAL peripheral handle, the Callback ID 00179 and a pointer to the user callback function. 00180 00181 [..] 00182 Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default 00183 weak function. 00184 @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle, 00185 and the Callback ID. 00186 This function allows to reset following callbacks: 00187 (+) InCpltCallback : Input FIFO transfer completed callback. 00188 (+) OutCpltCallback : Output FIFO transfer completed callback. 00189 (+) ErrorCallback : callback for error detection. 00190 (+) MspInitCallback : CRYP MspInit. 00191 (+) MspDeInitCallback : CRYP MspDeInit. 00192 00193 [..] 00194 By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET 00195 all callbacks are set to the corresponding weak functions : 00196 examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback(). 00197 Exception done for MspInit and MspDeInit functions that are 00198 reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when 00199 these callbacks are null (not registered beforehand). 00200 if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit() 00201 keep and use the user MspInit/MspDeInit functions (registered beforehand) 00202 00203 [..] 00204 Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only. 00205 Exception done MspInit/MspDeInit callbacks that can be registered/unregistered 00206 in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state, 00207 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. 00208 In that case first register the MspInit/MspDeInit user callbacks 00209 using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit() 00210 or @ref HAL_CRYP_Init() function. 00211 00212 [..] 00213 When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or 00214 not defined, the callback registration feature is not available and all callbacks 00215 are set to the corresponding weak functions. 00216 00217 @endverbatim 00218 00219 Table 1. Initial Counter Block (ICB) 00220 +-------------------------------------------------------+ 00221 | Initialization vector (IV) | Counter | 00222 |----------------|----------------|-----------|---------| 00223 127 95 63 31 0 00224 00225 00226 Bit Number Register Contents 00227 ---------- --------------- ----------- 00228 127 ...96 CRYP_IV1R[31:0] ICB[127:96] 00229 95 ...64 CRYP_IV1L[31:0] B0[95:64] 00230 63 ... 32 CRYP_IV0R[31:0] ICB[63:32] 00231 31 ... 0 CRYP_IV0L[31:0] ICB[31:0], where 32-bit counter= 0x2 00232 00233 Table 2. GCM last block definition 00234 00235 +-------------------------------------------------------------------+ 00236 | Bit[0] | Bit[32] | Bit[64] | Bit[96] | 00237 |-----------|--------------------|-----------|----------------------| 00238 | 0x0 | Header length[31:0]| 0x0 | Payload length[31:0] | 00239 |-----------|--------------------|-----------|----------------------| 00240 00241 Table 3. B0 block 00242 Octet Number Contents 00243 ------------ --------- 00244 0 Flags 00245 1 ... 15-q Nonce N 00246 16-q ... 15 Q 00247 00248 the Flags field is formatted as follows: 00249 00250 Bit Number Contents 00251 ---------- ---------------------- 00252 7 Reserved (always zero) 00253 6 Adata 00254 5 ... 3 (t-2)/2 00255 2 ... 0 [q-1]3 00256 00257 Table 4. CTRx block 00258 Bit Number Register Contents 00259 ---------- --------------- ----------- 00260 127 ...96 CRYP_IV1R[31:0] B0[127:96], where Q length bits are set to 0, except for 00261 bit 0 that is set to 1 00262 95 ...64 CRYP_IV1L[31:0] B0[95:64] 00263 63 ... 32 CRYP_IV0R[31:0] B0[63:32] 00264 31 ... 0 CRYP_IV0L[31:0] B0[31:0], where flag bits set to 0 00265 */ 00266 00267 /* Includes ------------------------------------------------------------------*/ 00268 #include "stm32h7xx_hal.h" 00269 00270 /** @addtogroup STM32H7xx_HAL_Driver 00271 * @{ 00272 */ 00273 00274 #if defined (CRYP) 00275 00276 /** @defgroup CRYP CRYP 00277 * @brief CRYP HAL module driver. 00278 * @{ 00279 */ 00280 00281 00282 #ifdef HAL_CRYP_MODULE_ENABLED 00283 00284 /* Private typedef -----------------------------------------------------------*/ 00285 /* Private define ------------------------------------------------------------*/ 00286 /** @addtogroup CRYP_Private_Defines 00287 * @{ 00288 */ 00289 #define CRYP_TIMEOUT_KEYPREPARATION 82U /*The latency of key preparation operation is 82 clock cycles.*/ 00290 #define CRYP_TIMEOUT_GCMCCMINITPHASE 299U /* The latency of GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/ 00291 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE 290U /* The latency of GCM/CCM header phase is 290 clock cycles.*/ 00292 00293 #define CRYP_PHASE_READY 0x00000001U /*!< CRYP peripheral is ready for initialization. */ 00294 #define CRYP_PHASE_PROCESS 0x00000002U /*!< CRYP peripheral is in processing phase */ 00295 00296 #define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */ 00297 #define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0 /*!< GCM/GMAC or CCM header phase */ 00298 #define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1 /*!< GCM(/CCM) payload phase */ 00299 #define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH /*!< GCM/GMAC or CCM final phase */ 00300 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */ 00301 #define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR /*!< Decryption */ 00302 00303 00304 /* CTR1 information to use in CCM algorithm */ 00305 #define CRYP_CCM_CTR1_0 0x07FFFFFFU 00306 #define CRYP_CCM_CTR1_1 0xFFFFFF00U 00307 #define CRYP_CCM_CTR1_2 0x00000001U 00308 00309 /** 00310 * @} 00311 */ 00312 00313 00314 /* Private macro -------------------------------------------------------------*/ 00315 /** @addtogroup CRYP_Private_Macros 00316 * @{ 00317 */ 00318 00319 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__) do{(__HANDLE__)->Instance->CR &= (uint32_t)(~CRYP_CR_GCM_CCMPH);\ 00320 (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\ 00321 }while(0) 00322 00323 #define HAL_CRYP_FIFO_FLUSH(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRYP_CR_FFLUSH) 00324 00325 00326 /** 00327 * @} 00328 */ 00329 00330 /* Private struct -------------------------------------------------------------*/ 00331 /* Private variables ---------------------------------------------------------*/ 00332 /* Private function prototypes -----------------------------------------------*/ 00333 /** @addtogroup CRYP_Private_Functions_prototypes 00334 * @{ 00335 */ 00336 00337 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr); 00338 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma); 00339 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma); 00340 static void CRYP_DMAError(DMA_HandleTypeDef *hdma); 00341 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize); 00342 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp); 00343 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00344 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp); 00345 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp); 00346 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp); 00347 #if !defined (CRYP_VER_2_2) 00348 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00349 #endif /*End of not defined CRYP_VER_2_2*/ 00350 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp); 00351 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp); 00352 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00353 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00354 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp); 00355 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp); 00356 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout); 00357 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00358 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00359 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp); 00360 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp); 00361 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp); 00362 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp); 00363 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00364 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00365 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00366 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); 00367 00368 /** 00369 * @} 00370 */ 00371 00372 /* Exported functions ---------------------------------------------------------*/ 00373 00374 /** @defgroup CRYP_Exported_Functions CRYP Exported Functions 00375 * @{ 00376 */ 00377 00378 00379 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions 00380 * @brief CRYP Initialization and Configuration functions. 00381 * 00382 @verbatim 00383 ======================================================================================== 00384 ##### Initialization, de-initialization and Set and Get configuration functions ##### 00385 ======================================================================================== 00386 [..] This section provides functions allowing to: 00387 (+) Initialize the CRYP 00388 (+) DeInitialize the CRYP 00389 (+) Initialize the CRYP MSP 00390 (+) DeInitialize the CRYP MSP 00391 (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef 00392 Parameters which are configured in This section are : 00393 (++) Key size 00394 (++) Data Type : 32,16, 8 or 1bit 00395 (++) AlgoMode : for CRYP1 IP 00396 ECB and CBC in DES/TDES Standard 00397 ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard. 00398 (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef 00399 00400 00401 @endverbatim 00402 * @{ 00403 */ 00404 00405 00406 /** 00407 * @brief Initializes the CRYP according to the specified 00408 * parameters in the CRYP_ConfigTypeDef and creates the associated handle. 00409 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 00410 * the configuration information for CRYP module 00411 * @retval HAL status 00412 */ 00413 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp) 00414 { 00415 /* Check the CRYP handle allocation */ 00416 if (hcryp == NULL) 00417 { 00418 return HAL_ERROR; 00419 } 00420 00421 /* Check parameters */ 00422 assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize)); 00423 assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType)); 00424 assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm)); 00425 assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip)); 00426 00427 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 00428 if (hcryp->State == HAL_CRYP_STATE_RESET) 00429 { 00430 /* Allocate lock resource and initialize it */ 00431 hcryp->Lock = HAL_UNLOCKED; 00432 00433 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */ 00434 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */ 00435 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */ 00436 00437 if (hcryp->MspInitCallback == NULL) 00438 { 00439 hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit */ 00440 } 00441 00442 /* Init the low level hardware */ 00443 hcryp->MspInitCallback(hcryp); 00444 } 00445 #else 00446 if (hcryp->State == HAL_CRYP_STATE_RESET) 00447 { 00448 /* Allocate lock resource and initialize it */ 00449 hcryp->Lock = HAL_UNLOCKED; 00450 00451 /* Init the low level hardware */ 00452 HAL_CRYP_MspInit(hcryp); 00453 } 00454 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */ 00455 00456 /* Set the key size(This bit field is don't care in the DES or TDES modes) data type and Algorithm */ 00457 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE, 00458 hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm); 00459 #if !defined (CRYP_VER_2_2) 00460 /* Read Device ID to indicate CRYP1 IP Version */ 00461 hcryp->Version = HAL_GetREVID(); 00462 #endif /*End of not defined CRYP_VER_2_2*/ 00463 /* Reset Error Code field */ 00464 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE; 00465 00466 /* Reset peripheral Key and IV configuration flag */ 00467 hcryp->KeyIVConfig = 0U; 00468 00469 /* Change the CRYP state */ 00470 hcryp->State = HAL_CRYP_STATE_READY; 00471 00472 /* Set the default CRYP phase */ 00473 hcryp->Phase = CRYP_PHASE_READY; 00474 00475 /* Return function status */ 00476 return HAL_OK; 00477 } 00478 00479 /** 00480 * @brief De-Initializes the CRYP peripheral. 00481 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 00482 * the configuration information for CRYP module 00483 * @retval HAL status 00484 */ 00485 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp) 00486 { 00487 /* Check the CRYP handle allocation */ 00488 if (hcryp == NULL) 00489 { 00490 return HAL_ERROR; 00491 } 00492 00493 /* Set the default CRYP phase */ 00494 hcryp->Phase = CRYP_PHASE_READY; 00495 00496 /* Reset CrypInCount and CrypOutCount */ 00497 hcryp->CrypInCount = 0; 00498 hcryp->CrypOutCount = 0; 00499 hcryp->CrypHeaderCount = 0; 00500 00501 /* Disable the CRYP peripheral clock */ 00502 __HAL_CRYP_DISABLE(hcryp); 00503 00504 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 00505 if (hcryp->MspDeInitCallback == NULL) 00506 { 00507 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit */ 00508 } 00509 /* DeInit the low level hardware */ 00510 hcryp->MspDeInitCallback(hcryp); 00511 00512 #else 00513 /* DeInit the low level hardware: CLOCK, NVIC.*/ 00514 HAL_CRYP_MspDeInit(hcryp); 00515 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 00516 00517 /* Change the CRYP state */ 00518 hcryp->State = HAL_CRYP_STATE_RESET; 00519 00520 /* Release Lock */ 00521 __HAL_UNLOCK(hcryp); 00522 00523 /* Return function status */ 00524 return HAL_OK; 00525 } 00526 00527 /** 00528 * @brief Configure the CRYP according to the specified 00529 * parameters in the CRYP_ConfigTypeDef 00530 * @param hcryp: pointer to a CRYP_HandleTypeDef structure 00531 * @param pConf: pointer to a CRYP_ConfigTypeDef structure that contains 00532 * the configuration information for CRYP module 00533 * @retval HAL status 00534 */ 00535 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf) 00536 { 00537 /* Check the CRYP handle allocation */ 00538 if ((hcryp == NULL) || (pConf == NULL)) 00539 { 00540 return HAL_ERROR; 00541 } 00542 00543 /* Check parameters */ 00544 assert_param(IS_CRYP_KEYSIZE(pConf->KeySize)); 00545 assert_param(IS_CRYP_DATATYPE(pConf->DataType)); 00546 assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm)); 00547 00548 if (hcryp->State == HAL_CRYP_STATE_READY) 00549 { 00550 /* Change the CRYP state */ 00551 hcryp->State = HAL_CRYP_STATE_BUSY; 00552 00553 /* Process locked */ 00554 __HAL_LOCK(hcryp); 00555 00556 /* Set CRYP parameters */ 00557 hcryp->Init.DataType = pConf->DataType; 00558 hcryp->Init.pKey = pConf->pKey; 00559 hcryp->Init.Algorithm = pConf->Algorithm; 00560 hcryp->Init.KeySize = pConf->KeySize; 00561 hcryp->Init.pInitVect = pConf->pInitVect; 00562 hcryp->Init.Header = pConf->Header; 00563 hcryp->Init.HeaderSize = pConf->HeaderSize; 00564 hcryp->Init.B0 = pConf->B0; 00565 hcryp->Init.DataWidthUnit = pConf->DataWidthUnit; 00566 00567 /* Set the key size(This bit field is don't care in the DES or TDES modes) data type, AlgoMode and operating mode*/ 00568 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE, 00569 hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm); 00570 00571 /* Process Unlocked */ 00572 __HAL_UNLOCK(hcryp); 00573 00574 /* Reset Error Code field */ 00575 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE; 00576 00577 /* Change the CRYP state */ 00578 hcryp->State = HAL_CRYP_STATE_READY; 00579 00580 /* Set the default CRYP phase */ 00581 hcryp->Phase = CRYP_PHASE_READY; 00582 00583 /* Return function status */ 00584 return HAL_OK; 00585 } 00586 else 00587 { 00588 /* Process Unlocked */ 00589 __HAL_UNLOCK(hcryp); 00590 00591 /* Busy error code field */ 00592 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 00593 return HAL_ERROR; 00594 } 00595 } 00596 00597 /** 00598 * @brief Get CRYP Configuration parameters in associated handle. 00599 * @param pConf: pointer to a CRYP_ConfigTypeDef structure 00600 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 00601 * the configuration information for CRYP module 00602 * @retval HAL status 00603 */ 00604 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf) 00605 { 00606 /* Check the CRYP handle allocation */ 00607 if ((hcryp == NULL) || (pConf == NULL)) 00608 { 00609 return HAL_ERROR; 00610 } 00611 00612 if (hcryp->State == HAL_CRYP_STATE_READY) 00613 { 00614 /* Change the CRYP state */ 00615 hcryp->State = HAL_CRYP_STATE_BUSY; 00616 00617 /* Process locked */ 00618 __HAL_LOCK(hcryp); 00619 00620 /* Get CRYP parameters */ 00621 pConf->DataType = hcryp->Init.DataType; 00622 pConf->pKey = hcryp->Init.pKey; 00623 pConf->Algorithm = hcryp->Init.Algorithm; 00624 pConf->KeySize = hcryp->Init.KeySize ; 00625 pConf->pInitVect = hcryp->Init.pInitVect; 00626 pConf->Header = hcryp->Init.Header ; 00627 pConf->HeaderSize = hcryp->Init.HeaderSize; 00628 pConf->B0 = hcryp->Init.B0; 00629 pConf->DataWidthUnit = hcryp->Init.DataWidthUnit; 00630 00631 /* Process Unlocked */ 00632 __HAL_UNLOCK(hcryp); 00633 00634 /* Change the CRYP state */ 00635 hcryp->State = HAL_CRYP_STATE_READY; 00636 00637 /* Return function status */ 00638 return HAL_OK; 00639 } 00640 else 00641 { 00642 /* Process Unlocked */ 00643 __HAL_UNLOCK(hcryp); 00644 00645 /* Busy error code field */ 00646 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 00647 return HAL_ERROR; 00648 } 00649 } 00650 /** 00651 * @brief Initializes the CRYP MSP. 00652 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 00653 * the configuration information for CRYP module 00654 * @retval None 00655 */ 00656 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp) 00657 { 00658 /* Prevent unused argument(s) compilation warning */ 00659 UNUSED(hcryp); 00660 00661 /* NOTE : This function Should not be modified, when the callback is needed, 00662 the HAL_CRYP_MspInit could be implemented in the user file 00663 */ 00664 } 00665 00666 /** 00667 * @brief DeInitializes CRYP MSP. 00668 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 00669 * the configuration information for CRYP module 00670 * @retval None 00671 */ 00672 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp) 00673 { 00674 /* Prevent unused argument(s) compilation warning */ 00675 UNUSED(hcryp); 00676 00677 /* NOTE : This function Should not be modified, when the callback is needed, 00678 the HAL_CRYP_MspDeInit could be implemented in the user file 00679 */ 00680 } 00681 00682 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 00683 /** 00684 * @brief Register a User CRYP Callback 00685 * To be used instead of the weak predefined callback 00686 * @param hcryp cryp handle 00687 * @param CallbackID ID of the callback to be registered 00688 * This parameter can be one of the following values: 00689 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID 00690 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID 00691 * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID 00692 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID 00693 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID 00694 * @param pCallback pointer to the Callback function 00695 * @retval status 00696 */ 00697 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID, 00698 pCRYP_CallbackTypeDef pCallback) 00699 { 00700 HAL_StatusTypeDef status = HAL_OK; 00701 00702 if (pCallback == NULL) 00703 { 00704 /* Update the error code */ 00705 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; 00706 00707 return HAL_ERROR; 00708 } 00709 /* Process locked */ 00710 __HAL_LOCK(hcryp); 00711 00712 if (hcryp->State == HAL_CRYP_STATE_READY) 00713 { 00714 switch (CallbackID) 00715 { 00716 case HAL_CRYP_INPUT_COMPLETE_CB_ID : 00717 hcryp->InCpltCallback = pCallback; 00718 break; 00719 00720 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID : 00721 hcryp->OutCpltCallback = pCallback; 00722 break; 00723 00724 case HAL_CRYP_ERROR_CB_ID : 00725 hcryp->ErrorCallback = pCallback; 00726 break; 00727 00728 case HAL_CRYP_MSPINIT_CB_ID : 00729 hcryp->MspInitCallback = pCallback; 00730 break; 00731 00732 case HAL_CRYP_MSPDEINIT_CB_ID : 00733 hcryp->MspDeInitCallback = pCallback; 00734 break; 00735 00736 default : 00737 /* Update the error code */ 00738 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; 00739 /* Return error status */ 00740 status = HAL_ERROR; 00741 break; 00742 } 00743 } 00744 else if (hcryp->State == HAL_CRYP_STATE_RESET) 00745 { 00746 switch (CallbackID) 00747 { 00748 case HAL_CRYP_MSPINIT_CB_ID : 00749 hcryp->MspInitCallback = pCallback; 00750 break; 00751 00752 case HAL_CRYP_MSPDEINIT_CB_ID : 00753 hcryp->MspDeInitCallback = pCallback; 00754 break; 00755 00756 default : 00757 /* Update the error code */ 00758 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; 00759 /* Return error status */ 00760 status = HAL_ERROR; 00761 break; 00762 } 00763 } 00764 else 00765 { 00766 /* Update the error code */ 00767 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; 00768 /* Return error status */ 00769 status = HAL_ERROR; 00770 } 00771 00772 /* Release Lock */ 00773 __HAL_UNLOCK(hcryp); 00774 00775 return status; 00776 } 00777 00778 /** 00779 * @brief Unregister an CRYP Callback 00780 * CRYP callabck is redirected to the weak predefined callback 00781 * @param hcryp cryp handle 00782 * @param CallbackID ID of the callback to be unregistered 00783 * This parameter can be one of the following values: 00784 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID 00785 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID 00786 * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID 00787 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID 00788 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID 00789 * @retval status 00790 */ 00791 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID) 00792 { 00793 HAL_StatusTypeDef status = HAL_OK; 00794 00795 /* Process locked */ 00796 __HAL_LOCK(hcryp); 00797 00798 if (hcryp->State == HAL_CRYP_STATE_READY) 00799 { 00800 switch (CallbackID) 00801 { 00802 case HAL_CRYP_INPUT_COMPLETE_CB_ID : 00803 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */ 00804 break; 00805 00806 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID : 00807 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */ 00808 break; 00809 00810 case HAL_CRYP_ERROR_CB_ID : 00811 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */ 00812 break; 00813 00814 case HAL_CRYP_MSPINIT_CB_ID : 00815 hcryp->MspInitCallback = HAL_CRYP_MspInit; 00816 break; 00817 00818 case HAL_CRYP_MSPDEINIT_CB_ID : 00819 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; 00820 break; 00821 00822 default : 00823 /* Update the error code */ 00824 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; 00825 /* Return error status */ 00826 status = HAL_ERROR; 00827 break; 00828 } 00829 } 00830 else if (hcryp->State == HAL_CRYP_STATE_RESET) 00831 { 00832 switch (CallbackID) 00833 { 00834 case HAL_CRYP_MSPINIT_CB_ID : 00835 hcryp->MspInitCallback = HAL_CRYP_MspInit; 00836 break; 00837 00838 case HAL_CRYP_MSPDEINIT_CB_ID : 00839 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; 00840 break; 00841 00842 default : 00843 /* Update the error code */ 00844 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; 00845 /* Return error status */ 00846 status = HAL_ERROR; 00847 break; 00848 } 00849 } 00850 else 00851 { 00852 /* Update the error code */ 00853 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;; 00854 /* Return error status */ 00855 status = HAL_ERROR; 00856 } 00857 00858 /* Release Lock */ 00859 __HAL_UNLOCK(hcryp); 00860 00861 return status; 00862 } 00863 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 00864 00865 /** 00866 * @} 00867 */ 00868 00869 /** @defgroup CRYP_Exported_Functions_Group2 Encrypt Decrypt functions 00870 * @brief CRYP processing functions. 00871 * 00872 @verbatim 00873 ============================================================================== 00874 ##### Encrypt Decrypt functions ##### 00875 ============================================================================== 00876 [..] This section provides API allowing to Encrypt/Decrypt Data following 00877 Standard DES/TDES or AES, and Algorithm configured by the user: 00878 (+) Standard DES/TDES only supported by CRYP1 IP, below list of Algorithm supported : 00879 (++) Electronic Code Book(ECB) 00880 (++) Cipher Block Chaining (CBC) 00881 (+) Standard AES supported by CRYP1 IP , list of Algorithm supported: 00882 (++) Electronic Code Book(ECB) 00883 (++) Cipher Block Chaining (CBC) 00884 (++) Counter mode (CTR) 00885 (++) Cipher Block Chaining (CBC) 00886 (++) Counter mode (CTR) 00887 (++) Galois/counter mode (GCM) 00888 (++) Counter with Cipher Block Chaining-Message(CCM) 00889 [..] Three processing functions are available: 00890 (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt 00891 (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT 00892 (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA 00893 00894 @endverbatim 00895 * @{ 00896 */ 00897 00898 00899 /** 00900 * @brief Encryption mode. 00901 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 00902 * the configuration information for CRYP module 00903 * @param Input: Pointer to the input buffer (plaintext) 00904 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit. 00905 * @param Output: Pointer to the output buffer(ciphertext) 00906 * @param Timeout: Specify Timeout value 00907 * @retval HAL status 00908 */ 00909 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output, 00910 uint32_t Timeout) 00911 { 00912 uint32_t algo; 00913 HAL_StatusTypeDef status; 00914 00915 if (hcryp->State == HAL_CRYP_STATE_READY) 00916 { 00917 /* Change state Busy */ 00918 hcryp->State = HAL_CRYP_STATE_BUSY; 00919 00920 /* Process locked */ 00921 __HAL_LOCK(hcryp); 00922 00923 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/ 00924 hcryp->CrypInCount = 0U; 00925 hcryp->CrypOutCount = 0U; 00926 hcryp->pCrypInBuffPtr = Input; 00927 hcryp->pCrypOutBuffPtr = Output; 00928 00929 /* Calculate Size parameter in Byte*/ 00930 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) 00931 { 00932 hcryp->Size = Size * 4U; 00933 } 00934 else 00935 { 00936 hcryp->Size = Size; 00937 } 00938 00939 /* Set Encryption operating mode*/ 00940 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT); 00941 00942 /* algo get algorithm selected */ 00943 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE; 00944 00945 switch (algo) 00946 { 00947 case CRYP_DES_ECB: 00948 case CRYP_DES_CBC: 00949 case CRYP_TDES_ECB: 00950 case CRYP_TDES_CBC: 00951 00952 /*Set Key */ 00953 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey); 00954 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1); 00955 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 00956 { 00957 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2); 00958 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3); 00959 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4); 00960 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5); 00961 } 00962 00963 /*Set Initialization Vector (IV)*/ 00964 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 00965 { 00966 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 00967 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 00968 } 00969 00970 /* Flush FIFO */ 00971 HAL_CRYP_FIFO_FLUSH(hcryp); 00972 00973 /* Set the phase */ 00974 hcryp->Phase = CRYP_PHASE_PROCESS; 00975 00976 /* Statrt DES/TDES encryption process */ 00977 status = CRYP_TDES_Process(hcryp, Timeout); 00978 break; 00979 00980 case CRYP_AES_ECB: 00981 case CRYP_AES_CBC: 00982 case CRYP_AES_CTR: 00983 00984 /* AES encryption */ 00985 status = CRYP_AES_Encrypt(hcryp, Timeout); 00986 break; 00987 00988 case CRYP_AES_GCM: 00989 00990 /* AES GCM encryption */ 00991 status = CRYP_AESGCM_Process(hcryp, Timeout); 00992 break; 00993 00994 case CRYP_AES_CCM: 00995 00996 /* AES CCM encryption */ 00997 status = CRYP_AESCCM_Process(hcryp, Timeout); 00998 break; 00999 01000 default: 01001 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; 01002 status = HAL_ERROR; 01003 break; 01004 } 01005 01006 if (status == HAL_OK) 01007 { 01008 /* Change the CRYP peripheral state */ 01009 hcryp->State = HAL_CRYP_STATE_READY; 01010 01011 /* Process unlocked */ 01012 __HAL_UNLOCK(hcryp); 01013 } 01014 } 01015 else 01016 { 01017 /* Process unlocked */ 01018 __HAL_UNLOCK(hcryp); 01019 01020 /* Busy error code field */ 01021 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 01022 status = HAL_ERROR; 01023 } 01024 01025 /* Return function status */ 01026 return status ; 01027 } 01028 01029 /** 01030 * @brief Decryption mode. 01031 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01032 * the configuration information for CRYP module 01033 * @param Input: Pointer to the input buffer (ciphertext ) 01034 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit 01035 * @param Output: Pointer to the output buffer(plaintext) 01036 * @param Timeout: Specify Timeout value 01037 * @retval HAL status 01038 */ 01039 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output, 01040 uint32_t Timeout) 01041 { 01042 HAL_StatusTypeDef status; 01043 uint32_t algo; 01044 01045 if (hcryp->State == HAL_CRYP_STATE_READY) 01046 { 01047 /* Change state Busy */ 01048 hcryp->State = HAL_CRYP_STATE_BUSY; 01049 01050 /* Process locked */ 01051 __HAL_LOCK(hcryp); 01052 01053 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/ 01054 hcryp->CrypInCount = 0U; 01055 hcryp->CrypOutCount = 0U; 01056 hcryp->pCrypInBuffPtr = Input; 01057 hcryp->pCrypOutBuffPtr = Output; 01058 01059 /* Calculate Size parameter in Byte*/ 01060 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) 01061 { 01062 hcryp->Size = Size * 4U; 01063 } 01064 else 01065 { 01066 hcryp->Size = Size; 01067 } 01068 01069 /* Set Decryption operating mode*/ 01070 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT); 01071 01072 /* algo get algorithm selected */ 01073 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE; 01074 01075 switch (algo) 01076 { 01077 case CRYP_DES_ECB: 01078 case CRYP_DES_CBC: 01079 case CRYP_TDES_ECB: 01080 case CRYP_TDES_CBC: 01081 01082 /*Set Key */ 01083 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey); 01084 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1); 01085 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01086 { 01087 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2); 01088 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3); 01089 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4); 01090 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5); 01091 } 01092 01093 /*Set Initialization Vector (IV)*/ 01094 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01095 { 01096 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 01097 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 01098 } 01099 01100 /* Flush FIFO */ 01101 HAL_CRYP_FIFO_FLUSH(hcryp); 01102 01103 /* Set the phase */ 01104 hcryp->Phase = CRYP_PHASE_PROCESS; 01105 01106 /* Start DES/TDES decryption process */ 01107 status = CRYP_TDES_Process(hcryp, Timeout); 01108 01109 break; 01110 01111 case CRYP_AES_ECB: 01112 case CRYP_AES_CBC: 01113 case CRYP_AES_CTR: 01114 01115 /* AES decryption */ 01116 status = CRYP_AES_Decrypt(hcryp, Timeout); 01117 break; 01118 01119 case CRYP_AES_GCM: 01120 01121 /* AES GCM decryption */ 01122 status = CRYP_AESGCM_Process(hcryp, Timeout) ; 01123 break; 01124 01125 case CRYP_AES_CCM: 01126 01127 /* AES CCM decryption */ 01128 status = CRYP_AESCCM_Process(hcryp, Timeout); 01129 break; 01130 01131 default: 01132 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; 01133 status = HAL_ERROR; 01134 break; 01135 } 01136 01137 if (status == HAL_OK) 01138 { 01139 /* Change the CRYP peripheral state */ 01140 hcryp->State = HAL_CRYP_STATE_READY; 01141 01142 /* Process unlocked */ 01143 __HAL_UNLOCK(hcryp); 01144 } 01145 } 01146 else 01147 { 01148 /* Process unlocked */ 01149 __HAL_UNLOCK(hcryp); 01150 01151 /* Busy error code field */ 01152 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 01153 status = HAL_ERROR; 01154 } 01155 01156 /* Return function status */ 01157 return status; 01158 } 01159 01160 /** 01161 * @brief Encryption in interrupt mode. 01162 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01163 * the configuration information for CRYP module 01164 * @param Input: Pointer to the input buffer (plaintext) 01165 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit 01166 * @param Output: Pointer to the output buffer(ciphertext) 01167 * @retval HAL status 01168 */ 01169 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output) 01170 { 01171 uint32_t algo; 01172 HAL_StatusTypeDef status; 01173 01174 if (hcryp->State == HAL_CRYP_STATE_READY) 01175 { 01176 /* Change state Busy */ 01177 hcryp->State = HAL_CRYP_STATE_BUSY; 01178 01179 /* Process locked */ 01180 __HAL_LOCK(hcryp); 01181 01182 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/ 01183 hcryp->CrypInCount = 0U; 01184 hcryp->CrypOutCount = 0U; 01185 hcryp->pCrypInBuffPtr = Input; 01186 hcryp->pCrypOutBuffPtr = Output; 01187 01188 /* Calculate Size parameter in Byte*/ 01189 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) 01190 { 01191 hcryp->Size = Size * 4U; 01192 } 01193 else 01194 { 01195 hcryp->Size = Size; 01196 } 01197 01198 /* Set encryption operating mode*/ 01199 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT); 01200 01201 /* algo get algorithm selected */ 01202 algo = (hcryp->Instance->CR & CRYP_CR_ALGOMODE); 01203 01204 switch (algo) 01205 { 01206 case CRYP_DES_ECB: 01207 case CRYP_DES_CBC: 01208 case CRYP_TDES_ECB: 01209 case CRYP_TDES_CBC: 01210 01211 /*Set Key */ 01212 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey); 01213 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1); 01214 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01215 { 01216 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2); 01217 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3); 01218 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4); 01219 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5); 01220 } 01221 /* Set the Initialization Vector*/ 01222 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01223 { 01224 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 01225 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 01226 } 01227 01228 /* Flush FIFO */ 01229 HAL_CRYP_FIFO_FLUSH(hcryp); 01230 01231 /* Set the phase */ 01232 hcryp->Phase = CRYP_PHASE_PROCESS; 01233 01234 /* Enable interrupts */ 01235 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 01236 01237 /* Enable CRYP to start DES/TDES process*/ 01238 __HAL_CRYP_ENABLE(hcryp); 01239 01240 status = HAL_OK; 01241 break; 01242 01243 case CRYP_AES_ECB: 01244 case CRYP_AES_CBC: 01245 case CRYP_AES_CTR: 01246 01247 status = CRYP_AES_Encrypt_IT(hcryp); 01248 break; 01249 01250 case CRYP_AES_GCM: 01251 01252 status = CRYP_AESGCM_Process_IT(hcryp) ; 01253 break; 01254 01255 case CRYP_AES_CCM: 01256 01257 status = CRYP_AESCCM_Process_IT(hcryp); 01258 break; 01259 01260 default: 01261 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; 01262 status = HAL_ERROR; 01263 break; 01264 } 01265 } 01266 else 01267 { 01268 /* Busy error code field */ 01269 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 01270 status = HAL_ERROR; 01271 } 01272 01273 /* Return function status */ 01274 return status ; 01275 } 01276 01277 /** 01278 * @brief Decryption in itnterrupt mode. 01279 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01280 * the configuration information for CRYP module 01281 * @param Input: Pointer to the input buffer (ciphertext ) 01282 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit 01283 * @param Output: Pointer to the output buffer(plaintext) 01284 * @retval HAL status 01285 */ 01286 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output) 01287 { 01288 uint32_t algo; 01289 HAL_StatusTypeDef status = HAL_OK; 01290 01291 if (hcryp->State == HAL_CRYP_STATE_READY) 01292 { 01293 /* Change state Busy */ 01294 hcryp->State = HAL_CRYP_STATE_BUSY; 01295 01296 /* Process locked */ 01297 __HAL_LOCK(hcryp); 01298 01299 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/ 01300 hcryp->CrypInCount = 0U; 01301 hcryp->CrypOutCount = 0U; 01302 hcryp->pCrypInBuffPtr = Input; 01303 hcryp->pCrypOutBuffPtr = Output; 01304 01305 /* Calculate Size parameter in Byte*/ 01306 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) 01307 { 01308 hcryp->Size = Size * 4U; 01309 } 01310 else 01311 { 01312 hcryp->Size = Size; 01313 } 01314 01315 /* Set decryption operating mode*/ 01316 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT); 01317 01318 /* algo get algorithm selected */ 01319 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE; 01320 01321 switch (algo) 01322 { 01323 case CRYP_DES_ECB: 01324 case CRYP_DES_CBC: 01325 case CRYP_TDES_ECB: 01326 case CRYP_TDES_CBC: 01327 01328 /*Set Key */ 01329 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey); 01330 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1); 01331 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01332 { 01333 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2); 01334 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3); 01335 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4); 01336 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5); 01337 } 01338 01339 /* Set the Initialization Vector*/ 01340 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01341 { 01342 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 01343 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 01344 } 01345 /* Flush FIFO */ 01346 HAL_CRYP_FIFO_FLUSH(hcryp); 01347 01348 /* Set the phase */ 01349 hcryp->Phase = CRYP_PHASE_PROCESS; 01350 01351 /* Enable interrupts */ 01352 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 01353 01354 /* Enable CRYP and start DES/TDES process*/ 01355 __HAL_CRYP_ENABLE(hcryp); 01356 01357 break; 01358 01359 case CRYP_AES_ECB: 01360 case CRYP_AES_CBC: 01361 case CRYP_AES_CTR: 01362 01363 /* AES decryption */ 01364 status = CRYP_AES_Decrypt_IT(hcryp); 01365 break; 01366 01367 case CRYP_AES_GCM: 01368 01369 /* AES GCM decryption */ 01370 status = CRYP_AESGCM_Process_IT(hcryp) ; 01371 break; 01372 01373 case CRYP_AES_CCM: 01374 01375 /* AES CCMdecryption */ 01376 status = CRYP_AESCCM_Process_IT(hcryp); 01377 break; 01378 01379 default: 01380 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; 01381 status = HAL_ERROR; 01382 break; 01383 } 01384 } 01385 else 01386 { 01387 /* Busy error code field */ 01388 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 01389 status = HAL_ERROR; 01390 } 01391 01392 /* Return function status */ 01393 return status; 01394 } 01395 01396 /** 01397 * @brief Encryption in DMA mode. 01398 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01399 * the configuration information for CRYP module 01400 * @param Input: Pointer to the input buffer (plaintext) 01401 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit 01402 * @param Output: Pointer to the output buffer(ciphertext) 01403 * @retval HAL status 01404 */ 01405 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output) 01406 { 01407 HAL_StatusTypeDef status = HAL_OK; 01408 uint32_t algo; 01409 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 01410 01411 if (hcryp->State == HAL_CRYP_STATE_READY) 01412 { 01413 /* Change state Busy */ 01414 hcryp->State = HAL_CRYP_STATE_BUSY; 01415 01416 /* Process locked */ 01417 __HAL_LOCK(hcryp); 01418 01419 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/ 01420 hcryp->CrypInCount = 0U; 01421 hcryp->CrypOutCount = 0U; 01422 hcryp->pCrypInBuffPtr = Input; 01423 hcryp->pCrypOutBuffPtr = Output; 01424 01425 /* Calculate Size parameter in Byte*/ 01426 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) 01427 { 01428 hcryp->Size = Size * 4U; 01429 } 01430 else 01431 { 01432 hcryp->Size = Size; 01433 } 01434 01435 /* Set encryption operating mode*/ 01436 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT); 01437 01438 /* algo get algorithm selected */ 01439 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE; 01440 01441 switch (algo) 01442 { 01443 case CRYP_DES_ECB: 01444 case CRYP_DES_CBC: 01445 case CRYP_TDES_ECB: 01446 case CRYP_TDES_CBC: 01447 01448 /*Set Key */ 01449 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey); 01450 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1); 01451 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01452 { 01453 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2); 01454 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3); 01455 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4); 01456 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5); 01457 } 01458 01459 /* Set the Initialization Vector*/ 01460 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01461 { 01462 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 01463 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 01464 } 01465 01466 /* Flush FIFO */ 01467 HAL_CRYP_FIFO_FLUSH(hcryp); 01468 01469 /* Set the phase */ 01470 hcryp->Phase = CRYP_PHASE_PROCESS; 01471 01472 /* Start DMA process transfer for DES/TDES */ 01473 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr)); 01474 01475 break; 01476 01477 case CRYP_AES_ECB: 01478 case CRYP_AES_CBC: 01479 case CRYP_AES_CTR: 01480 01481 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 01482 { 01483 if (hcryp->KeyIVConfig == 1U) 01484 { 01485 /* If the Key and IV configuration has to be done only once 01486 and if it has already been done, skip it */ 01487 DoKeyIVConfig = 0U; 01488 } 01489 else 01490 { 01491 /* If the Key and IV configuration has to be done only once 01492 and if it has not been done already, do it and set KeyIVConfig 01493 to keep track it won't have to be done again next time */ 01494 hcryp->KeyIVConfig = 1U; 01495 } 01496 } 01497 01498 if (DoKeyIVConfig == 1U) 01499 { 01500 /* Set the Key*/ 01501 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 01502 01503 /* Set the Initialization Vector*/ 01504 if (hcryp->Init.Algorithm != CRYP_AES_ECB) 01505 { 01506 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 01507 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U); 01508 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U); 01509 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U); 01510 } 01511 } /* if (DoKeyIVConfig == 1U) */ 01512 01513 /* Set the phase */ 01514 hcryp->Phase = CRYP_PHASE_PROCESS; 01515 01516 /* Start DMA process transfer for AES */ 01517 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr)); 01518 break; 01519 01520 case CRYP_AES_GCM: 01521 01522 /* AES GCM encryption */ 01523 status = CRYP_AESGCM_Process_DMA(hcryp) ; 01524 break; 01525 01526 case CRYP_AES_CCM: 01527 01528 /* AES CCM encryption */ 01529 status = CRYP_AESCCM_Process_DMA(hcryp); 01530 break; 01531 01532 default: 01533 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; 01534 status = HAL_ERROR; 01535 break; 01536 } 01537 } 01538 else 01539 { 01540 /* Busy error code field */ 01541 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 01542 status = HAL_ERROR; 01543 } 01544 01545 /* Return function status */ 01546 return status; 01547 } 01548 01549 /** 01550 * @brief Decryption in DMA mode. 01551 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01552 * the configuration information for CRYP module 01553 * @param Input: Pointer to the input buffer (ciphertext ) 01554 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit 01555 * @param Output: Pointer to the output buffer(plaintext) 01556 * @retval HAL status 01557 */ 01558 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output) 01559 { 01560 uint32_t algo; 01561 HAL_StatusTypeDef status = HAL_OK; 01562 01563 if (hcryp->State == HAL_CRYP_STATE_READY) 01564 { 01565 /* Change state Busy */ 01566 hcryp->State = HAL_CRYP_STATE_BUSY; 01567 01568 /* Process locked */ 01569 __HAL_LOCK(hcryp); 01570 01571 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/ 01572 hcryp->CrypInCount = 0U; 01573 hcryp->CrypOutCount = 0U; 01574 hcryp->pCrypInBuffPtr = Input; 01575 hcryp->pCrypOutBuffPtr = Output; 01576 01577 /* Calculate Size parameter in Byte*/ 01578 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) 01579 { 01580 hcryp->Size = Size * 4U; 01581 } 01582 else 01583 { 01584 hcryp->Size = Size; 01585 } 01586 01587 /* Set decryption operating mode*/ 01588 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT); 01589 01590 /* algo get algorithm selected */ 01591 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE; 01592 01593 switch (algo) 01594 { 01595 case CRYP_DES_ECB: 01596 case CRYP_DES_CBC: 01597 case CRYP_TDES_ECB: 01598 case CRYP_TDES_CBC: 01599 01600 /*Set Key */ 01601 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey); 01602 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1); 01603 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01604 { 01605 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2); 01606 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3); 01607 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4); 01608 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5); 01609 } 01610 01611 /* Set the Initialization Vector*/ 01612 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01613 { 01614 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 01615 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 01616 } 01617 01618 /* Flush FIFO */ 01619 HAL_CRYP_FIFO_FLUSH(hcryp); 01620 01621 /* Set the phase */ 01622 hcryp->Phase = CRYP_PHASE_PROCESS; 01623 01624 /* Start DMA process transfer for DES/TDES */ 01625 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr)); 01626 break; 01627 01628 case CRYP_AES_ECB: 01629 case CRYP_AES_CBC: 01630 case CRYP_AES_CTR: 01631 01632 /* AES decryption */ 01633 status = CRYP_AES_Decrypt_DMA(hcryp); 01634 break; 01635 01636 case CRYP_AES_GCM: 01637 01638 /* AES GCM decryption */ 01639 status = CRYP_AESGCM_Process_DMA(hcryp) ; 01640 01641 break; 01642 01643 case CRYP_AES_CCM: 01644 01645 /* AES CCM decryption */ 01646 status = CRYP_AESCCM_Process_DMA(hcryp); 01647 break; 01648 01649 default: 01650 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; 01651 status = HAL_ERROR; 01652 break; 01653 } 01654 } 01655 else 01656 { 01657 /* Busy error code field */ 01658 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 01659 status = HAL_ERROR; 01660 } 01661 01662 /* Return function status */ 01663 return status; 01664 } 01665 01666 /** 01667 * @} 01668 */ 01669 01670 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management 01671 * @brief CRYP IRQ handler. 01672 * 01673 @verbatim 01674 ============================================================================== 01675 ##### CRYP IRQ handler management ##### 01676 ============================================================================== 01677 [..] This section provides CRYP IRQ handler and callback functions. 01678 (+) HAL_CRYP_IRQHandler CRYP interrupt request 01679 (+) HAL_CRYP_InCpltCallback input data transfer complete callback 01680 (+) HAL_CRYP_OutCpltCallback output data transfer complete callback 01681 (+) HAL_CRYP_ErrorCallback CRYP error callback 01682 (+) HAL_CRYP_GetState return the CRYP state 01683 (+) HAL_CRYP_GetError return the CRYP error code 01684 @endverbatim 01685 * @{ 01686 */ 01687 01688 /** 01689 * @brief This function handles cryptographic interrupt request. 01690 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01691 * the configuration information for CRYP module 01692 * @retval None 01693 */ 01694 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp) 01695 { 01696 uint32_t itstatus = hcryp->Instance->MISR; 01697 01698 if ((itstatus & (CRYP_IT_INI | CRYP_IT_OUTI)) != 0U) 01699 { 01700 if ((hcryp->Init.Algorithm == CRYP_DES_ECB) || (hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC)) 01701 { 01702 CRYP_TDES_IT(hcryp); /* DES or TDES*/ 01703 } 01704 else if ((hcryp->Init.Algorithm == CRYP_AES_ECB) || (hcryp->Init.Algorithm == CRYP_AES_CBC) || (hcryp->Init.Algorithm == CRYP_AES_CTR)) 01705 { 01706 CRYP_AES_IT(hcryp); /*AES*/ 01707 } 01708 01709 else if ((hcryp->Init.Algorithm == CRYP_AES_GCM) || (hcryp->Init.Algorithm == CRYP_CR_ALGOMODE_AES_CCM)) 01710 { 01711 /* if header phase */ 01712 if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER) 01713 { 01714 CRYP_GCMCCM_SetHeaderPhase_IT(hcryp); 01715 } 01716 else /* if payload phase */ 01717 { 01718 CRYP_GCMCCM_SetPayloadPhase_IT(hcryp); 01719 } 01720 } 01721 else 01722 { 01723 /* Nothing to do */ 01724 } 01725 } 01726 } 01727 01728 /** 01729 * @brief Return the CRYP error code. 01730 * @param hcryp : pointer to a CRYP_HandleTypeDef structure that contains 01731 * the configuration information for the CRYP IP 01732 * @retval CRYP error code 01733 */ 01734 uint32_t HAL_CRYP_GetError(CRYP_HandleTypeDef *hcryp) 01735 { 01736 return hcryp->ErrorCode; 01737 } 01738 01739 /** 01740 * @brief Returns the CRYP state. 01741 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01742 * the configuration information for CRYP module. 01743 * @retval HAL state 01744 */ 01745 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp) 01746 { 01747 return hcryp->State; 01748 } 01749 01750 /** 01751 * @brief Input FIFO transfer completed callback. 01752 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01753 * the configuration information for CRYP module. 01754 * @retval None 01755 */ 01756 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp) 01757 { 01758 /* Prevent unused argument(s) compilation warning */ 01759 UNUSED(hcryp); 01760 01761 /* NOTE : This function Should not be modified, when the callback is needed, 01762 the HAL_CRYP_InCpltCallback could be implemented in the user file 01763 */ 01764 } 01765 01766 /** 01767 * @brief Output FIFO transfer completed callback. 01768 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01769 * the configuration information for CRYP module. 01770 * @retval None 01771 */ 01772 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp) 01773 { 01774 /* Prevent unused argument(s) compilation warning */ 01775 UNUSED(hcryp); 01776 01777 /* NOTE : This function Should not be modified, when the callback is needed, 01778 the HAL_CRYP_OutCpltCallback could be implemented in the user file 01779 */ 01780 } 01781 01782 /** 01783 * @brief CRYP error callback. 01784 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01785 * the configuration information for CRYP module. 01786 * @retval None 01787 */ 01788 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp) 01789 { 01790 /* Prevent unused argument(s) compilation warning */ 01791 UNUSED(hcryp); 01792 01793 /* NOTE : This function Should not be modified, when the callback is needed, 01794 the HAL_CRYP_ErrorCallback could be implemented in the user file 01795 */ 01796 } 01797 /** 01798 * @} 01799 */ 01800 01801 /* Private functions ---------------------------------------------------------*/ 01802 /** @addtogroup CRYP_Private_Functions 01803 * @{ 01804 */ 01805 01806 /** 01807 * @brief Encryption in ECB/CBC Algorithm with DES/TDES standard. 01808 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01809 * the configuration information for CRYP module 01810 * @param Timeout: Timeout value 01811 * @retval HAL status 01812 */ 01813 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 01814 { 01815 01816 uint32_t temp; /* Temporary CrypOutBuff */ 01817 uint16_t incount; /* Temporary CrypInCount Value */ 01818 uint16_t outcount; /* Temporary CrypOutCount Value */ 01819 01820 /* Enable CRYP */ 01821 __HAL_CRYP_ENABLE(hcryp); 01822 /*Temporary CrypOutCount Value*/ 01823 outcount = hcryp->CrypOutCount; 01824 01825 /*Start processing*/ 01826 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U))) 01827 { 01828 /* Temporary CrypInCount Value */ 01829 incount = hcryp->CrypInCount; 01830 /* Write plain data and get cipher data */ 01831 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U))) 01832 { 01833 /* Write the input block in the IN FIFO */ 01834 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 01835 hcryp->CrypInCount++; 01836 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 01837 hcryp->CrypInCount++; 01838 } 01839 01840 /* Wait for OFNE flag to be raised */ 01841 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK) 01842 { 01843 /* Disable the CRYP peripheral clock */ 01844 __HAL_CRYP_DISABLE(hcryp); 01845 01846 /* Change state & errorCode*/ 01847 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 01848 hcryp->State = HAL_CRYP_STATE_READY; 01849 01850 /* Process unlocked */ 01851 __HAL_UNLOCK(hcryp); 01852 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 01853 /*Call registered error callback*/ 01854 hcryp->ErrorCallback(hcryp); 01855 #else 01856 /*Call legacy weak error callback*/ 01857 HAL_CRYP_ErrorCallback(hcryp); 01858 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 01859 } 01860 01861 /*Temporary CrypOutCount Value*/ 01862 outcount = hcryp->CrypOutCount; 01863 01864 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U))) 01865 { 01866 /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer */ 01867 temp = hcryp->Instance->DOUT; 01868 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp; 01869 hcryp->CrypOutCount++; 01870 temp = hcryp->Instance->DOUT; 01871 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp; 01872 hcryp->CrypOutCount++; 01873 } 01874 /*Temporary CrypOutCount Value*/ 01875 outcount = hcryp->CrypOutCount; 01876 } 01877 /* Disable CRYP */ 01878 __HAL_CRYP_DISABLE(hcryp); 01879 /* Change the CRYP state */ 01880 hcryp->State = HAL_CRYP_STATE_READY; 01881 01882 /* Return function status */ 01883 return HAL_OK; 01884 } 01885 01886 /** 01887 * @brief CRYP block input/output data handling under interruption with DES/TDES standard. 01888 * @note The function is called under interruption only, once 01889 * interruptions have been enabled by CRYP_Decrypt_IT() and CRYP_Encrypt_IT(). 01890 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 01891 * the configuration information for CRYP module. 01892 * @retval HAL status 01893 */ 01894 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp) 01895 { 01896 uint32_t temp; /* Temporary CrypOutBuff */ 01897 01898 if (hcryp->State == HAL_CRYP_STATE_BUSY) 01899 { 01900 if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI) != 0x0U) 01901 { 01902 if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_INRIS) != 0x0U) 01903 { 01904 /* Write input block in the IN FIFO */ 01905 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 01906 hcryp->CrypInCount++; 01907 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 01908 hcryp->CrypInCount++; 01909 01910 if (hcryp->CrypInCount == (hcryp->Size / 4U)) 01911 { 01912 /* Disable interruption */ 01913 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); 01914 01915 /* Call the input data transfer complete callback */ 01916 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 01917 /*Call registered Input complete callback*/ 01918 hcryp->InCpltCallback(hcryp); 01919 #else 01920 /*Call legacy weak Input complete callback*/ 01921 HAL_CRYP_InCpltCallback(hcryp); 01922 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 01923 } 01924 } 01925 } 01926 01927 if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI) != 0x0U) 01928 { 01929 if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_OUTRIS) != 0x0U) 01930 { 01931 /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer */ 01932 temp = hcryp->Instance->DOUT; 01933 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp; 01934 hcryp->CrypOutCount++; 01935 temp = hcryp->Instance->DOUT; 01936 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp; 01937 hcryp->CrypOutCount++; 01938 if (hcryp->CrypOutCount == (hcryp->Size / 4U)) 01939 { 01940 /* Disable interruption */ 01941 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); 01942 01943 /* Disable CRYP */ 01944 __HAL_CRYP_DISABLE(hcryp); 01945 01946 /* Process unlocked */ 01947 __HAL_UNLOCK(hcryp); 01948 01949 /* Change the CRYP state */ 01950 hcryp->State = HAL_CRYP_STATE_READY; 01951 01952 /* Call output transfer complete callback */ 01953 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 01954 /*Call registered Output complete callback*/ 01955 hcryp->OutCpltCallback(hcryp); 01956 #else 01957 /*Call legacy weak Output complete callback*/ 01958 HAL_CRYP_OutCpltCallback(hcryp); 01959 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 01960 01961 } 01962 } 01963 } 01964 } 01965 else 01966 { 01967 /* Process unlocked */ 01968 __HAL_UNLOCK(hcryp); 01969 /* Busy error code field */ 01970 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 01971 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 01972 /*Call registered error callback*/ 01973 hcryp->ErrorCallback(hcryp); 01974 #else 01975 /*Call legacy weak error callback*/ 01976 HAL_CRYP_ErrorCallback(hcryp); 01977 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 01978 } 01979 } 01980 01981 /** 01982 * @brief Encryption in ECB/CBC & CTR Algorithm with AES Standard 01983 * @param hcryp: pointer to a CRYP_HandleTypeDef structure 01984 * @param Timeout: specify Timeout value 01985 * @retval HAL status 01986 */ 01987 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 01988 { 01989 uint16_t outcount; /* Temporary CrypOutCount Value */ 01990 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 01991 01992 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 01993 { 01994 if (hcryp->KeyIVConfig == 1U) 01995 { 01996 /* If the Key and IV configuration has to be done only once 01997 and if it has already been done, skip it */ 01998 DoKeyIVConfig = 0U; 01999 } 02000 else 02001 { 02002 /* If the Key and IV configuration has to be done only once 02003 and if it has not been done already, do it and set KeyIVConfig 02004 to keep track it won't have to be done again next time */ 02005 hcryp->KeyIVConfig = 1U; 02006 } 02007 } 02008 02009 if (DoKeyIVConfig == 1U) 02010 { 02011 /* Set the Key*/ 02012 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 02013 02014 if (hcryp->Init.Algorithm != CRYP_AES_ECB) 02015 { 02016 /* Set the Initialization Vector*/ 02017 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 02018 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U); 02019 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U); 02020 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U); 02021 } 02022 } /* if (DoKeyIVConfig == 1U) */ 02023 02024 /* Set the phase */ 02025 hcryp->Phase = CRYP_PHASE_PROCESS; 02026 02027 /* Enable CRYP */ 02028 __HAL_CRYP_ENABLE(hcryp); 02029 /*Temporary CrypOutCount Value*/ 02030 outcount = hcryp->CrypOutCount; 02031 02032 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U))) 02033 { 02034 /* Write plain Ddta and get cipher data */ 02035 CRYP_AES_ProcessData(hcryp, Timeout); 02036 /*Temporary CrypOutCount Value*/ 02037 outcount = hcryp->CrypOutCount; 02038 } 02039 02040 /* Disable CRYP */ 02041 __HAL_CRYP_DISABLE(hcryp); 02042 02043 /* Change the CRYP state */ 02044 hcryp->State = HAL_CRYP_STATE_READY; 02045 02046 /* Return function status */ 02047 return HAL_OK; 02048 } 02049 02050 /** 02051 * @brief Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode 02052 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 02053 * the configuration information for CRYP module 02054 * @retval HAL status 02055 */ 02056 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp) 02057 { 02058 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 02059 02060 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 02061 { 02062 if (hcryp->KeyIVConfig == 1U) 02063 { 02064 /* If the Key and IV configuration has to be done only once 02065 and if it has already been done, skip it */ 02066 DoKeyIVConfig = 0U; 02067 } 02068 else 02069 { 02070 /* If the Key and IV configuration has to be done only once 02071 and if it has not been done already, do it and set KeyIVConfig 02072 to keep track it won't have to be done again next time */ 02073 hcryp->KeyIVConfig = 1U; 02074 } 02075 } 02076 02077 if (DoKeyIVConfig == 1U) 02078 { 02079 /* Set the Key*/ 02080 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 02081 02082 if (hcryp->Init.Algorithm != CRYP_AES_ECB) 02083 { 02084 /* Set the Initialization Vector*/ 02085 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 02086 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U); 02087 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U); 02088 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U); 02089 } 02090 } /* if (DoKeyIVConfig == 1U) */ 02091 02092 /* Set the phase */ 02093 hcryp->Phase = CRYP_PHASE_PROCESS; 02094 02095 if (hcryp->Size != 0U) 02096 { 02097 /* Enable interrupts */ 02098 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 02099 02100 /* Enable CRYP */ 02101 __HAL_CRYP_ENABLE(hcryp); 02102 } 02103 else 02104 { 02105 /* Change the CRYP state */ 02106 hcryp->State = HAL_CRYP_STATE_READY; 02107 02108 /* Process unlocked */ 02109 __HAL_UNLOCK(hcryp); 02110 } 02111 02112 /* Return function status */ 02113 return HAL_OK; 02114 } 02115 02116 /** 02117 * @brief Decryption in ECB/CBC & CTR mode with AES Standard 02118 * @param hcryp: pointer to a CRYP_HandleTypeDef structure 02119 * @param Timeout: Specify Timeout value 02120 * @retval HAL status 02121 */ 02122 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 02123 { 02124 uint16_t outcount; /* Temporary CrypOutCount Value */ 02125 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 02126 02127 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 02128 { 02129 if (hcryp->KeyIVConfig == 1U) 02130 { 02131 /* If the Key and IV configuration has to be done only once 02132 and if it has already been done, skip it */ 02133 DoKeyIVConfig = 0U; 02134 } 02135 else 02136 { 02137 /* If the Key and IV configuration has to be done only once 02138 and if it has not been done already, do it and set KeyIVConfig 02139 to keep track it won't have to be done again next time */ 02140 hcryp->KeyIVConfig = 1U; 02141 } 02142 } 02143 02144 if (DoKeyIVConfig == 1U) 02145 { 02146 /* Key preparation for ECB/CBC */ 02147 if (hcryp->Init.Algorithm != CRYP_AES_CTR) /*ECB or CBC*/ 02148 { 02149 /* change ALGOMODE to key preparation for decryption*/ 02150 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY); 02151 02152 /* Set the Key*/ 02153 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 02154 02155 /* Enable CRYP */ 02156 __HAL_CRYP_ENABLE(hcryp); 02157 02158 /* Wait for BUSY flag to be raised */ 02159 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK) 02160 { 02161 /* Disable the CRYP peripheral clock */ 02162 __HAL_CRYP_DISABLE(hcryp); 02163 02164 /* Change state */ 02165 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 02166 hcryp->State = HAL_CRYP_STATE_READY; 02167 02168 /* Process unlocked */ 02169 __HAL_UNLOCK(hcryp); 02170 return HAL_ERROR; 02171 } 02172 /* Turn back to ALGOMODE of the configuration */ 02173 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm); 02174 } 02175 else /*Algorithm CTR */ 02176 { 02177 /* Set the Key*/ 02178 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 02179 } 02180 02181 /* Set IV */ 02182 if (hcryp->Init.Algorithm != CRYP_AES_ECB) 02183 { 02184 /* Set the Initialization Vector*/ 02185 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 02186 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 02187 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2); 02188 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3); 02189 } 02190 } /* if (DoKeyIVConfig == 1U) */ 02191 02192 /* Set the phase */ 02193 hcryp->Phase = CRYP_PHASE_PROCESS; 02194 02195 /* Enable CRYP */ 02196 __HAL_CRYP_ENABLE(hcryp); 02197 02198 /*Temporary CrypOutCount Value*/ 02199 outcount = hcryp->CrypOutCount; 02200 02201 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U))) 02202 { 02203 /* Write plain data and get cipher data */ 02204 CRYP_AES_ProcessData(hcryp, Timeout); 02205 /*Temporary CrypOutCount Value*/ 02206 outcount = hcryp->CrypOutCount; 02207 } 02208 02209 /* Disable CRYP */ 02210 __HAL_CRYP_DISABLE(hcryp); 02211 02212 /* Change the CRYP state */ 02213 hcryp->State = HAL_CRYP_STATE_READY; 02214 02215 /* Return function status */ 02216 return HAL_OK; 02217 } 02218 /** 02219 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode 02220 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 02221 * the configuration information for CRYP module 02222 * @retval HAL status 02223 */ 02224 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp) 02225 { 02226 __IO uint32_t count = 0U; 02227 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 02228 02229 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 02230 { 02231 if (hcryp->KeyIVConfig == 1U) 02232 { 02233 /* If the Key and IV configuration has to be done only once 02234 and if it has already been done, skip it */ 02235 DoKeyIVConfig = 0U; 02236 } 02237 else 02238 { 02239 /* If the Key and IV configuration has to be done only once 02240 and if it has not been done already, do it and set KeyIVConfig 02241 to keep track it won't have to be done again next time */ 02242 hcryp->KeyIVConfig = 1U; 02243 } 02244 } 02245 02246 if (DoKeyIVConfig == 1U) 02247 { 02248 /* Key preparation for ECB/CBC */ 02249 if (hcryp->Init.Algorithm != CRYP_AES_CTR) 02250 { 02251 /* change ALGOMODE to key preparation for decryption*/ 02252 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY); 02253 02254 /* Set the Key*/ 02255 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 02256 02257 /* Enable CRYP */ 02258 __HAL_CRYP_ENABLE(hcryp); 02259 02260 /* Wait for BUSY flag to be raised */ 02261 count = CRYP_TIMEOUT_KEYPREPARATION; 02262 do 02263 { 02264 count-- ; 02265 if (count == 0U) 02266 { 02267 /* Change state */ 02268 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 02269 hcryp->State = HAL_CRYP_STATE_READY; 02270 02271 /* Process unlocked */ 02272 __HAL_UNLOCK(hcryp); 02273 return HAL_ERROR; 02274 } 02275 } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)); 02276 02277 /* Turn back to ALGOMODE of the configuration */ 02278 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm); 02279 } 02280 else /*Algorithm CTR */ 02281 { 02282 /* Set the Key*/ 02283 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 02284 } 02285 02286 /* Set IV */ 02287 if (hcryp->Init.Algorithm != CRYP_AES_ECB) 02288 { 02289 /* Set the Initialization Vector*/ 02290 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 02291 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 02292 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2); 02293 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3); 02294 } 02295 } /* if (DoKeyIVConfig == 1U) */ 02296 02297 /* Set the phase */ 02298 hcryp->Phase = CRYP_PHASE_PROCESS; 02299 if (hcryp->Size != 0U) 02300 { 02301 /* Enable interrupts */ 02302 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 02303 02304 /* Enable CRYP */ 02305 __HAL_CRYP_ENABLE(hcryp); 02306 } 02307 else 02308 { 02309 /* Process locked */ 02310 __HAL_UNLOCK(hcryp); 02311 02312 /* Change the CRYP state */ 02313 hcryp->State = HAL_CRYP_STATE_READY; 02314 } 02315 /* Return function status */ 02316 return HAL_OK; 02317 } 02318 /** 02319 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode 02320 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 02321 * the configuration information for CRYP module 02322 * @retval HAL status 02323 */ 02324 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp) 02325 { 02326 __IO uint32_t count = 0U; 02327 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 02328 02329 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 02330 { 02331 if (hcryp->KeyIVConfig == 1U) 02332 { 02333 /* If the Key and IV configuration has to be done only once 02334 and if it has already been done, skip it */ 02335 DoKeyIVConfig = 0U; 02336 } 02337 else 02338 { 02339 /* If the Key and IV configuration has to be done only once 02340 and if it has not been done already, do it and set KeyIVConfig 02341 to keep track it won't have to be done again next time */ 02342 hcryp->KeyIVConfig = 1U; 02343 } 02344 } 02345 02346 if (DoKeyIVConfig == 1U) 02347 { 02348 /* Key preparation for ECB/CBC */ 02349 if (hcryp->Init.Algorithm != CRYP_AES_CTR) 02350 { 02351 /* change ALGOMODE to key preparation for decryption*/ 02352 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY); 02353 02354 /* Set the Key*/ 02355 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 02356 02357 /* Enable CRYP */ 02358 __HAL_CRYP_ENABLE(hcryp); 02359 02360 /* Wait for BUSY flag to be raised */ 02361 count = CRYP_TIMEOUT_KEYPREPARATION; 02362 do 02363 { 02364 count-- ; 02365 if (count == 0U) 02366 { 02367 /* Disable the CRYP peripheral clock */ 02368 __HAL_CRYP_DISABLE(hcryp); 02369 02370 /* Change state */ 02371 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 02372 hcryp->State = HAL_CRYP_STATE_READY; 02373 02374 /* Process unlocked */ 02375 __HAL_UNLOCK(hcryp); 02376 return HAL_ERROR; 02377 } 02378 } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)); 02379 02380 /* Turn back to ALGOMODE of the configuration */ 02381 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm); 02382 } 02383 else /*Algorithm CTR */ 02384 { 02385 /* Set the Key*/ 02386 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 02387 } 02388 02389 if (hcryp->Init.Algorithm != CRYP_AES_ECB) 02390 { 02391 /* Set the Initialization Vector*/ 02392 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 02393 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 02394 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2); 02395 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3); 02396 } 02397 } /* if (DoKeyIVConfig == 1U) */ 02398 02399 /* Set the phase */ 02400 hcryp->Phase = CRYP_PHASE_PROCESS; 02401 02402 if (hcryp->Size != 0U) 02403 { 02404 /* Set the input and output addresses and start DMA transfer */ 02405 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr)); 02406 } 02407 else 02408 { 02409 /* Process unlocked */ 02410 __HAL_UNLOCK(hcryp); 02411 02412 /* Change the CRYP state */ 02413 hcryp->State = HAL_CRYP_STATE_READY; 02414 } 02415 02416 /* Return function status */ 02417 return HAL_OK; 02418 } 02419 02420 02421 /** 02422 * @brief DMA CRYP input data process complete callback. 02423 * @param hdma: DMA handle 02424 * @retval None 02425 */ 02426 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma) 02427 { 02428 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02429 02430 /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit 02431 in the DMACR register */ 02432 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN); 02433 02434 /* Call input data transfer complete callback */ 02435 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02436 /*Call registered Input complete callback*/ 02437 hcryp->InCpltCallback(hcryp); 02438 #else 02439 /*Call legacy weak Input complete callback*/ 02440 HAL_CRYP_InCpltCallback(hcryp); 02441 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02442 } 02443 02444 /** 02445 * @brief DMA CRYP output data process complete callback. 02446 * @param hdma: DMA handle 02447 * @retval None 02448 */ 02449 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma) 02450 { 02451 uint32_t count; 02452 uint32_t npblb; 02453 uint32_t lastwordsize; 02454 uint32_t temp; /* Temporary CrypOutBuff */ 02455 uint32_t temp_cr_algodir; 02456 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02457 02458 02459 /* Disable the DMA transfer for output FIFO */ 02460 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN); 02461 02462 /* Last block transfer in case of GCM or CCM with Size not %16*/ 02463 if (((hcryp->Size) % 16U) != 0U) 02464 { 02465 /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA */ 02466 hcryp->CrypInCount = (hcryp->Size / 16U) * 4U ; 02467 hcryp->CrypOutCount = hcryp->CrypInCount; 02468 02469 /* Compute the number of padding bytes in last block of payload */ 02470 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size); 02471 02472 #if !defined (CRYP_VER_2_2) 02473 if (hcryp->Version >= REV_ID_B) 02474 #endif /*End of not defined CRYP_VER_2_2*/ 02475 { 02476 /* Case of AES GCM payload encryption or AES CCM payload decryption to get right tag */ 02477 temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR; 02478 if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) || 02479 ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM))) 02480 { 02481 /* Disable the CRYP */ 02482 __HAL_CRYP_DISABLE(hcryp); 02483 02484 /* Specify the number of non-valid bytes using NPBLB register*/ 02485 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20); 02486 02487 /* Enable CRYP to start the final phase */ 02488 __HAL_CRYP_ENABLE(hcryp); 02489 } 02490 } 02491 02492 /* Number of valid words (lastwordsize) in last block */ 02493 if ((npblb % 4U) == 0U) 02494 { 02495 lastwordsize = (16U - npblb) / 4U; 02496 } 02497 else 02498 { 02499 lastwordsize = ((16U - npblb) / 4U) + 1U; 02500 } 02501 /* Write the last input block in the IN FIFO */ 02502 for (count = 0U; count < lastwordsize; count ++) 02503 { 02504 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 02505 hcryp->CrypInCount++; 02506 } 02507 /* Pad the data with zeros to have a complete block */ 02508 while (count < 4U) 02509 { 02510 hcryp->Instance->DIN = 0U; 02511 count++; 02512 } 02513 /* Wait for OFNE flag to be raised */ 02514 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE; 02515 do 02516 { 02517 count-- ; 02518 if (count == 0U) 02519 { 02520 /* Disable the CRYP peripheral clock */ 02521 __HAL_CRYP_DISABLE(hcryp); 02522 02523 /* Change state */ 02524 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 02525 hcryp->State = HAL_CRYP_STATE_READY; 02526 02527 /* Process unlocked */ 02528 __HAL_UNLOCK(hcryp); 02529 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02530 /*Call registered error callback*/ 02531 hcryp->ErrorCallback(hcryp); 02532 #else 02533 /*Call legacy weak error callback*/ 02534 HAL_CRYP_ErrorCallback(hcryp); 02535 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02536 } 02537 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)); 02538 02539 /*Read the output block from the output FIFO */ 02540 for (count = 0U; count < 4U; count++) 02541 { 02542 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */ 02543 temp = hcryp->Instance->DOUT; 02544 02545 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp; 02546 hcryp->CrypOutCount++; 02547 } 02548 } /*End of last block transfer in case of GCM or CCM */ 02549 02550 if ((hcryp->Init.Algorithm & CRYP_AES_GCM) != CRYP_AES_GCM) 02551 { 02552 /* Disable CRYP (not allowed in GCM)*/ 02553 __HAL_CRYP_DISABLE(hcryp); 02554 } 02555 02556 /* Change the CRYP state to ready */ 02557 hcryp->State = HAL_CRYP_STATE_READY; 02558 02559 /* Process unlocked */ 02560 __HAL_UNLOCK(hcryp); 02561 02562 /* Call output data transfer complete callback */ 02563 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02564 /*Call registered Output complete callback*/ 02565 hcryp->OutCpltCallback(hcryp); 02566 #else 02567 /*Call legacy weak Output complete callback*/ 02568 HAL_CRYP_OutCpltCallback(hcryp); 02569 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02570 } 02571 02572 /** 02573 * @brief DMA CRYP communication error callback. 02574 * @param hdma: DMA handle 02575 * @retval None 02576 */ 02577 static void CRYP_DMAError(DMA_HandleTypeDef *hdma) 02578 { 02579 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02580 02581 /* Change the CRYP peripheral state */ 02582 hcryp->State = HAL_CRYP_STATE_READY; 02583 02584 /* DMA error code field */ 02585 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA; 02586 02587 /* Call error callback */ 02588 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02589 /*Call registered error callback*/ 02590 hcryp->ErrorCallback(hcryp); 02591 #else 02592 /*Call legacy weak error callback*/ 02593 HAL_CRYP_ErrorCallback(hcryp); 02594 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02595 } 02596 02597 /** 02598 * @brief Set the DMA configuration and start the DMA transfer 02599 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 02600 * the configuration information for CRYP module 02601 * @param inputaddr: address of the input buffer 02602 * @param Size: size of the input buffer, must be a multiple of 16. 02603 * @param outputaddr: address of the output buffer 02604 * @retval None 02605 */ 02606 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr) 02607 { 02608 /* Set the CRYP DMA transfer complete callback */ 02609 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt; 02610 02611 /* Set the DMA input error callback */ 02612 hcryp->hdmain->XferErrorCallback = CRYP_DMAError; 02613 02614 /* Set the CRYP DMA transfer complete callback */ 02615 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt; 02616 02617 /* Set the DMA output error callback */ 02618 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError; 02619 02620 /* Enable CRYP */ 02621 __HAL_CRYP_ENABLE(hcryp); 02622 02623 /* Enable the input DMA Stream */ 02624 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DIN, Size) != HAL_OK) 02625 { 02626 /* DMA error code field */ 02627 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA; 02628 02629 /* Call error callback */ 02630 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02631 /*Call registered error callback*/ 02632 hcryp->ErrorCallback(hcryp); 02633 #else 02634 /*Call legacy weak error callback*/ 02635 HAL_CRYP_ErrorCallback(hcryp); 02636 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02637 } 02638 02639 /* Enable the output DMA Stream */ 02640 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size) != HAL_OK) 02641 { 02642 /* DMA error code field */ 02643 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA; 02644 02645 /* Call error callback */ 02646 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02647 /*Call registered error callback*/ 02648 hcryp->ErrorCallback(hcryp); 02649 #else 02650 /*Call legacy weak error callback*/ 02651 HAL_CRYP_ErrorCallback(hcryp); 02652 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02653 } 02654 /* Enable In/Out DMA request */ 02655 hcryp->Instance->DMACR = CRYP_DMACR_DOEN | CRYP_DMACR_DIEN; 02656 } 02657 02658 /** 02659 * @brief Process Data: Write Input data in polling mode and used in AES functions. 02660 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 02661 * the configuration information for CRYP module 02662 * @param Timeout: Specify Timeout value 02663 * @retval None 02664 */ 02665 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 02666 { 02667 02668 uint32_t temp[4]; /* Temporary CrypOutBuff */ 02669 uint16_t incount; /* Temporary CrypInCount Value */ 02670 uint16_t outcount; /* Temporary CrypOutCount Value */ 02671 uint32_t i; 02672 02673 /*Temporary CrypOutCount Value*/ 02674 incount = hcryp->CrypInCount; 02675 02676 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < ((hcryp->Size) / 4U))) 02677 { 02678 /* Write the input block in the IN FIFO */ 02679 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 02680 hcryp->CrypInCount++; 02681 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 02682 hcryp->CrypInCount++; 02683 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 02684 hcryp->CrypInCount++; 02685 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 02686 hcryp->CrypInCount++; 02687 } 02688 02689 /* Wait for OFNE flag to be raised */ 02690 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK) 02691 { 02692 /* Disable the CRYP peripheral clock */ 02693 __HAL_CRYP_DISABLE(hcryp); 02694 02695 /* Change state & error code*/ 02696 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 02697 hcryp->State = HAL_CRYP_STATE_READY; 02698 02699 /* Process unlocked */ 02700 __HAL_UNLOCK(hcryp); 02701 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02702 /*Call registered error callback*/ 02703 hcryp->ErrorCallback(hcryp); 02704 #else 02705 /*Call legacy weak error callback*/ 02706 HAL_CRYP_ErrorCallback(hcryp); 02707 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02708 } 02709 /*Temporary CrypOutCount Value*/ 02710 outcount = hcryp->CrypOutCount; 02711 02712 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < ((hcryp->Size) / 4U))) 02713 { 02714 /* Read the output block from the Output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */ 02715 for (i = 0U; i < 4U; i++) 02716 { 02717 temp[i] = hcryp->Instance->DOUT; 02718 } 02719 i = 0U; 02720 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U)) 02721 { 02722 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i]; 02723 hcryp->CrypOutCount++; 02724 i++; 02725 } 02726 } 02727 } 02728 02729 /** 02730 * @brief Handle CRYP block input/output data handling under interruption. 02731 * @note The function is called under interruption only, once 02732 * interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT. 02733 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 02734 * the configuration information for CRYP module. 02735 * @retval HAL status 02736 */ 02737 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp) 02738 { 02739 uint32_t temp[4]; /* Temporary CrypOutBuff */ 02740 uint16_t incount; /* Temporary CrypInCount Value */ 02741 uint16_t outcount; /* Temporary CrypOutCount Value */ 02742 uint32_t i; 02743 02744 if (hcryp->State == HAL_CRYP_STATE_BUSY) 02745 { 02746 /*Temporary CrypOutCount Value*/ 02747 incount = hcryp->CrypInCount; 02748 02749 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U))) 02750 { 02751 /* Write the input block in the IN FIFO */ 02752 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 02753 hcryp->CrypInCount++; 02754 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 02755 hcryp->CrypInCount++; 02756 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 02757 hcryp->CrypInCount++; 02758 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 02759 hcryp->CrypInCount++; 02760 if (hcryp->CrypInCount == (hcryp->Size / 4U)) 02761 { 02762 /* Disable interrupts */ 02763 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); 02764 02765 /* Call the input data transfer complete callback */ 02766 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02767 /*Call registered Input complete callback*/ 02768 hcryp->InCpltCallback(hcryp); 02769 #else 02770 /*Call legacy weak Input complete callback*/ 02771 HAL_CRYP_InCpltCallback(hcryp); 02772 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02773 } 02774 } 02775 02776 /*Temporary CrypOutCount Value*/ 02777 outcount = hcryp->CrypOutCount; 02778 02779 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U))) 02780 { 02781 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */ 02782 for (i = 0U; i < 4U; i++) 02783 { 02784 temp[i] = hcryp->Instance->DOUT; 02785 } 02786 i = 0U; 02787 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U)) 02788 { 02789 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i]; 02790 hcryp->CrypOutCount++; 02791 i++; 02792 } 02793 if (hcryp->CrypOutCount == (hcryp->Size / 4U)) 02794 { 02795 /* Disable interrupts */ 02796 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); 02797 02798 /* Change the CRYP state */ 02799 hcryp->State = HAL_CRYP_STATE_READY; 02800 02801 /* Disable CRYP */ 02802 __HAL_CRYP_DISABLE(hcryp); 02803 02804 /* Process unlocked */ 02805 __HAL_UNLOCK(hcryp); 02806 02807 /* Call output transfer complete callback */ 02808 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02809 /*Call registered Output complete callback*/ 02810 hcryp->OutCpltCallback(hcryp); 02811 #else 02812 /*Call legacy weak Output complete callback*/ 02813 HAL_CRYP_OutCpltCallback(hcryp); 02814 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02815 } 02816 } 02817 } 02818 else 02819 { 02820 /* Process unlocked */ 02821 __HAL_UNLOCK(hcryp); 02822 /* Busy error code field */ 02823 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 02824 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 02825 /*Call registered error callback*/ 02826 hcryp->ErrorCallback(hcryp); 02827 #else 02828 /*Call legacy weak error callback*/ 02829 HAL_CRYP_ErrorCallback(hcryp); 02830 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 02831 } 02832 } 02833 02834 /** 02835 * @brief Writes Key in Key registers. 02836 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 02837 * the configuration information for CRYP module 02838 * @param KeySize: Size of Key 02839 * @retval None 02840 */ 02841 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize) 02842 { 02843 switch (KeySize) 02844 { 02845 case CRYP_KEYSIZE_256B: 02846 hcryp->Instance->K0LR = *(uint32_t *)(hcryp->Init.pKey); 02847 hcryp->Instance->K0RR = *(uint32_t *)(hcryp->Init.pKey + 1); 02848 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey + 2); 02849 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 3); 02850 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 4); 02851 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 5); 02852 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 6); 02853 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 7); 02854 break; 02855 case CRYP_KEYSIZE_192B: 02856 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey); 02857 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1); 02858 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2); 02859 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3); 02860 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4); 02861 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5); 02862 break; 02863 case CRYP_KEYSIZE_128B: 02864 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey); 02865 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 1); 02866 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 2); 02867 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 3); 02868 02869 break; 02870 default: 02871 break; 02872 } 02873 } 02874 02875 /** 02876 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG 02877 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 02878 * the configuration information for CRYP module 02879 * @param Timeout: Timeout duration 02880 * @retval HAL status 02881 */ 02882 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 02883 { 02884 uint32_t tickstart; 02885 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U; 02886 uint32_t npblb ; 02887 uint32_t temp[4]; /* Temporary CrypOutBuff */ 02888 uint32_t index ; 02889 uint32_t lastwordsize ; 02890 uint16_t outcount; /* Temporary CrypOutCount Value */ 02891 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 02892 02893 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 02894 { 02895 if (hcryp->KeyIVConfig == 1U) 02896 { 02897 /* If the Key and IV configuration has to be done only once 02898 and if it has already been done, skip it */ 02899 DoKeyIVConfig = 0U; 02900 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ 02901 } 02902 else 02903 { 02904 /* If the Key and IV configuration has to be done only once 02905 and if it has not been done already, do it and set KeyIVConfig 02906 to keep track it won't have to be done again next time */ 02907 hcryp->KeyIVConfig = 1U; 02908 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ 02909 } 02910 } 02911 else 02912 { 02913 hcryp->SizesSum = hcryp->Size; 02914 } 02915 02916 if (DoKeyIVConfig == 1U) 02917 { 02918 /* Reset CrypHeaderCount */ 02919 hcryp->CrypHeaderCount = 0U; 02920 02921 /****************************** Init phase **********************************/ 02922 02923 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 02924 02925 /* Set the key */ 02926 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 02927 02928 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/ 02929 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 02930 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 02931 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2); 02932 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3); 02933 02934 /* Enable the CRYP peripheral */ 02935 __HAL_CRYP_ENABLE(hcryp); 02936 02937 /* Get tick */ 02938 tickstart = HAL_GetTick(); 02939 02940 /*Wait for the CRYPEN bit to be cleared*/ 02941 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 02942 { 02943 /* Check for the Timeout */ 02944 if (Timeout != HAL_MAX_DELAY) 02945 { 02946 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 02947 { 02948 /* Disable the CRYP peripheral clock */ 02949 __HAL_CRYP_DISABLE(hcryp); 02950 02951 /* Change state */ 02952 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 02953 hcryp->State = HAL_CRYP_STATE_READY; 02954 02955 /* Process unlocked */ 02956 __HAL_UNLOCK(hcryp); 02957 return HAL_ERROR; 02958 } 02959 } 02960 } 02961 02962 /************************ Header phase *************************************/ 02963 02964 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK) 02965 { 02966 return HAL_ERROR; 02967 } 02968 02969 /*************************Payload phase ************************************/ 02970 02971 /* Set the phase */ 02972 hcryp->Phase = CRYP_PHASE_PROCESS; 02973 02974 /* Disable the CRYP peripheral */ 02975 __HAL_CRYP_DISABLE(hcryp); 02976 02977 #if !defined (CRYP_VER_2_2) 02978 if (hcryp->Version >= REV_ID_B) 02979 #endif /*End of not defined CRYP_VER_2_2*/ 02980 { 02981 /* Set to 0 the number of non-valid bytes using NPBLB register*/ 02982 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U); 02983 } 02984 02985 /* Select payload phase once the header phase is performed */ 02986 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 02987 02988 /* Enable the CRYP peripheral */ 02989 __HAL_CRYP_ENABLE(hcryp); 02990 } /* if (DoKeyIVConfig == 1U) */ 02991 02992 if ((hcryp->Size % 16U) != 0U) 02993 { 02994 /* recalculate wordsize */ 02995 wordsize = ((wordsize / 4U) * 4U) ; 02996 } 02997 02998 /* Get tick */ 02999 tickstart = HAL_GetTick(); 03000 /*Temporary CrypOutCount Value*/ 03001 outcount = hcryp->CrypOutCount; 03002 03003 /* Write input data and get output Data */ 03004 while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize)) 03005 { 03006 /* Write plain data and get cipher data */ 03007 CRYP_AES_ProcessData(hcryp, Timeout); 03008 03009 /*Temporary CrypOutCount Value*/ 03010 outcount = hcryp->CrypOutCount; 03011 03012 /* Check for the Timeout */ 03013 if (Timeout != HAL_MAX_DELAY) 03014 { 03015 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 03016 { 03017 /* Disable the CRYP peripheral clock */ 03018 __HAL_CRYP_DISABLE(hcryp); 03019 03020 /* Change state & error code */ 03021 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03022 hcryp->State = HAL_CRYP_STATE_READY; 03023 03024 /* Process unlocked */ 03025 __HAL_UNLOCK(hcryp); 03026 return HAL_ERROR; 03027 } 03028 } 03029 } 03030 03031 if ((hcryp->Size % 16U) != 0U) 03032 { 03033 03034 #if !defined (CRYP_VER_2_2) 03035 if (hcryp->Version >= REV_ID_B) 03036 #endif /*End of not defined CRYP_VER_2_2*/ 03037 { 03038 /* Compute the number of padding bytes in last block of payload */ 03039 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size); 03040 03041 /* Set Npblb in case of AES GCM payload encryption to get right tag*/ 03042 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT) 03043 { 03044 /* Disable the CRYP */ 03045 __HAL_CRYP_DISABLE(hcryp); 03046 03047 /* Specify the number of non-valid bytes using NPBLB register*/ 03048 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20); 03049 03050 /* Enable CRYP to start the final phase */ 03051 __HAL_CRYP_ENABLE(hcryp); 03052 } 03053 /* Number of valid words (lastwordsize) in last block */ 03054 if ((npblb % 4U) == 0U) 03055 { 03056 lastwordsize = (16U - npblb) / 4U; 03057 } 03058 else 03059 { 03060 lastwordsize = ((16U - npblb) / 4U) + 1U; 03061 } 03062 03063 /* Write the last input block in the IN FIFO */ 03064 for (index = 0U; index < lastwordsize; index ++) 03065 { 03066 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 03067 hcryp->CrypInCount++; 03068 } 03069 03070 /* Pad the data with zeros to have a complete block */ 03071 while (index < 4U) 03072 { 03073 hcryp->Instance->DIN = 0U; 03074 index++; 03075 } 03076 03077 /* Wait for OFNE flag to be raised */ 03078 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK) 03079 { 03080 /* Disable the CRYP peripheral clock */ 03081 __HAL_CRYP_DISABLE(hcryp); 03082 03083 /* Change state */ 03084 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03085 hcryp->State = HAL_CRYP_STATE_READY; 03086 03087 /* Process Unlocked */ 03088 __HAL_UNLOCK(hcryp); 03089 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 03090 /*Call registered error callback*/ 03091 hcryp->ErrorCallback(hcryp); 03092 #else 03093 /*Call legacy weak error callback*/ 03094 HAL_CRYP_ErrorCallback(hcryp); 03095 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 03096 } 03097 03098 /*Read the output block from the output FIFO */ 03099 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) 03100 { 03101 for (index = 0U; index < 4U; index++) 03102 { 03103 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */ 03104 temp[index] = hcryp->Instance->DOUT; 03105 } 03106 for (index=0; index<lastwordsize; index++) 03107 { 03108 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index]; 03109 hcryp->CrypOutCount++; 03110 } 03111 } 03112 } 03113 #if !defined (CRYP_VER_2_2) 03114 else /* Workaround to be used */ 03115 { 03116 /* Workaround 2 for STM32H7 below rev.B To generate correct TAG only when size of the last block of 03117 payload is inferior to 128 bits, in case of GCM encryption or CCM decryption*/ 03118 CRYP_Workaround(hcryp, Timeout); 03119 } /* end of NPBLB or Workaround*/ 03120 #endif /*End of not defined CRYP_VER_2_2*/ 03121 } 03122 03123 /* Return function status */ 03124 return HAL_OK; 03125 } 03126 03127 /** 03128 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode 03129 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 03130 * the configuration information for CRYP module 03131 * @retval HAL status 03132 */ 03133 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp) 03134 { 03135 __IO uint32_t count = 0U; 03136 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 03137 03138 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 03139 { 03140 if (hcryp->KeyIVConfig == 1U) 03141 { 03142 /* If the Key and IV configuration has to be done only once 03143 and if it has already been done, skip it */ 03144 DoKeyIVConfig = 0U; 03145 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ 03146 } 03147 else 03148 { 03149 /* If the Key and IV configuration has to be done only once 03150 and if it has not been done already, do it and set KeyIVConfig 03151 to keep track it won't have to be done again next time */ 03152 hcryp->KeyIVConfig = 1U; 03153 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ 03154 } 03155 } 03156 else 03157 { 03158 hcryp->SizesSum = hcryp->Size; 03159 } 03160 03161 /* Configure Key, IV and process message (header and payload) */ 03162 if (DoKeyIVConfig == 1U) 03163 { 03164 /* Reset CrypHeaderCount */ 03165 hcryp->CrypHeaderCount = 0U; 03166 03167 /******************************* Init phase *********************************/ 03168 03169 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 03170 03171 /* Set the key */ 03172 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 03173 03174 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/ 03175 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 03176 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 03177 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2); 03178 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3); 03179 03180 /* Enable the CRYP peripheral */ 03181 __HAL_CRYP_ENABLE(hcryp); 03182 03183 /*Wait for the CRYPEN bit to be cleared*/ 03184 count = CRYP_TIMEOUT_GCMCCMINITPHASE; 03185 do 03186 { 03187 count-- ; 03188 if (count == 0U) 03189 { 03190 /* Disable the CRYP peripheral clock */ 03191 __HAL_CRYP_DISABLE(hcryp); 03192 03193 /* Change state */ 03194 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03195 hcryp->State = HAL_CRYP_STATE_READY; 03196 03197 /* Process unlocked */ 03198 __HAL_UNLOCK(hcryp); 03199 return HAL_ERROR; 03200 } 03201 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN); 03202 03203 /***************************** Header phase *********************************/ 03204 03205 /* Select header phase */ 03206 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 03207 } /* end of if (DoKeyIVConfig == 1U) */ 03208 /* Enable interrupts */ 03209 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI); 03210 03211 /* Enable CRYP */ 03212 __HAL_CRYP_ENABLE(hcryp); 03213 03214 /* Return function status */ 03215 return HAL_OK; 03216 } 03217 03218 03219 /** 03220 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA 03221 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 03222 * the configuration information for CRYP module 03223 * @retval HAL status 03224 */ 03225 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp) 03226 { 03227 __IO uint32_t count = 0U; 03228 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ; 03229 uint32_t index; 03230 uint32_t npblb; 03231 uint32_t lastwordsize; 03232 uint32_t temp[4]; /* Temporary CrypOutBuff */ 03233 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 03234 03235 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 03236 { 03237 if (hcryp->KeyIVConfig == 1U) 03238 { 03239 /* If the Key and IV configuration has to be done only once 03240 and if it has already been done, skip it */ 03241 DoKeyIVConfig = 0U; 03242 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ 03243 } 03244 else 03245 { 03246 /* If the Key and IV configuration has to be done only once 03247 and if it has not been done already, do it and set KeyIVConfig 03248 to keep track it won't have to be done again next time */ 03249 hcryp->KeyIVConfig = 1U; 03250 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ 03251 } 03252 } 03253 else 03254 { 03255 hcryp->SizesSum = hcryp->Size; 03256 } 03257 03258 if (DoKeyIVConfig == 1U) 03259 { 03260 /* Reset CrypHeaderCount */ 03261 hcryp->CrypHeaderCount = 0U; 03262 03263 /*************************** Init phase ************************************/ 03264 03265 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 03266 03267 /* Set the key */ 03268 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 03269 03270 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/ 03271 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect); 03272 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1); 03273 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2); 03274 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3); 03275 03276 /* Enable the CRYP peripheral */ 03277 __HAL_CRYP_ENABLE(hcryp); 03278 03279 /*Wait for the CRYPEN bit to be cleared*/ 03280 count = CRYP_TIMEOUT_GCMCCMINITPHASE; 03281 do 03282 { 03283 count-- ; 03284 if (count == 0U) 03285 { 03286 /* Disable the CRYP peripheral clock */ 03287 __HAL_CRYP_DISABLE(hcryp); 03288 03289 /* Change state */ 03290 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03291 hcryp->State = HAL_CRYP_STATE_READY; 03292 03293 /* Process unlocked */ 03294 __HAL_UNLOCK(hcryp); 03295 return HAL_ERROR; 03296 } 03297 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN); 03298 03299 /************************ Header phase *************************************/ 03300 03301 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK) 03302 { 03303 return HAL_ERROR; 03304 } 03305 03306 /************************ Payload phase ************************************/ 03307 03308 /* Set the phase */ 03309 hcryp->Phase = CRYP_PHASE_PROCESS; 03310 03311 /* Disable the CRYP peripheral */ 03312 __HAL_CRYP_DISABLE(hcryp); 03313 03314 #if !defined (CRYP_VER_2_2) 03315 if (hcryp->Version >= REV_ID_B) 03316 #endif /*End of not defined CRYP_VER_2_2*/ 03317 { 03318 /* Set to 0 the number of non-valid bytes using NPBLB register*/ 03319 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U); 03320 } 03321 03322 /* Select payload phase once the header phase is performed */ 03323 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 03324 03325 } /* if (DoKeyIVConfig == 1U) */ 03326 03327 if (hcryp->Size == 0U) 03328 { 03329 /* Process unLocked */ 03330 __HAL_UNLOCK(hcryp); 03331 03332 /* Change the CRYP state and phase */ 03333 hcryp->State = HAL_CRYP_STATE_READY; 03334 } 03335 else if (hcryp->Size >= 16U) 03336 { 03337 /* for STM32H7 below rev.B : Size should be %4 otherwise Tag will be incorrectly generated for GCM Encryption: 03338 Workaround is implemented in polling mode, so if last block of payload <128bit don't use DMA mode otherwise TAG is incorrectly generated */ 03339 03340 /*DMA transfer must not include the last block in case of Size is not %16 */ 03341 wordsize = wordsize - (wordsize % 4U); 03342 03343 /*DMA transfer */ 03344 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr)); 03345 } 03346 else /* length of input data is < 16 */ 03347 { 03348 /* Compute the number of padding bytes in last block of payload */ 03349 npblb = 16U - (uint32_t)hcryp->Size; 03350 03351 #if !defined (CRYP_VER_2_2) 03352 if (hcryp->Version >= REV_ID_B) 03353 #endif /*End of not defined CRYP_VER_2_2*/ 03354 { 03355 /* Set Npblb in case of AES GCM payload encryption to get right tag*/ 03356 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT) 03357 { 03358 /* Specify the number of non-valid bytes using NPBLB register*/ 03359 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20); 03360 } 03361 } 03362 /* Enable CRYP to start the final phase */ 03363 __HAL_CRYP_ENABLE(hcryp); 03364 03365 /* Number of valid words (lastwordsize) in last block */ 03366 if ((npblb % 4U) == 0U) 03367 { 03368 lastwordsize = (16U - npblb) / 4U; 03369 } 03370 else 03371 { 03372 lastwordsize = ((16U - npblb) / 4U) + 1U; 03373 } 03374 03375 /* Write the last input block in the IN FIFO */ 03376 for (index = 0; index < lastwordsize; index ++) 03377 { 03378 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 03379 hcryp->CrypInCount++; 03380 } 03381 03382 /* Pad the data with zeros to have a complete block */ 03383 while (index < 4U) 03384 { 03385 hcryp->Instance->DIN = 0U; 03386 index++; 03387 } 03388 03389 /* Wait for OFNE flag to be raised */ 03390 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE; 03391 do 03392 { 03393 count-- ; 03394 if (count == 0U) 03395 { 03396 /* Disable the CRYP peripheral clock */ 03397 __HAL_CRYP_DISABLE(hcryp); 03398 03399 /* Change state */ 03400 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03401 hcryp->State = HAL_CRYP_STATE_READY; 03402 03403 /* Process unlocked */ 03404 __HAL_UNLOCK(hcryp); 03405 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 03406 /*Call registered error callback*/ 03407 hcryp->ErrorCallback(hcryp); 03408 #else 03409 /*Call legacy weak error callback*/ 03410 HAL_CRYP_ErrorCallback(hcryp); 03411 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 03412 } 03413 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)); 03414 03415 /*Read the output block from the output FIFO */ 03416 for (index = 0U; index < 4U; index++) 03417 { 03418 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */ 03419 temp[index] = hcryp->Instance->DOUT; 03420 } 03421 for (index=0; index<lastwordsize; index++) 03422 { 03423 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index]; 03424 hcryp->CrypOutCount++; 03425 } 03426 03427 /* Change the CRYP state to ready */ 03428 hcryp->State = HAL_CRYP_STATE_READY; 03429 03430 /* Process unlocked */ 03431 __HAL_UNLOCK(hcryp); 03432 } 03433 03434 /* Return function status */ 03435 return HAL_OK; 03436 } 03437 03438 03439 /** 03440 * @brief AES CCM encryption/decryption processing in polling mode 03441 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 03442 * the configuration information for CRYP module 03443 * @param Timeout: Timeout duration 03444 * @retval HAL status 03445 */ 03446 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 03447 { 03448 uint32_t tickstart; 03449 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U; 03450 uint32_t npblb ; 03451 uint32_t lastwordsize ; 03452 uint32_t temp[4] ; /* Temporary CrypOutBuff */ 03453 uint32_t index ; 03454 uint16_t outcount; /* Temporary CrypOutCount Value */ 03455 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 03456 03457 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 03458 { 03459 if (hcryp->KeyIVConfig == 1U) 03460 { 03461 /* If the Key and IV configuration has to be done only once 03462 and if it has already been done, skip it */ 03463 DoKeyIVConfig = 0U; 03464 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ 03465 } 03466 else 03467 { 03468 /* If the Key and IV configuration has to be done only once 03469 and if it has not been done already, do it and set KeyIVConfig 03470 to keep track it won't have to be done again next time */ 03471 hcryp->KeyIVConfig = 1U; 03472 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ 03473 } 03474 } 03475 else 03476 { 03477 hcryp->SizesSum = hcryp->Size; 03478 } 03479 03480 if (DoKeyIVConfig == 1U) 03481 { 03482 /* Reset CrypHeaderCount */ 03483 hcryp->CrypHeaderCount = 0U; 03484 03485 /********************** Init phase ******************************************/ 03486 03487 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 03488 03489 /* Set the key */ 03490 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 03491 03492 /* Set the initialization vector (IV) with CTR1 information */ 03493 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0; 03494 hcryp->Instance->IV0RR = hcryp->Init.B0[1]; 03495 hcryp->Instance->IV1LR = hcryp->Init.B0[2]; 03496 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2; 03497 03498 /* Enable the CRYP peripheral */ 03499 __HAL_CRYP_ENABLE(hcryp); 03500 03501 #if defined (CRYP_VER_2_2) 03502 { 03503 /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/ 03504 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0); 03505 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1); 03506 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2); 03507 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3); 03508 } 03509 #else 03510 if (hcryp->Version >= REV_ID_B) 03511 { 03512 /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/ 03513 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0); 03514 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1); 03515 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2); 03516 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3); 03517 } 03518 else /* data has to be swapped according to the DATATYPE */ 03519 { 03520 if (hcryp->Init.DataType == CRYP_DATATYPE_8B) 03521 { 03522 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0)); 03523 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1)); 03524 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2)); 03525 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3)); 03526 } 03527 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B) 03528 { 03529 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16); 03530 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16); 03531 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16); 03532 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16); 03533 } 03534 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B) 03535 { 03536 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0)); 03537 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1)); 03538 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2)); 03539 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3)); 03540 } 03541 else 03542 { 03543 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0); 03544 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1); 03545 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2); 03546 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3); 03547 } 03548 } 03549 #endif 03550 /* Get tick */ 03551 tickstart = HAL_GetTick(); 03552 03553 /*Wait for the CRYPEN bit to be cleared*/ 03554 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) 03555 { 03556 /* Check for the Timeout */ 03557 if (Timeout != HAL_MAX_DELAY) 03558 { 03559 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 03560 { 03561 /* Disable the CRYP peripheral clock */ 03562 __HAL_CRYP_DISABLE(hcryp); 03563 03564 /* Change state */ 03565 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03566 hcryp->State = HAL_CRYP_STATE_READY; 03567 03568 /* Process unlocked */ 03569 __HAL_UNLOCK(hcryp); 03570 return HAL_ERROR; 03571 } 03572 } 03573 } 03574 03575 /************************* Header phase *************************************/ 03576 /* Header block(B1) : associated data length expressed in bytes concatenated 03577 with Associated Data (A)*/ 03578 03579 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK) 03580 { 03581 return HAL_ERROR; 03582 } 03583 /********************** Payload phase ***************************************/ 03584 03585 /* Set the phase */ 03586 hcryp->Phase = CRYP_PHASE_PROCESS; 03587 03588 /* Disable the CRYP peripheral */ 03589 __HAL_CRYP_DISABLE(hcryp); 03590 #if !defined (CRYP_VER_2_2) 03591 if (hcryp->Version >= REV_ID_B) 03592 #endif /*End of not defined CRYP_VER_2_2*/ 03593 { 03594 /* Set to 0 the number of non-valid bytes using NPBLB register*/ 03595 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U); 03596 } 03597 03598 /* Select payload phase once the header phase is performed */ 03599 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 03600 03601 /* Enable the CRYP peripheral */ 03602 __HAL_CRYP_ENABLE(hcryp); 03603 03604 } /* if (DoKeyIVConfig == 1U) */ 03605 03606 if ((hcryp->Size % 16U) != 0U) 03607 { 03608 /* recalculate wordsize */ 03609 wordsize = ((wordsize / 4U) * 4U) ; 03610 } 03611 /* Get tick */ 03612 tickstart = HAL_GetTick(); 03613 03614 /*Temporary CrypOutCount Value*/ 03615 outcount = hcryp->CrypOutCount; 03616 03617 /* Write input data and get output data */ 03618 while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize)) 03619 { 03620 /* Write plain data and get cipher data */ 03621 CRYP_AES_ProcessData(hcryp, Timeout); 03622 03623 /*Temporary CrypOutCount Value*/ 03624 outcount = hcryp->CrypOutCount; 03625 03626 /* Check for the Timeout */ 03627 if (Timeout != HAL_MAX_DELAY) 03628 { 03629 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 03630 { 03631 /* Disable the CRYP peripheral clock */ 03632 __HAL_CRYP_DISABLE(hcryp); 03633 03634 /* Change state */ 03635 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03636 hcryp->State = HAL_CRYP_STATE_READY; 03637 03638 /* Process unlocked */ 03639 __HAL_UNLOCK(hcryp); 03640 return HAL_ERROR; 03641 } 03642 } 03643 } 03644 03645 if ((hcryp->Size % 16U) != 0U) 03646 { 03647 #if !defined (CRYP_VER_2_2) 03648 if (hcryp->Version >= REV_ID_B) 03649 #endif /*End of not defined CRYP_VER_2_2*/ 03650 { 03651 /* Compute the number of padding bytes in last block of payload */ 03652 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size); 03653 03654 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT) 03655 { 03656 /* Disable the CRYP */ 03657 __HAL_CRYP_DISABLE(hcryp); 03658 03659 /* Set Npblb in case of AES CCM payload decryption to get right tag */ 03660 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20); 03661 03662 /* Enable CRYP to start the final phase */ 03663 __HAL_CRYP_ENABLE(hcryp); 03664 } 03665 03666 /* Number of valid words (lastwordsize) in last block */ 03667 if ((npblb % 4U) == 0U) 03668 { 03669 lastwordsize = (16U - npblb) / 4U; 03670 } 03671 else 03672 { 03673 lastwordsize = ((16U - npblb) / 4U) + 1U; 03674 } 03675 03676 /* Write the last input block in the IN FIFO */ 03677 for (index = 0U; index < lastwordsize; index ++) 03678 { 03679 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 03680 hcryp->CrypInCount++; 03681 } 03682 03683 /* Pad the data with zeros to have a complete block */ 03684 while (index < 4U) 03685 { 03686 hcryp->Instance->DIN = 0U; 03687 index++; 03688 } 03689 03690 /* Wait for OFNE flag to be raised */ 03691 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK) 03692 { 03693 /* Disable the CRYP peripheral clock */ 03694 __HAL_CRYP_DISABLE(hcryp); 03695 03696 /* Change state */ 03697 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03698 hcryp->State = HAL_CRYP_STATE_READY; 03699 03700 /* Process Unlocked */ 03701 __HAL_UNLOCK(hcryp); 03702 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 03703 /*Call registered error callback*/ 03704 hcryp->ErrorCallback(hcryp); 03705 #else 03706 /*Call legacy weak error callback*/ 03707 HAL_CRYP_ErrorCallback(hcryp); 03708 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 03709 } 03710 03711 /*Read the output block from the output FIFO */ 03712 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) 03713 { 03714 for (index = 0U; index < 4U; index++) 03715 { 03716 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */ 03717 temp[index] = hcryp->Instance->DOUT; 03718 } 03719 for (index=0; index<lastwordsize; index++) 03720 { 03721 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index]; 03722 hcryp->CrypOutCount++; 03723 } 03724 } 03725 } 03726 #if !defined (CRYP_VER_2_2) 03727 else /* No NPBLB, Workaround to be used */ 03728 { 03729 /* CRYP Workaround : CRYP1 generates correct TAG during CCM decryption only when ciphertext blocks size is multiple of 03730 128 bits. If lthe size of the last block of payload is inferior to 128 bits, when CCM decryption 03731 is selected, then the TAG message will be wrong.*/ 03732 CRYP_Workaround(hcryp, Timeout); 03733 } 03734 #endif /*End of not defined CRYP_VER_2_2*/ 03735 } 03736 03737 /* Return function status */ 03738 return HAL_OK; 03739 } 03740 03741 /** 03742 * @brief AES CCM encryption/decryption process in interrupt mode 03743 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 03744 * the configuration information for CRYP module 03745 * @retval HAL status 03746 */ 03747 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp) 03748 { 03749 __IO uint32_t count = 0U; 03750 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 03751 03752 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 03753 { 03754 if (hcryp->KeyIVConfig == 1U) 03755 { 03756 /* If the Key and IV configuration has to be done only once 03757 and if it has already been done, skip it */ 03758 DoKeyIVConfig = 0U; 03759 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ 03760 } 03761 else 03762 { 03763 /* If the Key and IV configuration has to be done only once 03764 and if it has not been done already, do it and set KeyIVConfig 03765 to keep track it won't have to be done again next time */ 03766 hcryp->KeyIVConfig = 1U; 03767 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ 03768 } 03769 } 03770 else 03771 { 03772 hcryp->SizesSum = hcryp->Size; 03773 } 03774 03775 /* Configure Key, IV and process message (header and payload) */ 03776 if (DoKeyIVConfig == 1U) 03777 { 03778 /* Reset CrypHeaderCount */ 03779 hcryp->CrypHeaderCount = 0U; 03780 03781 /************ Init phase ************/ 03782 03783 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 03784 03785 /* Set the key */ 03786 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 03787 03788 /* Set the initialization vector (IV) with CTR1 information */ 03789 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0; 03790 hcryp->Instance->IV0RR = hcryp->Init.B0[1]; 03791 hcryp->Instance->IV1LR = hcryp->Init.B0[2]; 03792 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2; 03793 03794 /* Enable the CRYP peripheral */ 03795 __HAL_CRYP_ENABLE(hcryp); 03796 03797 /*Write the B0 packet into CRYP_DR*/ 03798 #if !defined (CRYP_VER_2_2) 03799 if (hcryp->Version >= REV_ID_B) 03800 #endif /*End of not defined CRYP_VER_2_2*/ 03801 { 03802 /* for STM32H7 rev.B and above data has not to be swapped */ 03803 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0); 03804 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1); 03805 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2); 03806 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3); 03807 } 03808 #if !defined (CRYP_VER_2_2) 03809 else /* data has to be swapped according to the DATATYPE */ 03810 { 03811 if (hcryp->Init.DataType == CRYP_DATATYPE_8B) 03812 { 03813 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0)); 03814 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1)); 03815 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2)); 03816 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3)); 03817 } 03818 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B) 03819 { 03820 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16); 03821 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16); 03822 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16); 03823 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16); 03824 } 03825 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B) 03826 { 03827 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0)); 03828 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1)); 03829 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2)); 03830 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3)); 03831 } 03832 else 03833 { 03834 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0); 03835 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1); 03836 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2); 03837 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3); 03838 } 03839 } 03840 #endif /*End of not defined CRYP_VER_2_2*/ 03841 /*Wait for the CRYPEN bit to be cleared*/ 03842 count = CRYP_TIMEOUT_GCMCCMINITPHASE; 03843 do 03844 { 03845 count-- ; 03846 if (count == 0U) 03847 { 03848 /* Disable the CRYP peripheral clock */ 03849 __HAL_CRYP_DISABLE(hcryp); 03850 03851 /* Change state */ 03852 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03853 hcryp->State = HAL_CRYP_STATE_READY; 03854 03855 /* Process unlocked */ 03856 __HAL_UNLOCK(hcryp); 03857 return HAL_ERROR; 03858 } 03859 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN); 03860 03861 /* Select header phase */ 03862 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 03863 } /* end of if (DoKeyIVConfig == 1U) */ 03864 /* Enable interrupts */ 03865 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI); 03866 03867 /* Enable CRYP */ 03868 __HAL_CRYP_ENABLE(hcryp); 03869 03870 /* Return function status */ 03871 return HAL_OK; 03872 } 03873 /** 03874 * @brief AES CCM encryption/decryption process in DMA mode 03875 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 03876 * the configuration information for CRYP module 03877 * @retval HAL status 03878 */ 03879 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp) 03880 { 03881 __IO uint32_t count = 0U; 03882 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ; 03883 uint32_t index; 03884 uint32_t npblb; 03885 uint32_t lastwordsize; 03886 uint32_t temp[4]; /* Temporary CrypOutBuff */ 03887 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */ 03888 03889 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) 03890 { 03891 if (hcryp->KeyIVConfig == 1U) 03892 { 03893 /* If the Key and IV configuration has to be done only once 03894 and if it has already been done, skip it */ 03895 DoKeyIVConfig = 0U; 03896 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ 03897 } 03898 else 03899 { 03900 /* If the Key and IV configuration has to be done only once 03901 and if it has not been done already, do it and set KeyIVConfig 03902 to keep track it won't have to be done again next time */ 03903 hcryp->KeyIVConfig = 1U; 03904 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ 03905 } 03906 } 03907 else 03908 { 03909 hcryp->SizesSum = hcryp->Size; 03910 } 03911 03912 if (DoKeyIVConfig == 1U) 03913 { 03914 /* Reset CrypHeaderCount */ 03915 hcryp->CrypHeaderCount = 0U; 03916 03917 /************************** Init phase **************************************/ 03918 03919 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); 03920 03921 /* Set the key */ 03922 CRYP_SetKey(hcryp, hcryp->Init.KeySize); 03923 03924 /* Set the initialization vector (IV) with CTR1 information */ 03925 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0; 03926 hcryp->Instance->IV0RR = hcryp->Init.B0[1]; 03927 hcryp->Instance->IV1LR = hcryp->Init.B0[2]; 03928 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2; 03929 03930 /* Enable the CRYP peripheral */ 03931 __HAL_CRYP_ENABLE(hcryp); 03932 03933 /*Write the B0 packet into CRYP_DR*/ 03934 #if !defined (CRYP_VER_2_2) 03935 if (hcryp->Version >= REV_ID_B) 03936 #endif /*End of not defined CRYP_VER_2_2*/ 03937 { 03938 /* for STM32H7 rev.B and above data has not to be swapped */ 03939 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0); 03940 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1); 03941 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2); 03942 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3); 03943 } 03944 #if !defined (CRYP_VER_2_2) 03945 else /* data has to be swapped according to the DATATYPE */ 03946 { 03947 if (hcryp->Init.DataType == CRYP_DATATYPE_8B) 03948 { 03949 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0)); 03950 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1)); 03951 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2)); 03952 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3)); 03953 } 03954 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B) 03955 { 03956 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16); 03957 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16); 03958 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16); 03959 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16); 03960 } 03961 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B) 03962 { 03963 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0)); 03964 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1)); 03965 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2)); 03966 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3)); 03967 } 03968 else 03969 { 03970 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0); 03971 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1); 03972 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2); 03973 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3); 03974 } 03975 } 03976 #endif /*End of not defined CRYP_VER_2_2*/ 03977 /*Wait for the CRYPEN bit to be cleared*/ 03978 count = CRYP_TIMEOUT_GCMCCMINITPHASE; 03979 do 03980 { 03981 count-- ; 03982 if (count == 0U) 03983 { 03984 /* Disable the CRYP peripheral clock */ 03985 __HAL_CRYP_DISABLE(hcryp); 03986 03987 /* Change state */ 03988 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 03989 hcryp->State = HAL_CRYP_STATE_READY; 03990 03991 /* Process unlocked */ 03992 __HAL_UNLOCK(hcryp); 03993 return HAL_ERROR; 03994 } 03995 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN); 03996 03997 /********************* Header phase *****************************************/ 03998 03999 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK) 04000 { 04001 return HAL_ERROR; 04002 } 04003 04004 /******************** Payload phase *****************************************/ 04005 04006 /* Set the phase */ 04007 hcryp->Phase = CRYP_PHASE_PROCESS; 04008 04009 /* Disable the CRYP peripheral */ 04010 __HAL_CRYP_DISABLE(hcryp); 04011 #if !defined (CRYP_VER_2_2) 04012 if (hcryp->Version >= REV_ID_B) 04013 #endif /*End of not defined CRYP_VER_2_2*/ 04014 { 04015 /* Set to 0 the number of non-valid bytes using NPBLB register*/ 04016 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U); 04017 } 04018 04019 /* Select payload phase once the header phase is performed */ 04020 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 04021 } /* if (DoKeyIVConfig == 1U) */ 04022 04023 if (hcryp->Size == 0U) 04024 { 04025 /* Process unLocked */ 04026 __HAL_UNLOCK(hcryp); 04027 04028 /* Change the CRYP state and phase */ 04029 hcryp->State = HAL_CRYP_STATE_READY; 04030 } 04031 else if (hcryp->Size >= 16U) 04032 { 04033 /* for STM32H7 below rev.B :: Size should be %4 otherwise Tag will be incorrectly generated for CCM Decryption, Workaround is implemented in polling mode*/ 04034 /*DMA transfer must not include the last block in case of Size is not %16 */ 04035 wordsize = wordsize - (wordsize % 4U); 04036 04037 /*DMA transfer */ 04038 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t) wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr)); 04039 } 04040 else /* length of input data is < 16U */ 04041 { 04042 /* Compute the number of padding bytes in last block of payload */ 04043 npblb = 16U - (uint32_t)(hcryp->Size); 04044 04045 #if !defined (CRYP_VER_2_2) 04046 if (hcryp->Version >= REV_ID_B) 04047 #endif /*End of not defined CRYP_VER_2_2*/ 04048 { 04049 /* Set Npblb in case of AES CCM payload decryption to get right tag*/ 04050 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT) 04051 { 04052 /* Specify the number of non-valid bytes using NPBLB register*/ 04053 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20); 04054 } 04055 } 04056 /* Enable CRYP to start the final phase */ 04057 __HAL_CRYP_ENABLE(hcryp); 04058 04059 /* Number of valid words (lastwordsize) in last block */ 04060 if ((npblb % 4U) == 0U) 04061 { 04062 lastwordsize = (16U - npblb) / 4U; 04063 } 04064 else 04065 { 04066 lastwordsize = ((16U - npblb) / 4U) + 1U; 04067 } 04068 04069 /* Write the last input block in the IN FIFO */ 04070 for (index = 0U; index < lastwordsize; index ++) 04071 { 04072 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 04073 hcryp->CrypInCount++; 04074 } 04075 04076 /* Pad the data with zeros to have a complete block */ 04077 while (index < 4U) 04078 { 04079 hcryp->Instance->DIN = 0U; 04080 index++; 04081 } 04082 04083 /* Wait for OFNE flag to be raised */ 04084 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE; 04085 do 04086 { 04087 count-- ; 04088 if (count == 0U) 04089 { 04090 /* Disable the CRYP peripheral clock */ 04091 __HAL_CRYP_DISABLE(hcryp); 04092 04093 /* Change state */ 04094 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04095 hcryp->State = HAL_CRYP_STATE_READY; 04096 04097 /* Process unlocked */ 04098 __HAL_UNLOCK(hcryp); 04099 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 04100 /*Call registered error callback*/ 04101 hcryp->ErrorCallback(hcryp); 04102 #else 04103 /*Call legacy weak error callback*/ 04104 HAL_CRYP_ErrorCallback(hcryp); 04105 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 04106 } 04107 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)); 04108 04109 /*Read the output block from the output FIFO */ 04110 for (index = 0U; index < 4U; index++) 04111 { 04112 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */ 04113 temp[index] = hcryp->Instance->DOUT; 04114 } 04115 for (index=0; index<lastwordsize; index++) 04116 { 04117 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index]; 04118 hcryp->CrypOutCount++; 04119 } 04120 04121 /* Change the CRYP state to ready */ 04122 hcryp->State = HAL_CRYP_STATE_READY; 04123 04124 /* Process unlocked */ 04125 __HAL_UNLOCK(hcryp); 04126 } 04127 04128 /* Return function status */ 04129 return HAL_OK; 04130 } 04131 04132 /** 04133 * @brief Sets the payload phase in interrupt mode 04134 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 04135 * the configuration information for CRYP module 04136 * @retval state 04137 */ 04138 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp) 04139 { 04140 uint32_t loopcounter; 04141 uint32_t temp[4]; /* Temporary CrypOutBuff */ 04142 uint32_t lastwordsize; 04143 uint32_t npblb; 04144 uint32_t temp_cr_algodir; 04145 uint8_t negative = 0U; 04146 uint32_t i; 04147 04148 /***************************** Payload phase *******************************/ 04149 04150 if ((hcryp->Size / 4U) < hcryp->CrypInCount) 04151 { 04152 negative = 1U; 04153 } 04154 04155 if (hcryp->Size == 0U) 04156 { 04157 /* Disable interrupts */ 04158 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 04159 04160 /* Process unlocked */ 04161 __HAL_UNLOCK(hcryp); 04162 04163 /* Change the CRYP state */ 04164 hcryp->State = HAL_CRYP_STATE_READY; 04165 } 04166 04167 else if ((((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) && 04168 (negative == 0U)) 04169 { 04170 if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM)!= 0x0U) 04171 { 04172 /* Write the input block in the IN FIFO */ 04173 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 04174 hcryp->CrypInCount++; 04175 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 04176 hcryp->CrypInCount++; 04177 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 04178 hcryp->CrypInCount++; 04179 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 04180 hcryp->CrypInCount++; 04181 if (((hcryp->Size / 4U) == hcryp->CrypInCount) && ((hcryp->Size % 16U) == 0U)) 04182 { 04183 /* Disable interrupts */ 04184 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); 04185 /* Call the input data transfer complete callback */ 04186 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) 04187 /*Call registered Input complete callback*/ 04188 hcryp->InCpltCallback(hcryp); 04189 #else 04190 /*Call legacy weak Input complete callback*/ 04191 HAL_CRYP_InCpltCallback(hcryp); 04192 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 04193 } 04194 04195 if (hcryp->CrypOutCount < (hcryp->Size / 4U)) 04196 { 04197 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) 04198 { 04199 /* Read the output block from the Output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */ 04200 for (i = 0U; i < 4U; i++) 04201 { 04202 temp[i] = hcryp->Instance->DOUT; 04203 } 04204 i = 0U; 04205 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U)) 04206 { 04207 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i]; 04208 hcryp->CrypOutCount++; 04209 i++; 04210 } 04211 if (((hcryp->Size / 4U) == hcryp->CrypOutCount) && ((hcryp->Size % 16U) == 0U)) 04212 { 04213 /* Disable interrupts */ 04214 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); 04215 04216 /* Change the CRYP state */ 04217 hcryp->State = HAL_CRYP_STATE_READY; 04218 04219 /* Disable CRYP */ 04220 __HAL_CRYP_DISABLE(hcryp); 04221 04222 /* Process unlocked */ 04223 __HAL_UNLOCK(hcryp); 04224 04225 /* Call output transfer complete callback */ 04226 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) 04227 /*Call registered Output complete callback*/ 04228 hcryp->OutCpltCallback(hcryp); 04229 #else 04230 /*Call legacy weak Output complete callback*/ 04231 HAL_CRYP_OutCpltCallback(hcryp); 04232 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 04233 } 04234 } 04235 } 04236 } 04237 } 04238 else if ((hcryp->Size % 16U) != 0U) 04239 { 04240 /* Set padding only in case of input fifo interrupt */ 04241 if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM)!= 0x0U) 04242 { 04243 /* Compute the number of padding bytes in last block of payload */ 04244 npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size); 04245 04246 #if !defined (CRYP_VER_2_2) 04247 if (hcryp->Version >= REV_ID_B) 04248 #endif /*End of not defined CRYP_VER_2_2*/ 04249 { 04250 /* Set Npblb in case of AES GCM payload encryption and CCM decryption to get right tag */ 04251 temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR; 04252 04253 if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) || 04254 ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM))) 04255 { 04256 /* Disable the CRYP */ 04257 __HAL_CRYP_DISABLE(hcryp); 04258 04259 /* Specify the number of non-valid bytes using NPBLB register*/ 04260 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20); 04261 04262 /* Enable CRYP to start the final phase */ 04263 __HAL_CRYP_ENABLE(hcryp); 04264 } 04265 } 04266 04267 /* Number of valid words (lastwordsize) in last block */ 04268 if ((npblb % 4U) == 0U) 04269 { 04270 lastwordsize = (16U - npblb) / 4U; 04271 } 04272 else 04273 { 04274 lastwordsize = ((16U - npblb) / 4U) + 1U; 04275 } 04276 04277 /* Write the last input block in the IN FIFO */ 04278 for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++) 04279 { 04280 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 04281 hcryp->CrypInCount++; 04282 } 04283 /* Pad the data with zeros to have a complete block */ 04284 while (loopcounter < 4U) 04285 { 04286 hcryp->Instance->DIN = 0U; 04287 loopcounter++; 04288 } 04289 04290 /* Disable the input FIFO Interrupt */ 04291 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); 04292 } 04293 04294 /*Read the output block from the output FIFO */ 04295 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) 04296 { 04297 for (i = 0U; i < 4U; i++) 04298 { 04299 temp[i] = hcryp->Instance->DOUT; 04300 } 04301 if (( (hcryp->Size)/4U)==0U) 04302 { 04303 for (i = 0U; (uint16_t)i<((hcryp->Size)%4U); i++) 04304 { 04305 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i]; 04306 hcryp->CrypOutCount++; 04307 } 04308 } 04309 i = 0U; 04310 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U)) 04311 { 04312 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i]; 04313 hcryp->CrypOutCount++; 04314 i++; 04315 } 04316 } 04317 04318 /* Disable the output FIFO Interrupt */ 04319 if (hcryp->CrypOutCount >= ((hcryp->Size) / 4U)) 04320 { 04321 /* Disable interrupts */ 04322 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI | CRYP_IT_INI); 04323 04324 /* Change the CRYP peripheral state */ 04325 hcryp->State = HAL_CRYP_STATE_READY; 04326 04327 /* Process unlocked */ 04328 __HAL_UNLOCK(hcryp); 04329 04330 /* Call output transfer complete callback */ 04331 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) 04332 /*Call registered Output complete callback*/ 04333 hcryp->OutCpltCallback(hcryp); 04334 #else 04335 /*Call legacy weak Output complete callback*/ 04336 HAL_CRYP_OutCpltCallback(hcryp); 04337 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 04338 } 04339 } 04340 else 04341 { 04342 /* Nothing to do */ 04343 } 04344 } 04345 04346 04347 /** 04348 * @brief Sets the header phase in polling mode 04349 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 04350 * the configuration information for CRYP module(Header & HeaderSize) 04351 * @param Timeout: Timeout value 04352 * @retval state 04353 */ 04354 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 04355 { 04356 uint32_t loopcounter; 04357 uint32_t size_in_bytes; 04358 uint32_t tmp; 04359 uint32_t mask[4] = {0x0U, 0x0FFU, 0x0FFFFU, 0x0FFFFFFU}; 04360 04361 /***************************** Header phase for GCM/GMAC or CCM *********************************/ 04362 04363 04364 if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD) 04365 { 04366 size_in_bytes = hcryp->Init.HeaderSize * 4U; 04367 } 04368 else 04369 { 04370 size_in_bytes = hcryp->Init.HeaderSize; 04371 } 04372 04373 if ((size_in_bytes != 0U)) 04374 { 04375 /* Select header phase */ 04376 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 04377 04378 /* Enable the CRYP peripheral */ 04379 __HAL_CRYP_ENABLE(hcryp); 04380 04381 /* If size_in_bytes is a multiple of blocks (a multiple of four 32-bits words ) */ 04382 if ((size_in_bytes % 16U) == 0U) 04383 { 04384 /* No padding */ 04385 for (loopcounter = 0U; (loopcounter < (size_in_bytes / 4U)); loopcounter += 4U) 04386 04387 { 04388 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04389 hcryp->CrypHeaderCount++ ; 04390 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04391 hcryp->CrypHeaderCount++ ; 04392 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04393 hcryp->CrypHeaderCount++ ; 04394 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04395 hcryp->CrypHeaderCount++ ; 04396 04397 /* Wait for IFEM to be raised */ 04398 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK) 04399 { 04400 /* Disable the CRYP peripheral clock */ 04401 __HAL_CRYP_DISABLE(hcryp); 04402 04403 /* Change state */ 04404 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04405 hcryp->State = HAL_CRYP_STATE_READY; 04406 04407 /* Process unlocked */ 04408 __HAL_UNLOCK(hcryp); 04409 return HAL_ERROR; 04410 } 04411 } 04412 } 04413 else 04414 { 04415 /* Write header block in the IN FIFO without last block */ 04416 for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 16U) * 4U)); loopcounter += 4U) 04417 { 04418 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04419 hcryp->CrypHeaderCount++ ; 04420 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04421 hcryp->CrypHeaderCount++ ; 04422 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04423 hcryp->CrypHeaderCount++ ; 04424 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04425 hcryp->CrypHeaderCount++ ; 04426 04427 /* Wait for IFEM to be raised */ 04428 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK) 04429 { 04430 /* Disable the CRYP peripheral clock */ 04431 __HAL_CRYP_DISABLE(hcryp); 04432 04433 /* Change state */ 04434 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04435 hcryp->State = HAL_CRYP_STATE_READY; 04436 04437 /* Process unlocked */ 04438 __HAL_UNLOCK(hcryp); 04439 return HAL_ERROR; 04440 } 04441 } 04442 /* Last block optionally pad the data with zeros*/ 04443 for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 4U) % 4U)); loopcounter++) 04444 { 04445 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04446 hcryp->CrypHeaderCount++ ; 04447 } 04448 /* If the header size is a multiple of words */ 04449 if ((size_in_bytes % 4U) == 0U) 04450 { 04451 /* Pad the data with zeros to have a complete block */ 04452 while (loopcounter < 4U) 04453 { 04454 hcryp->Instance->DIN = 0x0U; 04455 loopcounter++; 04456 } 04457 } 04458 else 04459 { 04460 /* Enter last bytes, padded with zeroes */ 04461 tmp = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04462 tmp &= mask[size_in_bytes % 4U]; 04463 hcryp->Instance->DIN = tmp; 04464 loopcounter++; 04465 /* Pad the data with zeros to have a complete block */ 04466 while (loopcounter < 4U) 04467 { 04468 hcryp->Instance->DIN = 0x0U; 04469 loopcounter++; 04470 } 04471 } 04472 /* Wait for CCF IFEM to be raised */ 04473 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK) 04474 { 04475 /* Disable the CRYP peripheral clock */ 04476 __HAL_CRYP_DISABLE(hcryp); 04477 04478 /* Change state */ 04479 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04480 hcryp->State = HAL_CRYP_STATE_READY; 04481 04482 /* Process unlocked */ 04483 __HAL_UNLOCK(hcryp); 04484 return HAL_ERROR; 04485 } 04486 } 04487 /* Wait until the complete message has been processed */ 04488 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK) 04489 { 04490 /* Disable the CRYP peripheral clock */ 04491 __HAL_CRYP_DISABLE(hcryp); 04492 04493 /* Change state */ 04494 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04495 hcryp->State = HAL_CRYP_STATE_READY; 04496 04497 /* Process unlocked & return error */ 04498 __HAL_UNLOCK(hcryp); 04499 return HAL_ERROR; 04500 } 04501 } 04502 /* Return function status */ 04503 return HAL_OK; 04504 } 04505 04506 /** 04507 * @brief Sets the header phase when using DMA in process 04508 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 04509 * the configuration information for CRYP module(Header & HeaderSize) 04510 * @retval None 04511 */ 04512 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp) 04513 { 04514 __IO uint32_t count = 0U; 04515 uint32_t loopcounter; 04516 04517 /***************************** Header phase for GCM/GMAC or CCM *********************************/ 04518 if ((hcryp->Init.HeaderSize != 0U)) 04519 { 04520 /* Select header phase */ 04521 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); 04522 04523 /* Enable the CRYP peripheral */ 04524 __HAL_CRYP_ENABLE(hcryp); 04525 04526 if ((hcryp->Init.HeaderSize % 4U) == 0U) 04527 { 04528 /* HeaderSize %4, no padding */ 04529 for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U) 04530 { 04531 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04532 hcryp->CrypHeaderCount++ ; 04533 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04534 hcryp->CrypHeaderCount++ ; 04535 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04536 hcryp->CrypHeaderCount++ ; 04537 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04538 hcryp->CrypHeaderCount++ ; 04539 04540 /* Wait for IFEM to be raised */ 04541 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE; 04542 do 04543 { 04544 count-- ; 04545 if (count == 0U) 04546 { 04547 /* Disable the CRYP peripheral clock */ 04548 __HAL_CRYP_DISABLE(hcryp); 04549 04550 /* Change state */ 04551 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04552 hcryp->State = HAL_CRYP_STATE_READY; 04553 04554 /* Process unlocked */ 04555 __HAL_UNLOCK(hcryp); 04556 return HAL_ERROR; 04557 } 04558 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)); 04559 } 04560 } 04561 else 04562 { 04563 /*Write header block in the IN FIFO without last block */ 04564 for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U))); loopcounter += 4U) 04565 { 04566 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04567 hcryp->CrypHeaderCount++ ; 04568 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04569 hcryp->CrypHeaderCount++ ; 04570 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04571 hcryp->CrypHeaderCount++ ; 04572 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04573 hcryp->CrypHeaderCount++ ; 04574 04575 /* Wait for IFEM to be raised */ 04576 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE; 04577 do 04578 { 04579 count-- ; 04580 if (count == 0U) 04581 { 04582 /* Disable the CRYP peripheral clock */ 04583 __HAL_CRYP_DISABLE(hcryp); 04584 04585 /* Change state */ 04586 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04587 hcryp->State = HAL_CRYP_STATE_READY; 04588 04589 /* Process unlocked */ 04590 __HAL_UNLOCK(hcryp); 04591 return HAL_ERROR; 04592 } 04593 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)); 04594 } 04595 /* Last block optionally pad the data with zeros*/ 04596 for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++) 04597 { 04598 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04599 hcryp->CrypHeaderCount++ ; 04600 } 04601 while (loopcounter < 4U) 04602 { 04603 /* Pad the data with zeros to have a complete block */ 04604 hcryp->Instance->DIN = 0x0U; 04605 loopcounter++; 04606 } 04607 /* Wait for IFEM to be raised */ 04608 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE; 04609 do 04610 { 04611 count-- ; 04612 if (count == 0U) 04613 { 04614 /* Disable the CRYP peripheral clock */ 04615 __HAL_CRYP_DISABLE(hcryp); 04616 /* Change state */ 04617 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04618 hcryp->State = HAL_CRYP_STATE_READY; 04619 /* Process unlocked */ 04620 __HAL_UNLOCK(hcryp); 04621 return HAL_ERROR; 04622 } 04623 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)); 04624 } 04625 /* Wait until the complete message has been processed */ 04626 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE; 04627 do 04628 { 04629 count-- ; 04630 if (count == 0U) 04631 { 04632 /* Disable the CRYP peripheral clock */ 04633 __HAL_CRYP_DISABLE(hcryp); 04634 /* Change state */ 04635 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04636 hcryp->State = HAL_CRYP_STATE_READY; 04637 /* Process unlocked */ 04638 __HAL_UNLOCK(hcryp); 04639 return HAL_ERROR; 04640 } 04641 } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)); 04642 } 04643 04644 /* Return function status */ 04645 return HAL_OK; 04646 } 04647 04648 /** 04649 * @brief Sets the header phase in interrupt mode 04650 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 04651 * the configuration information for CRYP module(Header & HeaderSize) 04652 * @retval None 04653 */ 04654 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp) 04655 { 04656 uint32_t loopcounter; 04657 04658 /***************************** Header phase *********************************/ 04659 04660 if (hcryp->Init.HeaderSize == hcryp->CrypHeaderCount) 04661 { 04662 /* Disable interrupts */ 04663 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); 04664 04665 /* Disable the CRYP peripheral */ 04666 __HAL_CRYP_DISABLE(hcryp); 04667 04668 #if !defined (CRYP_VER_2_2) 04669 if (hcryp->Version >= REV_ID_B) 04670 #endif /*End of not defined CRYP_VER_2_2*/ 04671 { 04672 /* Set to 0 the number of non-valid bytes using NPBLB register*/ 04673 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U); 04674 } 04675 04676 /* Set the phase */ 04677 hcryp->Phase = CRYP_PHASE_PROCESS; 04678 04679 /* Select payload phase once the header phase is performed */ 04680 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); 04681 04682 /* Enable Interrupts */ 04683 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); 04684 04685 /* Enable the CRYP peripheral */ 04686 __HAL_CRYP_ENABLE(hcryp); 04687 } 04688 else if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount)) >= 4U) 04689 04690 { 04691 /* HeaderSize %4, no padding */ 04692 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04693 hcryp->CrypHeaderCount++ ; 04694 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04695 hcryp->CrypHeaderCount++ ; 04696 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04697 hcryp->CrypHeaderCount++ ; 04698 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04699 hcryp->CrypHeaderCount++ ; 04700 } 04701 else 04702 { 04703 /* Last block optionally pad the data with zeros*/ 04704 for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++) 04705 { 04706 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); 04707 hcryp->CrypHeaderCount++ ; 04708 } 04709 while (loopcounter < 4U) 04710 { 04711 /* Pad the data with zeros to have a complete block */ 04712 hcryp->Instance->DIN = 0x0U; 04713 loopcounter++; 04714 } 04715 } 04716 } 04717 04718 #if !defined (CRYP_VER_2_2) 04719 /** 04720 * @brief Workaround used for GCM/CCM mode. 04721 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 04722 * the configuration information for CRYP module 04723 * @param Timeout: Timeout value 04724 * @retval None 04725 */ 04726 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 04727 { 04728 uint32_t iv1temp; 04729 uint32_t temp[4] = {0}; 04730 uint32_t temp2[4] = {0}; 04731 uint32_t intermediate_data[4] = {0}; 04732 uint32_t index; 04733 uint32_t lastwordsize; 04734 uint32_t npblb; 04735 04736 /* Compute the number of padding bytes in last block of payload */ 04737 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size); 04738 04739 /* Number of valid words (lastwordsize) in last block */ 04740 if ((npblb % 4U) == 0U) 04741 { 04742 lastwordsize = (16U - npblb) / 4U; 04743 } 04744 else 04745 { 04746 lastwordsize = ((16U - npblb) / 4U) + 1U; 04747 } 04748 04749 /* Workaround 2, case GCM encryption */ 04750 if (hcryp->Init.Algorithm == CRYP_AES_GCM) 04751 { 04752 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT) 04753 { 04754 /*Workaround in order to properly compute authentication tags while doing 04755 a GCM encryption with the last block of payload size inferior to 128 bits*/ 04756 /* Disable CRYP to start the final phase */ 04757 __HAL_CRYP_DISABLE(hcryp); 04758 04759 /*Update CRYP_IV1R register and ALGOMODE*/ 04760 hcryp->Instance->IV1RR = ((hcryp->Instance->CSGCMCCM7R)-1U); 04761 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR); 04762 04763 /* Enable CRYP to start the final phase */ 04764 __HAL_CRYP_ENABLE(hcryp); 04765 } 04766 04767 for (index = 0; index < lastwordsize ; index ++) 04768 { 04769 /* Write the last input block in the IN FIFO */ 04770 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 04771 hcryp->CrypInCount++; 04772 } 04773 while (index < 4U) 04774 { 04775 /* Pad the data with zeros to have a complete block */ 04776 hcryp->Instance->DIN = 0U; 04777 index++; 04778 } 04779 /* Wait for OFNE flag to be raised */ 04780 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK) 04781 { 04782 /* Disable the CRYP peripheral clock */ 04783 __HAL_CRYP_DISABLE(hcryp); 04784 04785 /* Change state */ 04786 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04787 hcryp->State = HAL_CRYP_STATE_READY; 04788 04789 /* Process Unlocked */ 04790 __HAL_UNLOCK(hcryp); 04791 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 04792 /*Call registered error callback*/ 04793 hcryp->ErrorCallback(hcryp); 04794 #else 04795 /*Call legacy weak error callback*/ 04796 HAL_CRYP_ErrorCallback(hcryp); 04797 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 04798 } 04799 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) 04800 { 04801 for (index = 0U; index < 4U; index++) 04802 { 04803 /* Read the output block from the output FIFO */ 04804 intermediate_data[index] = hcryp->Instance->DOUT; 04805 04806 /* Intermediate data buffer to be used in for the workaround*/ 04807 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index]; 04808 hcryp->CrypOutCount++; 04809 } 04810 } 04811 04812 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT) 04813 { 04814 /*workaround in order to properly compute authentication tags while doing 04815 a GCM encryption with the last block of payload size inferior to 128 bits*/ 04816 /* Change the AES mode to GCM mode and Select Final phase */ 04817 /* configured CHMOD GCM */ 04818 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_GCM); 04819 04820 /* configured final phase */ 04821 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL); 04822 04823 if ( (hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_32B) 04824 { 04825 if ((npblb %4U)==1U) 04826 { 04827 intermediate_data[lastwordsize-1U] &= 0xFFFFFF00U; 04828 } 04829 if ((npblb %4U)==2U) 04830 { 04831 intermediate_data[lastwordsize-1U] &= 0xFFFF0000U; 04832 } 04833 if ((npblb %4U)==3U) 04834 { 04835 intermediate_data[lastwordsize-1U] &= 0xFF000000U; 04836 } 04837 } 04838 else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_8B) 04839 { 04840 if ((npblb %4U)==1U) 04841 { 04842 intermediate_data[lastwordsize-1U] &= __REV(0xFFFFFF00U); 04843 } 04844 if ((npblb %4U)==2U) 04845 { 04846 intermediate_data[lastwordsize-1U] &= __REV(0xFFFF0000U); 04847 } 04848 if ((npblb %4U)==3U) 04849 { 04850 intermediate_data[lastwordsize-1U] &= __REV(0xFF000000U); 04851 } 04852 } 04853 else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_16B) 04854 { 04855 if ((npblb %4U)==1U) 04856 { 04857 intermediate_data[lastwordsize-1U] &= __ROR((0xFFFFFF00U), 16); 04858 } 04859 if ((npblb %4U)==2U) 04860 { 04861 intermediate_data[lastwordsize-1U] &= __ROR((0xFFFF0000U), 16); 04862 } 04863 if ((npblb %4U)==3U) 04864 { 04865 intermediate_data[lastwordsize-1U] &= __ROR((0xFF000000U), 16); 04866 } 04867 } 04868 else /*CRYP_DATATYPE_1B*/ 04869 { 04870 if ((npblb %4U)==1U) 04871 { 04872 intermediate_data[lastwordsize-1U] &= __RBIT(0xFFFFFF00U); 04873 } 04874 if ((npblb %4U)==2U) 04875 { 04876 intermediate_data[lastwordsize-1U] &= __RBIT(0xFFFF0000U); 04877 } 04878 if ((npblb %4U)==3U) 04879 { 04880 intermediate_data[lastwordsize-1U] &= __RBIT(0xFF000000U); 04881 } 04882 } 04883 04884 for (index = 0U; index < lastwordsize ; index ++) 04885 { 04886 /*Write the intermediate_data in the IN FIFO */ 04887 hcryp->Instance->DIN = intermediate_data[index]; 04888 } 04889 while (index < 4U) 04890 { 04891 /* Pad the data with zeros to have a complete block */ 04892 hcryp->Instance->DIN = 0x0U; 04893 index++; 04894 } 04895 /* Wait for OFNE flag to be raised */ 04896 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK) 04897 { 04898 /* Disable the CRYP peripheral clock */ 04899 __HAL_CRYP_DISABLE(hcryp); 04900 04901 /* Change state */ 04902 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04903 hcryp->State = HAL_CRYP_STATE_READY; 04904 04905 /* Process unlocked */ 04906 __HAL_UNLOCK(hcryp); 04907 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) 04908 /*Call registered error callback*/ 04909 hcryp->ErrorCallback(hcryp); 04910 #else 04911 /*Call legacy weak error callback*/ 04912 HAL_CRYP_ErrorCallback(hcryp); 04913 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 04914 } 04915 04916 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) 04917 { 04918 for (index = 0U; index < 4U; index++) 04919 { 04920 intermediate_data[index] = hcryp->Instance->DOUT; 04921 } 04922 } 04923 } 04924 } /* End of GCM encryption */ 04925 else 04926 { 04927 /* Workaround 2, case CCM decryption, in order to properly compute 04928 authentication tags while doing a CCM decryption with the last block 04929 of payload size inferior to 128 bits*/ 04930 04931 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT) 04932 { 04933 iv1temp = hcryp->Instance->CSGCMCCM7R; 04934 04935 /* Disable CRYP to start the final phase */ 04936 __HAL_CRYP_DISABLE(hcryp); 04937 04938 temp[0] = hcryp->Instance->CSGCMCCM0R; 04939 temp[1] = hcryp->Instance->CSGCMCCM1R; 04940 temp[2] = hcryp->Instance->CSGCMCCM2R; 04941 temp[3] = hcryp->Instance->CSGCMCCM3R; 04942 04943 hcryp->Instance->IV1RR = iv1temp; 04944 04945 /* Configured CHMOD CTR */ 04946 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR); 04947 04948 /* Enable CRYP to start the final phase */ 04949 __HAL_CRYP_ENABLE(hcryp); 04950 } 04951 /* Last block optionally pad the data with zeros*/ 04952 for (index = 0U; index < lastwordsize; index ++) 04953 { 04954 /* Write the last Input block in the IN FIFO */ 04955 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); 04956 hcryp->CrypInCount++; 04957 } 04958 while (index < 4U) 04959 { 04960 /* Pad the data with zeros to have a complete block */ 04961 hcryp->Instance->DIN = 0U; 04962 index++; 04963 } 04964 /* Wait for OFNE flag to be raised */ 04965 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK) 04966 { 04967 /* Disable the CRYP peripheral clock */ 04968 __HAL_CRYP_DISABLE(hcryp); 04969 04970 /* Change state */ 04971 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 04972 hcryp->State = HAL_CRYP_STATE_READY; 04973 04974 /* Process Unlocked */ 04975 __HAL_UNLOCK(hcryp); 04976 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 04977 /*Call registered error callback*/ 04978 hcryp->ErrorCallback(hcryp); 04979 #else 04980 /*Call legacy weak error callback*/ 04981 HAL_CRYP_ErrorCallback(hcryp); 04982 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 04983 } 04984 04985 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) 04986 { 04987 for (index = 0U; index < 4U; index++) 04988 { 04989 /* Read the Output block from the Output FIFO */ 04990 intermediate_data[index] = hcryp->Instance->DOUT; 04991 04992 /*intermediate data buffer to be used in for the workaround*/ 04993 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index]; 04994 hcryp->CrypOutCount++; 04995 } 04996 } 04997 04998 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT) 04999 { 05000 temp2[0] = hcryp->Instance->CSGCMCCM0R; 05001 temp2[1] = hcryp->Instance->CSGCMCCM1R; 05002 temp2[2] = hcryp->Instance->CSGCMCCM2R; 05003 temp2[3] = hcryp->Instance->CSGCMCCM3R; 05004 05005 /* configured CHMOD CCM */ 05006 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CCM); 05007 05008 /* configured Header phase */ 05009 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_HEADER); 05010 05011 /*set to zero the bits corresponding to the padded bits*/ 05012 for (index = lastwordsize; index < 4U; index ++) 05013 { 05014 intermediate_data[index] = 0U; 05015 } 05016 05017 if ((npblb % 4U) == 1U) 05018 { 05019 intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U; 05020 } 05021 if ((npblb % 4U) == 2U) 05022 { 05023 intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U; 05024 } 05025 if ((npblb % 4U) == 3U) 05026 { 05027 intermediate_data[lastwordsize - 1U] &= 0xFF000000U; 05028 } 05029 05030 for (index = 0U; index < 4U ; index ++) 05031 { 05032 intermediate_data[index] ^= temp[index]; 05033 intermediate_data[index] ^= temp2[index]; 05034 } 05035 for (index = 0U; index < 4U; index ++) 05036 { 05037 /* Write the last Input block in the IN FIFO */ 05038 hcryp->Instance->DIN = intermediate_data[index] ; 05039 } 05040 05041 /* Wait for BUSY flag to be raised */ 05042 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK) 05043 { 05044 /* Disable the CRYP peripheral clock */ 05045 __HAL_CRYP_DISABLE(hcryp); 05046 05047 /* Change state */ 05048 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; 05049 hcryp->State = HAL_CRYP_STATE_READY; 05050 05051 /* Process Unlocked */ 05052 __HAL_UNLOCK(hcryp); 05053 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) 05054 /*Call registered error callback*/ 05055 hcryp->ErrorCallback(hcryp); 05056 #else 05057 /*Call legacy weak error callback*/ 05058 HAL_CRYP_ErrorCallback(hcryp); 05059 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ 05060 } 05061 } 05062 } /* End of CCM WKA*/ 05063 05064 /* Process Unlocked */ 05065 __HAL_UNLOCK(hcryp); 05066 } 05067 #endif /*End of not defined CRYP_VER_2_2*/ 05068 05069 /** 05070 * @brief Handle CRYP hardware block Timeout when waiting for IFEM flag to be raised. 05071 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 05072 * the configuration information for CRYP module. 05073 * @param Timeout: Timeout duration. 05074 * @retval HAL status 05075 */ 05076 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 05077 { 05078 uint32_t tickstart; 05079 05080 /* Get timeout */ 05081 tickstart = HAL_GetTick(); 05082 05083 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) 05084 { 05085 /* Check for the Timeout */ 05086 if (Timeout != HAL_MAX_DELAY) 05087 { 05088 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 05089 { 05090 return HAL_ERROR; 05091 } 05092 } 05093 } 05094 return HAL_OK; 05095 } 05096 /** 05097 * @brief Handle CRYP hardware block Timeout when waiting for BUSY flag to be raised. 05098 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 05099 * the configuration information for CRYP module. 05100 * @param Timeout: Timeout duration. 05101 * @retval HAL status 05102 */ 05103 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 05104 { 05105 uint32_t tickstart; 05106 05107 /* Get timeout */ 05108 tickstart = HAL_GetTick(); 05109 05110 while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)) 05111 { 05112 /* Check for the Timeout */ 05113 if (Timeout != HAL_MAX_DELAY) 05114 { 05115 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 05116 { 05117 return HAL_ERROR; 05118 } 05119 } 05120 } 05121 return HAL_OK; 05122 } 05123 05124 05125 /** 05126 * @brief Handle CRYP hardware block Timeout when waiting for OFNE flag to be raised. 05127 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains 05128 * the configuration information for CRYP module. 05129 * @param Timeout: Timeout duration. 05130 * @retval HAL status 05131 */ 05132 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout) 05133 { 05134 uint32_t tickstart; 05135 05136 /* Get timeout */ 05137 tickstart = HAL_GetTick(); 05138 05139 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) 05140 { 05141 /* Check for the Timeout */ 05142 if (Timeout != HAL_MAX_DELAY) 05143 { 05144 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 05145 { 05146 return HAL_ERROR; 05147 } 05148 } 05149 } 05150 return HAL_OK; 05151 } 05152 05153 05154 /** 05155 * @} 05156 */ 05157 05158 05159 05160 /** 05161 * @} 05162 */ 05163 05164 /** 05165 * @} 05166 */ 05167 05168 #endif /* HAL_CRYP_MODULE_ENABLED */ 05169 05170 05171 /** 05172 * @} 05173 */ 05174 #endif /* CRYP */ 05175 /** 05176 * @} 05177 */ 05178