1 /**
2   ******************************************************************************
3   * @file    stm32wlxx_hal_cryp.c
4   * @author  MCD Application Team
5   * @brief   CRYP HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Cryptography (CRYP) peripheral:
8   *           + Initialization, de-initialization, set config and get config  functions
9   *           + AES processing functions
10   *           + DMA callback functions
11   *           + CRYP IRQ handler management
12   *           + Peripheral State functions
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2020 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                      ##### How to use this driver #####
28   ==============================================================================
29     [..]
30       The CRYP HAL driver can be used in CRYP or TinyAES peripheral as follows:
31 
32       (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
33          (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()or __HAL_RCC_AES_CLK_ENABLE for TinyAES peripheral
34          (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT())
35              (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
36              (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
37              (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
38          (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA())
39              (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE()
40              (+++) Configure and enable two DMA streams one for managing data transfer from
41                  memory to peripheral (input stream) and another stream for managing data
42                  transfer from peripheral to memory (output stream)
43              (+++) Associate the initialized DMA handle to the CRYP DMA handle
44                  using  __HAL_LINKDMA()
45              (+++) Configure the priority and enable the NVIC for the transfer complete
46                  interrupt on the two DMA channels. The output channel should have higher
47                  priority than the input channel HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
48 
49       (#)Initialize the CRYP according to the specified parameters :
50          (##) The data type: 1-bit, 8-bit, 16-bit or 32-bit.
51          (##) The key size: 128, 192 or 256.
52          (##) The AlgoMode DES/ TDES Algorithm ECB/CBC or AES Algorithm ECB/CBC/CTR/GCM or CCM.
53          (##) The initialization vector (counter). It is not used in ECB mode.
54          (##) The key buffer used for encryption/decryption.
55              (+++) In some specific configurations, the key is written by the application
56                    code out of the HAL scope. In that case, user can still resort to the
57                    HAL APIs as usual but must make sure that pKey pointer is set to NULL.
58          (##) The DataWidthUnit field. It specifies whether the data length (or the payload length for authentication
59                algorithms) is in words or bytes.
60          (##) The Header used only in AES GCM and CCM Algorithm for authentication.
61          (##) The HeaderSize providing the size of the header buffer in words or bytes, depending upon HeaderWidthUnit field.
62          (##) The HeaderWidthUnit field. It specifies whether the header length (for authentication algorithms) is in words or bytes.
63          (##) The B0 block is the first authentication block used only in AES CCM mode.
64          (##) The KeyIVConfigSkip used to process several messages in a row (please see more information below).
65 
66       (#)Three processing (encryption/decryption) functions are available:
67          (##) Polling mode: encryption and decryption APIs are blocking functions
68               i.e. they process the data and wait till the processing is finished,
69               e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
70          (##) Interrupt mode: encryption and decryption APIs are not blocking functions
71               i.e. they process the data under interrupt,
72               e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
73          (##) DMA mode: encryption and decryption APIs are not blocking functions
74               i.e. the data transfer is ensured by DMA,
75               e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
76 
77       (#)When the processing function is called at first time after HAL_CRYP_Init()
78          the CRYP peripheral is configured and processes the buffer in input.
79          At second call, no need to Initialize the CRYP, user have to get current configuration via
80          HAL_CRYP_GetConfig() API, then only  HAL_CRYP_SetConfig() is requested to set
81          new parametres, finally user can  start encryption/decryption.
82 
83        (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
84 
85        (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt()
86           without having to configure again the Key or the Initialization Vector between each API call,
87           the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE.
88           Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA()
89           or HAL_CRYP_Decrypt_DMA().
90 
91     [..]
92       The cryptographic processor supports following standards:
93       (#) The data encryption standard (DES) and Triple-DES (TDES) supported only by CRYP1 peripheral:
94          (##)64-bit data block processing
95          (##) chaining modes supported :
96              (+++)  Electronic Code Book(ECB)
97              (+++)  Cipher Block Chaining (CBC)
98          (##) keys length supported :64-bit, 128-bit and 192-bit.
99       (#) The advanced encryption standard (AES) supported  by CRYP1 & TinyAES peripheral:
100          (##)128-bit data block processing
101          (##) chaining modes supported :
102              (+++)  Electronic Code Book(ECB)
103              (+++)  Cipher Block Chaining (CBC)
104              (+++)  Counter mode (CTR)
105              (+++)  Galois/counter mode (GCM/GMAC)
106              (+++)  Counter with Cipher Block Chaining-Message(CCM)
107          (##) keys length Supported :
108              (+++) for CRYP1 peripheral: 128-bit, 192-bit and 256-bit.
109              (+++) for TinyAES peripheral:  128-bit and 256-bit
110 
111     [..]
112     (@) Specific care must be taken to format the key and the Initialization Vector IV!
113 
114     [..] If the key is defined as a 128-bit long array key[127..0] = {b127 ... b0} where
115          b127 is the MSB and b0 the LSB, the key must be stored in MCU memory
116          (+) as a sequence of words where the MSB word comes first (occupies the
117            lowest memory address)
118           (++)   address n+0 : 0b b127 .. b120 b119 .. b112 b111 .. b104 b103 .. b96
119           (++)   address n+4 : 0b b95 .. b88 b87 .. b80 b79 .. b72 b71 .. b64
120           (++)   address n+8 : 0b b63 .. b56 b55 .. b48 b47 .. b40 b39 .. b32
121           (++)   address n+C : 0b b31 .. b24 b23 .. b16 b15 .. b8 b7 .. b0
122      [..] Hereafter, another illustration when considering a 128-bit long key made of 16 bytes {B15..B0}.
123          The 4 32-bit words that make the key must be stored as follows in MCU memory:
124           (+)    address n+0 : 0x B15 B14 B13 B12
125           (+)    address n+4 : 0x B11 B10 B9 B8
126           (+)    address n+8 : 0x B7 B6 B5 B4
127           (+)    address n+C : 0x B3 B2 B1 B0
128      [..]  which leads to the expected setting
129        (+)       AES_KEYR3 = 0x B15 B14 B13 B12
130        (+)       AES_KEYR2 = 0x B11 B10 B9 B8
131        (+)       AES_KEYR1 = 0x B7 B6 B5 B4
132        (+)       AES_KEYR0 = 0x B3 B2 B1 B0
133 
134     [..]  Same format must be applied for a 256-bit long key made of 32 bytes {B31..B0}.
135           The 8 32-bit words that make the key must be stored as follows in MCU memory:
136           (+)    address n+00 : 0x B31 B30 B29 B28
137           (+)    address n+04 : 0x B27 B26 B25 B24
138           (+)    address n+08 : 0x B23 B22 B21 B20
139           (+)    address n+0C : 0x B19 B18 B17 B16
140           (+)    address n+10 : 0x B15 B14 B13 B12
141           (+)    address n+14 : 0x B11 B10 B9 B8
142           (+)    address n+18 : 0x B7 B6 B5 B4
143           (+)    address n+1C : 0x B3 B2 B1 B0
144      [..]  which leads to the expected setting
145        (+)       AES_KEYR7 = 0x B31 B30 B29 B28
146        (+)       AES_KEYR6 = 0x B27 B26 B25 B24
147        (+)       AES_KEYR5 = 0x B23 B22 B21 B20
148        (+)       AES_KEYR4 = 0x B19 B18 B17 B16
149        (+)       AES_KEYR3 = 0x B15 B14 B13 B12
150        (+)       AES_KEYR2 = 0x B11 B10 B9 B8
151        (+)       AES_KEYR1 = 0x B7 B6 B5 B4
152        (+)       AES_KEYR0 = 0x B3 B2 B1 B0
153 
154     [..] Initialization Vector IV (4 32-bit words) format must follow the same as
155          that of a 128-bit long key.
156 
157     [..] Note that key and IV registers are not sensitive to swap mode selection.
158 
159     [..]  This section describes the AES Galois/counter mode (GCM) supported by both CRYP1 and TinyAES peripherals:
160       (#)  Algorithm supported :
161          (##) Galois/counter mode (GCM)
162          (##) Galois message authentication code (GMAC) :is exactly the same as
163               GCM algorithm composed only by an header.
164       (#)  Four phases are performed in GCM :
165          (##) Init phase: peripheral prepares the GCM hash subkey (H) and do the IV processing
166          (##) Header phase: peripheral processes the Additional Authenticated Data (AAD), with hash
167           computation only.
168          (##) Payload phase: peripheral processes the plaintext (P) with hash computation + keystream
169           encryption + data XORing. It works in a similar way for ciphertext (C).
170          (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data.
171       (#)  structure of message construction in GCM is defined as below  :
172          (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
173          (##) The authenticated header A (also knows as Additional Authentication Data AAD)
174           this part of the message is only authenticated, not encrypted.
175          (##) The plaintext message P is both authenticated and encrypted as ciphertext.
176           GCM standard specifies that ciphertext has same bit length as the plaintext.
177          (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
178           (on 64 bits)
179 
180     [..]  A more detailed description of the GCM message structure is available below.
181 
182     [..]  This section describe The AES Counter with Cipher Block Chaining-Message
183           Authentication Code (CCM) supported by both CRYP1 and TinyAES peripheral:
184       (#)  Specific parameters for CCM  :
185 
186          (##) B0 block  : follows NIST Special Publication 800-38C,
187          (##) B1 block (header)
188          (##) CTRx block  : control blocks
189 
190     [..]  A detailed description of the CCM message structure is available below.
191 
192       (#)  Four phases are performed in CCM for CRYP1 peripheral:
193          (##) Init phase: peripheral prepares the GCM hash subkey (H) and do the IV processing
194          (##) Header phase: peripheral processes the Additional Authenticated Data (AAD), with hash
195           computation only.
196          (##) Payload phase: peripheral processes the plaintext (P) with hash computation + keystream
197           encryption + data XORing. It works in a similar way for ciphertext (C).
198          (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data.
199       (#)    CCM in TinyAES peripheral:
200          (##) To perform message payload encryption or decryption AES is configured in CTR mode.
201          (##) For authentication two phases are performed :
202           - Header phase: peripheral processes the Additional Authenticated Data (AAD) first, then the cleartext message
203           only cleartext payload (not the ciphertext payload) is used and no outpout.
204          (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data.
205 
206   *** Callback registration ***
207   =============================
208 
209   [..]
210   The compilation define  USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
211   allows the user to configure dynamically the driver callbacks.
212   Use Functions HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
213   to register an interrupt callback.
214 
215   [..]
216   Function HAL_CRYP_RegisterCallback() allows to register following callbacks:
217     (+) InCpltCallback     :  Input FIFO transfer completed callback.
218     (+) OutCpltCallback    : Output FIFO transfer completed callback.
219     (+) ErrorCallback      : callback for error detection.
220     (+) MspInitCallback    : CRYP MspInit.
221     (+) MspDeInitCallback  : CRYP MspDeInit.
222   This function takes as parameters the HAL peripheral handle, the Callback ID
223   and a pointer to the user callback function.
224 
225   [..]
226   Use function HAL_CRYP_UnRegisterCallback() to reset a callback to the default
227   weak function.
228   HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
229   and the Callback ID.
230   This function allows to reset following callbacks:
231     (+) InCpltCallback     :  Input FIFO transfer completed callback.
232     (+) OutCpltCallback    : Output FIFO transfer completed callback.
233     (+) ErrorCallback      : callback for error detection.
234     (+) MspInitCallback    : CRYP MspInit.
235     (+) MspDeInitCallback  : CRYP MspDeInit.
236 
237   [..]
238   By default, after the HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
239   all callbacks are set to the corresponding weak functions :
240   examples HAL_CRYP_InCpltCallback() , HAL_CRYP_OutCpltCallback().
241   Exception done for MspInit and MspDeInit functions that are
242   reset to the legacy weak function in the HAL_CRYP_Init()/ HAL_CRYP_DeInit() only when
243   these callbacks are null (not registered beforehand).
244   if not, MspInit or MspDeInit are not null, the HAL_CRYP_Init() / HAL_CRYP_DeInit()
245   keep and use the user MspInit/MspDeInit functions (registered beforehand)
246 
247   [..]
248   Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
249   Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
250   in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
251   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
252   In that case first register the MspInit/MspDeInit user callbacks
253   using HAL_CRYP_RegisterCallback() before calling HAL_CRYP_DeInit()
254   or HAL_CRYP_Init() function.
255 
256   [..]
257   When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
258   not defined, the callback registration feature is not available and all callbacks
259   are set to the corresponding weak functions.
260 
261 
262   *** Suspend/Resume feature ***
263   ==============================
264 
265   [..]
266   The compilation define USE_HAL_CRYP_SUSPEND_RESUME when set to 1
267   allows the user to resort to the suspend/resume feature.
268   A low priority block processing can be suspended to process a high priority block
269   instead. When the high priority block processing is over, the low priority block
270   processing can be resumed, restarting from the point where it was suspended. This
271   feature is applicable only in non-blocking interrupt mode.
272 
273   [..] User must resort to HAL_CRYP_Suspend() to suspend the low priority block
274   processing. This API manages the hardware block processing suspension and saves all the
275   internal data that will be needed to restart later on. Upon HAL_CRYP_Suspend() completion,
276   the user can launch the processing of any other block (high priority block processing).
277 
278   [..] When the high priority block processing is over, user must invoke HAL_CRYP_Resume()
279   to resume the low priority block processing. Ciphering (or deciphering) restarts from
280   the suspension point and ends as usual.
281 
282   [..] HAL_CRYP_Suspend() reports an error when the suspension request is sent too late
283   (i.e when the low priority block processing is about to end). There is no use to
284   suspend the tag generation processing for authentication algorithms.
285 
286     [..]
287     (@) If the key is written out of HAL scope (case pKey pointer set to NULL by the user),
288         the block processing suspension/resumption mechanism is NOT applicable.
289 
290     [..]
291     (@) If the Key and Initialization Vector are configured only once and configuration is
292         skipped for consecutive processings (case KeyIVConfigSkip set to CRYP_KEYIVCONFIG_ONCE),
293         the block processing suspension/resumption mechanism is NOT applicable.
294 
295   @endverbatim
296   ******************************************************************************
297   */
298 
299 /* Includes ------------------------------------------------------------------*/
300 #include "stm32wlxx_hal.h"
301 
302 /** @addtogroup STM32WLxx_HAL_Driver
303   * @{
304   */
305 
306 /** @addtogroup CRYP
307   * @{
308   */
309 
310 
311 #ifdef HAL_CRYP_MODULE_ENABLED
312 
313 /* Private typedef -----------------------------------------------------------*/
314 /* Private define ------------------------------------------------------------*/
315 /** @addtogroup CRYP_Private_Defines
316   * @{
317   */
318 #define CRYP_TIMEOUT_KEYPREPARATION      82U         /* The latency of key preparation operation is 82 clock cycles.*/
319 #define CRYP_TIMEOUT_GCMCCMINITPHASE     299U        /* The latency of  GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/
320 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE   290U        /* The latency of  GCM/CCM header phase is 290 clock cycles.*/
321 
322 #define CRYP_PHASE_READY                 0x00000001U /*!< CRYP peripheral is ready for initialization. */
323 #define CRYP_PHASE_PROCESS               0x00000002U /*!< CRYP peripheral is in processing phase */
324 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
325 #define  CRYP_PHASE_HEADER_SUSPENDED     0x00000004U    /*!< GCM/GMAC/CCM header phase is suspended */
326 #define  CRYP_PHASE_PAYLOAD_SUSPENDED    0x00000005U    /*!< GCM/CCM payload phase is suspended     */
327 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
328 #define  CRYP_PHASE_HEADER_DMA_FEED      0x00000006U    /*!< GCM/GMAC/CCM header is fed to the peripheral in DMA mode */
329 
330 #define CRYP_OPERATINGMODE_ENCRYPT                   0x00000000U     /*!< Encryption mode(Mode 1)  */
331 #define CRYP_OPERATINGMODE_KEYDERIVATION             AES_CR_MODE_0   /*!< Key derivation mode  only used when performing ECB and CBC decryptions (Mode 2) */
332 #define CRYP_OPERATINGMODE_DECRYPT                   AES_CR_MODE_1   /*!< Decryption    (Mode 3)    */
333 #define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT     AES_CR_MODE     /*!< Key derivation and decryption only used when performing ECB and CBC decryptions (Mode 4) */
334 #define CRYP_PHASE_INIT                              0x00000000U     /*!< GCM/GMAC (or CCM) init phase */
335 #define CRYP_PHASE_HEADER                            AES_CR_GCMPH_0  /*!< GCM/GMAC or CCM header phase */
336 #define CRYP_PHASE_PAYLOAD                           AES_CR_GCMPH_1  /*!< GCM(/CCM) payload phase      */
337 #define CRYP_PHASE_FINAL                             AES_CR_GCMPH    /*!< GCM/GMAC or CCM  final phase */
338 
339 /*  CTR1 information to use in CCM algorithm */
340 #define CRYP_CCM_CTR1_0                  0x07FFFFFFU
341 #define CRYP_CCM_CTR1_1                  0xFFFFFF00U
342 #define CRYP_CCM_CTR1_2                  0x00000001U
343 
344 /**
345   * @}
346   */
347 
348 /* Private macro -------------------------------------------------------------*/
349 /** @addtogroup CRYP_Private_Macros
350   * @{
351   */
352 
353 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__)   MODIFY_REG((__HANDLE__)->Instance->CR, AES_CR_GCMPH, (uint32_t)(__PHASE__))
354 
355 /**
356   * @}
357   */
358 
359 /* Private struct -------------------------------------------------------------*/
360 /* Private variables ---------------------------------------------------------*/
361 /* Private function prototypes -----------------------------------------------*/
362 /** @addtogroup CRYP_Private_Functions
363   * @{
364   */
365 
366 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
367 static HAL_StatusTypeDef CRYP_SetHeaderDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size);
368 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
369 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
370 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
371 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
372 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
373 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
374 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
375 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
376 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
377 static HAL_StatusTypeDef CRYP_GCMCCM_SetPayloadPhase_DMA(CRYP_HandleTypeDef *hcryp);
378 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
379 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
380 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
381 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
382 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
383 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
384 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
385 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
386 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
387 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
388 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
389 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
390 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
391 static void CRYP_ClearCCFlagWhenHigh(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
392 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
393 static void CRYP_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output);
394 static void CRYP_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input);
395 static void CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output);
396 static void CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input);
397 static void CRYP_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output, uint32_t KeySize);
398 static void CRYP_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input, uint32_t KeySize);
399 static void CRYP_PhaseProcessingResume(CRYP_HandleTypeDef *hcryp);
400 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
401 
402 
403 /**
404   * @}
405   */
406 
407 /* Exported functions ---------------------------------------------------------*/
408 
409 /** @addtogroup CRYP_Exported_Functions
410   * @{
411   */
412 
413 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
414   * @brief    Initialization and Configuration functions.
415   *
416 @verbatim
417   ========================================================================================
418      ##### Initialization, de-initialization and Set and Get configuration functions #####
419   ========================================================================================
420     [..]  This section provides functions allowing to:
421       (+) Initialize the CRYP
422       (+) DeInitialize the CRYP
423       (+) Initialize the CRYP MSP
424       (+) DeInitialize the CRYP MSP
425       (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
426           Parameters which are configured in This section are :
427           (++) Key size
428           (++) Data Type : 32,16, 8 or 1bit
429           (++) AlgoMode :
430               (+++) for CRYP1 peripheral :
431                  ECB and CBC in DES/TDES Standard
432                  ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
433               (+++) for TinyAES2 peripheral, only ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard are supported.
434       (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
435       (+) For interleave mode, API HAL_CRYP_SaveContext and HAL_CRYP_RestoreContext to be used to save then Restore CRYP
436         configuration and parameters. CRYP_IVCONFIG_ONCE should be selected for KeyIVConfigSkip parameter.
437 
438 @endverbatim
439   * @{
440   */
441 
442 /**
443   * @brief  Initializes the CRYP according to the specified
444   *         parameters in the CRYP_ConfigTypeDef and creates the associated handle.
445   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
446   *         the configuration information for CRYP module
447   * @retval HAL status
448   */
HAL_CRYP_Init(CRYP_HandleTypeDef * hcryp)449 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
450 {
451   /* Check the CRYP handle allocation */
452   if (hcryp == NULL)
453   {
454     return HAL_ERROR;
455   }
456 
457   /* Check parameters */
458   assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
459   assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
460   assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
461   assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
462 
463 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
464   if (hcryp->State == HAL_CRYP_STATE_RESET)
465   {
466     /* Allocate lock resource and initialize it */
467     hcryp->Lock = HAL_UNLOCKED;
468 
469     hcryp->InCpltCallback  = HAL_CRYP_InCpltCallback;  /* Legacy weak InCpltCallback   */
470     hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback  */
471     hcryp->ErrorCallback   = HAL_CRYP_ErrorCallback;   /* Legacy weak ErrorCallback    */
472 
473     if (hcryp->MspInitCallback == NULL)
474     {
475       hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit  */
476     }
477 
478     /* Init the low level hardware */
479     hcryp->MspInitCallback(hcryp);
480   }
481 #else
482   if (hcryp->State == HAL_CRYP_STATE_RESET)
483   {
484     /* Allocate lock resource and initialize it */
485     hcryp->Lock = HAL_UNLOCKED;
486 
487     /* Init the low level hardware */
488     HAL_CRYP_MspInit(hcryp);
489   }
490 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
491 
492   /* Set the key size (This bit field is do not care in the DES or TDES modes), data type and Algorithm */
493   MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD, hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
494 
495   /* Reset Error Code field */
496   hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
497 
498   /* Reset peripheral Key and IV configuration flag */
499   hcryp->KeyIVConfig = 0U;
500 
501   /* Change the CRYP state */
502   hcryp->State = HAL_CRYP_STATE_READY;
503 
504   /* Set the default CRYP phase */
505   hcryp->Phase = CRYP_PHASE_READY;
506 
507   /* Return function status */
508   return HAL_OK;
509 }
510 
511 /**
512   * @brief  De-Initializes the CRYP peripheral.
513   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
514   *         the configuration information for CRYP module
515   * @retval HAL status
516 */
HAL_CRYP_DeInit(CRYP_HandleTypeDef * hcryp)517 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
518 {
519   /* Check the CRYP handle allocation */
520   if (hcryp == NULL)
521   {
522     return HAL_ERROR;
523   }
524 
525   /* Set the default CRYP phase */
526   hcryp->Phase = CRYP_PHASE_READY;
527 
528   /* Reset CrypInCount and CrypOutCount */
529   hcryp->CrypInCount = 0;
530   hcryp->CrypOutCount = 0;
531   hcryp->CrypHeaderCount = 0;
532 
533   /* Disable the CRYP peripheral clock */
534   __HAL_CRYP_DISABLE(hcryp);
535 
536 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
537 
538   if (hcryp->MspDeInitCallback == NULL)
539   {
540     hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit  */
541   }
542   /* DeInit the low level hardware */
543   hcryp->MspDeInitCallback(hcryp);
544 
545 #else
546 
547   /* DeInit the low level hardware: CLOCK, NVIC.*/
548   HAL_CRYP_MspDeInit(hcryp);
549 
550 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
551 
552   /* Change the CRYP state */
553   hcryp->State = HAL_CRYP_STATE_RESET;
554 
555   /* Release Lock */
556   __HAL_UNLOCK(hcryp);
557 
558   /* Return function status */
559   return HAL_OK;
560 }
561 
562 /**
563   * @brief  Configure the CRYP according to the specified
564   *         parameters in the CRYP_ConfigTypeDef
565   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
566   * @param  pConf pointer to a CRYP_ConfigTypeDef structure that contains
567   *         the configuration information for CRYP module
568   * @retval HAL status
569   */
HAL_CRYP_SetConfig(CRYP_HandleTypeDef * hcryp,CRYP_ConfigTypeDef * pConf)570 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
571 {
572   /* Check the CRYP handle allocation */
573   if ((hcryp == NULL) || (pConf == NULL))
574   {
575     return HAL_ERROR;
576   }
577 
578   /* Check parameters */
579   assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
580   assert_param(IS_CRYP_DATATYPE(pConf->DataType));
581   assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
582 
583   if (hcryp->State == HAL_CRYP_STATE_READY)
584   {
585     /* Change the CRYP state */
586     hcryp->State = HAL_CRYP_STATE_BUSY;
587 
588     /* Process locked */
589     __HAL_LOCK(hcryp);
590 
591     /* Set  CRYP parameters  */
592     hcryp->Init.DataType        = pConf->DataType;
593     hcryp->Init.pKey            = pConf->pKey;
594     hcryp->Init.Algorithm       = pConf->Algorithm;
595     hcryp->Init.KeySize         = pConf->KeySize;
596     hcryp->Init.pInitVect       = pConf->pInitVect;
597     hcryp->Init.Header          = pConf->Header;
598     hcryp->Init.HeaderSize      = pConf->HeaderSize;
599     hcryp->Init.B0              = pConf->B0;
600     hcryp->Init.DataWidthUnit   = pConf->DataWidthUnit;
601     hcryp->Init.HeaderWidthUnit = pConf->HeaderWidthUnit;
602     hcryp->Init.KeyIVConfigSkip = pConf->KeyIVConfigSkip;
603 
604     /* Set the key size (This bit field is do not care in the DES or TDES modes), data type and operating mode*/
605     MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD, hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
606 
607     /*clear error flags*/
608     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
609 
610     /* Process Unlocked */
611     __HAL_UNLOCK(hcryp);
612 
613     /* Reset Error Code field */
614     hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
615 
616     /* Change the CRYP state */
617     hcryp->State = HAL_CRYP_STATE_READY;
618 
619     /* Set the default CRYP phase */
620     hcryp->Phase = CRYP_PHASE_READY;
621 
622     /* Return function status */
623     return HAL_OK;
624   }
625   else
626   {
627     /* Process Unlocked */
628     __HAL_UNLOCK(hcryp);
629 
630     /* Busy error code field */
631     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
632     return HAL_ERROR;
633   }
634 }
635 
636 /**
637   * @brief  Get CRYP Configuration parameters in associated handle.
638   * @param  pConf pointer to a CRYP_ConfigTypeDef structure
639   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
640   *         the configuration information for CRYP module
641   * @retval HAL status
642   */
HAL_CRYP_GetConfig(CRYP_HandleTypeDef * hcryp,CRYP_ConfigTypeDef * pConf)643 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
644 {
645   /* Check the CRYP handle allocation */
646   if ((hcryp == NULL) || (pConf == NULL))
647   {
648     return HAL_ERROR;
649   }
650 
651   if (hcryp->State == HAL_CRYP_STATE_READY)
652   {
653     /* Change the CRYP state */
654     hcryp->State = HAL_CRYP_STATE_BUSY;
655 
656     /* Process locked */
657     __HAL_LOCK(hcryp);
658 
659     /* Get  CRYP parameters  */
660     pConf->DataType        = hcryp->Init.DataType;
661     pConf->pKey            = hcryp->Init.pKey;
662     pConf->Algorithm       = hcryp->Init.Algorithm;
663     pConf->KeySize         = hcryp->Init.KeySize ;
664     pConf->pInitVect       = hcryp->Init.pInitVect;
665     pConf->Header          = hcryp->Init.Header ;
666     pConf->HeaderSize      = hcryp->Init.HeaderSize;
667     pConf->B0              = hcryp->Init.B0;
668     pConf->DataWidthUnit   = hcryp->Init.DataWidthUnit;
669     pConf->HeaderWidthUnit = hcryp->Init.HeaderWidthUnit;
670     pConf->KeyIVConfigSkip = hcryp->Init.KeyIVConfigSkip;
671 
672     /* Process Unlocked */
673     __HAL_UNLOCK(hcryp);
674 
675     /* Change the CRYP state */
676     hcryp->State = HAL_CRYP_STATE_READY;
677 
678     /* Return function status */
679     return HAL_OK;
680   }
681   else
682   {
683     /* Process Unlocked */
684     __HAL_UNLOCK(hcryp);
685 
686     /* Busy error code field */
687     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
688     return HAL_ERROR;
689   }
690 }
691 /**
692   * @brief  Initializes the CRYP MSP.
693   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
694   *         the configuration information for CRYP module
695   * @retval None
696   */
HAL_CRYP_MspInit(CRYP_HandleTypeDef * hcryp)697 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
698 {
699   /* Prevent unused argument(s) compilation warning */
700   UNUSED(hcryp);
701 
702   /* NOTE : This function should not be modified; when the callback is needed,
703             the HAL_CRYP_MspInit can be implemented in the user file
704    */
705 }
706 
707 /**
708   * @brief  DeInitializes CRYP MSP.
709   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
710   *         the configuration information for CRYP module
711   * @retval None
712   */
HAL_CRYP_MspDeInit(CRYP_HandleTypeDef * hcryp)713 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
714 {
715   /* Prevent unused argument(s) compilation warning */
716   UNUSED(hcryp);
717 
718   /* NOTE : This function should not be modified; when the callback is needed,
719             the HAL_CRYP_MspDeInit can be implemented in the user file
720    */
721 }
722 
723 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
724 /**
725   * @brief  Register a User CRYP Callback
726   *         To be used instead of the weak predefined callback
727   * @param hcryp cryp handle
728   * @param CallbackID ID of the callback to be registered
729   *        This parameter can be one of the following values:
730   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
731   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
732   *          @arg @ref HAL_CRYP_ERROR_CB_ID Error callback ID
733   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
734   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
735   * @param pCallback pointer to the Callback function
736   * @retval status
737   */
HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef * hcryp,HAL_CRYP_CallbackIDTypeDef CallbackID,pCRYP_CallbackTypeDef pCallback)738 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID, pCRYP_CallbackTypeDef pCallback)
739 {
740   HAL_StatusTypeDef status = HAL_OK;
741 
742   if (pCallback == NULL)
743   {
744     /* Update the error code */
745     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
746 
747     return HAL_ERROR;
748   }
749   /* Process locked */
750   __HAL_LOCK(hcryp);
751 
752   if (hcryp->State == HAL_CRYP_STATE_READY)
753   {
754     switch (CallbackID)
755     {
756       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
757         hcryp->InCpltCallback = pCallback;
758         break;
759 
760       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
761         hcryp->OutCpltCallback = pCallback;
762         break;
763 
764       case HAL_CRYP_ERROR_CB_ID :
765         hcryp->ErrorCallback = pCallback;
766         break;
767 
768       case HAL_CRYP_MSPINIT_CB_ID :
769         hcryp->MspInitCallback = pCallback;
770         break;
771 
772       case HAL_CRYP_MSPDEINIT_CB_ID :
773         hcryp->MspDeInitCallback = pCallback;
774         break;
775 
776       default :
777         /* Update the error code */
778         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
779         /* Return error status */
780         status =  HAL_ERROR;
781         break;
782     }
783   }
784   else if (hcryp->State == HAL_CRYP_STATE_RESET)
785   {
786     switch (CallbackID)
787     {
788       case HAL_CRYP_MSPINIT_CB_ID :
789         hcryp->MspInitCallback = pCallback;
790         break;
791 
792       case HAL_CRYP_MSPDEINIT_CB_ID :
793         hcryp->MspDeInitCallback = pCallback;
794         break;
795 
796       default :
797         /* Update the error code */
798         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
799         /* Return error status */
800         status =  HAL_ERROR;
801         break;
802     }
803   }
804   else
805   {
806     /* Update the error code */
807     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
808     /* Return error status */
809     status =  HAL_ERROR;
810   }
811 
812   /* Release Lock */
813   __HAL_UNLOCK(hcryp);
814 
815   return status;
816 }
817 
818 /**
819   * @brief  Unregister an CRYP Callback
820   *         CRYP callback is redirected to the weak predefined callback
821   * @param hcryp cryp handle
822   * @param CallbackID ID of the callback to be unregistered
823   *        This parameter can be one of the following values:
824   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
825   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
826   *          @arg @ref HAL_CRYP_ERROR_CB_ID Error callback ID
827   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
828   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
829   * @retval status
830   */
HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef * hcryp,HAL_CRYP_CallbackIDTypeDef CallbackID)831 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
832 {
833   HAL_StatusTypeDef status = HAL_OK;
834 
835   /* Process locked */
836   __HAL_LOCK(hcryp);
837 
838   if (hcryp->State == HAL_CRYP_STATE_READY)
839   {
840     switch (CallbackID)
841     {
842       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
843         hcryp->InCpltCallback = HAL_CRYP_InCpltCallback;  /* Legacy weak  InCpltCallback  */
844         break;
845 
846       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
847         hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback;         /* Legacy weak OutCpltCallback       */
848         break;
849 
850       case HAL_CRYP_ERROR_CB_ID :
851         hcryp->ErrorCallback = HAL_CRYP_ErrorCallback;           /* Legacy weak ErrorCallback        */
852         break;
853 
854       case HAL_CRYP_MSPINIT_CB_ID :
855         hcryp->MspInitCallback = HAL_CRYP_MspInit;
856         break;
857 
858       case HAL_CRYP_MSPDEINIT_CB_ID :
859         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
860         break;
861 
862       default :
863         /* Update the error code */
864         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
865         /* Return error status */
866         status =  HAL_ERROR;
867         break;
868     }
869   }
870   else if (hcryp->State == HAL_CRYP_STATE_RESET)
871   {
872     switch (CallbackID)
873     {
874       case HAL_CRYP_MSPINIT_CB_ID :
875         hcryp->MspInitCallback = HAL_CRYP_MspInit;
876         break;
877 
878       case HAL_CRYP_MSPDEINIT_CB_ID :
879         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
880         break;
881 
882       default :
883         /* Update the error code */
884         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
885         /* Return error status */
886         status =  HAL_ERROR;
887         break;
888     }
889   }
890   else
891   {
892     /* Update the error code */
893     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
894     /* Return error status */
895     status =  HAL_ERROR;
896   }
897 
898   /* Release Lock */
899   __HAL_UNLOCK(hcryp);
900 
901   return status;
902 }
903 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
904 
905 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
906 /**
907   * @brief  Request CRYP processing suspension when in interruption mode.
908   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
909   *         the configuration information for CRYP module.
910   * @note   Set the handle field SuspendRequest to the appropriate value so that
911   *         the on-going CRYP processing is suspended as soon as the required
912   *         conditions are met.
913   * @note   HAL_CRYP_ProcessSuspend() can only be invoked when the processing is done
914   *         in non-blocking interrupt mode.
915   * @note   It is advised not to suspend the CRYP processing when the DMA controller
916   *         is managing the data transfer.
917   * @retval None
918   */
HAL_CRYP_ProcessSuspend(CRYP_HandleTypeDef * hcryp)919 void HAL_CRYP_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
920 {
921   /* Set Handle SuspendRequest field */
922   hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
923 }
924 
925 
926 
927 /**
928   * @brief  CRYP processing suspension and peripheral internal parameters storage.
929   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
930   *         the configuration information for CRYP module
931   * @note   peripheral internal parameters are stored to be readily available when
932   *         suspended processing is resumed later on.
933   * @retval HAL status
934   */
HAL_CRYP_Suspend(CRYP_HandleTypeDef * hcryp)935 HAL_StatusTypeDef HAL_CRYP_Suspend(CRYP_HandleTypeDef *hcryp)
936 {
937   HAL_CRYP_STATETypeDef state;
938 
939   /* Request suspension */
940   HAL_CRYP_ProcessSuspend(hcryp);
941 
942   do
943   {
944     state = HAL_CRYP_GetState(hcryp);
945   } while ((state != HAL_CRYP_STATE_SUSPENDED) && (state != HAL_CRYP_STATE_READY));
946 
947   if (HAL_CRYP_GetState(hcryp) == HAL_CRYP_STATE_READY)
948   {
949     /* Processing was already over or was about to end. No suspension done */
950     return HAL_ERROR;
951   }
952   else
953   {
954     /* Suspend Processing */
955 
956     /* If authentication algorithms on-going, carry out first saving steps
957        before disable the peripheral */
958     if ((hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC) || \
959          (hcryp->Init.Algorithm == CRYP_AES_CCM))
960     {
961         /* Save Suspension registers */
962         CRYP_Read_SuspendRegisters(hcryp, hcryp->SUSPxR_saved);
963         /* Save Key */
964         CRYP_Read_KeyRegisters(hcryp, hcryp->Key_saved, hcryp->Init.KeySize);
965         /* Save IV */
966         CRYP_Read_IVRegisters(hcryp, hcryp->IV_saved);
967     }
968     /* Disable AES */
969     __HAL_CRYP_DISABLE(hcryp);
970 
971     /* Save low-priority block CRYP handle parameters */
972     hcryp->Init_saved              = hcryp->Init;
973     hcryp->pCrypInBuffPtr_saved    = hcryp->pCrypInBuffPtr;
974     hcryp->pCrypOutBuffPtr_saved   = hcryp->pCrypOutBuffPtr;
975     hcryp->CrypInCount_saved       = hcryp->CrypInCount;
976     hcryp->CrypOutCount_saved      = hcryp->CrypOutCount;
977     hcryp->Phase_saved             = hcryp->Phase;
978     hcryp->State_saved             = hcryp->State;
979     hcryp->Size_saved              = ( (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) ? (hcryp->Size /4U) : hcryp->Size);
980     hcryp->SizesSum_saved          = hcryp->SizesSum;
981     hcryp->AutoKeyDerivation_saved = hcryp->AutoKeyDerivation;
982     hcryp->CrypHeaderCount_saved   = hcryp->CrypHeaderCount;
983     hcryp->SuspendRequest          = HAL_CRYP_SUSPEND_NONE;
984 
985     if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
986         (hcryp->Init.Algorithm == CRYP_AES_CTR))
987     {
988       /* Save Initialisation Vector registers */
989       CRYP_Read_IVRegisters(hcryp, hcryp->IV_saved);
990     }
991 
992     /* Save Control register */
993     hcryp->CR_saved = hcryp->Instance->CR;
994 
995   }
996   return HAL_OK;
997 }
998 
999 
1000 /**
1001   * @brief  CRYP processing resumption.
1002   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1003   *         the configuration information for CRYP module
1004   * @note   Processing restarts at the exact point where it was suspended, based
1005   *         on the parameters saved at suspension time.
1006   * @retval HAL status
1007   */
HAL_CRYP_Resume(CRYP_HandleTypeDef * hcryp)1008 HAL_StatusTypeDef HAL_CRYP_Resume(CRYP_HandleTypeDef *hcryp)
1009 {
1010   /* Check the CRYP handle allocation */
1011   if (hcryp == NULL)
1012   {
1013     return HAL_ERROR;
1014   }
1015 
1016   if (hcryp->State_saved != HAL_CRYP_STATE_SUSPENDED)
1017   {
1018     /* CRYP was not suspended */
1019     return HAL_ERROR;
1020   }
1021   else
1022   {
1023 
1024     /* Restore low-priority block CRYP handle parameters */
1025     hcryp->Init            = hcryp->Init_saved;
1026     hcryp->State           = hcryp->State_saved;
1027 
1028     /* Chaining algorithms case */
1029     if ((hcryp->Init_saved.Algorithm == CRYP_AES_ECB) || \
1030         (hcryp->Init_saved.Algorithm == CRYP_AES_CBC) || \
1031         (hcryp->Init_saved.Algorithm == CRYP_AES_CTR))
1032     {
1033       /* Restore low-priority block CRYP handle parameters */
1034       hcryp->AutoKeyDerivation = hcryp->AutoKeyDerivation_saved;
1035 
1036       if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
1037         (hcryp->Init.Algorithm == CRYP_AES_CTR))
1038       {
1039         hcryp->Init.pInitVect     = hcryp->IV_saved;
1040       }
1041       __HAL_CRYP_DISABLE(hcryp);
1042       (void) HAL_CRYP_Init(hcryp);
1043     }
1044     else    /* Authentication algorithms case */
1045     {
1046       /* Restore low-priority block CRYP handle parameters */
1047       hcryp->Phase           = hcryp->Phase_saved;
1048       hcryp->CrypHeaderCount = hcryp->CrypHeaderCount_saved;
1049       hcryp->SizesSum        = hcryp->SizesSum_saved;
1050 
1051       /* Disable AES and write-back SUSPxR registers */;
1052       __HAL_CRYP_DISABLE(hcryp);
1053       /* Restore AES Suspend Registers */
1054       CRYP_Write_SuspendRegisters(hcryp, hcryp->SUSPxR_saved);
1055       /* Restore Control,  Key and IV Registers, then enable AES */
1056       hcryp->Instance->CR = hcryp->CR_saved;
1057       CRYP_Write_KeyRegisters(hcryp, hcryp->Key_saved, hcryp->Init.KeySize);
1058       CRYP_Write_IVRegisters(hcryp, hcryp->IV_saved);
1059 
1060       /* At the same time, set handle state back to READY to be able to resume the AES calculations
1061       without the processing APIs returning HAL_BUSY when called. */
1062       hcryp->State        = HAL_CRYP_STATE_READY;
1063     }
1064 
1065 
1066     /* Resume low-priority block processing under IT */
1067     hcryp->ResumingFlag = 1U;
1068     if (READ_BIT(hcryp->CR_saved, AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
1069     {
1070       if (HAL_CRYP_Encrypt_IT(hcryp, hcryp->pCrypInBuffPtr_saved, hcryp->Size_saved, hcryp->pCrypOutBuffPtr_saved) != HAL_OK)
1071       {
1072         return HAL_ERROR;
1073       }
1074     }
1075     else
1076     {
1077       if (HAL_CRYP_Decrypt_IT(hcryp, hcryp->pCrypInBuffPtr_saved, hcryp->Size_saved, hcryp->pCrypOutBuffPtr_saved) != HAL_OK)
1078       {
1079         return HAL_ERROR;
1080       }
1081     }
1082   }
1083   return HAL_OK;
1084 }
1085 #endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */
1086 
1087 /**
1088   * @brief  CRYP peripheral parameters storage when processing Interleaved mode .
1089   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1090   *         the configuration information for CRYP module
1091   * @param  pcont pointer to a CRYP_ContextTypeDef structure where CRYP parameters will be stored.
1092   * @retval HAL status
1093   */
HAL_CRYP_SaveContext(CRYP_HandleTypeDef * hcryp,CRYP_ContextTypeDef * pcont)1094 HAL_StatusTypeDef  HAL_CRYP_SaveContext(CRYP_HandleTypeDef *hcryp, CRYP_ContextTypeDef *pcont)
1095 {
1096   /* Check the CRYP handle allocation */
1097   if ((hcryp == NULL) || (pcont == NULL))
1098   {
1099     return HAL_ERROR;
1100   }
1101 
1102   if (hcryp->State == HAL_CRYP_STATE_READY)
1103   {
1104     /* Save CRYP handle parameters */
1105     pcont->DataType        = (uint32_t)(hcryp->Init.DataType);
1106     pcont->KeySize         = (uint32_t)(hcryp->Init.KeySize);
1107     pcont->pKey            = hcryp->Init.pKey;
1108     pcont->pInitVect       = hcryp->Init.pInitVect;
1109     pcont->Algorithm       = (uint32_t)(hcryp->Init.Algorithm);
1110     pcont->DataWidthUnit   = (uint32_t)(hcryp->Init.DataWidthUnit);
1111     pcont->KeyIVConfigSkip = (uint32_t)(hcryp->Init.KeyIVConfigSkip);
1112     pcont->Phase           = (uint32_t)(hcryp->Phase);
1113     pcont->KeyIVConfig     = (uint32_t)(hcryp->KeyIVConfig);
1114 
1115     /* Save CRYP CR register content */
1116     pcont->CR_Reg = READ_REG(hcryp->Instance->CR);
1117 
1118     if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
1119         (hcryp->Init.Algorithm == CRYP_AES_CTR))
1120     {
1121       /* Save Initialisation Vector registers */
1122       pcont->IVR0_Reg = READ_REG(hcryp->Instance->IVR0);
1123       pcont->IVR1_Reg = READ_REG(hcryp->Instance->IVR1);
1124       pcont->IVR2_Reg = READ_REG(hcryp->Instance->IVR2);
1125       pcont->IVR3_Reg = READ_REG(hcryp->Instance->IVR3);
1126     }
1127 
1128     /* To load Key for next piece of message */
1129     hcryp->KeyIVConfig = 0;
1130 
1131     return HAL_OK;
1132   }
1133   else
1134   {
1135     /* Busy error code field */
1136     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1137     return HAL_ERROR;
1138   }
1139 
1140 }
1141 
1142 /**
1143   * @brief  Restore CRYP parameters needed for Interleaved mode.
1144   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1145   *         the configuration information for CRYP module
1146   * @param  pcont pointer to a CRYP_ContextTypeDef structure that contains CRYP parameters stored.
1147   * @retval HAL status
1148   */
HAL_CRYP_RestoreContext(CRYP_HandleTypeDef * hcryp,CRYP_ContextTypeDef * pcont)1149 HAL_StatusTypeDef HAL_CRYP_RestoreContext(CRYP_HandleTypeDef *hcryp, CRYP_ContextTypeDef *pcont)
1150 {
1151   /* Check the CRYP handle allocation */
1152   if ((hcryp == NULL) || (pcont == NULL))
1153   {
1154     return HAL_ERROR;
1155   }
1156 
1157   if (hcryp->State == HAL_CRYP_STATE_READY)
1158   {
1159     /* Restore CRYP handle parameters */
1160     hcryp->Init.DataType        = pcont->DataType;
1161     hcryp->Init.KeySize         = pcont->KeySize;
1162     hcryp->Init.pKey            = pcont->pKey;
1163     hcryp->Init.pInitVect       = pcont->pInitVect;
1164     hcryp->Init.Algorithm       = pcont->Algorithm;
1165     hcryp->Init.DataWidthUnit   = pcont->DataWidthUnit;
1166     hcryp->Init.KeyIVConfigSkip = pcont->KeyIVConfigSkip;
1167     hcryp->Phase                = pcont->Phase;
1168     hcryp->KeyIVConfig          = pcont->KeyIVConfig;
1169 
1170     /* Restore CRYP CR register content */
1171     WRITE_REG(hcryp->Instance->CR, (uint32_t)(pcont->CR_Reg));
1172 
1173     if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
1174         (hcryp->Init.Algorithm == CRYP_AES_CTR))
1175     {
1176       /* Restore Initialisation Vector registers */
1177       WRITE_REG(hcryp->Instance->IVR0, (uint32_t)(pcont->IVR0_Reg));
1178       WRITE_REG(hcryp->Instance->IVR1, (uint32_t)(pcont->IVR1_Reg));
1179       WRITE_REG(hcryp->Instance->IVR2, (uint32_t)(pcont->IVR2_Reg));
1180       WRITE_REG(hcryp->Instance->IVR3, (uint32_t)(pcont->IVR3_Reg));
1181     }
1182     return HAL_OK;
1183   }
1184   else
1185   {
1186     /* Busy error code field */
1187     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1188     return HAL_ERROR;
1189   }
1190 }
1191 
1192 /**
1193   * @}
1194   */
1195 
1196 /** @defgroup CRYP_Exported_Functions_Group2 Encryption Decryption functions
1197   * @brief    Encryption Decryption functions.
1198   *
1199 @verbatim
1200   ==============================================================================
1201                       ##### Encrypt Decrypt  functions #####
1202   ==============================================================================
1203     [..]  This section provides API allowing to Encrypt/Decrypt Data following
1204           Standard DES/TDES or AES, and Algorithm configured by the user:
1205       (+) Standard DES/TDES only supported by CRYP1 peripheral, below list of Algorithm supported :
1206            - Electronic Code Book(ECB)
1207            - Cipher Block Chaining (CBC)
1208       (+) Standard AES  supported by CRYP1 peripheral & TinyAES, list of Algorithm supported:
1209            - Electronic Code Book(ECB)
1210            - Cipher Block Chaining (CBC)
1211            - Counter mode (CTR)
1212            - Cipher Block Chaining (CBC)
1213            - Counter mode (CTR)
1214            - Galois/counter mode (GCM)
1215            - Counter with Cipher Block Chaining-Message(CCM)
1216     [..]  Three processing functions are available:
1217       (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
1218       (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
1219       (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
1220 
1221 @endverbatim
1222   * @{
1223   */
1224 
1225 /* GCM message structure additional details
1226 
1227                                   ICB
1228           +-------------------------------------------------------+
1229           |       Initialization vector (IV)      |  Counter      |
1230           |----------------|----------------|-----------|---------|
1231          127              95                63            31       0
1232 
1233 
1234               Bit Number    Register           Contents
1235               ----------   ---------------       -----------
1236               127 ...96    CRYP_IV1R[31:0]     ICB[127:96]
1237               95  ...64    CRYP_IV1L[31:0]     B0[95:64]
1238               63 ... 32    CRYP_IV0R[31:0]     ICB[63:32]
1239               31 ... 0     CRYP_IV0L[31:0]     ICB[31:0], where 32-bit counter= 0x2
1240 
1241 
1242 
1243                                  GCM last block definition
1244           +-------------------------------------------------------------------+
1245           |  Bit[0]   |  Bit[32]           |  Bit[64]  | Bit[96]              |
1246           |-----------|--------------------|-----------|----------------------|
1247           |   0x0     | Header length[31:0]|     0x0   | Payload length[31:0] |
1248           |-----------|--------------------|-----------|----------------------|
1249 
1250 */
1251 
1252 /* CCM message blocks description
1253 
1254          (##) B0 block  : According to NIST Special Publication 800-38C,
1255             The first block B0 is formatted as follows, where l(m) is encoded in
1256             most-significant-byte first order:
1257 
1258                 Octet Number   Contents
1259                 ------------   ---------
1260                 0              Flags
1261                 1 ... 15-q     Nonce N
1262                 16-q ... 15    Q
1263 
1264             the Flags field is formatted as follows:
1265 
1266                 Bit Number   Contents
1267                 ----------   ----------------------
1268                 7            Reserved (always zero)
1269                 6            Adata
1270                 5 ... 3      (t-2)/2
1271                 2 ... 0      [q-1]3
1272 
1273               - Q: a bit string representation of the octet length of P (plaintext)
1274               - q The octet length of the binary representation of the octet length of the payload
1275               - A nonce (N), n The octet length of the where n+q=15.
1276               - Flags: most significant octet containing four flags for control information,
1277               - t The octet length of the MAC.
1278          (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
1279               the associated data length expressed in bytes (a) defined as below:
1280             - If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
1281             - If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
1282             - If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
1283          (##) CTRx block  : control blocks
1284             - Generation of CTR1 from first block B0 information :
1285               equal to B0 with first 5 bits zeroed and most significant bits storing octet
1286               length of P also zeroed, then incremented by one
1287 
1288                 Bit Number    Register           Contents
1289                 ----------   ---------------       -----------
1290                 127 ...96    CRYP_IV1R[31:0]     B0[127:96], where Q length bits are set to 0, except for
1291                                                  bit 0 that is set to 1
1292                 95  ...64    CRYP_IV1L[31:0]     B0[95:64]
1293                 63 ... 32    CRYP_IV0R[31:0]     B0[63:32]
1294                 31 ... 0     CRYP_IV0L[31:0]     B0[31:0], where flag bits set to 0
1295 
1296             - Generation of CTR0: same as CTR1 with bit[0] set to zero.
1297 
1298 */
1299 
1300 /**
1301   * @brief  Encryption mode.
1302   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1303   *         the configuration information for CRYP module
1304   * @param  Input Pointer to the input buffer (plaintext)
1305   * @param  Size Length of the plaintext buffer in bytes or words (depending upon DataWidthUnit field)
1306   * @param  Output Pointer to the output buffer(ciphertext)
1307   * @param  Timeout Specify Timeout value
1308   * @retval HAL status
1309   */
HAL_CRYP_Encrypt(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output,uint32_t Timeout)1310 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output, uint32_t Timeout)
1311 {
1312   uint32_t algo;
1313   HAL_StatusTypeDef status;
1314 #ifdef  USE_FULL_ASSERT
1315   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1316 
1317   /* Check input buffer size */
1318   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1319 #endif /* USE_FULL_ASSERT */
1320 
1321   if (hcryp->State == HAL_CRYP_STATE_READY)
1322   {
1323     /* Change state Busy */
1324     hcryp->State = HAL_CRYP_STATE_BUSY;
1325 
1326     /* Process locked */
1327     __HAL_LOCK(hcryp);
1328 
1329     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1330     hcryp->CrypInCount = 0U;
1331     hcryp->CrypOutCount = 0U;
1332     hcryp->pCrypInBuffPtr = Input;
1333     hcryp->pCrypOutBuffPtr = Output;
1334 
1335     /*  Calculate Size parameter in Byte*/
1336     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1337     {
1338       hcryp->Size = Size * 4U;
1339     }
1340     else
1341     {
1342       hcryp->Size = Size;
1343     }
1344 
1345     /* Set the operating mode*/
1346     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
1347 
1348     /* algo get algorithm selected */
1349     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1350 
1351     switch (algo)
1352     {
1353 
1354       case CRYP_AES_ECB:
1355       case CRYP_AES_CBC:
1356       case CRYP_AES_CTR:
1357 
1358         /* AES encryption */
1359         status = CRYP_AES_Encrypt(hcryp, Timeout);
1360         break;
1361 
1362       case CRYP_AES_GCM_GMAC:
1363 
1364         /* AES GCM encryption */
1365         status = CRYP_AESGCM_Process(hcryp, Timeout) ;
1366         break;
1367 
1368       case CRYP_AES_CCM:
1369 
1370         /* AES CCM encryption */
1371         status = CRYP_AESCCM_Process(hcryp, Timeout);
1372         break;
1373 
1374       default:
1375         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1376         status = HAL_ERROR;
1377         break;
1378     }
1379 
1380     if (status == HAL_OK)
1381     {
1382       /* Change the CRYP peripheral state */
1383       hcryp->State = HAL_CRYP_STATE_READY;
1384 
1385       /* Process unlocked */
1386       __HAL_UNLOCK(hcryp);
1387     }
1388   }
1389   else
1390   {
1391     /* Busy error code field */
1392     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1393     status = HAL_ERROR;
1394   }
1395 
1396   /* Return function status */
1397   return status;
1398 }
1399 
1400 /**
1401   * @brief  Decryption mode.
1402   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1403   *         the configuration information for CRYP module
1404   * @param  Input Pointer to the input buffer (ciphertext )
1405   * @param  Size Length of the plaintext buffer in bytes or words (depending upon DataWidthUnit field)
1406   * @param  Output Pointer to the output buffer(plaintext)
1407   * @param  Timeout Specify Timeout value
1408   * @retval HAL status
1409   */
HAL_CRYP_Decrypt(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output,uint32_t Timeout)1410 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output, uint32_t Timeout)
1411 {
1412   HAL_StatusTypeDef status;
1413   uint32_t algo;
1414 #ifdef  USE_FULL_ASSERT
1415   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1416 
1417   /* Check input buffer size */
1418   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1419 #endif /* USE_FULL_ASSERT */
1420 
1421   if (hcryp->State == HAL_CRYP_STATE_READY)
1422   {
1423     /* Change state Busy */
1424     hcryp->State = HAL_CRYP_STATE_BUSY;
1425 
1426     /* Process locked */
1427     __HAL_LOCK(hcryp);
1428 
1429     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr  parameters*/
1430     hcryp->CrypInCount = 0U;
1431     hcryp->CrypOutCount = 0U;
1432     hcryp->pCrypInBuffPtr = Input;
1433     hcryp->pCrypOutBuffPtr = Output;
1434 
1435     /*  Calculate Size parameter in Byte*/
1436     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1437     {
1438       hcryp->Size = Size * 4U;
1439     }
1440     else
1441     {
1442       hcryp->Size = Size;
1443     }
1444 
1445     /* Set Decryption operating mode*/
1446     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
1447 
1448     /* algo get algorithm selected */
1449     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1450 
1451     switch (algo)
1452     {
1453 
1454       case CRYP_AES_ECB:
1455       case CRYP_AES_CBC:
1456       case CRYP_AES_CTR:
1457 
1458         /* AES decryption */
1459         status = CRYP_AES_Decrypt(hcryp, Timeout);
1460         break;
1461 
1462       case CRYP_AES_GCM_GMAC:
1463 
1464         /* AES GCM decryption */
1465         status = CRYP_AESGCM_Process(hcryp, Timeout) ;
1466         break;
1467 
1468       case CRYP_AES_CCM:
1469 
1470         /* AES CCM decryption */
1471         status = CRYP_AESCCM_Process(hcryp, Timeout);
1472         break;
1473 
1474       default:
1475         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1476         status = HAL_ERROR;
1477         break;
1478     }
1479 
1480     if (status == HAL_OK)
1481     {
1482       /* Change the CRYP peripheral state */
1483       hcryp->State = HAL_CRYP_STATE_READY;
1484 
1485       /* Process unlocked */
1486       __HAL_UNLOCK(hcryp);
1487     }
1488   }
1489   else
1490   {
1491     /* Busy error code field */
1492     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1493     status = HAL_ERROR;
1494   }
1495 
1496   /* Return function status */
1497   return status;
1498 }
1499 
1500 /**
1501   * @brief  Encryption in interrupt mode.
1502   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1503   *         the configuration information for CRYP module
1504   * @param  Input Pointer to the input buffer (plaintext)
1505   * @param  Size Length of the plaintext buffer in bytes or words (depending upon DataWidthUnit field)
1506   * @param  Output Pointer to the output buffer(ciphertext)
1507   * @retval HAL status
1508   */
HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1509 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1510 {
1511   HAL_StatusTypeDef status;
1512   uint32_t algo;
1513 #ifdef  USE_FULL_ASSERT
1514   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1515 
1516   /* Check input buffer size */
1517   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1518 #endif /* USE_FULL_ASSERT */
1519 
1520   if (hcryp->State == HAL_CRYP_STATE_READY)
1521   {
1522     /* Change state Busy */
1523     hcryp->State = HAL_CRYP_STATE_BUSY;
1524 
1525     /* Process locked */
1526     __HAL_LOCK(hcryp);
1527 
1528     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1529 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
1530    if (hcryp->ResumingFlag == 1U)
1531    {
1532      hcryp->ResumingFlag = 0U;
1533      if (hcryp->Phase != CRYP_PHASE_HEADER_SUSPENDED)
1534      {
1535        hcryp->CrypInCount = (uint16_t) hcryp->CrypInCount_saved;
1536        hcryp->CrypOutCount = (uint16_t) hcryp->CrypOutCount_saved;
1537      }
1538      else
1539      {
1540     hcryp->CrypInCount = 0U;
1541     hcryp->CrypOutCount = 0U;
1542      }
1543    }
1544    else
1545 #endif  /* USE_HAL_CRYP_SUSPEND_RESUME */
1546    {
1547     hcryp->CrypInCount = 0U;
1548     hcryp->CrypOutCount = 0U;
1549    }
1550 
1551     hcryp->pCrypInBuffPtr = Input;
1552     hcryp->pCrypOutBuffPtr = Output;
1553 
1554     /*  Calculate Size parameter in Byte*/
1555     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1556     {
1557       hcryp->Size = Size * 4U;
1558     }
1559     else
1560     {
1561       hcryp->Size = Size;
1562     }
1563 
1564     /* Set encryption operating mode*/
1565     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
1566 
1567     /* algo get algorithm selected */
1568     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1569 
1570     switch (algo)
1571     {
1572 
1573       case CRYP_AES_ECB:
1574       case CRYP_AES_CBC:
1575       case CRYP_AES_CTR:
1576 
1577         /* AES encryption */
1578         status = CRYP_AES_Encrypt_IT(hcryp);
1579         break;
1580 
1581       case CRYP_AES_GCM_GMAC:
1582 
1583         /* AES GCM encryption */
1584         status = CRYP_AESGCM_Process_IT(hcryp) ;
1585         break;
1586 
1587       case CRYP_AES_CCM:
1588 
1589         /* AES CCM encryption */
1590         status = CRYP_AESCCM_Process_IT(hcryp);
1591         break;
1592 
1593       default:
1594         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1595         status = HAL_ERROR;
1596         break;
1597     }
1598   }
1599   else
1600   {
1601     /* Busy error code field */
1602     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1603     status = HAL_ERROR;
1604   }
1605 
1606   /* Return function status */
1607   return status;
1608 }
1609 
1610 /**
1611   * @brief  Decryption in interrupt mode.
1612   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1613   *         the configuration information for CRYP module
1614   * @param  Input Pointer to the input buffer (ciphertext )
1615   * @param  Size Length of the plaintext buffer in bytes or words (depending upon DataWidthUnit field)
1616   * @param  Output Pointer to the output buffer(plaintext)
1617   * @retval HAL status
1618   */
HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1619 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1620 {
1621   HAL_StatusTypeDef status;
1622   uint32_t algo;
1623 #ifdef  USE_FULL_ASSERT
1624   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1625 
1626   /* Check input buffer size */
1627   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1628 #endif /* USE_FULL_ASSERT */
1629 
1630   if (hcryp->State == HAL_CRYP_STATE_READY)
1631   {
1632     /* Change state Busy */
1633     hcryp->State = HAL_CRYP_STATE_BUSY;
1634 
1635     /* Process locked */
1636     __HAL_LOCK(hcryp);
1637 
1638     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1639 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
1640    if (hcryp->ResumingFlag == 1U)
1641    {
1642      hcryp->ResumingFlag = 0U;
1643      if (hcryp->Phase != CRYP_PHASE_HEADER_SUSPENDED)
1644      {
1645        hcryp->CrypInCount = (uint16_t) hcryp->CrypInCount_saved;
1646        hcryp->CrypOutCount = (uint16_t) hcryp->CrypOutCount_saved;
1647      }
1648      else
1649      {
1650     hcryp->CrypInCount = 0U;
1651     hcryp->CrypOutCount = 0U;
1652      }
1653    }
1654    else
1655 #endif  /* USE_HAL_CRYP_SUSPEND_RESUME */
1656    {
1657      hcryp->CrypInCount = 0U;
1658      hcryp->CrypOutCount = 0U;
1659    }
1660     hcryp->pCrypInBuffPtr = Input;
1661     hcryp->pCrypOutBuffPtr = Output;
1662 
1663     /*  Calculate Size parameter in Byte*/
1664     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1665     {
1666       hcryp->Size = Size * 4U;
1667     }
1668     else
1669     {
1670       hcryp->Size = Size;
1671     }
1672 
1673     /* Set decryption operating mode*/
1674     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
1675 
1676     /* algo get algorithm selected */
1677     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1678 
1679     switch (algo)
1680     {
1681 
1682       case CRYP_AES_ECB:
1683       case CRYP_AES_CBC:
1684       case CRYP_AES_CTR:
1685 
1686         /* AES decryption */
1687         status = CRYP_AES_Decrypt_IT(hcryp);
1688         break;
1689 
1690       case CRYP_AES_GCM_GMAC:
1691 
1692         /* AES GCM decryption */
1693         status = CRYP_AESGCM_Process_IT(hcryp) ;
1694         break;
1695 
1696       case CRYP_AES_CCM:
1697 
1698         /* AES CCM decryption */
1699         status = CRYP_AESCCM_Process_IT(hcryp);
1700         break;
1701 
1702       default:
1703         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1704         status = HAL_ERROR;
1705         break;
1706     }
1707   }
1708   else
1709   {
1710     /* Busy error code field */
1711     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1712     status = HAL_ERROR;
1713   }
1714 
1715   /* Return function status */
1716   return status;
1717 }
1718 
1719 /**
1720   * @brief  Encryption in DMA mode.
1721   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1722   *         the configuration information for CRYP module
1723   * @param  Input Pointer to the input buffer (plaintext)
1724   * @param  Size Length of the plaintext buffer in bytes or words (depending upon DataWidthUnit field)
1725   * @param  Output Pointer to the output buffer(ciphertext)
1726   * @retval HAL status
1727   */
HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1728 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1729 {
1730   HAL_StatusTypeDef status;
1731   uint32_t algo;
1732   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1733 #ifdef  USE_FULL_ASSERT
1734   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1735 
1736   /* Check input buffer size */
1737   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1738 #endif /* USE_FULL_ASSERT */
1739 
1740   if (hcryp->State == HAL_CRYP_STATE_READY)
1741   {
1742     /* Change state Busy */
1743     hcryp->State = HAL_CRYP_STATE_BUSY;
1744 
1745     /* Process locked */
1746     __HAL_LOCK(hcryp);
1747 
1748     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1749     hcryp->CrypInCount = 0U;
1750     hcryp->CrypOutCount = 0U;
1751     hcryp->pCrypInBuffPtr = Input;
1752     hcryp->pCrypOutBuffPtr = Output;
1753 
1754     /*  Calculate Size parameter in Byte*/
1755     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1756     {
1757       hcryp->Size = Size * 4U;
1758     }
1759     else
1760     {
1761       hcryp->Size = Size;
1762     }
1763 
1764     /* Set encryption operating mode*/
1765     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
1766 
1767     /* algo get algorithm selected */
1768     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1769 
1770     switch (algo)
1771     {
1772 
1773       case CRYP_AES_ECB:
1774       case CRYP_AES_CBC:
1775       case CRYP_AES_CTR:
1776 
1777         if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1778         {
1779           if (hcryp->KeyIVConfig == 1U)
1780           {
1781             /* If the Key and IV configuration has to be done only once
1782                and if it has already been done, skip it */
1783             DoKeyIVConfig = 0U;
1784           }
1785           else
1786           {
1787             /* If the Key and IV configuration has to be done only once
1788                and if it has not been done already, do it and set KeyIVConfig
1789                to keep track it won't have to be done again next time */
1790             hcryp->KeyIVConfig = 1U;
1791           }
1792         }
1793 
1794         if (DoKeyIVConfig == 1U)
1795         {
1796           /*  Set the Key*/
1797           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1798 
1799           /* Set the Initialization Vector*/
1800           if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1801           {
1802             hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
1803             hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
1804             hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
1805             hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
1806           }
1807         } /* if (DoKeyIVConfig == 1U) */
1808 
1809         /* Set the phase */
1810         hcryp->Phase = CRYP_PHASE_PROCESS;
1811 
1812         /* Start DMA process transfer for AES */
1813         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
1814         status = HAL_OK;
1815         break;
1816 
1817       case CRYP_AES_GCM_GMAC:
1818 
1819         /* AES GCM encryption */
1820         status = CRYP_AESGCM_Process_DMA(hcryp) ;
1821         break;
1822 
1823       case CRYP_AES_CCM:
1824 
1825         /* AES CCM encryption */
1826         status = CRYP_AESCCM_Process_DMA(hcryp);
1827         break;
1828 
1829       default:
1830         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1831         status = HAL_ERROR;
1832         break;
1833     }
1834   }
1835   else
1836   {
1837     /* Busy error code field */
1838     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1839     status = HAL_ERROR;
1840   }
1841 
1842   /* Return function status */
1843   return status;
1844 }
1845 
1846 /**
1847   * @brief  Decryption in DMA mode.
1848   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1849   *         the configuration information for CRYP module
1850   * @param  Input Pointer to the input buffer (ciphertext )
1851   * @param  Size Length of the plaintext buffer in bytes or words (depending upon DataWidthUnit field)
1852   * @param  Output Pointer to the output buffer(plaintext)
1853   * @retval HAL status
1854   */
HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1855 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1856 {
1857   HAL_StatusTypeDef status;
1858   uint32_t algo;
1859 #ifdef  USE_FULL_ASSERT
1860   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1861 
1862   /* Check input buffer size */
1863   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1864 #endif /* USE_FULL_ASSERT */
1865 
1866   if (hcryp->State == HAL_CRYP_STATE_READY)
1867   {
1868 
1869     /* Change state Busy */
1870     hcryp->State = HAL_CRYP_STATE_BUSY;
1871 
1872     /* Process locked */
1873     __HAL_LOCK(hcryp);
1874 
1875     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1876     hcryp->CrypInCount = 0U;
1877     hcryp->CrypOutCount = 0U;
1878     hcryp->pCrypInBuffPtr = Input;
1879     hcryp->pCrypOutBuffPtr = Output;
1880 
1881     /*  Calculate Size parameter in Byte*/
1882     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1883     {
1884       hcryp->Size = Size * 4U;
1885     }
1886     else
1887     {
1888       hcryp->Size = Size;
1889     }
1890 
1891     /* Set decryption operating mode*/
1892     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
1893 
1894     /* algo get algorithm selected */
1895     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1896 
1897     switch (algo)
1898     {
1899 
1900       case CRYP_AES_ECB:
1901       case CRYP_AES_CBC:
1902       case CRYP_AES_CTR:
1903 
1904         /* AES decryption */
1905         status = CRYP_AES_Decrypt_DMA(hcryp);
1906         break;
1907 
1908       case CRYP_AES_GCM_GMAC:
1909 
1910         /* AES GCM decryption */
1911         status = CRYP_AESGCM_Process_DMA(hcryp) ;
1912         break;
1913 
1914       case CRYP_AES_CCM:
1915 
1916         /* AES CCM decryption */
1917         status = CRYP_AESCCM_Process_DMA(hcryp);
1918         break;
1919 
1920       default:
1921         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1922         status = HAL_ERROR;
1923         break;
1924     }
1925   }
1926   else
1927   {
1928     /* Busy error code field */
1929     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1930     status = HAL_ERROR;
1931   }
1932   /* Return function status */
1933   return status;
1934 }
1935 
1936 /**
1937   * @}
1938   */
1939 
1940 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
1941   * @brief    CRYP IRQ handler.
1942   *
1943 @verbatim
1944   ==============================================================================
1945                 ##### CRYP IRQ handler management #####
1946   ==============================================================================
1947 [..]  This section provides CRYP IRQ handler and callback functions.
1948       (+) HAL_CRYP_IRQHandler CRYP interrupt request
1949       (+) HAL_CRYP_InCpltCallback input data transfer complete callback
1950       (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
1951       (+) HAL_CRYP_ErrorCallback  CRYP error callback
1952       (+) HAL_CRYP_GetState return the CRYP state
1953       (+) HAL_CRYP_GetError return the CRYP error code
1954 @endverbatim
1955   * @{
1956   */
1957 
1958 /**
1959   * @brief  This function handles cryptographic interrupt request.
1960   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1961   *         the configuration information for CRYP module
1962   * @retval None
1963   */
HAL_CRYP_IRQHandler(CRYP_HandleTypeDef * hcryp)1964 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
1965 {
1966 
1967   /* Check if error occurred */
1968   if (__HAL_CRYP_GET_IT_SOURCE(hcryp,CRYP_IT_ERRIE) != RESET)
1969   {
1970     /* If write Error occurred */
1971     if (__HAL_CRYP_GET_FLAG(hcryp,CRYP_IT_WRERR) != RESET)
1972     {
1973       hcryp->ErrorCode |= HAL_CRYP_ERROR_WRITE;
1974     }
1975     /* If read Error occurred */
1976     if (__HAL_CRYP_GET_FLAG(hcryp,CRYP_IT_RDERR) != RESET)
1977     {
1978       hcryp->ErrorCode |= HAL_CRYP_ERROR_READ;
1979     }
1980   }
1981 
1982   if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_IT_CCF) != RESET)
1983   {
1984     if(__HAL_CRYP_GET_IT_SOURCE(hcryp, CRYP_IT_CCFIE) != RESET)
1985   {
1986     /* Clear computation complete flag */
1987     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1988 
1989     if ((hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC) || (hcryp->Init.Algorithm == CRYP_AES_CCM))
1990     {
1991 
1992       /* if header phase */
1993       if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
1994       {
1995         CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
1996       }
1997       else  /* if payload phase */
1998       {
1999         CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
2000       }
2001     }
2002     else  /* AES Algorithm ECB,CBC or CTR*/
2003     {
2004       CRYP_AES_IT(hcryp);
2005     }
2006   }
2007 }
2008 }
2009 
2010 /**
2011   * @brief  Return the CRYP error code.
2012   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2013   *                 the configuration information for the  CRYP peripheral
2014   * @retval CRYP error code
2015   */
HAL_CRYP_GetError(CRYP_HandleTypeDef * hcryp)2016 uint32_t HAL_CRYP_GetError(CRYP_HandleTypeDef *hcryp)
2017 {
2018   return hcryp->ErrorCode;
2019 }
2020 
2021 /**
2022   * @brief  Returns the CRYP state.
2023   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2024   *         the configuration information for CRYP module.
2025   * @retval HAL state
2026   */
HAL_CRYP_GetState(CRYP_HandleTypeDef * hcryp)2027 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp)
2028 {
2029   return hcryp->State;
2030 }
2031 
2032 /**
2033   * @brief  Input FIFO transfer completed callback.
2034   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2035   *         the configuration information for CRYP module.
2036   * @retval None
2037   */
HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef * hcryp)2038 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
2039 {
2040   /* Prevent unused argument(s) compilation warning */
2041   UNUSED(hcryp);
2042 
2043   /* NOTE : This function should not be modified; when the callback is needed,
2044             the HAL_CRYP_InCpltCallback can be implemented in the user file
2045    */
2046 }
2047 
2048 /**
2049   * @brief  Output FIFO transfer completed callback.
2050   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2051   *         the configuration information for CRYP module.
2052   * @retval None
2053   */
HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef * hcryp)2054 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
2055 {
2056   /* Prevent unused argument(s) compilation warning */
2057   UNUSED(hcryp);
2058 
2059   /* NOTE : This function should not be modified; when the callback is needed,
2060             the HAL_CRYP_OutCpltCallback can be implemented in the user file
2061    */
2062 }
2063 
2064 /**
2065   * @brief  CRYP error callback.
2066   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2067   *         the configuration information for CRYP module.
2068   * @retval None
2069   */
HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef * hcryp)2070 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
2071 {
2072   /* Prevent unused argument(s) compilation warning */
2073   UNUSED(hcryp);
2074 
2075   /* NOTE : This function should not be modified; when the callback is needed,
2076             the HAL_CRYP_ErrorCallback can be implemented in the user file
2077    */
2078 }
2079 /**
2080   * @}
2081   */
2082 
2083 /**
2084   * @}
2085   */
2086 
2087 /* Private functions ---------------------------------------------------------*/
2088 /** @addtogroup CRYP_Private_Functions
2089   * @{
2090   */
2091 
2092 /**
2093   * @brief  Encryption in ECB/CBC & CTR Algorithm with AES Standard
2094   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
2095   * @param  Timeout specify Timeout value
2096   * @retval HAL status
2097   */
CRYP_AES_Encrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2098 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2099 {
2100   uint16_t incount;  /* Temporary CrypInCount Value */
2101   uint16_t outcount;  /* Temporary CrypOutCount Value */
2102   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2103 
2104   if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)|| (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE))
2105   {
2106     if (hcryp->KeyIVConfig == 1U)
2107     {
2108       /* If the Key and IV configuration has to be done only once
2109          and if it has already been done, skip it */
2110       DoKeyIVConfig = 0U;
2111     }
2112     else
2113     {
2114       /* If the Key and IV configuration has to be done only once
2115          and if it has not been done already, do it and set KeyIVConfig
2116          to keep track it won't have to be done again next time */
2117       hcryp->KeyIVConfig = 1U;
2118     }
2119   }
2120 
2121   if (DoKeyIVConfig == 1U)
2122   {
2123     /*  Set the Key*/
2124     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2125 
2126     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2127     {
2128       /* Set the Initialization Vector*/
2129       hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2130       hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2131       hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2132       hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2133     }
2134   } /* if (DoKeyIVConfig == 1U) */
2135   else
2136   {
2137     /* interleave mode Key configuration  */
2138     if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE)
2139     {
2140       /* Set the Key */
2141       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2142     }
2143   }
2144   /* Set the phase */
2145   hcryp->Phase = CRYP_PHASE_PROCESS;
2146 
2147   /* Enable CRYP */
2148   __HAL_CRYP_ENABLE(hcryp);
2149 
2150   incount = hcryp->CrypInCount;
2151   outcount = hcryp->CrypOutCount;
2152   while ((incount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2153   {
2154     /* Write plain Ddta and get cipher data */
2155     CRYP_AES_ProcessData(hcryp, Timeout);
2156     incount = hcryp->CrypInCount;
2157     outcount = hcryp->CrypOutCount;
2158   }
2159 
2160   /* Disable CRYP */
2161   __HAL_CRYP_DISABLE(hcryp);
2162 
2163   /* Change the CRYP state */
2164   hcryp->State = HAL_CRYP_STATE_READY;
2165 
2166   /* Return function status */
2167   return HAL_OK;
2168 }
2169 
2170 /**
2171   * @brief  Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2172   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2173   *         the configuration information for CRYP module
2174   * @retval HAL status
2175   */
CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef * hcryp)2176 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
2177 {
2178   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2179 
2180   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2181   {
2182     if (hcryp->KeyIVConfig == 1U)
2183     {
2184       /* If the Key and IV configuration has to be done only once
2185          and if it has already been done, skip it */
2186       DoKeyIVConfig = 0U;
2187     }
2188     else
2189     {
2190       /* If the Key and IV configuration has to be done only once
2191          and if it has not been done already, do it and set KeyIVConfig
2192          to keep track it won't have to be done again next time */
2193       hcryp->KeyIVConfig = 1U;
2194     }
2195   }
2196 
2197   if (DoKeyIVConfig == 1U)
2198   {
2199     /*  Set the Key*/
2200     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2201 
2202     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2203     {
2204       /* Set the Initialization Vector*/
2205       hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2206       hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2207       hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2208       hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2209     }
2210   } /* if (DoKeyIVConfig == 1U) */
2211 
2212   /* Set the phase */
2213   hcryp->Phase = CRYP_PHASE_PROCESS;
2214 
2215   if (hcryp->Size != 0U)
2216   {
2217 
2218     /* Enable computation complete flag and error interrupts */
2219     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
2220 
2221     /* Enable CRYP */
2222     __HAL_CRYP_ENABLE(hcryp);
2223 
2224     /* Write the input block in the IN FIFO */
2225     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2226     hcryp->CrypInCount++;
2227     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2228     hcryp->CrypInCount++;
2229     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2230     hcryp->CrypInCount++;
2231     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2232     hcryp->CrypInCount++;
2233   }
2234   else
2235   {
2236     /* Change the CRYP state */
2237     hcryp->State = HAL_CRYP_STATE_READY;
2238 
2239     /* Process unlocked */
2240     __HAL_UNLOCK(hcryp);
2241   }
2242 
2243   /* Return function status */
2244   return HAL_OK;
2245 }
2246 
2247 /**
2248   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard
2249   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
2250   * @param  Timeout Specify Timeout value
2251   * @retval HAL status
2252 */
CRYP_AES_Decrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2253 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2254 {
2255   uint16_t incount;  /* Temporary CrypInCount Value */
2256   uint16_t outcount;  /* Temporary CrypOutCount Value */
2257   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2258 
2259   if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) || (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE))
2260   {
2261     if (hcryp->KeyIVConfig == 1U)
2262     {
2263       /* If the Key and IV configuration has to be done only once
2264          and if it has already been done, skip it */
2265       DoKeyIVConfig = 0U;
2266     }
2267     else
2268     {
2269       /* If the Key and IV configuration has to be done only once
2270          and if it has not been done already, do it and set KeyIVConfig
2271          to keep track it won't have to be done again next time */
2272       hcryp->KeyIVConfig = 1U;
2273     }
2274   }
2275 
2276   if (DoKeyIVConfig == 1U)
2277   {
2278     /*  Key preparation for ECB/CBC */
2279     if (hcryp->Init.Algorithm != CRYP_AES_CTR)   /*ECB or CBC*/
2280     {
2281       if (hcryp->AutoKeyDerivation == DISABLE)/*Mode 2 Key preparation*/
2282       {
2283         /* Set key preparation for decryption operating mode*/
2284         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2285 
2286         /*  Set the Key*/
2287         CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2288 
2289         /* Enable CRYP */
2290         __HAL_CRYP_ENABLE(hcryp);
2291 
2292         /* Wait for CCF flag to be raised */
2293         if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2294         {
2295           /* Disable the CRYP peripheral clock */
2296           __HAL_CRYP_DISABLE(hcryp);
2297 
2298           /* Change state & error code*/
2299           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2300           hcryp->State = HAL_CRYP_STATE_READY;
2301 
2302           /* Process unlocked */
2303           __HAL_UNLOCK(hcryp);
2304           return HAL_ERROR;
2305         }
2306         /* Clear CCF Flag */
2307         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2308 
2309         /* Return to decryption operating mode(Mode 3)*/
2310         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2311       }
2312       else /*Mode 4 : decryption & Key preparation*/
2313       {
2314         /*  Set the Key*/
2315         CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2316 
2317         /* Set decryption & Key preparation operating mode*/
2318         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT);
2319       }
2320     }
2321     else  /*Algorithm CTR */
2322     {
2323       /*  Set the Key*/
2324       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2325     }
2326 
2327     /* Set IV */
2328     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2329     {
2330       /* Set the Initialization Vector*/
2331       hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2332       hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2333       hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2334       hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2335     }
2336   } /* if (DoKeyIVConfig == 1U) */
2337   else /* if (dokeyivconfig == 0U) */
2338   {
2339     /* interleave mode Key configuration  */
2340     if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE)
2341     {
2342       /*  Key preparation for ECB/CBC */
2343       if (hcryp->Init.Algorithm != CRYP_AES_CTR)   /*ECB or CBC*/
2344       {
2345         if (hcryp->AutoKeyDerivation == DISABLE)/*Mode 2 Key preparation*/
2346         {
2347           /* Set key preparation for decryption operating mode*/
2348           MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2349 
2350           /*  Set the Key*/
2351           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2352 
2353           /* Enable CRYP */
2354           __HAL_CRYP_ENABLE(hcryp);
2355 
2356           /* Wait for CCF flag to be raised */
2357           if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2358           {
2359             /* Disable the CRYP peripheral clock */
2360             __HAL_CRYP_DISABLE(hcryp);
2361 
2362             /* Change state & error code*/
2363             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2364             hcryp->State = HAL_CRYP_STATE_READY;
2365 
2366             /* Process unlocked */
2367             __HAL_UNLOCK(hcryp);
2368             return HAL_ERROR;
2369           }
2370           /* Clear CCF Flag */
2371           __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2372 
2373           /* Return to decryption operating mode(Mode 3)*/
2374           MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2375         }
2376         else /*Mode 4 : decryption & Key preparation*/
2377         {
2378           /*  Set the Key*/
2379           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2380 
2381           /* Set decryption & Key preparation operating mode*/
2382           MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT);
2383         }
2384       }
2385       else  /*Algorithm CTR */
2386       {
2387         /*  Set the Key*/
2388         CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2389       }
2390     }
2391   }
2392 
2393   /* Set the phase */
2394   hcryp->Phase = CRYP_PHASE_PROCESS;
2395 
2396   /* Enable CRYP */
2397   __HAL_CRYP_ENABLE(hcryp);
2398 
2399   incount = hcryp->CrypInCount;
2400   outcount = hcryp->CrypOutCount;
2401   while ((incount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2402   {
2403     /* Write plain data and get cipher data */
2404     CRYP_AES_ProcessData(hcryp, Timeout);
2405     incount = hcryp->CrypInCount;
2406     outcount = hcryp->CrypOutCount;
2407   }
2408 
2409   /* Disable CRYP */
2410   __HAL_CRYP_DISABLE(hcryp);
2411 
2412   /* Change the CRYP state */
2413   hcryp->State = HAL_CRYP_STATE_READY;
2414 
2415   /* Return function status */
2416   return HAL_OK;
2417 }
2418 /**
2419   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2420   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2421   *         the configuration information for CRYP module
2422   * @retval HAL status
2423   */
CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef * hcryp)2424 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
2425 {
2426   __IO uint32_t count = 0U;
2427   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2428 
2429   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2430   {
2431     if (hcryp->KeyIVConfig == 1U)
2432     {
2433       /* If the Key and IV configuration has to be done only once
2434          and if it has already been done, skip it */
2435       DoKeyIVConfig = 0U;
2436     }
2437     else
2438     {
2439       /* If the Key and IV configuration has to be done only once
2440          and if it has not been done already, do it and set KeyIVConfig
2441          to keep track it won't have to be done again next time */
2442       hcryp->KeyIVConfig = 1U;
2443     }
2444   }
2445 
2446   if (DoKeyIVConfig == 1U)
2447   {
2448     /*  Key preparation for ECB/CBC */
2449     if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2450     {
2451       if (hcryp->AutoKeyDerivation == DISABLE)/*Mode 2 Key preparation*/
2452       {
2453         /* Set key preparation for decryption operating mode*/
2454         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2455 
2456         /*  Set the Key*/
2457         CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2458 
2459         /* Enable CRYP */
2460         __HAL_CRYP_ENABLE(hcryp);
2461 
2462         /* Wait for CCF flag to be raised */
2463         count = CRYP_TIMEOUT_KEYPREPARATION;
2464         do
2465         {
2466           count-- ;
2467           if (count == 0U)
2468           {
2469             /* Disable the CRYP peripheral clock */
2470             __HAL_CRYP_DISABLE(hcryp);
2471 
2472             /* Change state */
2473             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2474             hcryp->State = HAL_CRYP_STATE_READY;
2475 
2476             /* Process unlocked */
2477             __HAL_UNLOCK(hcryp);
2478             return HAL_ERROR;
2479           }
2480         }
2481         while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
2482 
2483         /* Clear CCF Flag */
2484         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2485 
2486         /* Return to decryption operating mode(Mode 3)*/
2487         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2488       }
2489       else /*Mode 4 : decryption & key preparation*/
2490       {
2491         /*  Set the Key*/
2492         CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2493 
2494         /* Set decryption & key preparation operating mode*/
2495         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT);
2496       }
2497     }
2498     else  /*Algorithm CTR */
2499     {
2500       /*  Set the Key*/
2501       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2502     }
2503 
2504     /* Set IV */
2505     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2506     {
2507       /* Set the Initialization Vector*/
2508       hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2509       hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2510       hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2511       hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2512     }
2513   } /* if (DoKeyIVConfig == 1U) */
2514 
2515   /* Set the phase */
2516   hcryp->Phase = CRYP_PHASE_PROCESS;
2517   if (hcryp->Size != 0U)
2518   {
2519     /* Enable computation complete flag and error interrupts */
2520     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
2521 
2522     /* Enable CRYP */
2523     __HAL_CRYP_ENABLE(hcryp);
2524 
2525     /* Write the input block in the IN FIFO */
2526     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2527     hcryp->CrypInCount++;
2528     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2529     hcryp->CrypInCount++;
2530     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2531     hcryp->CrypInCount++;
2532     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2533     hcryp->CrypInCount++;
2534   }
2535   else
2536   {
2537     /* Process locked */
2538     __HAL_UNLOCK(hcryp);
2539 
2540     /* Change the CRYP state */
2541     hcryp->State = HAL_CRYP_STATE_READY;
2542   }
2543 
2544   /* Return function status */
2545   return HAL_OK;
2546 }
2547 /**
2548   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
2549   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2550   *         the configuration information for CRYP module
2551   * @retval HAL status
2552   */
CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef * hcryp)2553 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
2554 {
2555   __IO uint32_t count = 0U;
2556   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2557 
2558   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2559   {
2560     if (hcryp->KeyIVConfig == 1U)
2561     {
2562       /* If the Key and IV configuration has to be done only once
2563          and if it has already been done, skip it */
2564       DoKeyIVConfig = 0U;
2565     }
2566     else
2567     {
2568       /* If the Key and IV configuration has to be done only once
2569          and if it has not been done already, do it and set KeyIVConfig
2570          to keep track it won't have to be done again next time */
2571       hcryp->KeyIVConfig = 1U;
2572     }
2573   }
2574 
2575   if (DoKeyIVConfig == 1U)
2576   {
2577     /*  Key preparation for ECB/CBC */
2578     if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2579     {
2580       if (hcryp->AutoKeyDerivation == DISABLE)/*Mode 2 key preparation*/
2581       {
2582         /* Set key preparation for decryption operating mode*/
2583         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2584 
2585         /*  Set the Key*/
2586         CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2587 
2588         /* Enable CRYP */
2589         __HAL_CRYP_ENABLE(hcryp);
2590 
2591         /* Wait for CCF flag to be raised */
2592         count = CRYP_TIMEOUT_KEYPREPARATION;
2593         do
2594         {
2595           count-- ;
2596           if (count == 0U)
2597           {
2598             /* Disable the CRYP peripheral clock */
2599             __HAL_CRYP_DISABLE(hcryp);
2600 
2601             /* Change state */
2602             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2603             hcryp->State = HAL_CRYP_STATE_READY;
2604 
2605             /* Process unlocked */
2606             __HAL_UNLOCK(hcryp);
2607             return HAL_ERROR;
2608           }
2609         }
2610         while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
2611 
2612         /* Clear CCF Flag */
2613         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2614 
2615         /* Return to decryption operating mode(Mode 3)*/
2616         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2617       }
2618       else /*Mode 4 : decryption & key preparation*/
2619       {
2620         /*  Set the Key*/
2621         CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2622 
2623         /* Set decryption & Key preparation operating mode*/
2624         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT);
2625       }
2626     }
2627     else  /*Algorithm CTR */
2628     {
2629       /*  Set the Key*/
2630       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2631     }
2632 
2633     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2634     {
2635       /* Set the Initialization Vector*/
2636       hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2637       hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2638       hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2639       hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2640     }
2641   } /* if (DoKeyIVConfig == 1U) */
2642 
2643   /* Set the phase */
2644   hcryp->Phase = CRYP_PHASE_PROCESS;
2645 
2646   if (hcryp->Size != 0U)
2647   {
2648     /* Set the input and output addresses and start DMA transfer */
2649     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
2650   }
2651   else
2652   {
2653     /* Process unlocked */
2654     __HAL_UNLOCK(hcryp);
2655 
2656     /* Change the CRYP state */
2657     hcryp->State = HAL_CRYP_STATE_READY;
2658   }
2659 
2660   /* Return function status */
2661   return HAL_OK;
2662 }
2663 
2664 
2665 /**
2666   * @brief  DMA CRYP input data process complete callback.
2667   * @param  hdma DMA handle
2668   * @retval None
2669   */
CRYP_DMAInCplt(DMA_HandleTypeDef * hdma)2670 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
2671 {
2672   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2673   uint32_t loopcounter;
2674   uint32_t headersize_in_bytes;
2675   uint32_t tmp;
2676   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
2677                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
2678                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU}; /*  8-bit data type */
2679 
2680   /* Stop the DMA transfers to the IN FIFO by clearing to "0" the DMAINEN */
2681   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
2682 
2683   if (hcryp->Phase == CRYP_PHASE_HEADER_DMA_FEED)
2684   {
2685     /* DMA is disabled, CCF is meaningful. Wait for computation completion before moving forward */
2686     CRYP_ClearCCFlagWhenHigh(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE);
2687 
2688     /* Set the phase */
2689     hcryp->Phase = CRYP_PHASE_PROCESS;
2690 
2691     if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
2692     {
2693       headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
2694     }
2695     else
2696     {
2697       headersize_in_bytes = hcryp->Init.HeaderSize;
2698     }
2699 
2700     if ((headersize_in_bytes % 16U) != 0U)
2701     {
2702       /* Write last words that couldn't be fed by DMA */
2703       hcryp->CrypHeaderCount = (uint16_t)((headersize_in_bytes / 16U) * 4U);
2704       for (loopcounter = 0U; (loopcounter < ((headersize_in_bytes / 4U) % 4U)); loopcounter++)
2705       {
2706         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
2707         hcryp->CrypHeaderCount++ ;
2708       }
2709       /* If the header size is a multiple of words */
2710       if ((headersize_in_bytes % 4U) == 0U)
2711       {
2712         /* Pad the data with zeros to have a complete block */
2713         while (loopcounter < 4U)
2714         {
2715           hcryp->Instance->DINR = 0x0U;
2716           loopcounter++;
2717         }
2718       }
2719       else
2720       {
2721         /* Enter last bytes, padded with zeros */
2722         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
2723         tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
2724         hcryp->Instance->DINR = tmp;
2725         loopcounter++;
2726         /* Pad the data with zeros to have a complete block */
2727         while (loopcounter < 4U)
2728         {
2729           hcryp->Instance->DINR = 0x0U;
2730           loopcounter++;
2731         }
2732       }
2733 
2734       /* Wait for computation completion before moving forward */
2735       CRYP_ClearCCFlagWhenHigh(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE);
2736     } /* if ((headersize_in_bytes % 16U) != 0U) */
2737 
2738     /* Set to 0 the number of non-valid bytes using NPBLB register*/
2739     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
2740 
2741     /* Select payload phase once the header phase is performed */
2742     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2743 
2744     /* Initiate payload DMA IN and processed data DMA OUT transfers */
2745     (void)CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp);
2746   }
2747   else
2748   {
2749     uint32_t algo;
2750     /* ECB, CBC or CTR end of input data feeding
2751        or
2752        end of GCM/CCM payload data feeding through DMA */
2753     algo = hcryp->Instance->CR & AES_CR_CHMOD;
2754 
2755     /* Don't call input data transfer complete callback only if
2756        it remains some input data to write to the peripheral.
2757        This case can only occur for GCM and CCM with a payload length
2758        not a multiple of 16 bytes */
2759     if (!(((algo == CRYP_AES_GCM_GMAC) || (algo == CRYP_AES_CCM)) && \
2760         (((hcryp->Size) % 16U) != 0U)))
2761     {
2762       /* Call input data transfer complete callback */
2763 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2764       /*Call registered Input complete callback*/
2765       hcryp->InCpltCallback(hcryp);
2766 #else
2767       /*Call legacy weak Input complete callback*/
2768       HAL_CRYP_InCpltCallback(hcryp);
2769 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2770     }
2771   } /* if (hcryp->Phase == CRYP_PHASE_HEADER_DMA_FEED) */
2772 }
2773 
2774 /**
2775   * @brief  DMA CRYP output data process complete callback.
2776   * @param  hdma DMA handle
2777   * @retval None
2778   */
CRYP_DMAOutCplt(DMA_HandleTypeDef * hdma)2779 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
2780 {
2781   uint32_t count;
2782   uint32_t npblb;
2783   uint32_t lastwordsize;
2784   uint32_t temp[4];  /* Temporary CrypOutBuff */
2785   uint32_t mode;
2786 
2787   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2788 
2789   /* Stop the DMA transfers to the OUT FIFO by clearing to "0" the DMAOUTEN */
2790   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
2791 
2792   /* Clear CCF flag */
2793   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2794 
2795   /* Last block transfer in case of GCM or CCM with Size not %16*/
2796   if (((hcryp->Size) % 16U) != 0U)
2797   {
2798     /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA  */
2799     hcryp->CrypInCount = (hcryp->Size / 16U) * 4U;
2800     hcryp->CrypOutCount = hcryp->CrypInCount;
2801 
2802     /* Compute the number of padding bytes in last block of payload */
2803     npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
2804 
2805     mode = hcryp->Instance->CR & AES_CR_MODE;
2806     if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
2807         ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
2808     {
2809       /* Specify the number of non-valid bytes using NPBLB register*/
2810       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
2811     }
2812 
2813     /* Number of valid words (lastwordsize) in last block */
2814     if ((npblb % 4U) == 0U)
2815     {
2816       lastwordsize = (16U - npblb) / 4U;
2817     }
2818     else
2819     {
2820       lastwordsize = ((16U - npblb) / 4U) + 1U;
2821     }
2822 
2823     /*  Last block optionally pad the data with zeros*/
2824     for (count = 0U; count < lastwordsize; count++)
2825     {
2826       hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2827       hcryp->CrypInCount++;
2828     }
2829     while (count < 4U)
2830     {
2831       /* Pad the data with zeros to have a complete block */
2832       hcryp->Instance->DINR = 0x0U;
2833       count++;
2834     }
2835     /* Call input data transfer complete callback */
2836 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2837     /*Call registered Input complete callback*/
2838     hcryp->InCpltCallback(hcryp);
2839 #else
2840     /*Call legacy weak Input complete callback*/
2841     HAL_CRYP_InCpltCallback(hcryp);
2842 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2843 
2844     /*Wait on CCF flag*/
2845     CRYP_ClearCCFlagWhenHigh(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE);
2846 
2847     /*Read the output block from the output FIFO */
2848     for (count = 0U; count < 4U; count++)
2849     {
2850       /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
2851       temp[count] = hcryp->Instance->DOUTR;
2852     }
2853 
2854     count = 0U;
2855     while((hcryp->CrypOutCount < ((hcryp->Size + 3U)/4U)) && (count<4U))
2856     {
2857       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[count];
2858       hcryp->CrypOutCount++;
2859       count++;
2860     }
2861   }
2862 
2863   if (((hcryp->Init.Algorithm & CRYP_AES_GCM_GMAC) != CRYP_AES_GCM_GMAC) && ((hcryp->Init.Algorithm & CRYP_AES_CCM) != CRYP_AES_CCM))
2864   {
2865     /* Disable CRYP (not allowed in  GCM)*/
2866     __HAL_CRYP_DISABLE(hcryp);
2867   }
2868 
2869   /* Change the CRYP state to ready */
2870   hcryp->State = HAL_CRYP_STATE_READY;
2871 
2872   /* Process unlocked */
2873   __HAL_UNLOCK(hcryp);
2874 
2875   /* Call output data transfer complete callback */
2876 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2877   /*Call registered Output complete callback*/
2878   hcryp->OutCpltCallback(hcryp);
2879 #else
2880   /*Call legacy weak Output complete callback*/
2881   HAL_CRYP_OutCpltCallback(hcryp);
2882 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2883 }
2884 
2885 /**
2886   * @brief  DMA CRYP communication error callback.
2887   * @param  hdma DMA handle
2888   * @retval None
2889   */
CRYP_DMAError(DMA_HandleTypeDef * hdma)2890 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
2891 {
2892   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2893 
2894   /* Change the CRYP peripheral state */
2895   hcryp->State = HAL_CRYP_STATE_READY;
2896 
2897   /* DMA error code field */
2898   hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2899 
2900   /* Clear CCF flag */
2901   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2902 
2903   /* Call error callback */
2904 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2905   /*Call registered error callback*/
2906   hcryp->ErrorCallback(hcryp);
2907 #else
2908   /*Call legacy weak error callback*/
2909   HAL_CRYP_ErrorCallback(hcryp);
2910 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2911 }
2912 
2913 /**
2914   * @brief  Set the DMA configuration and start the DMA transfer
2915   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2916   *         the configuration information for CRYP module
2917   * @param  inputaddr address of the input buffer
2918   * @param  Size size of the input and output buffers in words, must be a multiple of 4
2919   * @param  outputaddr address of the output buffer
2920   * @retval None
2921   */
CRYP_SetDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size,uint32_t outputaddr)2922 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2923 {
2924   /* Set the CRYP DMA transfer complete callback */
2925   hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2926 
2927   /* Set the DMA input error callback */
2928   hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2929 
2930   /* Set the CRYP DMA transfer complete callback */
2931   hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
2932 
2933   /* Set the DMA output error callback */
2934   hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
2935 
2936   if ((hcryp->Init.Algorithm & CRYP_AES_GCM_GMAC) != CRYP_AES_GCM_GMAC)
2937   {
2938     /* Enable CRYP (not allowed in  GCM & CCM)*/
2939     __HAL_CRYP_ENABLE(hcryp);
2940   }
2941 
2942   /* Enable the DMA input stream */
2943   if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size) != HAL_OK)
2944   {
2945     /* DMA error code field */
2946     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2947 
2948     /* Call error callback */
2949 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2950     /*Call registered error callback*/
2951     hcryp->ErrorCallback(hcryp);
2952 #else
2953     /*Call legacy weak error callback*/
2954     HAL_CRYP_ErrorCallback(hcryp);
2955 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2956   }
2957   /* Enable the DMA output stream */
2958   if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size) != HAL_OK)
2959   {
2960     /* DMA error code field */
2961     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2962 
2963     /* Call error callback */
2964 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2965     /*Call registered error callback*/
2966     hcryp->ErrorCallback(hcryp);
2967 #else
2968     /*Call legacy weak error callback*/
2969     HAL_CRYP_ErrorCallback(hcryp);
2970 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2971   }
2972   /* Enable In and Out DMA requests */
2973   SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
2974 }
2975 
2976 /**
2977   * @brief  Set the DMA configuration and start the header DMA transfer
2978   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2979   *         the configuration information for CRYP module
2980   * @param  inputaddr address of the input buffer
2981   * @param  Size size of the input buffer in words, must be a multiple of 4
2982   * @retval None
2983   */
CRYP_SetHeaderDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size)2984 static HAL_StatusTypeDef CRYP_SetHeaderDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size)
2985 {
2986   /* Set the CRYP DMA transfer complete callback */
2987   hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2988 
2989   /* Set the DMA input error callback */
2990   hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2991 
2992   /* Mark that header is fed to the peripheral in DMA mode */
2993   hcryp->Phase = CRYP_PHASE_HEADER_DMA_FEED;
2994   /* Enable the DMA input stream */
2995   if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size) != HAL_OK)
2996   {
2997     /* DMA error code field */
2998     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2999     hcryp->State = HAL_CRYP_STATE_READY;
3000 
3001     /* Process unlocked */
3002     __HAL_UNLOCK(hcryp);
3003     return HAL_ERROR;
3004     /* Call error callback */
3005   }
3006 
3007   /* Enable IN DMA requests */
3008   SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
3009 
3010   return HAL_OK;
3011 }
3012 
3013 /**
3014   * @brief  Process Data: Write Input data in polling mode and used in AES functions.
3015   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3016   *         the configuration information for CRYP module
3017   * @param  Timeout Specify Timeout value
3018   * @retval None
3019   */
CRYP_AES_ProcessData(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)3020 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3021 {
3022 
3023   uint32_t temp[4];  /* Temporary CrypOutBuff */
3024   uint32_t i;
3025 
3026   /* Write the input block in the IN FIFO */
3027   hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3028   hcryp->CrypInCount++;
3029   hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3030   hcryp->CrypInCount++;
3031   hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3032   hcryp->CrypInCount++;
3033   hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3034   hcryp->CrypInCount++;
3035 
3036   /* Wait for CCF flag to be raised */
3037   if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3038   {
3039     /* Disable the CRYP peripheral clock */
3040     __HAL_CRYP_DISABLE(hcryp);
3041 
3042     /* Change state */
3043     hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3044     hcryp->State = HAL_CRYP_STATE_READY;
3045 
3046     /* Process unlocked */
3047     __HAL_UNLOCK(hcryp);
3048     /*Call registered error callback*/
3049 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3050     hcryp->ErrorCallback(hcryp);
3051 #else
3052     /*Call legacy weak error callback*/
3053     HAL_CRYP_ErrorCallback(hcryp);
3054 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3055   }
3056 
3057   /* Clear CCF Flag */
3058   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3059 
3060   /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer*/
3061   for (i = 0U; i < 4U; i++)
3062   {
3063     temp[i] = hcryp->Instance->DOUTR;
3064   }
3065   i= 0U;
3066   while((hcryp->CrypOutCount < ((hcryp->Size + 3U)/4U)) && (i<4U))
3067   {
3068     *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
3069     hcryp->CrypOutCount++;
3070     i++;
3071   }
3072 }
3073 
3074 /**
3075   * @brief  Handle CRYP block input/output data handling under interruption.
3076   * @note   The function is called under interruption only, once
3077   *         interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT.
3078   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3079   *         the configuration information for CRYP module.
3080   * @retval HAL status
3081   */
CRYP_AES_IT(CRYP_HandleTypeDef * hcryp)3082 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp)
3083 {
3084   uint32_t temp[4];  /* Temporary CrypOutBuff */
3085   uint32_t i;
3086 
3087   if (hcryp->State == HAL_CRYP_STATE_BUSY)
3088   {
3089     /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer*/
3090     for (i = 0U; i < 4U; i++)
3091     {
3092       temp[i] = hcryp->Instance->DOUTR;
3093     }
3094     i= 0U;
3095     while((hcryp->CrypOutCount < ((hcryp->Size + 3U)/4U)) && (i<4U))
3096     {
3097       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
3098       hcryp->CrypOutCount++;
3099       i++;
3100     }
3101     if (hcryp->CrypOutCount ==  (hcryp->Size / 4U))
3102     {
3103       /* Disable Computation Complete flag and errors interrupts */
3104       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3105 
3106       /* Change the CRYP state */
3107       hcryp->State = HAL_CRYP_STATE_READY;
3108 
3109       /* Disable CRYP */
3110       __HAL_CRYP_DISABLE(hcryp);
3111 
3112       /* Process Unlocked */
3113       __HAL_UNLOCK(hcryp);
3114 
3115       /* Call Output transfer complete callback */
3116 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3117       /*Call registered Output complete callback*/
3118       hcryp->OutCpltCallback(hcryp);
3119 #else
3120       /*Call legacy weak Output complete callback*/
3121       HAL_CRYP_OutCpltCallback(hcryp);
3122 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3123     }
3124     else
3125     {
3126 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
3127       /* If suspension flag has been raised, suspend processing
3128          only if not already at the end of the payload */
3129       if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
3130       {
3131         /* Clear CCF Flag */
3132         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3133 
3134         /* reset SuspendRequest */
3135         hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
3136         /* Disable Computation Complete Flag and Errors Interrupts */
3137         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
3138         /* Change the CRYP state */
3139         hcryp->State = HAL_CRYP_STATE_SUSPENDED;
3140         /* Mark that the payload phase is suspended */
3141         hcryp->Phase = CRYP_PHASE_PAYLOAD_SUSPENDED;
3142 
3143        /* Process Unlocked */
3144         __HAL_UNLOCK(hcryp);
3145       }
3146       else
3147 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
3148       {
3149         /* Write the input block in the IN FIFO */
3150         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3151         hcryp->CrypInCount++;
3152         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3153         hcryp->CrypInCount++;
3154         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3155         hcryp->CrypInCount++;
3156         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3157         hcryp->CrypInCount++;
3158 
3159         if (hcryp->CrypInCount ==  (hcryp->Size / 4U))
3160         {
3161           /* Call Input transfer complete callback */
3162 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3163           /*Call registered Input complete callback*/
3164           hcryp->InCpltCallback(hcryp);
3165 #else
3166           /*Call legacy weak Input complete callback*/
3167           HAL_CRYP_InCpltCallback(hcryp);
3168 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3169         }
3170       }
3171     }
3172   }
3173   else
3174   {
3175     /* Busy error code field */
3176     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
3177 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3178     /*Call registered error callback*/
3179     hcryp->ErrorCallback(hcryp);
3180 #else
3181     /*Call legacy weak error callback*/
3182     HAL_CRYP_ErrorCallback(hcryp);
3183 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3184   }
3185 }
3186 
3187 /**
3188   * @brief  Writes Key in Key registers.
3189   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3190   *         the configuration information for CRYP module
3191   * @param  KeySize Size of Key
3192   * @note   If pKey is NULL, the Key registers are not written. This configuration
3193   *         occurs when the key is written out of HAL scope.
3194   * @retval None
3195   */
CRYP_SetKey(CRYP_HandleTypeDef * hcryp,uint32_t KeySize)3196 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
3197 {
3198   if (hcryp->Init.pKey != NULL)
3199   {
3200     switch (KeySize)
3201     {
3202       case CRYP_KEYSIZE_256B:
3203         hcryp->Instance->KEYR7 = *(uint32_t *)(hcryp->Init.pKey);
3204         hcryp->Instance->KEYR6 = *(uint32_t *)(hcryp->Init.pKey + 1U);
3205         hcryp->Instance->KEYR5 = *(uint32_t *)(hcryp->Init.pKey + 2U);
3206         hcryp->Instance->KEYR4 = *(uint32_t *)(hcryp->Init.pKey + 3U);
3207         hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey + 4U);
3208         hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 5U);
3209         hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 6U);
3210         hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 7U);
3211         break;
3212       case CRYP_KEYSIZE_128B:
3213         hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey);
3214         hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 1U);
3215         hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 2U);
3216         hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 3U);
3217 
3218         break;
3219       default:
3220         break;
3221     }
3222   }
3223 }
3224 
3225 /**
3226   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
3227   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3228   *         the configuration information for CRYP module
3229   * @param  Timeout Timeout duration
3230   * @retval HAL status
3231   */
CRYP_AESGCM_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)3232 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3233 {
3234   uint32_t tickstart;
3235   uint32_t wordsize = ((uint32_t)hcryp->Size / 4U) ;
3236   uint32_t npblb;
3237   uint32_t temp[4];  /* Temporary CrypOutBuff */
3238   uint32_t index;
3239   uint32_t lastwordsize;
3240   uint32_t incount;  /* Temporary CrypInCount Value */
3241   uint32_t outcount;  /* Temporary CrypOutCount Value */
3242   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3243 
3244   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3245   {
3246     if (hcryp->KeyIVConfig == 1U)
3247     {
3248       /* If the Key and IV configuration has to be done only once
3249          and if it has already been done, skip it */
3250       DoKeyIVConfig = 0U;
3251       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3252     }
3253     else
3254     {
3255       /* If the Key and IV configuration has to be done only once
3256          and if it has not been done already, do it and set KeyIVConfig
3257          to keep track it won't have to be done again next time */
3258       hcryp->KeyIVConfig = 1U;
3259       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3260     }
3261   }
3262   else
3263   {
3264     hcryp->SizesSum = hcryp->Size;
3265   }
3266 
3267   if (DoKeyIVConfig == 1U)
3268   {
3269 
3270     /*  Reset CrypHeaderCount */
3271     hcryp->CrypHeaderCount = 0U;
3272 
3273     /****************************** Init phase **********************************/
3274 
3275     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3276 
3277     /* Set the key */
3278     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3279 
3280     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3281     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
3282     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
3283     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
3284     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
3285 
3286     /* Enable the CRYP peripheral */
3287     __HAL_CRYP_ENABLE(hcryp);
3288 
3289     /* just wait for hash computation */
3290     if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3291     {
3292       /* Change state */
3293       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3294       hcryp->State = HAL_CRYP_STATE_READY;
3295 
3296       /* Process unlocked & return error */
3297       __HAL_UNLOCK(hcryp);
3298       return HAL_ERROR;
3299     }
3300     /* Clear CCF flag */
3301     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3302 
3303     /************************ Header phase *************************************/
3304 
3305     if (CRYP_GCMCCM_SetHeaderPhase(hcryp,  Timeout) != HAL_OK)
3306     {
3307       return HAL_ERROR;
3308     }
3309 
3310     /*************************Payload phase ************************************/
3311 
3312     /* Set the phase */
3313     hcryp->Phase = CRYP_PHASE_PROCESS;
3314 
3315     /* Select payload phase once the header phase is performed */
3316     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3317 
3318     /* Set to 0 the number of non-valid bytes using NPBLB register*/
3319     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3320 
3321   } /* if (DoKeyIVConfig == 1U) */
3322 
3323   if ((hcryp->Size % 16U) != 0U)
3324   {
3325     /* recalculate  wordsize */
3326     wordsize = ((wordsize / 4U) * 4U) ;
3327   }
3328 
3329   /* Get tick */
3330   tickstart = HAL_GetTick();
3331 
3332   /* Write input data and get output Data */
3333   incount = hcryp->CrypInCount;
3334   outcount = hcryp->CrypOutCount;
3335   while ((incount < wordsize) && (outcount < wordsize))
3336   {
3337     /* Write plain data and get cipher data */
3338     CRYP_AES_ProcessData(hcryp, Timeout);
3339 
3340     /* Check for the Timeout */
3341     if (Timeout != HAL_MAX_DELAY)
3342     {
3343       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3344       {
3345         /* Disable the CRYP peripheral clock */
3346         __HAL_CRYP_DISABLE(hcryp);
3347 
3348         /* Change state & error code */
3349         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3350         hcryp->State = HAL_CRYP_STATE_READY;
3351 
3352         /* Process unlocked */
3353         __HAL_UNLOCK(hcryp);
3354         return HAL_ERROR;
3355       }
3356     }
3357     incount = hcryp->CrypInCount;
3358     outcount = hcryp->CrypOutCount;
3359   }
3360 
3361   if ((hcryp->Size % 16U) != 0U)
3362   {
3363     /* Compute the number of padding bytes in last block of payload */
3364     npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
3365 
3366     /*  Set Npblb in case of AES GCM payload encryption to get right tag*/
3367     if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
3368     {
3369       /* Set to 0 the number of non-valid bytes using NPBLB register*/
3370       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3371     }
3372     /* Number of valid words (lastwordsize) in last block */
3373     if ((npblb % 4U) == 0U)
3374     {
3375       lastwordsize = (16U - npblb) / 4U;
3376     }
3377     else
3378     {
3379       lastwordsize = ((16U - npblb) / 4U) + 1U;
3380     }
3381     /*  last block optionally pad the data with zeros*/
3382     for (index = 0U; index < lastwordsize; index ++)
3383     {
3384       /* Write the last Input block in the IN FIFO */
3385       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3386       hcryp->CrypInCount++;
3387     }
3388     while (index < 4U)
3389     {
3390       /* pad the data with zeros to have a complete block */
3391       hcryp->Instance->DINR  = 0U;
3392       index++;
3393     }
3394     /* Wait for CCF flag to be raised */
3395     if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3396     {
3397       hcryp->State = HAL_CRYP_STATE_READY;
3398       __HAL_UNLOCK(hcryp);
3399 
3400 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3401       /*Call registered error callback*/
3402       hcryp->ErrorCallback(hcryp);
3403 #else
3404       /*Call legacy weak error callback*/
3405       HAL_CRYP_ErrorCallback(hcryp);
3406 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3407     }
3408 
3409     /* Clear CCF Flag */
3410     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3411 
3412     /*Read the output block from the output FIFO */
3413     for (index = 0U; index < 4U; index++)
3414     {
3415       /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3416       temp[index] = hcryp->Instance->DOUTR;
3417     }
3418     for (index = 0U; index < lastwordsize; index++)
3419     {
3420       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index];
3421       hcryp->CrypOutCount++;
3422     }
3423   }
3424 
3425   /* Return function status */
3426   return HAL_OK;
3427 }
3428 
3429 /**
3430   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
3431   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3432   *         the configuration information for CRYP module
3433   * @retval HAL status
3434   */
CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef * hcryp)3435 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3436 {
3437   __IO uint32_t count = 0U;
3438   uint32_t loopcounter;
3439   uint32_t lastwordsize;
3440   uint32_t npblb;
3441   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3442   uint32_t headersize_in_bytes;
3443   uint32_t tmp;
3444   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
3445                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
3446                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU}; /*  8-bit data type */
3447 
3448 
3449 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
3450   if ((hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED) || (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED))
3451   {
3452     CRYP_PhaseProcessingResume(hcryp);
3453     return HAL_OK;
3454   }
3455 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
3456 
3457   /* Manage header size given in bytes to handle cases where
3458      header size is not a multiple of 4 bytes */
3459   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
3460   {
3461     headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
3462   }
3463   else
3464   {
3465     headersize_in_bytes = hcryp->Init.HeaderSize;
3466   }
3467 
3468   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3469   {
3470     if (hcryp->KeyIVConfig == 1U)
3471     {
3472       /* If the Key and IV configuration has to be done only once
3473          and if it has already been done, skip it */
3474       DoKeyIVConfig = 0U;
3475       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3476     }
3477     else
3478     {
3479       /* If the Key and IV configuration has to be done only once
3480          and if it has not been done already, do it and set KeyIVConfig
3481          to keep track it won't have to be done again next time */
3482       hcryp->KeyIVConfig = 1U;
3483       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3484     }
3485   }
3486   else
3487   {
3488     hcryp->SizesSum = hcryp->Size;
3489   }
3490 
3491   /* Configure Key, IV and process message (header and payload) */
3492   if (DoKeyIVConfig == 1U)
3493   {
3494     /*  Reset CrypHeaderCount */
3495     hcryp->CrypHeaderCount = 0U;
3496 
3497     /******************************* Init phase *********************************/
3498 
3499     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3500 
3501     /* Set the key */
3502     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3503 
3504     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3505     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
3506     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
3507     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
3508     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
3509 
3510     /* Enable the CRYP peripheral */
3511     __HAL_CRYP_ENABLE(hcryp);
3512 
3513     /* just wait for hash computation */
3514     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3515     do
3516     {
3517       count-- ;
3518       if (count == 0U)
3519       {
3520         /* Disable the CRYP peripheral clock */
3521         __HAL_CRYP_DISABLE(hcryp);
3522 
3523         /* Change state */
3524         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3525         hcryp->State = HAL_CRYP_STATE_READY;
3526 
3527         /* Process unlocked */
3528         __HAL_UNLOCK(hcryp);
3529         return HAL_ERROR;
3530       }
3531     }
3532     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
3533 
3534     /* Clear CCF flag */
3535     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3536 
3537     /***************************** Header phase *********************************/
3538 
3539     /* Select header phase */
3540     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3541 
3542     /* Enable computation complete flag and error interrupts */
3543     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3544 
3545     /* Enable the CRYP peripheral */
3546     __HAL_CRYP_ENABLE(hcryp);
3547 
3548     if (hcryp->Init.HeaderSize == 0U) /*header phase is  skipped*/
3549     {
3550       /* Set the phase */
3551       hcryp->Phase = CRYP_PHASE_PROCESS;
3552 
3553       /* Select payload phase once the header phase is performed */
3554       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
3555 
3556       /* Set to 0 the number of non-valid bytes using NPBLB register*/
3557       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3558 
3559       /* Write the payload Input block in the IN FIFO */
3560       if (hcryp->Size == 0U)
3561       {
3562         /* Disable interrupts */
3563         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3564 
3565         /* Change the CRYP state */
3566         hcryp->State = HAL_CRYP_STATE_READY;
3567 
3568         /* Process unlocked */
3569         __HAL_UNLOCK(hcryp);
3570       }
3571       else if (hcryp->Size >= 16U)
3572       {
3573         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3574         hcryp->CrypInCount++;
3575         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3576         hcryp->CrypInCount++;
3577         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3578         hcryp->CrypInCount++;
3579         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3580         hcryp->CrypInCount++;
3581         if ((hcryp->CrypInCount ==  (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
3582         {
3583           /* Call Input transfer complete callback */
3584 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3585           /*Call registered Input complete callback*/
3586           hcryp->InCpltCallback(hcryp);
3587 #else
3588           /*Call legacy weak Input complete callback*/
3589           HAL_CRYP_InCpltCallback(hcryp);
3590 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3591         }
3592       }
3593       else /* Size < 16Bytes  : first block is the last block*/
3594       {
3595         /* Workaround not implemented for TinyAES2*/
3596         /* Size should be %4  otherwise Tag will  be incorrectly generated for GCM Encryption:
3597         Workaround is implemented in polling mode, so if last block of
3598         payload <128bit do not use CRYP_Encrypt_IT otherwise TAG is incorrectly generated for GCM Encryption. */
3599 
3600 
3601         /* Compute the number of padding bytes in last block of payload */
3602         npblb = 16U - ((uint32_t)hcryp->Size);
3603 
3604         if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
3605         {
3606           /* Set to 0 the number of non-valid bytes using NPBLB register*/
3607           MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3608         }
3609 
3610         /* Number of valid words (lastwordsize) in last block */
3611         if ((npblb % 4U) == 0U)
3612         {
3613           lastwordsize = (16U - npblb) / 4U;
3614         }
3615         else
3616         {
3617           lastwordsize = ((16U - npblb) / 4U) + 1U;
3618         }
3619 
3620         /*  last block optionally pad the data with zeros*/
3621         for (loopcounter = 0U; loopcounter < lastwordsize ; loopcounter++)
3622         {
3623           hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3624           hcryp->CrypInCount++;
3625         }
3626         while (loopcounter < 4U)
3627         {
3628           /* pad the data with zeros to have a complete block */
3629           hcryp->Instance->DINR = 0x0U;
3630           loopcounter++;
3631         }
3632         /* Call Input transfer complete callback */
3633 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3634         /*Call registered Input complete callback*/
3635         hcryp->InCpltCallback(hcryp);
3636 #else
3637         /*Call legacy weak Input complete callback*/
3638         HAL_CRYP_InCpltCallback(hcryp);
3639 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3640       }
3641     }
3642     /* Enter header data */
3643     /* Cher first whether header length is small enough to enter the full header in one shot */
3644     else if (headersize_in_bytes <= 16U)
3645     {
3646       /* Write header data, padded with zeros if need be */
3647       for (loopcounter = 0U; (loopcounter < (headersize_in_bytes / 4U)); loopcounter++)
3648       {
3649         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3650         hcryp->CrypHeaderCount++ ;
3651       }
3652       /* If the header size is a multiple of words */
3653       if ((headersize_in_bytes % 4U) == 0U)
3654       {
3655         /* Pad the data with zeros to have a complete block */
3656         while (loopcounter < 4U)
3657         {
3658           hcryp->Instance->DINR = 0x0U;
3659           loopcounter++;
3660           hcryp->CrypHeaderCount++;
3661         }
3662       }
3663       else
3664       {
3665         /* Enter last bytes, padded with zeros */
3666         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3667         tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
3668         hcryp->Instance->DINR = tmp;
3669         loopcounter++;
3670         hcryp->CrypHeaderCount++ ;
3671         /* Pad the data with zeros to have a complete block */
3672       while (loopcounter < 4U)
3673       {
3674         hcryp->Instance->DINR = 0x0U;
3675         loopcounter++;
3676           hcryp->CrypHeaderCount++;
3677         }
3678       }
3679     }
3680     else
3681     {
3682       /* Write the first input header block in the Input FIFO,
3683          the following header data will be fed after interrupt occurrence */
3684       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3685       hcryp->CrypHeaderCount++;
3686       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3687       hcryp->CrypHeaderCount++;
3688       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3689       hcryp->CrypHeaderCount++;
3690       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3691       hcryp->CrypHeaderCount++;
3692     }
3693 
3694   } /* end of if (DoKeyIVConfig == 1U) */
3695   else  /* Key and IV have already been configured,
3696           header has already been processed;
3697           only process here message payload */
3698   {
3699 
3700     /* Enable computation complete flag and error interrupts */
3701     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3702 
3703     /* Set to 0 the number of non-valid bytes using NPBLB register*/
3704     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3705 
3706     /* Write the payload Input block in the IN FIFO */
3707     if (hcryp->Size == 0U)
3708     {
3709       /* Disable interrupts */
3710       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3711 
3712       /* Change the CRYP state */
3713       hcryp->State = HAL_CRYP_STATE_READY;
3714 
3715       /* Process unlocked */
3716       __HAL_UNLOCK(hcryp);
3717     }
3718     else if (hcryp->Size >= 16U)
3719     {
3720       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3721       hcryp->CrypInCount++;
3722       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3723       hcryp->CrypInCount++;
3724       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3725       hcryp->CrypInCount++;
3726       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3727       hcryp->CrypInCount++;
3728       if ((hcryp->CrypInCount ==  (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
3729       {
3730         /* Call Input transfer complete callback */
3731 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3732         /*Call registered Input complete callback*/
3733         hcryp->InCpltCallback(hcryp);
3734 #else
3735         /*Call legacy weak Input complete callback*/
3736         HAL_CRYP_InCpltCallback(hcryp);
3737 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3738       }
3739     }
3740     else /* Size < 16Bytes  : first block is the last block*/
3741     {
3742       /* Workaround not implemented for TinyAES2*/
3743       /* Size should be %4  otherwise Tag will  be incorrectly generated for GCM Encryption:
3744       Workaround is implemented in polling mode, so if last block of
3745       payload <128bit do not use CRYP_Encrypt_IT otherwise TAG is incorrectly generated for GCM Encryption. */
3746 
3747 
3748       /* Compute the number of padding bytes in last block of payload */
3749       npblb = 16U - ((uint32_t)hcryp->Size);
3750 
3751       if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
3752       {
3753         /* Set to 0 the number of non-valid bytes using NPBLB register*/
3754         MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3755       }
3756 
3757       /* Number of valid words (lastwordsize) in last block */
3758       if ((npblb % 4U) == 0U)
3759       {
3760         lastwordsize = (16U - npblb) / 4U;
3761       }
3762       else
3763       {
3764         lastwordsize = ((16U - npblb) / 4U) + 1U;
3765       }
3766 
3767       /*  last block optionally pad the data with zeros*/
3768       for (loopcounter = 0U; loopcounter < lastwordsize ; loopcounter++)
3769       {
3770         hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3771         hcryp->CrypInCount++;
3772       }
3773       while (loopcounter < 4U)
3774       {
3775         /* pad the data with zeros to have a complete block */
3776         hcryp->Instance->DINR = 0x0U;
3777         loopcounter++;
3778       }
3779       /* Call Input transfer complete callback */
3780 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3781       /*Call registered Input complete callback*/
3782       hcryp->InCpltCallback(hcryp);
3783 #else
3784       /*Call legacy weak Input complete callback*/
3785       HAL_CRYP_InCpltCallback(hcryp);
3786 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3787     }
3788   }
3789 
3790   /* Return function status */
3791   return HAL_OK;
3792 }
3793 
3794 
3795 /**
3796   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
3797   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3798   *         the configuration information for CRYP module
3799   * @retval HAL status
3800   */
CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef * hcryp)3801 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3802 {
3803   uint32_t count;
3804   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3805 
3806   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3807   {
3808     if (hcryp->KeyIVConfig == 1U)
3809     {
3810       /* If the Key and IV configuration has to be done only once
3811          and if it has already been done, skip it */
3812       DoKeyIVConfig = 0U;
3813       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3814     }
3815     else
3816     {
3817       /* If the Key and IV configuration has to be done only once
3818          and if it has not been done already, do it and set KeyIVConfig
3819          to keep track it won't have to be done again next time */
3820       hcryp->KeyIVConfig = 1U;
3821       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3822     }
3823   }
3824   else
3825   {
3826     hcryp->SizesSum = hcryp->Size;
3827   }
3828 
3829   if (DoKeyIVConfig == 1U)
3830   {
3831 
3832     /*  Reset CrypHeaderCount */
3833     hcryp->CrypHeaderCount = 0U;
3834 
3835     /*************************** Init phase ************************************/
3836 
3837     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3838 
3839     /* Set the key */
3840     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3841 
3842     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3843     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
3844     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
3845     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
3846     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
3847 
3848     /* Enable the CRYP peripheral */
3849     __HAL_CRYP_ENABLE(hcryp);
3850 
3851     /* just wait for hash computation */
3852     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3853     do
3854     {
3855       count-- ;
3856       if (count == 0U)
3857       {
3858         /* Disable the CRYP peripheral clock */
3859         __HAL_CRYP_DISABLE(hcryp);
3860 
3861         /* Change state */
3862         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3863         hcryp->State = HAL_CRYP_STATE_READY;
3864 
3865         /* Process unlocked */
3866         __HAL_UNLOCK(hcryp);
3867         return HAL_ERROR;
3868       }
3869     }
3870     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
3871 
3872     /* Clear CCF flag */
3873     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3874 
3875     /************************ Header phase *************************************/
3876 
3877     if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
3878     {
3879       return HAL_ERROR;
3880     }
3881 
3882   }
3883   else
3884   {
3885     /* Initialization and header phases already done, only do payload phase */
3886     if (CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp) != HAL_OK)
3887     {
3888       return HAL_ERROR;
3889     }
3890   } /* if (DoKeyIVConfig == 1U) */
3891 
3892   /* Return function status */
3893   return HAL_OK;
3894 }
3895 
3896 
3897 /**
3898   * @brief  AES CCM encryption/decryption processing in polling mode
3899   *         for TinyAES peripheral, no encrypt/decrypt performed, only authentication preparation.
3900   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3901   *         the configuration information for CRYP module
3902   * @param  Timeout Timeout duration
3903   * @retval HAL status
3904   */
CRYP_AESCCM_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)3905 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3906 {
3907   uint32_t tickstart;
3908   uint32_t wordsize = ((uint32_t)hcryp->Size / 4U) ;
3909   uint32_t loopcounter;
3910   uint32_t npblb;
3911   uint32_t lastwordsize;
3912   uint32_t temp[4] ;  /* Temporary CrypOutBuff */
3913   uint32_t incount;  /* Temporary CrypInCount Value */
3914   uint32_t outcount;  /* Temporary CrypOutCount Value */
3915   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3916 
3917   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3918   {
3919     if (hcryp->KeyIVConfig == 1U)
3920     {
3921       /* If the Key and IV configuration has to be done only once
3922          and if it has already been done, skip it */
3923       DoKeyIVConfig = 0U;
3924       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3925     }
3926     else
3927     {
3928       /* If the Key and IV configuration has to be done only once
3929          and if it has not been done already, do it and set KeyIVConfig
3930          to keep track it won't have to be done again next time */
3931       hcryp->KeyIVConfig = 1U;
3932       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3933     }
3934   }
3935   else
3936   {
3937     hcryp->SizesSum = hcryp->Size;
3938   }
3939 
3940   if (DoKeyIVConfig == 1U)
3941   {
3942     /*  Reset CrypHeaderCount */
3943     hcryp->CrypHeaderCount = 0U;
3944 
3945     /********************** Init phase ******************************************/
3946 
3947     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3948 
3949     /* Set the key */
3950     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3951 
3952     /* Set the initialization vector (IV) with B0 */
3953     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0);
3954     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U);
3955     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U);
3956     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U);
3957 
3958     /* Enable the CRYP peripheral */
3959     __HAL_CRYP_ENABLE(hcryp);
3960 
3961     /* just wait for hash computation */
3962     if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3963     {
3964       /* Change state */
3965       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3966       hcryp->State = HAL_CRYP_STATE_READY;
3967 
3968       /* Process unlocked & return error */
3969       __HAL_UNLOCK(hcryp);
3970       return HAL_ERROR;
3971     }
3972     /* Clear CCF flag */
3973     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3974 
3975     /************************ Header phase *************************************/
3976     /* Header block(B1) : associated data length expressed in bytes concatenated
3977     with Associated Data (A)*/
3978     if (CRYP_GCMCCM_SetHeaderPhase(hcryp,  Timeout) != HAL_OK)
3979     {
3980       return HAL_ERROR;
3981     }
3982 
3983     /*************************Payload phase ************************************/
3984 
3985     /* Set the phase */
3986     hcryp->Phase = CRYP_PHASE_PROCESS;
3987 
3988     /* Select payload phase once the header phase is performed */
3989     MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
3990 
3991     /* Set to 0 the number of non-valid bytes using NPBLB register*/
3992     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3993 
3994   } /* if (DoKeyIVConfig == 1U) */
3995 
3996   if ((hcryp->Size % 16U) != 0U)
3997   {
3998     /* recalculate  wordsize */
3999     wordsize = ((wordsize / 4U) * 4U) ;
4000   }
4001   /* Get tick */
4002   tickstart = HAL_GetTick();
4003 
4004   /* Write input data and get output data */
4005   incount = hcryp->CrypInCount;
4006   outcount = hcryp->CrypOutCount;
4007   while ((incount < wordsize) && (outcount < wordsize))
4008   {
4009     /* Write plain data and get cipher data */
4010     CRYP_AES_ProcessData(hcryp, Timeout);
4011 
4012     /* Check for the Timeout */
4013     if (Timeout != HAL_MAX_DELAY)
4014     {
4015       if (((HAL_GetTick() - tickstart) > Timeout) ||(Timeout == 0U))
4016       {
4017         /* Disable the CRYP peripheral clock */
4018         __HAL_CRYP_DISABLE(hcryp);
4019 
4020         /* Change state */
4021         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4022         hcryp->State = HAL_CRYP_STATE_READY;
4023 
4024         /* Process unlocked */
4025         __HAL_UNLOCK(hcryp);
4026         return HAL_ERROR;
4027       }
4028     }
4029     incount = hcryp->CrypInCount;
4030     outcount = hcryp->CrypOutCount;
4031   }
4032 
4033   if ((hcryp->Size % 16U) != 0U)
4034   {
4035     /* Compute the number of padding bytes in last block of payload */
4036     npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
4037 
4038     if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_DECRYPT)
4039     {
4040       /* Set Npblb in case of AES CCM payload decryption to get right tag  */
4041       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20);
4042 
4043     }
4044     /* Number of valid words (lastwordsize) in last block */
4045     if ((npblb % 4U) == 0U)
4046     {
4047       lastwordsize = (16U - npblb) / 4U;
4048     }
4049     else
4050     {
4051       lastwordsize = ((16U - npblb) / 4U) + 1U;
4052     }
4053 
4054     /* Write the last input block in the IN FIFO */
4055     for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter ++)
4056     {
4057       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4058       hcryp->CrypInCount++;
4059     }
4060 
4061     /* Pad the data with zeros to have a complete block */
4062     while (loopcounter < 4U)
4063     {
4064       hcryp->Instance->DINR  = 0U;
4065       loopcounter++;
4066     }
4067     /* just wait for hash computation */
4068     if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
4069     {
4070       /* Change state */
4071       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4072       hcryp->State = HAL_CRYP_STATE_READY;
4073 
4074       /* Process unlocked & return error */
4075       __HAL_UNLOCK(hcryp);
4076       return HAL_ERROR;
4077     }
4078     /* Clear CCF flag */
4079     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4080 
4081     for (loopcounter = 0U; loopcounter < 4U; loopcounter++)
4082     {
4083       /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
4084       temp[loopcounter] = hcryp->Instance->DOUTR;
4085     }
4086     for (loopcounter = 0U; loopcounter<lastwordsize; loopcounter++)
4087     {
4088       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[loopcounter];
4089       hcryp->CrypOutCount++;
4090     }
4091   }
4092 
4093   /* Return function status */
4094   return HAL_OK;
4095 }
4096 
4097 /**
4098   * @brief  AES CCM encryption/decryption process in interrupt mode
4099   *         for TinyAES peripheral, no encrypt/decrypt performed, only authentication preparation.
4100   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
4101   *         the configuration information for CRYP module
4102   * @retval HAL status
4103   */
CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef * hcryp)4104 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
4105 {
4106   __IO uint32_t count = 0U;
4107   uint32_t loopcounter;
4108   uint32_t lastwordsize;
4109   uint32_t npblb;
4110   uint32_t mode;
4111   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
4112   uint32_t headersize_in_bytes;
4113   uint32_t tmp;
4114   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
4115                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
4116                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU}; /*  8-bit data type */
4117 
4118 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
4119   if ((hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED) || (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED))
4120   {
4121     CRYP_PhaseProcessingResume(hcryp);
4122     return HAL_OK;
4123   }
4124 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
4125 
4126   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
4127   {
4128     if (hcryp->KeyIVConfig == 1U)
4129     {
4130       /* If the Key and IV configuration has to be done only once
4131          and if it has already been done, skip it */
4132       DoKeyIVConfig = 0U;
4133       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
4134     }
4135     else
4136     {
4137       /* If the Key and IV configuration has to be done only once
4138          and if it has not been done already, do it and set KeyIVConfig
4139          to keep track it won't have to be done again next time */
4140       hcryp->KeyIVConfig = 1U;
4141       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
4142     }
4143   }
4144   else
4145   {
4146     hcryp->SizesSum = hcryp->Size;
4147   }
4148 
4149   /* Configure Key, IV and process message (header and payload) */
4150   if (DoKeyIVConfig == 1U)
4151   {
4152     /*  Reset CrypHeaderCount */
4153     hcryp->CrypHeaderCount = 0U;
4154 
4155     /********************** Init phase ******************************************/
4156 
4157     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
4158 
4159     /* Set the key */
4160     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4161 
4162     /* Set the initialization vector (IV) with B0 */
4163     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0);
4164     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U);
4165     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U);
4166     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U);
4167 
4168     /* Enable the CRYP peripheral */
4169     __HAL_CRYP_ENABLE(hcryp);
4170 
4171     /* just wait for hash computation */
4172     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
4173     do
4174     {
4175       count-- ;
4176       if (count == 0U)
4177       {
4178         /* Disable the CRYP peripheral clock */
4179         __HAL_CRYP_DISABLE(hcryp);
4180 
4181         /* Change state */
4182         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4183         hcryp->State = HAL_CRYP_STATE_READY;
4184 
4185         /* Process unlocked */
4186         __HAL_UNLOCK(hcryp);
4187         return HAL_ERROR;
4188       }
4189     }
4190     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
4191 
4192     /* Clear CCF flag */
4193     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4194 
4195     /***************************** Header phase *********************************/
4196 
4197     /* Select header phase */
4198     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4199 
4200     /* Enable computation complete flag and error interrupts */
4201     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
4202 
4203     /* Enable the CRYP peripheral */
4204     __HAL_CRYP_ENABLE(hcryp);
4205 
4206     if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
4207     {
4208       headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
4209     }
4210     else
4211     {
4212       headersize_in_bytes = hcryp->Init.HeaderSize;
4213     }
4214 
4215     if (headersize_in_bytes == 0U) /* Header phase is  skipped */
4216     {
4217       /* Set the phase */
4218       hcryp->Phase = CRYP_PHASE_PROCESS;
4219       /* Select payload phase once the header phase is performed */
4220       CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4221       /* Set to 0 the number of non-valid bytes using NPBLB register*/
4222       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
4223 
4224       if (hcryp->Init.Algorithm == CRYP_AES_CCM)
4225       {
4226         /* Increment CrypHeaderCount to pass in CRYP_GCMCCM_SetPayloadPhase_IT */
4227         hcryp->CrypHeaderCount++;
4228       }
4229       /* Write the payload Input block in the IN FIFO */
4230       if (hcryp->Size == 0U)
4231       {
4232         /* Disable interrupts */
4233         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
4234 
4235         /* Change the CRYP state */
4236         hcryp->State = HAL_CRYP_STATE_READY;
4237 
4238         /* Process unlocked */
4239         __HAL_UNLOCK(hcryp);
4240       }
4241       else if (hcryp->Size >= 16U)
4242       {
4243         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4244         hcryp->CrypInCount++;
4245         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4246         hcryp->CrypInCount++;
4247         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4248         hcryp->CrypInCount++;
4249         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4250         hcryp->CrypInCount++;
4251 
4252         if ((hcryp->CrypInCount ==  (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
4253         {
4254           /* Call Input transfer complete callback */
4255 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4256           /*Call registered Input complete callback*/
4257           hcryp->InCpltCallback(hcryp);
4258 #else
4259           /*Call legacy weak Input complete callback*/
4260           HAL_CRYP_InCpltCallback(hcryp);
4261 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4262         }
4263       }
4264       else /* Size < 4 words  : first block is the last block*/
4265       {
4266         /* Compute the number of padding bytes in last block of payload */
4267         npblb = 16U - (uint32_t)hcryp->Size;
4268 
4269         mode = hcryp->Instance->CR & AES_CR_MODE;
4270         if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
4271             ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4272         {
4273           /* Specify the number of non-valid bytes using NPBLB register*/
4274           MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4275         }
4276 
4277         /* Number of valid words (lastwordsize) in last block */
4278         if ((npblb % 4U) == 0U)
4279         {
4280           lastwordsize = (16U - npblb) / 4U;
4281         }
4282         else
4283         {
4284           lastwordsize = ((16U - npblb) / 4U) + 1U;
4285         }
4286 
4287         /*  Last block optionally pad the data with zeros*/
4288         for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4289         {
4290           hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4291           hcryp->CrypInCount++;
4292         }
4293         while (loopcounter < 4U)
4294         {
4295           /* Pad the data with zeros to have a complete block */
4296           hcryp->Instance->DINR = 0x0U;
4297           loopcounter++;
4298         }
4299         /* Call Input transfer complete callback */
4300 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4301         /*Call registered Input complete callback*/
4302         hcryp->InCpltCallback(hcryp);
4303 #else
4304         /*Call legacy weak Input complete callback*/
4305         HAL_CRYP_InCpltCallback(hcryp);
4306 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4307       }
4308     }
4309     /* Enter header data */
4310     /* Check first whether header length is small enough to enter the full header in one shot */
4311     else if (headersize_in_bytes <= 16U)
4312     {
4313       for (loopcounter = 0U; (loopcounter < (headersize_in_bytes / 4U)); loopcounter++)
4314       {
4315         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4316         hcryp->CrypHeaderCount++ ;
4317       }
4318       /* If the header size is a multiple of words */
4319       if ((headersize_in_bytes % 4U) == 0U)
4320       {
4321         /* Pad the data with zeros to have a complete block */
4322         while (loopcounter < 4U)
4323         {
4324           hcryp->Instance->DINR = 0x0U;
4325           loopcounter++;
4326         }
4327       }
4328       else
4329       {
4330         /* Enter last bytes, padded with zeros */
4331         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4332         tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
4333         hcryp->Instance->DINR = tmp;
4334         hcryp->CrypHeaderCount++;
4335         loopcounter++;
4336         /* Pad the data with zeros to have a complete block */
4337       while (loopcounter < 4U)
4338       {
4339         hcryp->Instance->DINR = 0x0U;
4340         loopcounter++;
4341       }
4342     }
4343       /* Call Input transfer complete callback */
4344 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4345       /*Call registered Input complete callback*/
4346       hcryp->InCpltCallback(hcryp);
4347 #else
4348       /*Call legacy weak Input complete callback*/
4349       HAL_CRYP_InCpltCallback(hcryp);
4350 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4351     }
4352     else
4353     {
4354       /* Write the first input header block in the Input FIFO,
4355          the following header data will be fed after interrupt occurrence */
4356       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4357       hcryp->CrypHeaderCount++;
4358       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4359       hcryp->CrypHeaderCount++;
4360       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4361       hcryp->CrypHeaderCount++;
4362       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4363       hcryp->CrypHeaderCount++;
4364     }/* if (hcryp->Init.HeaderSize == 0U) */ /* Header phase is  skipped*/
4365   } /* end of if (dokeyivconfig == 1U) */
4366   else  /* Key and IV have already been configured,
4367           header has already been processed;
4368           only process here message payload */
4369   {
4370     /* Write the payload Input block in the IN FIFO */
4371     if (hcryp->Size == 0U)
4372     {
4373       /* Disable interrupts */
4374       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
4375 
4376       /* Change the CRYP state */
4377       hcryp->State = HAL_CRYP_STATE_READY;
4378 
4379       /* Process unlocked */
4380       __HAL_UNLOCK(hcryp);
4381     }
4382     else if (hcryp->Size >= 16U)
4383     {
4384       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4385       hcryp->CrypInCount++;
4386       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4387       hcryp->CrypInCount++;
4388       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4389       hcryp->CrypInCount++;
4390       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4391       hcryp->CrypInCount++;
4392 
4393       if ((hcryp->CrypInCount ==  (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
4394       {
4395         /* Call Input transfer complete callback */
4396 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4397         /*Call registered Input complete callback*/
4398         hcryp->InCpltCallback(hcryp);
4399 #else
4400         /*Call legacy weak Input complete callback*/
4401         HAL_CRYP_InCpltCallback(hcryp);
4402 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4403       }
4404     }
4405     else /* Size < 4 words  : first block is the last block*/
4406     {
4407       /* Compute the number of padding bytes in last block of payload */
4408       npblb = 16U - (uint32_t)hcryp->Size;
4409 
4410       mode = hcryp->Instance->CR & AES_CR_MODE;
4411       if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
4412           ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4413       {
4414         /* Specify the number of non-valid bytes using NPBLB register*/
4415         MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4416       }
4417 
4418       /* Number of valid words (lastwordsize) in last block */
4419       if ((npblb % 4U) == 0U)
4420       {
4421         lastwordsize = (16U - npblb) / 4U;
4422       }
4423       else
4424       {
4425         lastwordsize = ((16U - npblb) / 4U) + 1U;
4426       }
4427 
4428       /*  Last block optionally pad the data with zeros*/
4429       for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4430       {
4431         hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4432         hcryp->CrypInCount++;
4433       }
4434       while (loopcounter < 4U)
4435       {
4436         /* Pad the data with zeros to have a complete block */
4437         hcryp->Instance->DINR = 0x0U;
4438         loopcounter++;
4439       }
4440       /* Call Input transfer complete callback */
4441 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4442       /*Call registered Input complete callback*/
4443       hcryp->InCpltCallback(hcryp);
4444 #else
4445       /*Call legacy weak Input complete callback*/
4446       HAL_CRYP_InCpltCallback(hcryp);
4447 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4448     }
4449   }
4450 
4451   /* Return function status */
4452   return HAL_OK;
4453 }
4454 
4455 /**
4456   * @brief  AES CCM encryption/decryption process in DMA mode
4457   *         for TinyAES peripheral, no encrypt/decrypt performed, only authentication preparation.
4458   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
4459   *         the configuration information for CRYP module
4460   * @retval HAL status
4461   */
CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef * hcryp)4462 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
4463 {
4464   uint32_t count;
4465   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
4466 
4467   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
4468   {
4469     if (hcryp->KeyIVConfig == 1U)
4470     {
4471       /* If the Key and IV configuration has to be done only once
4472          and if it has already been done, skip it */
4473       DoKeyIVConfig = 0U;
4474       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
4475     }
4476     else
4477     {
4478       /* If the Key and IV configuration has to be done only once
4479          and if it has not been done already, do it and set KeyIVConfig
4480          to keep track it won't have to be done again next time */
4481       hcryp->KeyIVConfig = 1U;
4482       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
4483     }
4484   }
4485   else
4486   {
4487     hcryp->SizesSum = hcryp->Size;
4488   }
4489 
4490   if (DoKeyIVConfig == 1U)
4491   {
4492 
4493     /*  Reset CrypHeaderCount */
4494     hcryp->CrypHeaderCount = 0U;
4495 
4496 
4497     /********************** Init phase ******************************************/
4498 
4499     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
4500 
4501     /* Set the key */
4502     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4503 
4504     /* Set the initialization vector (IV) with B0 */
4505     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0);
4506     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U);
4507     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U);
4508     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U);
4509 
4510     /* Enable the CRYP peripheral */
4511     __HAL_CRYP_ENABLE(hcryp);
4512 
4513     /* just wait for hash computation */
4514     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
4515     do
4516     {
4517       count-- ;
4518       if (count == 0U)
4519       {
4520         /* Disable the CRYP peripheral clock */
4521         __HAL_CRYP_DISABLE(hcryp);
4522 
4523         /* Change state */
4524         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4525         hcryp->State = HAL_CRYP_STATE_READY;
4526 
4527         /* Process unlocked */
4528         __HAL_UNLOCK(hcryp);
4529         return HAL_ERROR;
4530       }
4531     }
4532     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
4533 
4534     /* Clear CCF flag */
4535     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4536 
4537 
4538     /********************* Header phase *****************************************/
4539 
4540     if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
4541     {
4542       return HAL_ERROR;
4543     }
4544 
4545   }
4546   else
4547   {
4548     /* Initialization and header phases already done, only do payload phase */
4549     if (CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp) != HAL_OK)
4550     {
4551       return HAL_ERROR;
4552     }
4553   } /* if (DoKeyIVConfig == 1U) */
4554 
4555   /* Return function status */
4556   return HAL_OK;
4557 }
4558 
4559 /**
4560   * @brief  Sets the payload phase in interrupt mode
4561   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
4562   *         the configuration information for CRYP module
4563   * @retval state
4564   */
CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef * hcryp)4565 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
4566 {
4567   uint32_t loopcounter;
4568   uint32_t temp[4];  /* Temporary CrypOutBuff */
4569   uint32_t lastwordsize;
4570   uint32_t npblb;
4571   uint32_t mode;
4572   uint16_t incount;  /* Temporary CrypInCount Value */
4573   uint16_t outcount;  /* Temporary CrypOutCount Value */
4574   uint32_t i;
4575 
4576   /***************************** Payload phase *******************************/
4577 
4578   /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer*/
4579   for (i = 0U; i < 4U; i++)
4580   {
4581     temp[i] = hcryp->Instance->DOUTR;
4582   }
4583   i= 0U;
4584   while((hcryp->CrypOutCount < ((hcryp->Size + 3U)/4U)) && (i<4U))
4585   {
4586     *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4587     hcryp->CrypOutCount++;
4588     i++;
4589   }
4590   incount = hcryp->CrypInCount;
4591   outcount = hcryp->CrypOutCount;
4592   if ((outcount >=  (hcryp->Size / 4U)) && ((incount * 4U) >=  hcryp->Size))
4593   {
4594 
4595      /* When in CCM with Key and IV configuration skipped, don't disable interruptions */
4596      if (!((hcryp->Init.Algorithm == CRYP_AES_CCM) && (hcryp->KeyIVConfig == 1U)))
4597      {
4598       /* Disable computation complete flag and errors interrupts */
4599       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
4600      }
4601 
4602     /* Change the CRYP state */
4603     hcryp->State = HAL_CRYP_STATE_READY;
4604 
4605     /* Process unlocked */
4606     __HAL_UNLOCK(hcryp);
4607 
4608     /* Call output transfer complete callback */
4609 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4610     /*Call registered Output complete callback*/
4611     hcryp->OutCpltCallback(hcryp);
4612 #else
4613     /*Call legacy weak Output complete callback*/
4614     HAL_CRYP_OutCpltCallback(hcryp);
4615 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4616   }
4617 
4618   else if (((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U)
4619   {
4620 
4621 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
4622     /* If suspension flag has been raised, suspend processing
4623        only if not already at the end of the payload */
4624     if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
4625     {
4626       /* Clear CCF Flag */
4627       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4628 
4629       /* reset SuspendRequest */
4630       hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
4631       /* Disable Computation Complete Flag and Errors Interrupts */
4632       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
4633       /* Change the CRYP state */
4634       hcryp->State = HAL_CRYP_STATE_SUSPENDED;
4635       /* Mark that the payload phase is suspended */
4636       hcryp->Phase = CRYP_PHASE_PAYLOAD_SUSPENDED;
4637 
4638      /* Process Unlocked */
4639       __HAL_UNLOCK(hcryp);
4640     }
4641     else
4642 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
4643     {
4644     /* Write the input block in the IN FIFO */
4645     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4646     hcryp->CrypInCount++;
4647     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4648     hcryp->CrypInCount++;
4649     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4650     hcryp->CrypInCount++;
4651     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4652     hcryp->CrypInCount++;
4653     if ((hcryp->CrypInCount ==  (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
4654     {
4655       /* Call input transfer complete callback */
4656 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4657       /*Call registered Input complete callback*/
4658       hcryp->InCpltCallback(hcryp);
4659 #else
4660       /*Call legacy weak Input complete callback*/
4661       HAL_CRYP_InCpltCallback(hcryp);
4662 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4663     }
4664   }
4665   }
4666   else /* Last block of payload < 128bit*/
4667   {
4668     /* Compute the number of padding bytes in last block of payload */
4669     npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
4670 
4671     mode = hcryp->Instance->CR & AES_CR_MODE;
4672     if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
4673         ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4674     {
4675       /* Specify the number of non-valid bytes using NPBLB register*/
4676       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4677     }
4678 
4679     /* Number of valid words (lastwordsize) in last block */
4680     if ((npblb % 4U) == 0U)
4681     {
4682       lastwordsize = (16U - npblb) / 4U;
4683     }
4684     else
4685     {
4686       lastwordsize = ((16U - npblb) / 4U) + 1U;
4687     }
4688 
4689     /*  Last block optionally pad the data with zeros*/
4690     for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4691     {
4692       hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4693       hcryp->CrypInCount++;
4694     }
4695     while (loopcounter < 4U)
4696     {
4697       /* pad the data with zeros to have a complete block */
4698       hcryp->Instance->DINR = 0x0U;
4699       loopcounter++;
4700     }
4701       /* Call input transfer complete callback */
4702 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4703       /*Call registered Input complete callback*/
4704       hcryp->InCpltCallback(hcryp);
4705 #else
4706       /*Call legacy weak Input complete callback*/
4707       HAL_CRYP_InCpltCallback(hcryp);
4708 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4709   }
4710 }
4711 
4712 
4713 /**
4714   * @brief  Sets the payload phase in DMA mode
4715   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
4716   *         the configuration information for CRYP module
4717   * @retval state
4718   */
CRYP_GCMCCM_SetPayloadPhase_DMA(CRYP_HandleTypeDef * hcryp)4719 static HAL_StatusTypeDef CRYP_GCMCCM_SetPayloadPhase_DMA(CRYP_HandleTypeDef *hcryp)
4720 {
4721   uint16_t wordsize = hcryp->Size / 4U ;
4722   uint32_t index;
4723   uint32_t npblb;
4724   uint32_t lastwordsize;
4725   uint32_t temp[4];  /* Temporary CrypOutBuff */
4726   uint32_t count;
4727   uint32_t reg;
4728 
4729   /************************ Payload phase ************************************/
4730   if (hcryp->Size == 0U)
4731   {
4732     /* Process unLocked */
4733     __HAL_UNLOCK(hcryp);
4734 
4735     /* Change the CRYP state and phase */
4736     hcryp->State = HAL_CRYP_STATE_READY;
4737   }
4738   else if (hcryp->Size >= 16U)
4739   {
4740     /*DMA transfer must not include the last block in case of Size is not %16 */
4741     wordsize = wordsize - (wordsize % 4U);
4742 
4743     /*DMA transfer */
4744     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
4745   }
4746   else /* length of input data is < 16 */
4747   {
4748     /* Compute the number of padding bytes in last block of payload */
4749     npblb = 16U - (uint32_t)hcryp->Size;
4750 
4751     /* Set Npblb in case of AES GCM payload encryption or AES CCM payload decryption to get right tag*/
4752     reg = hcryp->Instance->CR & (AES_CR_CHMOD|AES_CR_MODE);
4753     if ((reg == (CRYP_AES_GCM_GMAC|CRYP_OPERATINGMODE_ENCRYPT)) ||\
4754         (reg == (CRYP_AES_CCM|CRYP_OPERATINGMODE_DECRYPT)))
4755     {
4756       /* Specify the number of non-valid bytes using NPBLB register*/
4757       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4758     }
4759 
4760     /* Number of valid words (lastwordsize) in last block */
4761     if ((npblb % 4U) == 0U)
4762     {
4763       lastwordsize = (16U - npblb) / 4U;
4764     }
4765     else
4766     {
4767       lastwordsize = ((16U - npblb) / 4U) + 1U;
4768     }
4769 
4770     /*  last block optionally pad the data with zeros*/
4771     for (index = 0U; index < lastwordsize; index ++)
4772     {
4773       /* Write the last Input block in the IN FIFO */
4774       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4775       hcryp->CrypInCount++;
4776     }
4777     while (index < 4U)
4778     {
4779       /* pad the data with zeros to have a complete block */
4780       hcryp->Instance->DINR  = 0U;
4781       index++;
4782     }
4783     /* Call the input data transfer complete callback */
4784 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4785     /*Call registered Input complete callback*/
4786     hcryp->InCpltCallback(hcryp);
4787 #else
4788     /*Call legacy weak Input complete callback*/
4789     HAL_CRYP_InCpltCallback(hcryp);
4790 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4791     /* Wait for CCF flag to be raised */
4792     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4793     do
4794     {
4795       count-- ;
4796       if (count == 0U)
4797       {
4798         /* Disable the CRYP peripheral clock */
4799         __HAL_CRYP_DISABLE(hcryp);
4800 
4801         /* Change state */
4802         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4803         hcryp->State = HAL_CRYP_STATE_READY;
4804 
4805         /* Process unlocked */
4806         __HAL_UNLOCK(hcryp);
4807         return HAL_ERROR;
4808       }
4809     }
4810     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
4811 
4812     /* Clear CCF Flag */
4813     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4814 
4815     /*Read the output block from the output FIFO */
4816     for (index = 0U; index < 4U; index++)
4817     {
4818       /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
4819       temp[index] = hcryp->Instance->DOUTR;
4820     }
4821     for (index = 0U; index < lastwordsize; index++)
4822     {
4823       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
4824       hcryp->CrypOutCount++;
4825     }
4826 
4827     /* Change the CRYP state to ready */
4828     hcryp->State = HAL_CRYP_STATE_READY;
4829 
4830     /* Process unlocked */
4831     __HAL_UNLOCK(hcryp);
4832 
4833       /* Call Output transfer complete callback */
4834 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4835       /*Call registered Output complete callback*/
4836       hcryp->OutCpltCallback(hcryp);
4837 #else
4838       /*Call legacy weak Output complete callback*/
4839       HAL_CRYP_OutCpltCallback(hcryp);
4840 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4841   }
4842 
4843   return HAL_OK;
4844 }
4845 
4846 /**
4847   * @brief  Sets the header phase in polling mode
4848   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
4849   *         the configuration information for CRYP module(Header & HeaderSize)
4850   * @param  Timeout Timeout value
4851   * @retval state
4852   */
CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)4853 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4854 {
4855   uint32_t loopcounter;
4856   uint32_t size_in_bytes;
4857   uint32_t tmp;
4858   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
4859                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
4860                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU}; /*  8-bit data type */
4861 
4862   /***************************** Header phase for GCM/GMAC or CCM *********************************/
4863   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
4864   {
4865     size_in_bytes = hcryp->Init.HeaderSize * 4U;
4866   }
4867   else
4868   {
4869     size_in_bytes = hcryp->Init.HeaderSize;
4870   }
4871 
4872   if ((size_in_bytes != 0U))
4873   {
4874     /* Select header phase */
4875     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4876 
4877     /* Enable the CRYP peripheral */
4878     __HAL_CRYP_ENABLE(hcryp);
4879 
4880     /* If size_in_bytes is a multiple of blocks (a multiple of four 32-bits words ) */
4881     if ((size_in_bytes % 16U) == 0U)
4882     {
4883       /*  No padding */
4884       for (loopcounter = 0U; (loopcounter < (size_in_bytes / 4U)); loopcounter += 4U)
4885       {
4886         /* Write the input block in the data input register */
4887         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4888         hcryp->CrypHeaderCount++ ;
4889         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4890         hcryp->CrypHeaderCount++ ;
4891         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4892         hcryp->CrypHeaderCount++ ;
4893         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4894         hcryp->CrypHeaderCount++ ;
4895 
4896         if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
4897         {
4898           /* Disable the CRYP peripheral clock */
4899           __HAL_CRYP_DISABLE(hcryp);
4900 
4901           /* Change state */
4902           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4903           hcryp->State = HAL_CRYP_STATE_READY;
4904 
4905           /* Process unlocked */
4906           __HAL_UNLOCK(hcryp);
4907           return HAL_ERROR;
4908         }
4909         /* Clear CCF flag */
4910         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4911       }
4912     }
4913     else
4914     {
4915       /* Write header block in the IN FIFO without last block */
4916       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 16U) * 4U)); loopcounter += 4U)
4917       {
4918         /* Write the input block in the data input register */
4919         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4920         hcryp->CrypHeaderCount++ ;
4921         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4922         hcryp->CrypHeaderCount++ ;
4923         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4924         hcryp->CrypHeaderCount++ ;
4925         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4926         hcryp->CrypHeaderCount++ ;
4927 
4928         if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
4929         {
4930           /* Disable the CRYP peripheral clock */
4931           __HAL_CRYP_DISABLE(hcryp);
4932 
4933           /* Change state */
4934           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4935           hcryp->State = HAL_CRYP_STATE_READY;
4936 
4937           /* Process unlocked */
4938           __HAL_UNLOCK(hcryp);
4939           return HAL_ERROR;
4940         }
4941         /* Clear CCF flag */
4942         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4943       }
4944       /* Write last complete words */
4945       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 4U) % 4U)); loopcounter++)
4946       {
4947         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4948         hcryp->CrypHeaderCount++ ;
4949       }
4950       /* If the header size is a multiple of words */
4951       if ((size_in_bytes % 4U) == 0U)
4952       {
4953         /* Pad the data with zeros to have a complete block */
4954         while (loopcounter < 4U)
4955         {
4956           hcryp->Instance->DINR = 0x0U;
4957           loopcounter++;
4958         }
4959       }
4960       else
4961       {
4962          /* Enter last bytes, padded with zeros */
4963          tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4964          tmp &= mask[(hcryp->Init.DataType * 2U) + (size_in_bytes % 4U)];
4965          hcryp->Instance->DINR = tmp;
4966          loopcounter++;
4967          /* Pad the data with zeros to have a complete block */
4968          while (loopcounter < 4U)
4969          {
4970            hcryp->Instance->DINR = 0x0U;
4971            loopcounter++;
4972          }
4973       }
4974 
4975       if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
4976       {
4977         /* Disable the CRYP peripheral clock */
4978         __HAL_CRYP_DISABLE(hcryp);
4979 
4980         /* Change state */
4981         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4982         hcryp->State = HAL_CRYP_STATE_READY;
4983 
4984         /* Process unlocked */
4985         __HAL_UNLOCK(hcryp);
4986         return HAL_ERROR;
4987       }
4988       /* Clear CCF flag */
4989       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4990     }
4991   }
4992   else
4993   {
4994     /*Workaround 1: only AES, before re-enabling the peripheral, datatype can be configured.*/
4995     MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE, hcryp->Init.DataType);
4996 
4997     /* Select header phase */
4998     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4999 
5000     /* Enable the CRYP peripheral */
5001     __HAL_CRYP_ENABLE(hcryp);
5002   }
5003   /* Return function status */
5004   return HAL_OK;
5005 }
5006 
5007 /**
5008   * @brief  Sets the header phase when using DMA in process
5009   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5010   *         the configuration information for CRYP module(Header & HeaderSize)
5011   * @retval None
5012   */
CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef * hcryp)5013 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp)
5014 {
5015   uint32_t loopcounter;
5016   uint32_t headersize_in_bytes;
5017   uint32_t tmp;
5018   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
5019                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
5020                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU}; /*  8-bit data type */
5021 
5022   /***************************** Header phase for GCM/GMAC or CCM *********************************/
5023   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
5024   {
5025     headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
5026   }
5027   else
5028   {
5029     headersize_in_bytes = hcryp->Init.HeaderSize;
5030   }
5031 
5032   /* Select header phase */
5033   CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
5034 
5035   /* Enable the CRYP peripheral */
5036   __HAL_CRYP_ENABLE(hcryp);
5037 
5038   /* Set the phase */
5039   hcryp->Phase = CRYP_PHASE_PROCESS;
5040 
5041   /* If header size is at least equal to 16 bytes, feed the header through DMA.
5042      If size_in_bytes is not a multiple of blocks (is not a multiple of four 32-bit words ),
5043      last bytes feeding and padding will be done in CRYP_DMAInCplt() */
5044   if (headersize_in_bytes >= 16U)
5045   {
5046     /* Initiate header DMA transfer */
5047     if (CRYP_SetHeaderDMAConfig(hcryp, (uint32_t)(hcryp->Init.Header), (uint16_t)((headersize_in_bytes / 16U) * 4U)) != HAL_OK)
5048     {
5049       return HAL_ERROR;
5050     }
5051   }
5052   else
5053   {
5054     if (headersize_in_bytes != 0U)
5055     {
5056       /* Header length is larger than 0 and strictly less than 16 bytes */
5057       /* Write last complete words */
5058       for (loopcounter = 0U; (loopcounter < (headersize_in_bytes / 4U)); loopcounter++)
5059       {
5060         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5061         hcryp->CrypHeaderCount++ ;
5062       }
5063       /* If the header size is a multiple of words */
5064       if ((headersize_in_bytes % 4U) == 0U)
5065       {
5066         /* Pad the data with zeros to have a complete block */
5067         while (loopcounter < 4U)
5068         {
5069           hcryp->Instance->DINR = 0x0U;
5070           loopcounter++;
5071         }
5072       }
5073       else
5074       {
5075         /* Enter last bytes, padded with zeros */
5076         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5077         tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
5078         hcryp->Instance->DINR = tmp;
5079         loopcounter++;
5080         /* Pad the data with zeros to have a complete block */
5081         while (loopcounter < 4U)
5082         {
5083           hcryp->Instance->DINR = 0x0U;
5084           loopcounter++;
5085         }
5086       }
5087 
5088       if (CRYP_WaitOnCCFlag(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE) != HAL_OK)
5089       {
5090         /* Disable the CRYP peripheral clock */
5091         __HAL_CRYP_DISABLE(hcryp);
5092 
5093         /* Change state */
5094         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5095         hcryp->State = HAL_CRYP_STATE_READY;
5096 
5097         /* Process unlocked */
5098         __HAL_UNLOCK(hcryp);
5099         return HAL_ERROR;
5100       }
5101       /* Clear CCF flag */
5102       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
5103     } /* if (headersize_in_bytes != 0U) */
5104 
5105     /* Move to payload phase if header length is null or
5106        if the header length was less than 16 and header written by software instead of DMA */
5107 
5108     /* Set to 0 the number of non-valid bytes using NPBLB register*/
5109     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
5110 
5111     /* Select payload phase once the header phase is performed */
5112     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
5113 
5114     /* Initiate payload DMA IN and processed data DMA OUT transfers */
5115     if (CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp) != HAL_OK)
5116     {
5117       return HAL_ERROR;
5118     }
5119   } /* if (headersize_in_bytes >= 16U) */
5120 
5121   /* Return function status */
5122   return HAL_OK;
5123 }
5124 
5125 /**
5126   * @brief  Sets the header phase in interrupt mode
5127   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5128   *         the configuration information for CRYP module(Header & HeaderSize)
5129   * @retval None
5130   */
CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef * hcryp)5131 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp)
5132 {
5133   uint32_t loopcounter;
5134   uint32_t lastwordsize;
5135   uint32_t npblb;
5136   uint32_t mode;
5137   uint32_t headersize_in_bytes;
5138   uint32_t tmp;
5139   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
5140                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
5141                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU}; /*  8-bit data type */
5142 
5143   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
5144   {
5145     headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
5146   }
5147   else
5148   {
5149     headersize_in_bytes = hcryp->Init.HeaderSize;
5150   }
5151 
5152   /***************************** Header phase *********************************/
5153   /* Test whether or not the header phase is over.
5154      If the test below is true, move to payload phase */
5155   if (headersize_in_bytes <= ((uint32_t)(hcryp->CrypHeaderCount) * 4U))
5156   {
5157     /* Set the phase */
5158     hcryp->Phase = CRYP_PHASE_PROCESS;
5159     /* Select payload phase */
5160     MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
5161     /* Set to 0 the number of non-valid bytes using NPBLB register*/
5162     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
5163 
5164     if (hcryp->Init.Algorithm == CRYP_AES_CCM)
5165     {
5166       /* Increment CrypHeaderCount to pass in CRYP_GCMCCM_SetPayloadPhase_IT */
5167       hcryp->CrypHeaderCount++;
5168     }
5169     /* Write the payload Input block in the IN FIFO */
5170     if (hcryp->Size == 0U)
5171     {
5172       /* Disable interrupts */
5173       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
5174 
5175       /* Change the CRYP state */
5176       hcryp->State = HAL_CRYP_STATE_READY;
5177 
5178       /* Process unlocked */
5179       __HAL_UNLOCK(hcryp);
5180     }
5181     else if (hcryp->Size >= 16U)
5182     {
5183       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5184       hcryp->CrypInCount++;
5185       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5186       hcryp->CrypInCount++;
5187       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5188       hcryp->CrypInCount++;
5189       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5190       hcryp->CrypInCount++;
5191 
5192       if ((hcryp->CrypInCount ==  (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
5193       {
5194         /* Call the input data transfer complete callback */
5195 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5196         /*Call registered Input complete callback*/
5197         hcryp->InCpltCallback(hcryp);
5198 #else
5199         /*Call legacy weak Input complete callback*/
5200         HAL_CRYP_InCpltCallback(hcryp);
5201 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5202       }
5203     }
5204     else /* Size < 4 words  : first block is the last block*/
5205     {
5206       /* Compute the number of padding bytes in last block of payload */
5207       npblb = 16U - ((uint32_t)hcryp->Size);
5208       mode = hcryp->Instance->CR & AES_CR_MODE;
5209       if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
5210           ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
5211       {
5212         /* Specify the number of non-valid bytes using NPBLB register*/
5213         MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
5214       }
5215 
5216       /* Number of valid words (lastwordsize) in last block */
5217       if ((npblb % 4U) == 0U)
5218       {
5219         lastwordsize = (16U - npblb) / 4U;
5220       }
5221       else
5222       {
5223         lastwordsize = ((16U - npblb) / 4U) + 1U;
5224       }
5225 
5226       /*  Last block optionally pad the data with zeros*/
5227       for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
5228       {
5229         hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5230         hcryp->CrypInCount++;
5231       }
5232       while (loopcounter < 4U)
5233       {
5234         /* Pad the data with zeros to have a complete block */
5235         hcryp->Instance->DINR = 0x0U;
5236         loopcounter++;
5237       }
5238       /* Call the input data transfer complete callback */
5239 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5240       /*Call registered Input complete callback*/
5241       hcryp->InCpltCallback(hcryp);
5242 #else
5243       /*Call legacy weak Input complete callback*/
5244       HAL_CRYP_InCpltCallback(hcryp);
5245 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5246     }
5247   }
5248   else if ((((headersize_in_bytes / 4U) - (hcryp->CrypHeaderCount)) >= 4U))
5249   {
5250     /* Can enter full 4 header words */
5251 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
5252     /* If suspension flag has been raised, suspend processing
5253        only if not already at the end of the header */
5254     if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
5255     {
5256       /* Clear CCF Flag */
5257       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
5258 
5259       /* reset SuspendRequest */
5260       hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
5261       /* Disable Computation Complete Flag and Errors Interrupts */
5262       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
5263       /* Change the CRYP state */
5264       hcryp->State = HAL_CRYP_STATE_SUSPENDED;
5265       /* Mark that the payload phase is suspended */
5266       hcryp->Phase = CRYP_PHASE_HEADER_SUSPENDED;
5267 
5268      /* Process Unlocked */
5269       __HAL_UNLOCK(hcryp);
5270     }
5271     else
5272 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
5273     {
5274     /* Write the input block in the IN FIFO */
5275     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5276     hcryp->CrypHeaderCount++;
5277     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5278     hcryp->CrypHeaderCount++;
5279     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5280     hcryp->CrypHeaderCount++;
5281     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5282     hcryp->CrypHeaderCount++;
5283   }
5284   }
5285   else /* Write last header block (4 words), padded with zeros if needed */
5286   {
5287 
5288     for (loopcounter = 0U; (loopcounter < ((headersize_in_bytes / 4U) % 4U)); loopcounter++)
5289     {
5290       hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5291       hcryp->CrypHeaderCount++ ;
5292     }
5293     /* If the header size is a multiple of words */
5294     if ((headersize_in_bytes % 4U) == 0U)
5295     {
5296       /* Pad the data with zeros to have a complete block */
5297       while (loopcounter < 4U)
5298       {
5299         hcryp->Instance->DINR = 0x0U;
5300         loopcounter++;
5301         hcryp->CrypHeaderCount++;
5302       }
5303     }
5304     else
5305     {
5306       /* Enter last bytes, padded with zeros */
5307       tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5308       tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
5309       hcryp->Instance->DINR = tmp;
5310       loopcounter++;
5311       hcryp->CrypHeaderCount++;
5312       /* Pad the data with zeros to have a complete block */
5313     while (loopcounter < 4U)
5314     {
5315       hcryp->Instance->DINR = 0x0U;
5316       loopcounter++;
5317         hcryp->CrypHeaderCount++;
5318       }
5319     }
5320   }
5321 }
5322 
5323 /**
5324   * @brief  Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
5325   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5326   *         the configuration information for CRYP module.
5327   * @param  Timeout Timeout duration.
5328   * @note   This function can only be used in thread mode.
5329   * @retval HAL status
5330   */
CRYP_WaitOnCCFlag(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5331 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5332 {
5333   uint32_t tickstart;
5334 
5335   /* Get timeout */
5336   tickstart = HAL_GetTick();
5337 
5338   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
5339   {
5340     /* Check for the Timeout */
5341     if (Timeout != HAL_MAX_DELAY)
5342     {
5343       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5344       {
5345         return HAL_ERROR;
5346       }
5347     }
5348   }
5349   return HAL_OK;
5350 }
5351 
5352 /**
5353   * @brief  Wait for Computation Complete Flag (CCF) to raise then clear it.
5354   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5355   *         the configuration information for CRYP module.
5356   * @param  Timeout Timeout duration.
5357   * @note   This function can be used in thread or handler mode.
5358   * @retval HAL status
5359   */
CRYP_ClearCCFlagWhenHigh(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5360 static void CRYP_ClearCCFlagWhenHigh(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5361 {
5362   uint32_t count = Timeout;
5363 
5364   do
5365   {
5366     count-- ;
5367     if (count == 0U)
5368     {
5369       /* Disable the CRYP peripheral clock */
5370       __HAL_CRYP_DISABLE(hcryp);
5371 
5372       /* Change state */
5373       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5374 
5375       /* Process unlocked */
5376       __HAL_UNLOCK(hcryp);
5377       hcryp->State = HAL_CRYP_STATE_READY;
5378 
5379 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5380     /*Call registered error callback*/
5381     hcryp->ErrorCallback(hcryp);
5382 #else
5383     /*Call legacy weak error callback*/
5384     HAL_CRYP_ErrorCallback(hcryp);
5385 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5386     }
5387   }
5388   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
5389 
5390   /* Clear CCF flag */
5391   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
5392 }
5393 
5394 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
5395 /**
5396   * @brief  In case of message processing suspension, read the Initialization Vector.
5397   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5398   *         the configuration information for CRYP module.
5399   * @param  Output Pointer to the buffer containing the saved Initialization Vector.
5400   * @note   This value has to be stored for reuse by writing the AES_IVRx registers
5401   *         as soon as the suspended processing has to be resumed.
5402   * @retval None
5403   */
CRYP_Read_IVRegisters(CRYP_HandleTypeDef * hcryp,uint32_t * Output)5404 static void CRYP_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output)
5405 {
5406   uint32_t outputaddr = (uint32_t)Output;
5407 
5408   *(uint32_t*)(outputaddr) = hcryp->Instance->IVR3;
5409   outputaddr+=4U;
5410   *(uint32_t*)(outputaddr) = hcryp->Instance->IVR2;
5411   outputaddr+=4U;
5412   *(uint32_t*)(outputaddr) = hcryp->Instance->IVR1;
5413   outputaddr+=4U;
5414   *(uint32_t*)(outputaddr) = hcryp->Instance->IVR0;
5415 }
5416 
5417 /**
5418   * @brief  In case of message processing resumption, rewrite the Initialization
5419   *         Vector in the AES_IVRx registers.
5420   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5421   *         the configuration information for CRYP module.
5422   * @param  Input Pointer to the buffer containing the saved Initialization Vector to
5423   *         write back in the CRYP hardware block.
5424   * @note   AES must be disabled when reconfiguring the IV values.
5425   * @retval None
5426   */
CRYP_Write_IVRegisters(CRYP_HandleTypeDef * hcryp,uint32_t * Input)5427 static void CRYP_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input)
5428 {
5429   uint32_t ivaddr = (uint32_t)Input;
5430 
5431   hcryp->Instance->IVR3 = *(uint32_t*)(ivaddr);
5432   ivaddr+=4U;
5433   hcryp->Instance->IVR2 = *(uint32_t*)(ivaddr);
5434   ivaddr+=4U;
5435   hcryp->Instance->IVR1 = *(uint32_t*)(ivaddr);
5436   ivaddr+=4U;
5437   hcryp->Instance->IVR0 = *(uint32_t*)(ivaddr);
5438 }
5439 
5440 /**
5441   * @brief  In case of message GCM/GMAC/CCM processing suspension,
5442   *         read the Suspend Registers.
5443   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5444   *         the configuration information for CRYP module.
5445   * @param  Output Pointer to the buffer containing the saved Suspend Registers.
5446   * @note   These values have to be stored for reuse by writing back the AES_SUSPxR registers
5447   *         as soon as the suspended processing has to be resumed.
5448   * @retval None
5449   */
CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef * hcryp,uint32_t * Output)5450 static void CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output)
5451 {
5452   uint32_t outputaddr = (uint32_t)Output;
5453   __IO uint32_t count = 0U;
5454 
5455   /* In case of GCM payload phase encryption, check that suspension can be carried out */
5456   if (READ_BIT(hcryp->Instance->CR, (AES_CR_CHMOD|AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_AES_GCM_GMAC|AES_CR_GCMPH_1|0x0U))
5457   {
5458 
5459       /* Wait for BUSY flag to be cleared */
5460       count = 0xFFF;
5461       do
5462       {
5463         count-- ;
5464         if(count == 0U)
5465         {
5466           /* Change state */
5467           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5468           hcryp->State = HAL_CRYP_STATE_READY;
5469 
5470           /* Process unlocked */
5471           __HAL_UNLOCK(hcryp);
5472           HAL_CRYP_ErrorCallback(hcryp);
5473           return;
5474         }
5475       }
5476       while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY));
5477 
5478   }
5479 
5480 
5481   *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP7R;
5482   outputaddr+=4U;
5483   *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP6R;
5484   outputaddr+=4U;
5485   *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP5R;
5486   outputaddr+=4U;
5487   *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP4R;
5488   outputaddr+=4U;
5489   *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP3R;
5490   outputaddr+=4U;
5491   *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP2R;
5492   outputaddr+=4U;
5493   *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP1R;
5494   outputaddr+=4U;
5495   *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP0R;
5496 }
5497 
5498 /**
5499   * @brief  In case of message GCM/GMAC/CCM processing resumption, rewrite the Suspend
5500   *         Registers in the AES_SUSPxR registers.
5501   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5502   *         the configuration information for CRYP module.
5503   * @param  Input Pointer to the buffer containing the saved suspend registers to
5504   *         write back in the CRYP hardware block.
5505   * @note   AES must be disabled when reconfiguring the suspend registers.
5506   * @retval None
5507   */
CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef * hcryp,uint32_t * Input)5508 static void CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input)
5509 {
5510   uint32_t ivaddr = (uint32_t)Input;
5511 
5512   hcryp->Instance->SUSP7R = *(uint32_t*)(ivaddr);
5513   ivaddr+=4U;
5514   hcryp->Instance->SUSP6R = *(uint32_t*)(ivaddr);
5515   ivaddr+=4U;
5516   hcryp->Instance->SUSP5R = *(uint32_t*)(ivaddr);
5517   ivaddr+=4U;
5518   hcryp->Instance->SUSP4R = *(uint32_t*)(ivaddr);
5519   ivaddr+=4U;
5520   hcryp->Instance->SUSP3R = *(uint32_t*)(ivaddr);
5521   ivaddr+=4U;
5522   hcryp->Instance->SUSP2R = *(uint32_t*)(ivaddr);
5523   ivaddr+=4U;
5524   hcryp->Instance->SUSP1R = *(uint32_t*)(ivaddr);
5525   ivaddr+=4U;
5526   hcryp->Instance->SUSP0R = *(uint32_t*)(ivaddr);
5527 }
5528 
5529 /**
5530   * @brief  In case of message GCM/GMAC/CCM processing suspension, read the Key Registers.
5531   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5532   *         the configuration information for CRYP module.
5533   * @param  Output Pointer to the buffer containing the saved Key Registers.
5534   * @param  KeySize Indicates the key size (128 or 256 bits).
5535   * @note   These values have to be stored for reuse by writing back the AES_KEYRx registers
5536   *         as soon as the suspended processing has to be resumed.
5537   * @retval None
5538   */
CRYP_Read_KeyRegisters(CRYP_HandleTypeDef * hcryp,uint32_t * Output,uint32_t KeySize)5539 static void CRYP_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output, uint32_t KeySize)
5540 {
5541   uint32_t keyaddr = (uint32_t)Output;
5542 
5543   switch (KeySize)
5544   {
5545     case CRYP_KEYSIZE_256B:
5546       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey);
5547       keyaddr+=4U;
5548       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 1U);
5549       keyaddr+=4U;
5550       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 2U);
5551       keyaddr+=4U;
5552       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 3U);
5553       keyaddr+=4U;
5554       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 4U);
5555       keyaddr+=4U;
5556       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 5U);
5557       keyaddr+=4U;
5558       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 6U);
5559       keyaddr+=4U;
5560       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 7U);
5561       break;
5562     case CRYP_KEYSIZE_128B:
5563       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey);
5564       keyaddr+=4U;
5565       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 1U);
5566       keyaddr+=4U;
5567       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 2U);
5568       keyaddr+=4U;
5569       *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 3U);
5570       break;
5571     default:
5572       break;
5573   }
5574 }
5575 
5576 /**
5577   * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key
5578   *         Registers in the AES_KEYRx registers.
5579   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5580   *         the configuration information for CRYP module.
5581   * @param  Input Pointer to the buffer containing the saved key registers to
5582   *         write back in the CRYP hardware block.
5583   * @param  KeySize Indicates the key size (128 or 256 bits)
5584   * @note   AES must be disabled when reconfiguring the Key registers.
5585   * @retval None
5586   */
CRYP_Write_KeyRegisters(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint32_t KeySize)5587 static void CRYP_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input, uint32_t KeySize)
5588 {
5589   uint32_t keyaddr = (uint32_t)Input;
5590 
5591   if (KeySize == CRYP_KEYSIZE_256B)
5592   {
5593     hcryp->Instance->KEYR7 = *(uint32_t*)(keyaddr);
5594     keyaddr+=4U;
5595     hcryp->Instance->KEYR6 = *(uint32_t*)(keyaddr);
5596     keyaddr+=4U;
5597     hcryp->Instance->KEYR5 = *(uint32_t*)(keyaddr);
5598     keyaddr+=4U;
5599     hcryp->Instance->KEYR4 = *(uint32_t*)(keyaddr);
5600     keyaddr+=4U;
5601   }
5602 
5603     hcryp->Instance->KEYR3 = *(uint32_t*)(keyaddr);
5604     keyaddr+=4U;
5605     hcryp->Instance->KEYR2 = *(uint32_t*)(keyaddr);
5606     keyaddr+=4U;
5607     hcryp->Instance->KEYR1 = *(uint32_t*)(keyaddr);
5608     keyaddr+=4U;
5609     hcryp->Instance->KEYR0 = *(uint32_t*)(keyaddr);
5610 }
5611 
5612 /**
5613   * @brief  Authentication phase resumption in case of GCM/GMAC/CCM process in interrupt mode
5614   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5615   *         the configuration information for CRYP module(Header & HeaderSize)
5616   * @retval None
5617   */
CRYP_PhaseProcessingResume(CRYP_HandleTypeDef * hcryp)5618 static void CRYP_PhaseProcessingResume(CRYP_HandleTypeDef *hcryp)
5619 {
5620   uint32_t loopcounter;
5621   uint16_t lastwordsize;
5622   uint16_t npblb;
5623   uint32_t cr_temp;
5624 
5625 
5626   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR | CRYP_CCF_CLEAR);
5627 
5628   /* Enable computation complete flag and error interrupts */
5629   __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
5630 
5631   /* Enable the CRYP peripheral */
5632   __HAL_CRYP_ENABLE(hcryp);
5633 
5634   /* Case of header phase resumption =================================================*/
5635   if (hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED)
5636   {
5637       /* Set the phase */
5638     hcryp->Phase = CRYP_PHASE_PROCESS;
5639 
5640     /* Select header phase */
5641     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
5642 
5643     if ((((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount)) >= 4U))
5644     {
5645       /* Write the input block in the IN FIFO */
5646       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount );
5647       hcryp->CrypHeaderCount++;
5648       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount );
5649       hcryp->CrypHeaderCount++;
5650       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount );
5651       hcryp->CrypHeaderCount++;
5652       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount );
5653       hcryp->CrypHeaderCount++;
5654     }
5655     else /*HeaderSize < 4 or HeaderSize >4 & HeaderSize %4 != 0*/
5656     {
5657       /*  Last block optionally pad the data with zeros*/
5658       for(loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize %4U ); loopcounter++)
5659       {
5660         hcryp->Instance->DINR = *(uint32_t*)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5661         hcryp->CrypHeaderCount++ ;
5662       }
5663       while(loopcounter <4U )
5664       {
5665         /* pad the data with zeros to have a complete block */
5666         hcryp->Instance->DINR = 0x0U;
5667         loopcounter++;
5668       }
5669     }
5670   }
5671   /* Case of payload phase resumption =================================================*/
5672   else
5673   {
5674     if (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED)
5675     {
5676 
5677       /* Set the phase */
5678       hcryp->Phase = CRYP_PHASE_PROCESS;
5679 
5680       /* Select payload phase once the header phase is performed */
5681       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
5682 
5683       /* Set to 0 the number of non-valid bytes using NPBLB register*/
5684       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
5685 
5686       if (((hcryp->Size/4U) - (hcryp->CrypInCount)) >= 4U)
5687       {
5688         /* Write the input block in the IN FIFO */
5689         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5690         hcryp->CrypInCount++;
5691         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5692         hcryp->CrypInCount++;
5693         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5694         hcryp->CrypInCount++;
5695         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5696         hcryp->CrypInCount++;
5697         if ((hcryp->CrypInCount ==  (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
5698         {
5699           /* Call input transfer complete callback */
5700 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5701           /*Call registered Input complete callback*/
5702           hcryp->InCpltCallback(hcryp);
5703 #else
5704           /*Call legacy weak Input complete callback*/
5705           HAL_CRYP_InCpltCallback(hcryp);
5706 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5707         }
5708       }
5709       else /* Last block of payload < 128bit*/
5710       {
5711         /* Compute the number of padding bytes in last block of payload */
5712         npblb = (((hcryp->Size/16U)+1U)*16U) - (hcryp->Size);
5713         cr_temp = hcryp->Instance->CR;
5714         if((((cr_temp & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
5715            (((cr_temp& AES_CR_MODE) == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
5716         {
5717           /* Specify the number of non-valid bytes using NPBLB register*/
5718             MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, ((uint32_t)npblb)<< 20U);
5719         }
5720 
5721         /* Number of valid words (lastwordsize) in last block */
5722         if ((npblb % 4U) ==0U)
5723         {
5724           lastwordsize = (16U-npblb)/4U;
5725         }
5726         else
5727         {
5728           lastwordsize = ((16U-npblb)/4U) +1U;
5729         }
5730 
5731         /*  Last block optionally pad the data with zeros*/
5732         for(loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
5733         {
5734           hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5735           hcryp->CrypInCount++;
5736         }
5737         while(loopcounter < 4U )
5738         {
5739           /* pad the data with zeros to have a complete block */
5740           hcryp->Instance->DINR = 0x0U;
5741           loopcounter++;
5742         }
5743       }
5744     }
5745   }
5746 }
5747 #endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */
5748 /**
5749   * @}
5750   */
5751 
5752 
5753 #endif /* HAL_CRYP_MODULE_ENABLED */
5754 
5755 
5756 /**
5757   * @}
5758   */
5759 
5760 /**
5761  * @}
5762  */
5763