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