1 /**
2 ******************************************************************************
3 * @file stm32l5xx_hal_cryp_ex.c
4 * @author MCD Application Team
5 * @brief CRYPEx HAL module driver.
6 * This file provides firmware functions to manage the extended
7 * functionalities of the Cryptography (CRYP) peripheral.
8 *
9 ******************************************************************************
10 * @attention
11 *
12 * <h2><center>© Copyright (c) 2019 STMicroelectronics.
13 * All rights reserved.</center></h2>
14 *
15 * This software component is licensed by ST under BSD 3-Clause license,
16 * the "License"; You may not use this file except in compliance with the
17 * License. You may obtain a copy of the License at:
18 * opensource.org/licenses/BSD-3-Clause
19 *
20 ******************************************************************************
21 */
22
23 /* Includes ------------------------------------------------------------------*/
24 #include "stm32l5xx_hal.h"
25
26 /** @addtogroup STM32L5xx_HAL_Driver
27 * @{
28 */
29
30 /** @addtogroup CRYPEx
31 * @{
32 */
33
34 #if defined(AES)
35
36 #ifdef HAL_CRYP_MODULE_ENABLED
37
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private define ------------------------------------------------------------*/
40 /** @addtogroup CRYPEx_Private_Defines
41 * @{
42 */
43
44 #define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */
45 #define CRYP_PHASE_HEADER AES_CR_GCMPH_0 /*!< GCM/GMAC or CCM header phase */
46 #define CRYP_PHASE_PAYLOAD AES_CR_GCMPH_1 /*!< GCM(/CCM) payload phase */
47 #define CRYP_PHASE_FINAL AES_CR_GCMPH /*!< GCM/GMAC or CCM final phase */
48
49 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */
50 #define CRYP_OPERATINGMODE_KEYDERIVATION AES_CR_MODE_0 /*!< Key derivation mode only used when performing ECB and CBC decryptions */
51 #define CRYP_OPERATINGMODE_DECRYPT AES_CR_MODE_1 /*!< Decryption */
52 #define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT AES_CR_MODE /*!< Key derivation and decryption only used when performing ECB and CBC decryptions */
53
54 #define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */
55 #define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
56
57 /* CTR0 information to use in CCM algorithm */
58 #define CRYP_CCM_CTR0_0 0x07FFFFFFU
59 #define CRYP_CCM_CTR0_3 0xFFFFFF00U
60
61 /**
62 * @}
63 */
64
65 /* Private macro -------------------------------------------------------------*/
66 /* Private variables ---------------------------------------------------------*/
67 /* Private function prototypes -----------------------------------------------*/
68
69 /* Exported functions---------------------------------------------------------*/
70 /** @addtogroup CRYPEx_Exported_Functions
71 * @{
72 */
73
74 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
75 * @brief Extended processing functions.
76 *
77 @verbatim
78 ==============================================================================
79 ##### Extended AES processing functions #####
80 ==============================================================================
81 [..] This section provides functions allowing to generate the authentication
82 TAG in Polling mode
83 (#)HAL_CRYPEx_AESGCM_GenerateAuthTAG
84 (#)HAL_CRYPEx_AESCCM_GenerateAuthTAG
85 they should be used after Encrypt/Decrypt operation.
86
87 @endverbatim
88 * @{
89 */
90
91 /**
92 * @brief generate the GCM authentication TAG.
93 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
94 * the configuration information for CRYP module
95 * @param AuthTag Pointer to the authentication buffer
96 * @param Timeout Timeout duration
97 * @retval HAL status
98 */
HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,uint32_t * AuthTag,uint32_t Timeout)99 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
100 {
101 uint32_t tickstart;
102 /* Assume first Init.HeaderSize is in words */
103 uint64_t headerlength = (uint64_t)hcryp->Init.HeaderSize * 32U; /* Header length in bits */
104 uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
105 uint32_t tagaddr = (uint32_t)AuthTag;
106
107 /* Correct headerlength if Init.HeaderSize is actually in bytes */
108 if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
109 {
110 headerlength /= 4U;
111 }
112
113 if (hcryp->State == HAL_CRYP_STATE_READY)
114 {
115 /* Process locked */
116 __HAL_LOCK(hcryp);
117
118 /* Change the CRYP peripheral state */
119 hcryp->State = HAL_CRYP_STATE_BUSY;
120
121 /* Check if initialization phase has already been performed */
122 if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
123 {
124 /* Change the CRYP phase */
125 hcryp->Phase = CRYPEx_PHASE_FINAL;
126 }
127 else /* Initialization phase has not been performed*/
128 {
129 /* Disable the Peripheral */
130 __HAL_CRYP_DISABLE(hcryp);
131
132 /* Sequence error code field */
133 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
134
135 /* Change the CRYP peripheral state */
136 hcryp->State = HAL_CRYP_STATE_READY;
137
138 /* Process unlocked */
139 __HAL_UNLOCK(hcryp);
140 return HAL_ERROR;
141 }
142
143 /* Select final phase */
144 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
145
146 /* Set the encrypt operating mode*/
147 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
148
149 /*TinyAES peripheral from V3.1.1 : data has to be inserted normally (no swapping)*/
150 /* Write into the AES_DINR register the number of bits in header (64 bits)
151 followed by the number of bits in the payload */
152
153 hcryp->Instance->DINR = 0U;
154 hcryp->Instance->DINR = (uint32_t)(headerlength);
155 hcryp->Instance->DINR = 0U;
156 hcryp->Instance->DINR = (uint32_t)(inputlength);
157
158 /* Wait for CCF flag to be raised */
159 tickstart = HAL_GetTick();
160 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
161 {
162 /* Check for the Timeout */
163 if (Timeout != HAL_MAX_DELAY)
164 {
165 if (((HAL_GetTick() - tickstart) > Timeout)||(Timeout == 0U))
166 {
167 /* Disable the CRYP peripheral clock */
168 __HAL_CRYP_DISABLE(hcryp);
169
170 /* Change state */
171 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
172 hcryp->State = HAL_CRYP_STATE_READY;
173
174 /* Process unlocked */
175 __HAL_UNLOCK(hcryp);
176 return HAL_ERROR;
177 }
178 }
179 }
180
181 /* Read the authentication TAG in the output FIFO */
182 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
183 tagaddr += 4U;
184 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
185 tagaddr += 4U;
186 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
187 tagaddr += 4U;
188 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
189
190 /* Clear CCF flag */
191 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
192
193 /* Disable the peripheral */
194 __HAL_CRYP_DISABLE(hcryp);
195
196 /* Change the CRYP peripheral state */
197 hcryp->State = HAL_CRYP_STATE_READY;
198
199 /* Process unlocked */
200 __HAL_UNLOCK(hcryp);
201 }
202 else
203 {
204 /* Busy error code field */
205 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
206 return HAL_ERROR;
207 }
208 /* Return function status */
209 return HAL_OK;
210 }
211
212 /**
213 * @brief AES CCM Authentication TAG generation.
214 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
215 * the configuration information for CRYP module
216 * @param AuthTag Pointer to the authentication buffer
217 * @param Timeout Timeout duration
218 * @retval HAL status
219 */
HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,uint32_t * AuthTag,uint32_t Timeout)220 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
221 {
222 uint32_t tagaddr = (uint32_t)AuthTag;
223 uint32_t tickstart;
224
225 if (hcryp->State == HAL_CRYP_STATE_READY)
226 {
227 /* Process locked */
228 __HAL_LOCK(hcryp);
229
230 /* Disable interrupts in case they were kept enabled to proceed
231 a single message in several iterations */
232 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
233
234 /* Change the CRYP peripheral state */
235 hcryp->State = HAL_CRYP_STATE_BUSY;
236
237 /* Check if initialization phase has already been performed */
238 if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
239 {
240 /* Change the CRYP phase */
241 hcryp->Phase = CRYPEx_PHASE_FINAL;
242 }
243 else /* Initialization phase has not been performed*/
244 {
245 /* Disable the peripheral */
246 __HAL_CRYP_DISABLE(hcryp);
247
248 /* Sequence error code field */
249 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
250
251 /* Change the CRYP peripheral state */
252 hcryp->State = HAL_CRYP_STATE_READY;
253
254 /* Process unlocked */
255 __HAL_UNLOCK(hcryp);
256 return HAL_ERROR;
257 }
258 /* Select final phase */
259 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
260
261 /* Set encrypt operating mode*/
262 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
263
264 /* Wait for CCF flag to be raised */
265 tickstart = HAL_GetTick();
266 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
267 {
268 /* Check for the Timeout */
269 if (Timeout != HAL_MAX_DELAY)
270 {
271 if (((HAL_GetTick() - tickstart) > Timeout) ||(Timeout == 0U))
272 {
273 /* Disable the CRYP peripheral Clock */
274 __HAL_CRYP_DISABLE(hcryp);
275
276 /* Change state */
277 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
278 hcryp->State = HAL_CRYP_STATE_READY;
279
280 /* Process unlocked */
281 __HAL_UNLOCK(hcryp);
282 return HAL_ERROR;
283 }
284 }
285 }
286
287 /* Read the authentication TAG in the output FIFO */
288 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
289 tagaddr += 4U;
290 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
291 tagaddr += 4U;
292 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
293 tagaddr += 4U;
294 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
295
296 /* Clear CCF Flag */
297 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
298
299
300 /* Change the CRYP peripheral state */
301 hcryp->State = HAL_CRYP_STATE_READY;
302
303 /* Process unlocked */
304 __HAL_UNLOCK(hcryp);
305
306 /* Disable CRYP */
307 __HAL_CRYP_DISABLE(hcryp);
308 }
309 else
310 {
311 /* Busy error code field */
312 hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
313 return HAL_ERROR;
314 }
315 /* Return function status */
316 return HAL_OK;
317 }
318
319 /**
320 * @}
321 */
322
323 /** @defgroup CRYPEx_Exported_Functions_Group2 Extended AES Key Derivations functions
324 * @brief Extended Key Derivations functions.
325 *
326 @verbatim
327 ==============================================================================
328 ##### Key Derivation functions #####
329 ==============================================================================
330 [..] This section provides functions allowing to Enable or Disable the
331 the AutoKeyDerivation parameter in CRYP_HandleTypeDef structure
332 These function are allowed only in TinyAES peripheral.
333 @endverbatim
334 * @{
335 */
336
337 /**
338 * @brief AES enable key derivation functions
339 * @param hcryp pointer to a CRYP_HandleTypeDef structure.
340 */
HAL_CRYPEx_EnableAutoKeyDerivation(CRYP_HandleTypeDef * hcryp)341 void HAL_CRYPEx_EnableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
342 {
343 if (hcryp->State == HAL_CRYP_STATE_READY)
344 {
345 hcryp->AutoKeyDerivation = ENABLE;
346 }
347 else
348 {
349 /* Busy error code field */
350 hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
351 }
352 }
353 /**
354 * @brief AES disable key derivation functions
355 * @param hcryp pointer to a CRYP_HandleTypeDef structure.
356 */
HAL_CRYPEx_DisableAutoKeyDerivation(CRYP_HandleTypeDef * hcryp)357 void HAL_CRYPEx_DisableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
358 {
359 if (hcryp->State == HAL_CRYP_STATE_READY)
360 {
361 hcryp->AutoKeyDerivation = DISABLE;
362 }
363 else
364 {
365 /* Busy error code field */
366 hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
367 }
368 }
369
370 /**
371 * @}
372 */
373
374 /**
375 * @}
376 */
377
378 #endif /* HAL_CRYP_MODULE_ENABLED */
379
380 #endif /* AES */
381 /**
382 * @}
383 */
384
385 /**
386 * @}
387 */
388
389 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
390