1 /**
2 ******************************************************************************
3 * @file stm32mp1xx_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) 2019 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
33 /* Includes ------------------------------------------------------------------*/
34 #include "stm32mp1xx_hal.h"
35
36 /** @addtogroup STM32MP1xx_HAL_Driver
37 * @{
38 */
39 #if defined (CRYP1) || defined (CRYP2)
40 /** @defgroup CRYPEx CRYPEx
41 * @brief CRYP Extension HAL module driver.
42 * @{
43 */
44
45 #ifdef HAL_CRYP_MODULE_ENABLED
46
47 /* Private typedef -----------------------------------------------------------*/
48 /* Private define ------------------------------------------------------------*/
49 /** @addtogroup CRYPEx_Private_Defines
50 * @{
51 */
52
53 #define CRYP_PHASE_INIT 0x00000000U
54 #define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0
55 #define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1
56 #define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH
57
58 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U
59 #define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR
60
61 #define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */
62 #define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
63
64 /* CTR0 information to use in CCM algorithm */
65 #define CRYP_CCM_CTR0_0 0x07FFFFFFU
66 #define CRYP_CCM_CTR0_3 0xFFFFFF00U
67
68 /**
69 * @}
70 */
71
72 /* Private macro -------------------------------------------------------------*/
73 /* Private variables ---------------------------------------------------------*/
74 /* Private function prototypes -----------------------------------------------*/
75
76
77
78 /* Exported functions---------------------------------------------------------*/
79 /** @addtogroup CRYPEx_Exported_Functions
80 * @{
81 */
82
83 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
84 * @brief CRYPEx Extended processing functions.
85 *
86 @verbatim
87 ==============================================================================
88 ##### Extended AES processing functions #####
89 ==============================================================================
90 [..] This section provides functions allowing to generate the authentication
91 TAG in Polling mode
92 (+)HAL_CRYPEx_AESGCM_GenerateAuthTAG
93 (+)HAL_CRYPEx_AESCCM_GenerateAuthTAG
94 they should be used after Encrypt/Decrypt operation.
95
96 @endverbatim
97 * @{
98 */
99
100
101 /**
102 * @brief generate the GCM authentication TAG.
103 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
104 * the configuration information for CRYP module
105 * @param AuthTag: Pointer to the authentication buffer
106 * @param Timeout: Timeout duration
107 * @retval HAL status
108 */
HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,uint32_t * AuthTag,uint32_t Timeout)109 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
110 {
111 uint32_t tickstart;
112 uint64_t headerlength = (uint64_t)(hcryp->Init.HeaderSize) * 32U; /* Header length in bits */
113 uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* input length in bits */
114 uint32_t tagaddr = (uint32_t)AuthTag;
115
116 if (hcryp->State == HAL_CRYP_STATE_READY)
117 {
118 /* Process locked */
119 __HAL_LOCK(hcryp);
120
121 /* Change the CRYP peripheral state */
122 hcryp->State = HAL_CRYP_STATE_BUSY;
123
124 /* Check if initialization phase has already been performed */
125 if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
126 {
127 /* Change the CRYP phase */
128 hcryp->Phase = CRYPEx_PHASE_FINAL;
129 }
130 else /* Initialization phase has not been performed*/
131 {
132 /* Disable the Peripheral */
133 __HAL_CRYP_DISABLE(hcryp);
134
135 /* Sequence error code field */
136 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
137
138 /* Change the CRYP peripheral state */
139 hcryp->State = HAL_CRYP_STATE_READY;
140
141 /* Process unlocked */
142 __HAL_UNLOCK(hcryp);
143 return HAL_ERROR;
144 }
145
146 /* Disable CRYP to start the final phase */
147 __HAL_CRYP_DISABLE(hcryp);
148
149 /* Select final phase */
150 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
151
152 /*ALGODIR bit must be set to �0�.*/
153 hcryp->Instance->CR &= ~CRYP_CR_ALGODIR;
154
155 /* Enable the CRYP peripheral */
156 __HAL_CRYP_ENABLE(hcryp);
157
158 /* Write the number of bits in header (64 bits) followed by the number of bits
159 in the payload */
160 hcryp->Instance->DIN = 0U;
161 hcryp->Instance->DIN = (uint32_t)(headerlength);
162 hcryp->Instance->DIN = 0U;
163 hcryp->Instance->DIN = (uint32_t)(inputlength);
164 /* Wait for OFNE flag to be raised */
165 tickstart = HAL_GetTick();
166 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
167 {
168 /* Check for the Timeout */
169 if (Timeout != HAL_MAX_DELAY)
170 {
171 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
172 {
173 /* Disable the CRYP Peripheral Clock */
174 __HAL_CRYP_DISABLE(hcryp);
175
176 /* Change state */
177 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
178 hcryp->State = HAL_CRYP_STATE_READY;
179
180 /* Process unlocked */
181 __HAL_UNLOCK(hcryp);
182 return HAL_ERROR;
183 }
184 }
185 }
186
187 /* Read the authentication TAG in the output FIFO */
188 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
189 tagaddr += 4U;
190 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
191 tagaddr += 4U;
192 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
193 tagaddr += 4U;
194 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
195
196 /* Disable the peripheral */
197 __HAL_CRYP_DISABLE(hcryp);
198
199 /* Change the CRYP peripheral state */
200 hcryp->State = HAL_CRYP_STATE_READY;
201
202 /* Process unlocked */
203 __HAL_UNLOCK(hcryp);
204 }
205 else
206 {
207 /* Busy error code field */
208 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
209 return HAL_ERROR;
210 }
211 /* Return function status */
212 return HAL_OK;
213 }
214
215 /**
216 * @brief AES CCM Authentication TAG generation.
217 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
218 * the configuration information for CRYP module
219 * @param AuthTag: Pointer to the authentication buffer
220 * @param Timeout: Timeout duration
221 * @retval HAL status
222 */
HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,uint32_t * AuthTag,uint32_t Timeout)223 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
224 {
225 uint32_t tagaddr = (uint32_t)AuthTag;
226 uint32_t ctr0 [4] = {0};
227 uint32_t ctr0addr = (uint32_t)ctr0;
228 uint32_t tickstart;
229
230 if (hcryp->State == HAL_CRYP_STATE_READY)
231 {
232 /* Process locked */
233 __HAL_LOCK(hcryp);
234
235 /* Change the CRYP peripheral state */
236 hcryp->State = HAL_CRYP_STATE_BUSY;
237
238 /* Check if initialization phase has already been performed */
239 if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
240 {
241 /* Change the CRYP phase */
242 hcryp->Phase = CRYPEx_PHASE_FINAL;
243 }
244 else /* Initialization phase has not been performed*/
245 {
246 /* Disable the peripheral */
247 __HAL_CRYP_DISABLE(hcryp);
248
249 /* Sequence error code field */
250 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
251
252 /* Change the CRYP peripheral state */
253 hcryp->State = HAL_CRYP_STATE_READY;
254
255 /* Process unlocked */
256 __HAL_UNLOCK(hcryp);
257 return HAL_ERROR;
258 }
259
260 /* Disable CRYP to start the final phase */
261 __HAL_CRYP_DISABLE(hcryp);
262
263 /* Select final phase & ALGODIR bit must be set to �0�. */
264 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH | CRYP_CR_ALGODIR, CRYP_PHASE_FINAL | CRYP_OPERATINGMODE_ENCRYPT);
265
266 /* Enable the CRYP peripheral */
267 __HAL_CRYP_ENABLE(hcryp);
268
269 /* Write the counter block in the IN FIFO, CTR0 information from B0
270 data has to be swapped according to the DATATYPE*/
271 ctr0[0] = (hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
272 ctr0[1] = hcryp->Init.B0[1];
273 ctr0[2] = hcryp->Init.B0[2];
274 ctr0[3] = hcryp->Init.B0[3] & CRYP_CCM_CTR0_3;
275
276 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
277 ctr0addr += 4U;
278 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
279 ctr0addr += 4U;
280 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
281 ctr0addr += 4U;
282 hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
283 /* Wait for OFNE flag to be raised */
284 tickstart = HAL_GetTick();
285 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
286 {
287 /* Check for the Timeout */
288 if (Timeout != HAL_MAX_DELAY)
289 {
290 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
291 {
292 /* Disable the CRYP peripheral Clock */
293 __HAL_CRYP_DISABLE(hcryp);
294
295 /* Change state */
296 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
297 hcryp->State = HAL_CRYP_STATE_READY;
298
299 /* Process unlocked */
300 __HAL_UNLOCK(hcryp);
301 return HAL_ERROR;
302 }
303 }
304 }
305
306 /* Read the Auth TAG in the IN FIFO */
307 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
308 tagaddr += 4U;
309 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
310 tagaddr += 4U;
311 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
312 tagaddr += 4U;
313 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
314
315 /* Change the CRYP peripheral state */
316 hcryp->State = HAL_CRYP_STATE_READY;
317
318 /* Process unlocked */
319 __HAL_UNLOCK(hcryp);
320
321 /* Disable CRYP */
322 __HAL_CRYP_DISABLE(hcryp);
323 }
324 else
325 {
326 /* Busy error code field */
327 hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
328 return HAL_ERROR;
329 }
330 /* Return function status */
331 return HAL_OK;
332 }
333
334 /**
335 * @}
336 */
337
338
339 #endif /* HAL_CRYP_MODULE_ENABLED */
340
341 /**
342 * @}
343 */
344 #endif /* CRYP1 || CRYP2 */
345 /**
346 * @}
347 */
348
349 /**
350 * @}
351 */
352