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