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