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

Last change on this file was 6, checked in by f.jahn, 8 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.