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