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