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