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>&copy; 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