source: trunk/firmware/Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_cryp.c

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