1 /**
2 ******************************************************************************
3 * @file stm32h7xx_hal_cryp_ex.c
4 * @author MCD Application Team
5 * @brief Extended CRYP HAL module driver
6 * This file provides firmware functions to manage the following
7 * functionalities of CRYP extension peripheral:
8 * + Extended AES processing functions
9 *
10 ******************************************************************************
11 * @attention
12 *
13 * Copyright (c) 2017 STMicroelectronics.
14 * All rights reserved.
15 *
16 * This software is licensed under terms that can be found in the LICENSE file
17 * in the root directory of this software component.
18 * If no LICENSE file comes with this software, it is provided AS-IS.
19 *
20 ******************************************************************************
21 @verbatim
22 ==============================================================================
23 ##### How to use this driver #####
24 ==============================================================================
25 [..]
26 The CRYP extension HAL driver can be used after AES-GCM or AES-CCM
27 Encryption/Decryption to get the authentication messages.
28
29 @endverbatim
30 */
31
32 /* Includes ------------------------------------------------------------------*/
33 #include "stm32h7xx_hal.h"
34
35 /** @addtogroup STM32H7xx_HAL_Driver
36 * @{
37 */
38 #if defined (CRYP)
39 /** @defgroup CRYPEx CRYPEx
40 * @brief CRYP Extension HAL module driver.
41 * @{
42 */
43
44 #ifdef HAL_CRYP_MODULE_ENABLED
45
46 /* Private typedef -----------------------------------------------------------*/
47 /* Private define ------------------------------------------------------------*/
48 /** @addtogroup CRYPEx_Private_Defines
49 * @{
50 */
51
52 #define CRYP_PHASE_INIT 0x00000000U
53 #define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0
54 #define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1
55 #define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH
56
57 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U
58 #define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR
59
60 #define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */
61 #define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
62
63 /* CTR0 information to use in CCM algorithm */
64 #define CRYP_CCM_CTR0_0 0x07FFFFFFU
65 #define CRYP_CCM_CTR0_3 0xFFFFFF00U
66
67 /**
68 * @}
69 */
70
71 /* Private macro -------------------------------------------------------------*/
72 /* Private variables ---------------------------------------------------------*/
73 /* Private function prototypes -----------------------------------------------*/
74
75
76
77 /* Exported functions---------------------------------------------------------*/
78 /** @addtogroup CRYPEx_Exported_Functions
79 * @{
80 */
81
82 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
83 * @brief CRYPEx Extended processing functions.
84 *
85 @verbatim
86 ==============================================================================
87 ##### Extended AES processing functions #####
88 ==============================================================================
89 [..] This section provides functions allowing to generate the authentication
90 TAG in Polling mode
91 (+)HAL_CRYPEx_AESGCM_GenerateAuthTAG
92 (+)HAL_CRYPEx_AESCCM_GenerateAuthTAG
93 they should be used after Encrypt/Decrypt operation.
94
95 @endverbatim
96 * @{
97 */
98
99
100 /**
101 * @brief generate the GCM authentication TAG.
102 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
103 * the configuration information for CRYP module
104 * @param AuthTag: Pointer to the authentication buffer
105 * the AuthTag generated here is 128bits length, if the TAG length is
106 * less than 128bits, user should consider only the valid part of AuthTag
107 * buffer which correspond exactly to TAG length.
108 * @param Timeout: Timeout duration
109 * @retval HAL status
110 */
HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,uint32_t * AuthTag,uint32_t Timeout)111 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
112 {
113 uint32_t tickstart;
114 uint64_t headerlength = (uint64_t)(hcryp->Init.HeaderSize) * 32U; /* Header length in bits */
115 uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
116 uint32_t tagaddr = (uint32_t)AuthTag;
117
118 /* Correct header length if Init.HeaderSize is actually in bytes */
119 if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
120 {
121 headerlength /= 4U;
122 }
123
124 if (hcryp->State == HAL_CRYP_STATE_READY)
125 {
126 /* Process locked */
127 __HAL_LOCK(hcryp);
128
129 /* Change the CRYP peripheral state */
130 hcryp->State = HAL_CRYP_STATE_BUSY;
131
132 /* Check if initialization phase has already been performed */
133 if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
134 {
135 /* Change the CRYP phase */
136 hcryp->Phase = CRYPEx_PHASE_FINAL;
137 }
138 else /* Initialization phase has not been performed*/
139 {
140 /* Disable the Peripheral */
141 __HAL_CRYP_DISABLE(hcryp);
142
143 /* Sequence error code field */
144 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
145
146 /* Change the CRYP peripheral state */
147 hcryp->State = HAL_CRYP_STATE_READY;
148
149 /* Process unlocked */
150 __HAL_UNLOCK(hcryp);
151 return HAL_ERROR;
152 }
153
154 /* Disable CRYP to start the final phase */
155 __HAL_CRYP_DISABLE(hcryp);
156
157 /* Select final phase */
158 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
159
160 /*ALGODIR bit must be set to '0'.*/
161 hcryp->Instance->CR &= ~CRYP_CR_ALGODIR;
162
163 /* Enable the CRYP peripheral */
164 __HAL_CRYP_ENABLE(hcryp);
165
166 /* Write the number of bits in header (64 bits) followed by the number of bits
167 in the payload */
168 #if !defined (CRYP_VER_2_2)
169 /* STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/
170 if (hcryp->Version >= REV_ID_B)
171 #endif /*End of not defined CRYP_VER_2_2*/
172 {
173 hcryp->Instance->DIN = 0U;
174 hcryp->Instance->DIN = (uint32_t)(headerlength);
175 hcryp->Instance->DIN = 0U;
176 hcryp->Instance->DIN = (uint32_t)(inputlength);
177 }
178 #if !defined (CRYP_VER_2_2)
179 else/* data has to be swapped according to the DATATYPE */
180 {
181 if (hcryp->Init.DataType == CRYP_BIT_SWAP)
182 {
183 hcryp->Instance->DIN = 0U;
184 hcryp->Instance->DIN = __RBIT((uint32_t)(headerlength));
185 hcryp->Instance->DIN = 0U;
186 hcryp->Instance->DIN = __RBIT((uint32_t)(inputlength));
187 }
188 else if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
189 {
190 hcryp->Instance->DIN = 0U;
191 hcryp->Instance->DIN = __REV((uint32_t)(headerlength));
192 hcryp->Instance->DIN = 0U;
193 hcryp->Instance->DIN = __REV((uint32_t)(inputlength));
194 }
195 else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
196 {
197 hcryp->Instance->DIN = 0U;
198 hcryp->Instance->DIN = __ROR((uint32_t)headerlength, 16U);
199 hcryp->Instance->DIN = 0U;
200 hcryp->Instance->DIN = __ROR((uint32_t)inputlength, 16U);
201 }
202 else if (hcryp->Init.DataType == CRYP_NO_SWAP)
203 {
204 hcryp->Instance->DIN = 0U;
205 hcryp->Instance->DIN = (uint32_t)(headerlength);
206 hcryp->Instance->DIN = 0U;
207 hcryp->Instance->DIN = (uint32_t)(inputlength);
208 }
209 else
210 {
211 /* Nothing to do */
212 }
213 }
214 #endif /*End of not defined CRYP_VER_2_2*/
215 /* Wait for OFNE flag to be raised */
216 tickstart = HAL_GetTick();
217 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
218 {
219 /* Check for the Timeout */
220 if (Timeout != HAL_MAX_DELAY)
221 {
222 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
223 {
224 /* Disable the CRYP Peripheral Clock */
225 __HAL_CRYP_DISABLE(hcryp);
226
227 /* Change state */
228 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
229 hcryp->State = HAL_CRYP_STATE_READY;
230
231 /* Process unlocked */
232 __HAL_UNLOCK(hcryp);
233 return HAL_ERROR;
234 }
235 }
236 }
237
238 /* Read the authentication TAG in the output FIFO */
239 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
240 tagaddr += 4U;
241 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
242 tagaddr += 4U;
243 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
244 tagaddr += 4U;
245 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
246
247 /* Disable the peripheral */
248 __HAL_CRYP_DISABLE(hcryp);
249
250 /* Change the CRYP peripheral state */
251 hcryp->State = HAL_CRYP_STATE_READY;
252
253 /* Process unlocked */
254 __HAL_UNLOCK(hcryp);
255 }
256 else
257 {
258 /* Busy error code field */
259 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
260 return HAL_ERROR;
261 }
262 /* Return function status */
263 return HAL_OK;
264 }
265
266 /**
267 * @brief AES CCM Authentication TAG generation.
268 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
269 * the configuration information for CRYP module
270 * @param AuthTag: Pointer to the authentication buffer
271 * the AuthTag generated here is 128bits length, if the TAG length is
272 * less than 128bits, user should consider only the valid part of AuthTag
273 * buffer which correspond exactly to TAG length.
274 * @param Timeout: Timeout duration
275 * @retval HAL status
276 */
HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,uint32_t * AuthTag,uint32_t Timeout)277 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
278 {
279 uint32_t tagaddr = (uint32_t)AuthTag;
280 uint32_t ctr0 [4] = {0};
281 uint32_t ctr0addr = (uint32_t)ctr0;
282 uint32_t tickstart;
283
284 if (hcryp->State == HAL_CRYP_STATE_READY)
285 {
286 /* Process locked */
287 __HAL_LOCK(hcryp);
288
289 /* Change the CRYP peripheral state */
290 hcryp->State = HAL_CRYP_STATE_BUSY;
291
292 /* Check if initialization phase has already been performed */
293 if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
294 {
295 /* Change the CRYP phase */
296 hcryp->Phase = CRYPEx_PHASE_FINAL;
297 }
298 else /* Initialization phase has not been performed*/
299 {
300 /* Disable the peripheral */
301 __HAL_CRYP_DISABLE(hcryp);
302
303 /* Sequence error code field */
304 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
305
306 /* Change the CRYP peripheral state */
307 hcryp->State = HAL_CRYP_STATE_READY;
308
309 /* Process unlocked */
310 __HAL_UNLOCK(hcryp);
311 return HAL_ERROR;
312 }
313
314 /* Disable CRYP to start the final phase */
315 __HAL_CRYP_DISABLE(hcryp);
316
317 /* Select final phase & ALGODIR bit must be set to '0'. */
318 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH | CRYP_CR_ALGODIR, CRYP_PHASE_FINAL | CRYP_OPERATINGMODE_ENCRYPT);
319
320 /* Enable the CRYP peripheral */
321 __HAL_CRYP_ENABLE(hcryp);
322
323 /* Write the counter block in the IN FIFO, CTR0 information from B0
324 data has to be swapped according to the DATATYPE*/
325 ctr0[0] = (hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
326 ctr0[1] = hcryp->Init.B0[1];
327 ctr0[2] = hcryp->Init.B0[2];
328 ctr0[3] = hcryp->Init.B0[3] & CRYP_CCM_CTR0_3;
329
330 #if !defined (CRYP_VER_2_2)
331 /*STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/
332 if (hcryp->Version >= REV_ID_B)
333 #endif /*End of not defined CRYP_VER_2_2*/
334 {
335 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
336 ctr0addr += 4U;
337 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
338 ctr0addr += 4U;
339 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
340 ctr0addr += 4U;
341 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
342 }
343 #if !defined (CRYP_VER_2_2)
344 else /* data has to be swapped according to the DATATYPE */
345 {
346 if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
347 {
348 hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
349 ctr0addr += 4U;
350 hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
351 ctr0addr += 4U;
352 hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
353 ctr0addr += 4U;
354 hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
355 }
356 else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
357 {
358 hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
359 ctr0addr += 4U;
360 hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
361 ctr0addr += 4U;
362 hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
363 ctr0addr += 4U;
364 hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
365 }
366 else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
367 {
368 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
369 ctr0addr += 4U;
370 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
371 ctr0addr += 4U;
372 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
373 ctr0addr += 4U;
374 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
375 }
376 else
377 {
378 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
379 ctr0addr += 4U;
380 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
381 ctr0addr += 4U;
382 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
383 ctr0addr += 4U;
384 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
385 }
386 }
387 #endif /*End of not defined CRYP_VER_2_2*/
388 /* Wait for OFNE flag to be raised */
389 tickstart = HAL_GetTick();
390 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
391 {
392 /* Check for the Timeout */
393 if (Timeout != HAL_MAX_DELAY)
394 {
395 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
396 {
397 /* Disable the CRYP peripheral Clock */
398 __HAL_CRYP_DISABLE(hcryp);
399
400 /* Change state */
401 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
402 hcryp->State = HAL_CRYP_STATE_READY;
403
404 /* Process unlocked */
405 __HAL_UNLOCK(hcryp);
406 return HAL_ERROR;
407 }
408 }
409 }
410
411 /* Read the Auth TAG in the IN FIFO */
412 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
413 tagaddr += 4U;
414 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
415 tagaddr += 4U;
416 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
417 tagaddr += 4U;
418 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
419
420 /* Change the CRYP peripheral state */
421 hcryp->State = HAL_CRYP_STATE_READY;
422
423 /* Process unlocked */
424 __HAL_UNLOCK(hcryp);
425
426 /* Disable CRYP */
427 __HAL_CRYP_DISABLE(hcryp);
428 }
429 else
430 {
431 /* Busy error code field */
432 hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
433 return HAL_ERROR;
434 }
435 /* Return function status */
436 return HAL_OK;
437 }
438
439 /**
440 * @}
441 */
442
443
444 #endif /* HAL_CRYP_MODULE_ENABLED */
445
446 /**
447 * @}
448 */
449 #endif /* CRYP */
450 /**
451 * @}
452 */
453
454 /**
455 * @}
456 */
457