sidestep
[mTask.git] / int / com / lib / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_cryp_ex.c
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_cryp_ex.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 22-April-2016
7 * @brief Extended CRYP HAL module driver
8 * This file provides firmware functions to manage the following
9 * functionalities of CRYP extension peripheral:
10 * + Extended AES processing functions
11 *
12 @verbatim
13 ==============================================================================
14 ##### How to use this driver #####
15 ==============================================================================
16 [..]
17 The CRYP Extension HAL driver can be used as follows:
18 (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
19 (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
20 (##) In case of using interrupts (e.g. HAL_CRYPEx_AESGCM_Encrypt_IT())
21 (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
22 (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
23 (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
24 (##) In case of using DMA to control data transfer (e.g. HAL_AES_ECB_Encrypt_DMA())
25 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
26 (+++) Configure and enable two DMA streams one for managing data transfer from
27 memory to peripheral (input stream) and another stream for managing data
28 transfer from peripheral to memory (output stream)
29 (+++) Associate the initialized DMA handle to the CRYP DMA handle
30 using __HAL_LINKDMA()
31 (+++) Configure the priority and enable the NVIC for the transfer complete
32 interrupt on the two DMA Streams. The output stream should have higher
33 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
34 (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly:
35 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit
36 (##) The key size: 128, 192 and 256. This parameter is relevant only for AES
37 (##) The encryption/decryption key. Its size depends on the algorithm
38 used for encryption/decryption
39 (##) The initialization vector (counter). It is not used ECB mode.
40 (#)Three processing (encryption/decryption) functions are available:
41 (##) Polling mode: encryption and decryption APIs are blocking functions
42 i.e. they process the data and wait till the processing is finished
43 e.g. HAL_CRYPEx_AESGCM_Encrypt()
44 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
45 i.e. they process the data under interrupt
46 e.g. HAL_CRYPEx_AESGCM_Encrypt_IT()
47 (##) DMA mode: encryption and decryption APIs are not blocking functions
48 i.e. the data transfer is ensured by DMA
49 e.g. HAL_CRYPEx_AESGCM_Encrypt_DMA()
50 (#)When the processing function is called at first time after HAL_CRYP_Init()
51 the CRYP peripheral is initialized and processes the buffer in input.
52 At second call, the processing function performs an append of the already
53 processed buffer.
54 When a new data block is to be processed, call HAL_CRYP_Init() then the
55 processing function.
56 (#)In AES-GCM and AES-CCM modes are an authenticated encryption algorithms
57 which provide authentication messages.
58 HAL_AES_GCM_Finish() and HAL_AES_CCM_Finish() are used to provide those
59 authentication messages.
60 Call those functions after the processing ones (polling, interrupt or DMA).
61 e.g. in AES-CCM mode call HAL_CRYPEx_AESCCM_Encrypt() to encrypt the plain data
62 then call HAL_CRYPEx_AESCCM_Finish() to get the authentication message
63 -@- For CCM Encrypt/Decrypt API's, only DataType = 8-bit is supported by this version.
64 -@- The HAL_CRYPEx_AESGCM_xxxx() implementation is limited to 32bits inputs data length
65 (Plain/Cyphertext, Header) compared with GCM standards specifications (800-38D).
66 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
67
68 @endverbatim
69 ******************************************************************************
70 * @attention
71 *
72 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
73 *
74 * Redistribution and use in source and binary forms, with or without modification,
75 * are permitted provided that the following conditions are met:
76 * 1. Redistributions of source code must retain the above copyright notice,
77 * this list of conditions and the following disclaimer.
78 * 2. Redistributions in binary form must reproduce the above copyright notice,
79 * this list of conditions and the following disclaimer in the documentation
80 * and/or other materials provided with the distribution.
81 * 3. Neither the name of STMicroelectronics nor the names of its contributors
82 * may be used to endorse or promote products derived from this software
83 * without specific prior written permission.
84 *
85 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
86 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
87 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
89 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
90 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
91 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
92 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
93 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
94 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95 *
96 ******************************************************************************
97 */
98
99 /* Includes ------------------------------------------------------------------*/
100 #include "stm32f7xx_hal.h"
101
102 /** @addtogroup STM32F7xx_HAL_Driver
103 * @{
104 */
105 #if defined (STM32F756xx) || defined (STM32F777xx) || defined (STM32F779xx)
106 /** @defgroup CRYPEx CRYPEx
107 * @brief CRYP Extension HAL module driver.
108 * @{
109 */
110
111
112 #ifdef HAL_CRYP_MODULE_ENABLED
113
114 /* Private typedef -----------------------------------------------------------*/
115 /* Private define ------------------------------------------------------------*/
116 /** @addtogroup CRYPEx_Private_define
117 * @{
118 */
119 #define CRYPEx_TIMEOUT_VALUE 1
120 /**
121 * @}
122 */
123
124 /* Private macro -------------------------------------------------------------*/
125 /* Private variables ---------------------------------------------------------*/
126 /* Private function prototypes -----------------------------------------------*/
127 /** @defgroup CRYPEx_Private_Functions_prototypes CRYP Private Functions Prototypes
128 * @{
129 */
130 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector);
131 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize);
132 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout);
133 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout);
134 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma);
135 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma);
136 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma);
137 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
138 /**
139 * @}
140 */
141
142 /* Private functions ---------------------------------------------------------*/
143 /** @addtogroup CRYPEx_Private_Functions
144 * @{
145 */
146
147 /**
148 * @brief DMA CRYP Input Data process complete callback.
149 * @param hdma: DMA handle
150 * @retval None
151 */
152 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma)
153 {
154 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
155
156 /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit
157 in the DMACR register */
158 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
159
160 /* Call input data transfer complete callback */
161 HAL_CRYP_InCpltCallback(hcryp);
162 }
163
164 /**
165 * @brief DMA CRYP Output Data process complete callback.
166 * @param hdma: DMA handle
167 * @retval None
168 */
169 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma)
170 {
171 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
172
173 /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit
174 in the DMACR register */
175 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
176
177 /* Enable the CRYP peripheral */
178 __HAL_CRYP_DISABLE(hcryp);
179
180 /* Change the CRYP peripheral state */
181 hcryp->State = HAL_CRYP_STATE_READY;
182
183 /* Call output data transfer complete callback */
184 HAL_CRYP_OutCpltCallback(hcryp);
185 }
186
187 /**
188 * @brief DMA CRYP communication error callback.
189 * @param hdma: DMA handle
190 * @retval None
191 */
192 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma)
193 {
194 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
195 hcryp->State= HAL_CRYP_STATE_READY;
196 HAL_CRYP_ErrorCallback(hcryp);
197 }
198
199 /**
200 * @brief Writes the Key in Key registers.
201 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
202 * the configuration information for CRYP module
203 * @param Key: Pointer to Key buffer
204 * @param KeySize: Size of Key
205 * @retval None
206 */
207 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize)
208 {
209 uint32_t keyaddr = (uint32_t)Key;
210
211 switch(KeySize)
212 {
213 case CRYP_KEYSIZE_256B:
214 /* Key Initialisation */
215 hcryp->Instance->K0LR = __REV(*(uint32_t*)(keyaddr));
216 keyaddr+=4;
217 hcryp->Instance->K0RR = __REV(*(uint32_t*)(keyaddr));
218 keyaddr+=4;
219 hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
220 keyaddr+=4;
221 hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
222 keyaddr+=4;
223 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
224 keyaddr+=4;
225 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
226 keyaddr+=4;
227 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
228 keyaddr+=4;
229 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
230 break;
231 case CRYP_KEYSIZE_192B:
232 hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
233 keyaddr+=4;
234 hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
235 keyaddr+=4;
236 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
237 keyaddr+=4;
238 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
239 keyaddr+=4;
240 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
241 keyaddr+=4;
242 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
243 break;
244 case CRYP_KEYSIZE_128B:
245 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
246 keyaddr+=4;
247 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
248 keyaddr+=4;
249 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
250 keyaddr+=4;
251 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
252 break;
253 default:
254 break;
255 }
256 }
257
258 /**
259 * @brief Writes the InitVector/InitCounter in IV registers.
260 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
261 * the configuration information for CRYP module
262 * @param InitVector: Pointer to InitVector/InitCounter buffer
263 * @retval None
264 */
265 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector)
266 {
267 uint32_t ivaddr = (uint32_t)InitVector;
268
269 hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr));
270 ivaddr+=4;
271 hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr));
272 ivaddr+=4;
273 hcryp->Instance->IV1LR = __REV(*(uint32_t*)(ivaddr));
274 ivaddr+=4;
275 hcryp->Instance->IV1RR = __REV(*(uint32_t*)(ivaddr));
276 }
277
278 /**
279 * @brief Process Data: Writes Input data in polling mode and read the Output data.
280 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
281 * the configuration information for CRYP module
282 * @param Input: Pointer to the Input buffer.
283 * @param Ilength: Length of the Input buffer, must be a multiple of 16
284 * @param Output: Pointer to the returned buffer
285 * @param Timeout: Timeout value
286 * @retval None
287 */
288 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout)
289 {
290 uint32_t tickstart = 0;
291 uint32_t i = 0;
292 uint32_t inputaddr = (uint32_t)Input;
293 uint32_t outputaddr = (uint32_t)Output;
294
295 for(i=0; (i < Ilength); i+=16)
296 {
297 /* Write the Input block in the IN FIFO */
298 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
299 inputaddr+=4;
300 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
301 inputaddr+=4;
302 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
303 inputaddr+=4;
304 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
305 inputaddr+=4;
306
307 /* Get tick */
308 tickstart = HAL_GetTick();
309
310 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
311 {
312 /* Check for the Timeout */
313 if(Timeout != HAL_MAX_DELAY)
314 {
315 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
316 {
317 /* Change state */
318 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
319
320 /* Process Unlocked */
321 __HAL_UNLOCK(hcryp);
322
323 return HAL_TIMEOUT;
324 }
325 }
326 }
327 /* Read the Output block from the OUT FIFO */
328 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
329 outputaddr+=4;
330 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
331 outputaddr+=4;
332 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
333 outputaddr+=4;
334 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
335 outputaddr+=4;
336 }
337 /* Return function status */
338 return HAL_OK;
339 }
340
341 /**
342 * @brief Sets the header phase
343 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
344 * the configuration information for CRYP module
345 * @param Input: Pointer to the Input buffer.
346 * @param Ilength: Length of the Input buffer, must be a multiple of 16
347 * @param Timeout: Timeout value
348 * @retval None
349 */
350 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout)
351 {
352 uint32_t tickstart = 0;
353 uint32_t loopcounter = 0;
354 uint32_t headeraddr = (uint32_t)Input;
355
356 /***************************** Header phase *********************************/
357 if(hcryp->Init.HeaderSize != 0)
358 {
359 /* Select header phase */
360 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
361 /* Enable the CRYP peripheral */
362 __HAL_CRYP_ENABLE(hcryp);
363
364 for(loopcounter = 0; (loopcounter < hcryp->Init.HeaderSize); loopcounter+=16)
365 {
366 /* Get tick */
367 tickstart = HAL_GetTick();
368
369 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
370 {
371 /* Check for the Timeout */
372 if(Timeout != HAL_MAX_DELAY)
373 {
374 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
375 {
376 /* Change state */
377 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
378
379 /* Process Unlocked */
380 __HAL_UNLOCK(hcryp);
381
382 return HAL_TIMEOUT;
383 }
384 }
385 }
386 /* Write the Input block in the IN FIFO */
387 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
388 headeraddr+=4;
389 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
390 headeraddr+=4;
391 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
392 headeraddr+=4;
393 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
394 headeraddr+=4;
395 }
396
397 /* Wait until the complete message has been processed */
398
399 /* Get tick */
400 tickstart = HAL_GetTick();
401
402 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
403 {
404 /* Check for the Timeout */
405 if(Timeout != HAL_MAX_DELAY)
406 {
407 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
408 {
409 /* Change state */
410 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
411
412 /* Process Unlocked */
413 __HAL_UNLOCK(hcryp);
414
415 return HAL_TIMEOUT;
416 }
417 }
418 }
419 }
420 /* Return function status */
421 return HAL_OK;
422 }
423
424 /**
425 * @brief Sets the DMA configuration and start the DMA transfer.
426 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
427 * the configuration information for CRYP module
428 * @param inputaddr: Address of the Input buffer
429 * @param Size: Size of the Input buffer, must be a multiple of 16
430 * @param outputaddr: Address of the Output buffer
431 * @retval None
432 */
433 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
434 {
435 /* Set the CRYP DMA transfer complete callback */
436 hcryp->hdmain->XferCpltCallback = CRYPEx_GCMCCM_DMAInCplt;
437 /* Set the DMA error callback */
438 hcryp->hdmain->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
439
440 /* Set the CRYP DMA transfer complete callback */
441 hcryp->hdmaout->XferCpltCallback = CRYPEx_GCMCCM_DMAOutCplt;
442 /* Set the DMA error callback */
443 hcryp->hdmaout->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
444
445 /* Enable the CRYP peripheral */
446 __HAL_CRYP_ENABLE(hcryp);
447
448 /* Enable the DMA In DMA Stream */
449 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DR, Size/4);
450
451 /* Enable In DMA request */
452 hcryp->Instance->DMACR = CRYP_DMACR_DIEN;
453
454 /* Enable the DMA Out DMA Stream */
455 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size/4);
456
457 /* Enable Out DMA request */
458 hcryp->Instance->DMACR |= CRYP_DMACR_DOEN;
459 }
460
461 /**
462 * @}
463 */
464
465 /* Exported functions---------------------------------------------------------*/
466 /** @addtogroup CRYPEx_Exported_Functions
467 * @{
468 */
469
470 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
471 * @brief Extended processing functions.
472 *
473 @verbatim
474 ==============================================================================
475 ##### Extended AES processing functions #####
476 ==============================================================================
477 [..] This section provides functions allowing to:
478 (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes
479 (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes
480 (+) Finish the processing. This function is available only for GCM and CCM
481 [..] Three processing methods are available:
482 (+) Polling mode
483 (+) Interrupt mode
484 (+) DMA mode
485
486 @endverbatim
487 * @{
488 */
489
490
491 /**
492 * @brief Initializes the CRYP peripheral in AES CCM encryption mode then
493 * encrypt pPlainData. The cypher data are available in pCypherData.
494 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
495 * the configuration information for CRYP module
496 * @param pPlainData: Pointer to the plaintext buffer
497 * @param Size: Length of the plaintext buffer, must be a multiple of 16
498 * @param pCypherData: Pointer to the cyphertext buffer
499 * @param Timeout: Timeout duration
500 * @retval HAL status
501 */
502 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
503 {
504 uint32_t tickstart = 0;
505 uint32_t headersize = hcryp->Init.HeaderSize;
506 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
507 uint32_t loopcounter = 0;
508 uint32_t bufferidx = 0;
509 uint8_t blockb0[16] = {0};/* Block B0 */
510 uint8_t ctr[16] = {0}; /* Counter */
511 uint32_t b0addr = (uint32_t)blockb0;
512
513 /* Process Locked */
514 __HAL_LOCK(hcryp);
515
516 /* Change the CRYP peripheral state */
517 hcryp->State = HAL_CRYP_STATE_BUSY;
518
519 /* Check if initialization phase has already been performed */
520 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
521 {
522 /************************ Formatting the header block *********************/
523 if(headersize != 0)
524 {
525 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
526 if(headersize < 65280)
527 {
528 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
529 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
530 headersize += 2;
531 }
532 else
533 {
534 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
535 hcryp->Init.pScratch[bufferidx++] = 0xFF;
536 hcryp->Init.pScratch[bufferidx++] = 0xFE;
537 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
538 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
539 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
540 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
541 headersize += 6;
542 }
543 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
544 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
545 {
546 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
547 }
548 /* Check if the header size is modulo 16 */
549 if ((headersize % 16) != 0)
550 {
551 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
552 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
553 {
554 hcryp->Init.pScratch[loopcounter] = 0;
555 }
556 /* Set the header size to modulo 16 */
557 headersize = ((headersize/16) + 1) * 16;
558 }
559 /* Set the pointer headeraddr to hcryp->Init.pScratch */
560 headeraddr = (uint32_t)hcryp->Init.pScratch;
561 }
562 /*********************** Formatting the block B0 **************************/
563 if(headersize != 0)
564 {
565 blockb0[0] = 0x40;
566 }
567 /* Flags byte */
568 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
569 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
570 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
571
572 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
573 {
574 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
575 }
576 for ( ; loopcounter < 13; loopcounter++)
577 {
578 blockb0[loopcounter+1] = 0;
579 }
580
581 blockb0[14] = (Size >> 8);
582 blockb0[15] = (Size & 0xFF);
583
584 /************************* Formatting the initial counter *****************/
585 /* Byte 0:
586 Bits 7 and 6 are reserved and shall be set to 0
587 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
588 are distinct from B0
589 Bits 0, 1, and 2 contain the same encoding of q as in B0
590 */
591 ctr[0] = blockb0[0] & 0x07;
592 /* byte 1 to NonceSize is the IV (Nonce) */
593 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
594 {
595 ctr[loopcounter] = blockb0[loopcounter];
596 }
597 /* Set the LSB to 1 */
598 ctr[15] |= 0x01;
599
600 /* Set the key */
601 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
602
603 /* Set the CRYP peripheral in AES CCM mode */
604 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
605
606 /* Set the Initialization Vector */
607 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
608
609 /* Select init phase */
610 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
611
612 b0addr = (uint32_t)blockb0;
613 /* Write the blockb0 block in the IN FIFO */
614 hcryp->Instance->DR = *(uint32_t*)(b0addr);
615 b0addr+=4;
616 hcryp->Instance->DR = *(uint32_t*)(b0addr);
617 b0addr+=4;
618 hcryp->Instance->DR = *(uint32_t*)(b0addr);
619 b0addr+=4;
620 hcryp->Instance->DR = *(uint32_t*)(b0addr);
621
622 /* Enable the CRYP peripheral */
623 __HAL_CRYP_ENABLE(hcryp);
624
625 /* Get tick */
626 tickstart = HAL_GetTick();
627
628 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
629 {
630 /* Check for the Timeout */
631 if(Timeout != HAL_MAX_DELAY)
632 {
633 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
634 {
635 /* Change state */
636 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
637
638 /* Process Unlocked */
639 __HAL_UNLOCK(hcryp);
640
641 return HAL_TIMEOUT;
642 }
643 }
644 }
645 /***************************** Header phase *******************************/
646 if(headersize != 0)
647 {
648 /* Select header phase */
649 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
650
651 /* Enable the CRYP peripheral */
652 __HAL_CRYP_ENABLE(hcryp);
653
654 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
655 {
656 /* Get tick */
657 tickstart = HAL_GetTick();
658
659 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
660 {
661 {
662 /* Check for the Timeout */
663 if(Timeout != HAL_MAX_DELAY)
664 {
665 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
666 {
667 /* Change state */
668 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
669
670 /* Process Unlocked */
671 __HAL_UNLOCK(hcryp);
672
673 return HAL_TIMEOUT;
674 }
675 }
676 }
677 }
678 /* Write the header block in the IN FIFO */
679 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
680 headeraddr+=4;
681 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
682 headeraddr+=4;
683 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
684 headeraddr+=4;
685 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
686 headeraddr+=4;
687 }
688
689 /* Get tick */
690 tickstart = HAL_GetTick();
691
692 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
693 {
694 /* Check for the Timeout */
695 if(Timeout != HAL_MAX_DELAY)
696 {
697 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
698 {
699 /* Change state */
700 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
701
702 /* Process Unlocked */
703 __HAL_UNLOCK(hcryp);
704
705 return HAL_TIMEOUT;
706 }
707 }
708 }
709 }
710 /* Save formatted counter into the scratch buffer pScratch */
711 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
712 {
713 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
714 }
715 /* Reset bit 0 */
716 hcryp->Init.pScratch[15] &= 0xfe;
717
718 /* Select payload phase once the header phase is performed */
719 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
720
721 /* Flush FIFO */
722 __HAL_CRYP_FIFO_FLUSH(hcryp);
723
724 /* Enable the CRYP peripheral */
725 __HAL_CRYP_ENABLE(hcryp);
726
727 /* Set the phase */
728 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
729 }
730
731 /* Write Plain Data and Get Cypher Data */
732 if(CRYPEx_GCMCCM_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK)
733 {
734 return HAL_TIMEOUT;
735 }
736
737 /* Change the CRYP peripheral state */
738 hcryp->State = HAL_CRYP_STATE_READY;
739
740 /* Process Unlocked */
741 __HAL_UNLOCK(hcryp);
742
743 /* Return function status */
744 return HAL_OK;
745 }
746
747 /**
748 * @brief Initializes the CRYP peripheral in AES GCM encryption mode then
749 * encrypt pPlainData. The cypher data are available in pCypherData.
750 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
751 * the configuration information for CRYP module
752 * @param pPlainData: Pointer to the plaintext buffer
753 * @param Size: Length of the plaintext buffer, must be a multiple of 16
754 * @param pCypherData: Pointer to the cyphertext buffer
755 * @param Timeout: Timeout duration
756 * @retval HAL status
757 */
758 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
759 {
760 uint32_t tickstart = 0;
761
762 /* Process Locked */
763 __HAL_LOCK(hcryp);
764
765 /* Change the CRYP peripheral state */
766 hcryp->State = HAL_CRYP_STATE_BUSY;
767
768 /* Check if initialization phase has already been performed */
769 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
770 {
771 /* Set the key */
772 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
773
774 /* Set the CRYP peripheral in AES GCM mode */
775 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
776
777 /* Set the Initialization Vector */
778 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
779
780 /* Flush FIFO */
781 __HAL_CRYP_FIFO_FLUSH(hcryp);
782
783 /* Enable the CRYP peripheral */
784 __HAL_CRYP_ENABLE(hcryp);
785
786 /* Get tick */
787 tickstart = HAL_GetTick();
788
789 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
790 {
791 /* Check for the Timeout */
792 if(Timeout != HAL_MAX_DELAY)
793 {
794 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
795 {
796 /* Change state */
797 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
798
799 /* Process Unlocked */
800 __HAL_UNLOCK(hcryp);
801
802 return HAL_TIMEOUT;
803 }
804 }
805 }
806
807 /* Set the header phase */
808 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
809 {
810 return HAL_TIMEOUT;
811 }
812
813 /* Disable the CRYP peripheral */
814 __HAL_CRYP_DISABLE(hcryp);
815
816 /* Select payload phase once the header phase is performed */
817 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
818
819 /* Flush FIFO */
820 __HAL_CRYP_FIFO_FLUSH(hcryp);
821
822 /* Enable the CRYP peripheral */
823 __HAL_CRYP_ENABLE(hcryp);
824
825 /* Set the phase */
826 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
827 }
828
829 /* Write Plain Data and Get Cypher Data */
830 if(CRYPEx_GCMCCM_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK)
831 {
832 return HAL_TIMEOUT;
833 }
834
835 /* Change the CRYP peripheral state */
836 hcryp->State = HAL_CRYP_STATE_READY;
837
838 /* Process Unlocked */
839 __HAL_UNLOCK(hcryp);
840
841 /* Return function status */
842 return HAL_OK;
843 }
844
845 /**
846 * @brief Initializes the CRYP peripheral in AES GCM decryption mode then
847 * decrypted pCypherData. The cypher data are available in pPlainData.
848 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
849 * the configuration information for CRYP module
850 * @param pCypherData: Pointer to the cyphertext buffer
851 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
852 * @param pPlainData: Pointer to the plaintext buffer
853 * @param Timeout: Timeout duration
854 * @retval HAL status
855 */
856 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
857 {
858 uint32_t tickstart = 0;
859
860 /* Process Locked */
861 __HAL_LOCK(hcryp);
862
863 /* Change the CRYP peripheral state */
864 hcryp->State = HAL_CRYP_STATE_BUSY;
865
866 /* Check if initialization phase has already been performed */
867 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
868 {
869 /* Set the key */
870 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
871
872 /* Set the CRYP peripheral in AES GCM decryption mode */
873 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
874
875 /* Set the Initialization Vector */
876 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
877
878 /* Flush FIFO */
879 __HAL_CRYP_FIFO_FLUSH(hcryp);
880
881 /* Enable the CRYP peripheral */
882 __HAL_CRYP_ENABLE(hcryp);
883
884 /* Get tick */
885 tickstart = HAL_GetTick();
886
887 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
888 {
889 /* Check for the Timeout */
890 if(Timeout != HAL_MAX_DELAY)
891 {
892 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
893 {
894 /* Change state */
895 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
896
897 /* Process Unlocked */
898 __HAL_UNLOCK(hcryp);
899
900 return HAL_TIMEOUT;
901 }
902 }
903 }
904
905 /* Set the header phase */
906 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
907 {
908 return HAL_TIMEOUT;
909 }
910 /* Disable the CRYP peripheral */
911 __HAL_CRYP_DISABLE(hcryp);
912
913 /* Select payload phase once the header phase is performed */
914 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
915
916 /* Enable the CRYP peripheral */
917 __HAL_CRYP_ENABLE(hcryp);
918
919 /* Set the phase */
920 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
921 }
922
923 /* Write Plain Data and Get Cypher Data */
924 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
925 {
926 return HAL_TIMEOUT;
927 }
928
929 /* Change the CRYP peripheral state */
930 hcryp->State = HAL_CRYP_STATE_READY;
931
932 /* Process Unlocked */
933 __HAL_UNLOCK(hcryp);
934
935 /* Return function status */
936 return HAL_OK;
937 }
938
939 /**
940 * @brief Computes the authentication TAG.
941 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
942 * the configuration information for CRYP module
943 * @param Size: Total length of the plain/cyphertext buffer
944 * @param AuthTag: Pointer to the authentication buffer
945 * @param Timeout: Timeout duration
946 * @retval HAL status
947 */
948 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint32_t Size, uint8_t *AuthTag, uint32_t Timeout)
949 {
950 uint32_t tickstart = 0;
951 uint64_t headerlength = hcryp->Init.HeaderSize * 8; /* Header length in bits */
952 uint64_t inputlength = Size * 8; /* input length in bits */
953 uint32_t tagaddr = (uint32_t)AuthTag;
954
955 /* Process Locked */
956 __HAL_LOCK(hcryp);
957
958 /* Change the CRYP peripheral state */
959 hcryp->State = HAL_CRYP_STATE_BUSY;
960
961 /* Check if initialization phase has already been performed */
962 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
963 {
964 /* Change the CRYP phase */
965 hcryp->Phase = HAL_CRYP_PHASE_FINAL;
966
967 /* Disable CRYP to start the final phase */
968 __HAL_CRYP_DISABLE(hcryp);
969
970 /* Select final phase */
971 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
972
973 /* Enable the CRYP peripheral */
974 __HAL_CRYP_ENABLE(hcryp);
975
976 /* Write the number of bits in header (64 bits) followed by the number of bits
977 in the payload */
978 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
979 {
980 hcryp->Instance->DR = __RBIT(headerlength >> 32);
981 hcryp->Instance->DR = __RBIT(headerlength);
982 hcryp->Instance->DR = __RBIT(inputlength >> 32);
983 hcryp->Instance->DR = __RBIT(inputlength);
984 }
985 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
986 {
987 hcryp->Instance->DR = __REV(headerlength >> 32);
988 hcryp->Instance->DR = __REV(headerlength);
989 hcryp->Instance->DR = __REV(inputlength >> 32);
990 hcryp->Instance->DR = __REV(inputlength);
991 }
992 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
993 {
994 hcryp->Instance->DR = __ROR((uint32_t)(headerlength >> 32), 16);
995 hcryp->Instance->DR = __ROR((uint32_t)headerlength, 16);
996 hcryp->Instance->DR = __ROR((uint32_t)(inputlength >> 32), 16);
997 hcryp->Instance->DR = __ROR((uint32_t)inputlength, 16);
998 }
999 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
1000 {
1001 hcryp->Instance->DR = (uint32_t)(headerlength >> 32);
1002 hcryp->Instance->DR = (uint32_t)(headerlength);
1003 hcryp->Instance->DR = (uint32_t)(inputlength >> 32);
1004 hcryp->Instance->DR = (uint32_t)(inputlength);
1005 }
1006 /* Get tick */
1007 tickstart = HAL_GetTick();
1008
1009 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
1010 {
1011 /* Check for the Timeout */
1012 if(Timeout != HAL_MAX_DELAY)
1013 {
1014 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1015 {
1016 /* Change state */
1017 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1018
1019 /* Process Unlocked */
1020 __HAL_UNLOCK(hcryp);
1021
1022 return HAL_TIMEOUT;
1023 }
1024 }
1025 }
1026
1027 /* Read the Auth TAG in the IN FIFO */
1028 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
1029 tagaddr+=4;
1030 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
1031 tagaddr+=4;
1032 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
1033 tagaddr+=4;
1034 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
1035 }
1036
1037 /* Change the CRYP peripheral state */
1038 hcryp->State = HAL_CRYP_STATE_READY;
1039
1040 /* Process Unlocked */
1041 __HAL_UNLOCK(hcryp);
1042
1043 /* Return function status */
1044 return HAL_OK;
1045 }
1046
1047 /**
1048 * @brief Computes the authentication TAG for AES CCM mode.
1049 * @note This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt()
1050 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1051 * the configuration information for CRYP module
1052 * @param AuthTag: Pointer to the authentication buffer
1053 * @param Timeout: Timeout duration
1054 * @retval HAL status
1055 */
1056 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout)
1057 {
1058 uint32_t tickstart = 0;
1059 uint32_t tagaddr = (uint32_t)AuthTag;
1060 uint32_t ctraddr = (uint32_t)hcryp->Init.pScratch;
1061 uint32_t temptag[4] = {0}; /* Temporary TAG (MAC) */
1062 uint32_t loopcounter;
1063
1064 /* Process Locked */
1065 __HAL_LOCK(hcryp);
1066
1067 /* Change the CRYP peripheral state */
1068 hcryp->State = HAL_CRYP_STATE_BUSY;
1069
1070 /* Check if initialization phase has already been performed */
1071 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
1072 {
1073 /* Change the CRYP phase */
1074 hcryp->Phase = HAL_CRYP_PHASE_FINAL;
1075
1076 /* Disable CRYP to start the final phase */
1077 __HAL_CRYP_DISABLE(hcryp);
1078
1079 /* Select final phase */
1080 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
1081
1082 /* Enable the CRYP peripheral */
1083 __HAL_CRYP_ENABLE(hcryp);
1084
1085 /* Write the counter block in the IN FIFO */
1086 hcryp->Instance->DR = *(uint32_t*)ctraddr;
1087 ctraddr+=4;
1088 hcryp->Instance->DR = *(uint32_t*)ctraddr;
1089 ctraddr+=4;
1090 hcryp->Instance->DR = *(uint32_t*)ctraddr;
1091 ctraddr+=4;
1092 hcryp->Instance->DR = *(uint32_t*)ctraddr;
1093
1094 /* Get tick */
1095 tickstart = HAL_GetTick();
1096
1097 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
1098 {
1099 /* Check for the Timeout */
1100 if(Timeout != HAL_MAX_DELAY)
1101 {
1102 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1103 {
1104 /* Change state */
1105 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1106
1107 /* Process Unlocked */
1108 __HAL_UNLOCK(hcryp);
1109
1110 return HAL_TIMEOUT;
1111 }
1112 }
1113 }
1114
1115 /* Read the Auth TAG in the IN FIFO */
1116 temptag[0] = hcryp->Instance->DOUT;
1117 temptag[1] = hcryp->Instance->DOUT;
1118 temptag[2] = hcryp->Instance->DOUT;
1119 temptag[3] = hcryp->Instance->DOUT;
1120 }
1121
1122 /* Copy temporary authentication TAG in user TAG buffer */
1123 for(loopcounter = 0; loopcounter < hcryp->Init.TagSize ; loopcounter++)
1124 {
1125 /* Set the authentication TAG buffer */
1126 *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
1127 }
1128
1129 /* Change the CRYP peripheral state */
1130 hcryp->State = HAL_CRYP_STATE_READY;
1131
1132 /* Process Unlocked */
1133 __HAL_UNLOCK(hcryp);
1134
1135 /* Return function status */
1136 return HAL_OK;
1137 }
1138
1139 /**
1140 * @brief Initializes the CRYP peripheral in AES CCM decryption mode then
1141 * decrypted pCypherData. The cypher data are available in pPlainData.
1142 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1143 * the configuration information for CRYP module
1144 * @param pPlainData: Pointer to the plaintext buffer
1145 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1146 * @param pCypherData: Pointer to the cyphertext buffer
1147 * @param Timeout: Timeout duration
1148 * @retval HAL status
1149 */
1150 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
1151 {
1152 uint32_t tickstart = 0;
1153 uint32_t headersize = hcryp->Init.HeaderSize;
1154 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
1155 uint32_t loopcounter = 0;
1156 uint32_t bufferidx = 0;
1157 uint8_t blockb0[16] = {0};/* Block B0 */
1158 uint8_t ctr[16] = {0}; /* Counter */
1159 uint32_t b0addr = (uint32_t)blockb0;
1160
1161 /* Process Locked */
1162 __HAL_LOCK(hcryp);
1163
1164 /* Change the CRYP peripheral state */
1165 hcryp->State = HAL_CRYP_STATE_BUSY;
1166
1167 /* Check if initialization phase has already been performed */
1168 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1169 {
1170 /************************ Formatting the header block *********************/
1171 if(headersize != 0)
1172 {
1173 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1174 if(headersize < 65280)
1175 {
1176 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
1177 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
1178 headersize += 2;
1179 }
1180 else
1181 {
1182 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1183 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
1184 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
1185 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
1186 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
1187 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
1188 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
1189 headersize += 6;
1190 }
1191 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1192 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
1193 {
1194 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
1195 }
1196 /* Check if the header size is modulo 16 */
1197 if ((headersize % 16) != 0)
1198 {
1199 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1200 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
1201 {
1202 hcryp->Init.pScratch[loopcounter] = 0;
1203 }
1204 /* Set the header size to modulo 16 */
1205 headersize = ((headersize/16) + 1) * 16;
1206 }
1207 /* Set the pointer headeraddr to hcryp->Init.pScratch */
1208 headeraddr = (uint32_t)hcryp->Init.pScratch;
1209 }
1210 /*********************** Formatting the block B0 **************************/
1211 if(headersize != 0)
1212 {
1213 blockb0[0] = 0x40;
1214 }
1215 /* Flags byte */
1216 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
1217 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
1218 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
1219
1220 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
1221 {
1222 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
1223 }
1224 for ( ; loopcounter < 13; loopcounter++)
1225 {
1226 blockb0[loopcounter+1] = 0;
1227 }
1228
1229 blockb0[14] = (Size >> 8);
1230 blockb0[15] = (Size & 0xFF);
1231
1232 /************************* Formatting the initial counter *****************/
1233 /* Byte 0:
1234 Bits 7 and 6 are reserved and shall be set to 0
1235 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
1236 blocks are distinct from B0
1237 Bits 0, 1, and 2 contain the same encoding of q as in B0
1238 */
1239 ctr[0] = blockb0[0] & 0x07;
1240 /* byte 1 to NonceSize is the IV (Nonce) */
1241 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
1242 {
1243 ctr[loopcounter] = blockb0[loopcounter];
1244 }
1245 /* Set the LSB to 1 */
1246 ctr[15] |= 0x01;
1247
1248 /* Set the key */
1249 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1250
1251 /* Set the CRYP peripheral in AES CCM mode */
1252 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
1253
1254 /* Set the Initialization Vector */
1255 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
1256
1257 /* Select init phase */
1258 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
1259
1260 b0addr = (uint32_t)blockb0;
1261 /* Write the blockb0 block in the IN FIFO */
1262 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1263 b0addr+=4;
1264 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1265 b0addr+=4;
1266 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1267 b0addr+=4;
1268 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1269
1270 /* Enable the CRYP peripheral */
1271 __HAL_CRYP_ENABLE(hcryp);
1272
1273 /* Get tick */
1274 tickstart = HAL_GetTick();
1275
1276 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1277 {
1278 /* Check for the Timeout */
1279 if(Timeout != HAL_MAX_DELAY)
1280 {
1281 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1282 {
1283 /* Change state */
1284 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1285
1286 /* Process Unlocked */
1287 __HAL_UNLOCK(hcryp);
1288
1289 return HAL_TIMEOUT;
1290 }
1291 }
1292 }
1293 /***************************** Header phase *******************************/
1294 if(headersize != 0)
1295 {
1296 /* Select header phase */
1297 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
1298
1299 /* Enable Crypto processor */
1300 __HAL_CRYP_ENABLE(hcryp);
1301
1302 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1303 {
1304 /* Get tick */
1305 tickstart = HAL_GetTick();
1306
1307 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
1308 {
1309 /* Check for the Timeout */
1310 if(Timeout != HAL_MAX_DELAY)
1311 {
1312 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1313 {
1314 /* Change state */
1315 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1316
1317 /* Process Unlocked */
1318 __HAL_UNLOCK(hcryp);
1319
1320 return HAL_TIMEOUT;
1321 }
1322 }
1323 }
1324 /* Write the header block in the IN FIFO */
1325 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1326 headeraddr+=4;
1327 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1328 headeraddr+=4;
1329 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1330 headeraddr+=4;
1331 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1332 headeraddr+=4;
1333 }
1334
1335 /* Get tick */
1336 tickstart = HAL_GetTick();
1337
1338 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1339 {
1340 /* Check for the Timeout */
1341 if(Timeout != HAL_MAX_DELAY)
1342 {
1343 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1344 {
1345 /* Change state */
1346 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1347
1348 /* Process Unlocked */
1349 __HAL_UNLOCK(hcryp);
1350
1351 return HAL_TIMEOUT;
1352 }
1353 }
1354 }
1355 }
1356 /* Save formatted counter into the scratch buffer pScratch */
1357 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
1358 {
1359 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1360 }
1361 /* Reset bit 0 */
1362 hcryp->Init.pScratch[15] &= 0xfe;
1363 /* Select payload phase once the header phase is performed */
1364 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
1365
1366 /* Flush FIFO */
1367 __HAL_CRYP_FIFO_FLUSH(hcryp);
1368
1369 /* Enable the CRYP peripheral */
1370 __HAL_CRYP_ENABLE(hcryp);
1371
1372 /* Set the phase */
1373 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1374 }
1375
1376 /* Write Plain Data and Get Cypher Data */
1377 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
1378 {
1379 return HAL_TIMEOUT;
1380 }
1381
1382 /* Change the CRYP peripheral state */
1383 hcryp->State = HAL_CRYP_STATE_READY;
1384
1385 /* Process Unlocked */
1386 __HAL_UNLOCK(hcryp);
1387
1388 /* Return function status */
1389 return HAL_OK;
1390 }
1391
1392 /**
1393 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using IT.
1394 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1395 * the configuration information for CRYP module
1396 * @param pPlainData: Pointer to the plaintext buffer
1397 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1398 * @param pCypherData: Pointer to the cyphertext buffer
1399 * @retval HAL status
1400 */
1401 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1402 {
1403 uint32_t tickstart = 0;
1404 uint32_t inputaddr;
1405 uint32_t outputaddr;
1406
1407 if(hcryp->State == HAL_CRYP_STATE_READY)
1408 {
1409 /* Process Locked */
1410 __HAL_LOCK(hcryp);
1411
1412 /* Get the buffer addresses and sizes */
1413 hcryp->CrypInCount = Size;
1414 hcryp->pCrypInBuffPtr = pPlainData;
1415 hcryp->pCrypOutBuffPtr = pCypherData;
1416 hcryp->CrypOutCount = Size;
1417
1418 /* Change the CRYP peripheral state */
1419 hcryp->State = HAL_CRYP_STATE_BUSY;
1420
1421 /* Check if initialization phase has already been performed */
1422 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1423 {
1424 /* Set the key */
1425 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1426
1427 /* Set the CRYP peripheral in AES GCM mode */
1428 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
1429
1430 /* Set the Initialization Vector */
1431 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
1432
1433 /* Flush FIFO */
1434 __HAL_CRYP_FIFO_FLUSH(hcryp);
1435
1436 /* Enable CRYP to start the init phase */
1437 __HAL_CRYP_ENABLE(hcryp);
1438
1439 /* Get tick */
1440 tickstart = HAL_GetTick();
1441
1442 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1443 {
1444 /* Check for the Timeout */
1445
1446 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1447 {
1448 /* Change state */
1449 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1450
1451 /* Process Unlocked */
1452 __HAL_UNLOCK(hcryp);
1453
1454 return HAL_TIMEOUT;
1455
1456 }
1457 }
1458
1459 /* Set the header phase */
1460 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
1461 {
1462 return HAL_TIMEOUT;
1463 }
1464 /* Disable the CRYP peripheral */
1465 __HAL_CRYP_DISABLE(hcryp);
1466
1467 /* Select payload phase once the header phase is performed */
1468 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
1469
1470 /* Flush FIFO */
1471 __HAL_CRYP_FIFO_FLUSH(hcryp);
1472
1473 /* Set the phase */
1474 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1475 }
1476
1477 if(Size != 0)
1478 {
1479 /* Enable Interrupts */
1480 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1481 /* Enable the CRYP peripheral */
1482 __HAL_CRYP_ENABLE(hcryp);
1483 }
1484 else
1485 {
1486 /* Process Locked */
1487 __HAL_UNLOCK(hcryp);
1488 /* Change the CRYP state and phase */
1489 hcryp->State = HAL_CRYP_STATE_READY;
1490 }
1491 /* Return function status */
1492 return HAL_OK;
1493 }
1494 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
1495 {
1496 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1497 /* Write the Input block in the IN FIFO */
1498 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1499 inputaddr+=4;
1500 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1501 inputaddr+=4;
1502 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1503 inputaddr+=4;
1504 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1505 hcryp->pCrypInBuffPtr += 16;
1506 hcryp->CrypInCount -= 16;
1507 if(hcryp->CrypInCount == 0)
1508 {
1509 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1510 /* Call the Input data transfer complete callback */
1511 HAL_CRYP_InCpltCallback(hcryp);
1512 }
1513 }
1514 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
1515 {
1516 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1517 /* Read the Output block from the Output FIFO */
1518 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1519 outputaddr+=4;
1520 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1521 outputaddr+=4;
1522 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1523 outputaddr+=4;
1524 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1525 hcryp->pCrypOutBuffPtr += 16;
1526 hcryp->CrypOutCount -= 16;
1527 if(hcryp->CrypOutCount == 0)
1528 {
1529 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1530 /* Process Unlocked */
1531 __HAL_UNLOCK(hcryp);
1532 /* Change the CRYP peripheral state */
1533 hcryp->State = HAL_CRYP_STATE_READY;
1534 /* Call Input transfer complete callback */
1535 HAL_CRYP_OutCpltCallback(hcryp);
1536 }
1537 }
1538
1539 /* Return function status */
1540 return HAL_OK;
1541 }
1542
1543 /**
1544 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
1545 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1546 * the configuration information for CRYP module
1547 * @param pPlainData: Pointer to the plaintext buffer
1548 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1549 * @param pCypherData: Pointer to the cyphertext buffer
1550 * @retval HAL status
1551 */
1552 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1553 {
1554 uint32_t tickstart = 0;
1555 uint32_t inputaddr;
1556 uint32_t outputaddr;
1557
1558 uint32_t headersize = hcryp->Init.HeaderSize;
1559 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
1560 uint32_t loopcounter = 0;
1561 uint32_t bufferidx = 0;
1562 uint8_t blockb0[16] = {0};/* Block B0 */
1563 uint8_t ctr[16] = {0}; /* Counter */
1564 uint32_t b0addr = (uint32_t)blockb0;
1565
1566 if(hcryp->State == HAL_CRYP_STATE_READY)
1567 {
1568 /* Process Locked */
1569 __HAL_LOCK(hcryp);
1570
1571 hcryp->CrypInCount = Size;
1572 hcryp->pCrypInBuffPtr = pPlainData;
1573 hcryp->pCrypOutBuffPtr = pCypherData;
1574 hcryp->CrypOutCount = Size;
1575
1576 /* Change the CRYP peripheral state */
1577 hcryp->State = HAL_CRYP_STATE_BUSY;
1578
1579 /* Check if initialization phase has already been performed */
1580 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1581 {
1582 /************************ Formatting the header block *******************/
1583 if(headersize != 0)
1584 {
1585 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1586 if(headersize < 65280)
1587 {
1588 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
1589 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
1590 headersize += 2;
1591 }
1592 else
1593 {
1594 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1595 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
1596 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
1597 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
1598 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
1599 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
1600 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
1601 headersize += 6;
1602 }
1603 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1604 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
1605 {
1606 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
1607 }
1608 /* Check if the header size is modulo 16 */
1609 if ((headersize % 16) != 0)
1610 {
1611 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1612 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
1613 {
1614 hcryp->Init.pScratch[loopcounter] = 0;
1615 }
1616 /* Set the header size to modulo 16 */
1617 headersize = ((headersize/16) + 1) * 16;
1618 }
1619 /* Set the pointer headeraddr to hcryp->Init.pScratch */
1620 headeraddr = (uint32_t)hcryp->Init.pScratch;
1621 }
1622 /*********************** Formatting the block B0 ************************/
1623 if(headersize != 0)
1624 {
1625 blockb0[0] = 0x40;
1626 }
1627 /* Flags byte */
1628 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
1629 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
1630 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
1631
1632 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
1633 {
1634 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
1635 }
1636 for ( ; loopcounter < 13; loopcounter++)
1637 {
1638 blockb0[loopcounter+1] = 0;
1639 }
1640
1641 blockb0[14] = (Size >> 8);
1642 blockb0[15] = (Size & 0xFF);
1643
1644 /************************* Formatting the initial counter ***************/
1645 /* Byte 0:
1646 Bits 7 and 6 are reserved and shall be set to 0
1647 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
1648 blocks are distinct from B0
1649 Bits 0, 1, and 2 contain the same encoding of q as in B0
1650 */
1651 ctr[0] = blockb0[0] & 0x07;
1652 /* byte 1 to NonceSize is the IV (Nonce) */
1653 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
1654 {
1655 ctr[loopcounter] = blockb0[loopcounter];
1656 }
1657 /* Set the LSB to 1 */
1658 ctr[15] |= 0x01;
1659
1660 /* Set the key */
1661 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1662
1663 /* Set the CRYP peripheral in AES CCM mode */
1664 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
1665
1666 /* Set the Initialization Vector */
1667 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
1668
1669 /* Select init phase */
1670 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
1671
1672 b0addr = (uint32_t)blockb0;
1673 /* Write the blockb0 block in the IN FIFO */
1674 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1675 b0addr+=4;
1676 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1677 b0addr+=4;
1678 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1679 b0addr+=4;
1680 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1681
1682 /* Enable the CRYP peripheral */
1683 __HAL_CRYP_ENABLE(hcryp);
1684
1685 /* Get tick */
1686 tickstart = HAL_GetTick();
1687
1688 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1689 {
1690 /* Check for the Timeout */
1691 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1692 {
1693 /* Change state */
1694 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1695
1696 /* Process Unlocked */
1697 __HAL_UNLOCK(hcryp);
1698
1699 return HAL_TIMEOUT;
1700 }
1701 }
1702 /***************************** Header phase *****************************/
1703 if(headersize != 0)
1704 {
1705 /* Select header phase */
1706 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
1707
1708 /* Enable Crypto processor */
1709 __HAL_CRYP_ENABLE(hcryp);
1710
1711 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1712 {
1713 /* Get tick */
1714 tickstart = HAL_GetTick();
1715
1716 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
1717 {
1718 /* Check for the Timeout */
1719 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1720 {
1721 /* Change state */
1722 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1723
1724 /* Process Unlocked */
1725 __HAL_UNLOCK(hcryp);
1726
1727 return HAL_TIMEOUT;
1728 }
1729 }
1730 /* Write the header block in the IN FIFO */
1731 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1732 headeraddr+=4;
1733 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1734 headeraddr+=4;
1735 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1736 headeraddr+=4;
1737 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1738 headeraddr+=4;
1739 }
1740
1741 /* Get tick */
1742 tickstart = HAL_GetTick();
1743
1744 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1745 {
1746 /* Check for the Timeout */
1747 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1748 {
1749 /* Change state */
1750 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1751
1752 /* Process Unlocked */
1753 __HAL_UNLOCK(hcryp);
1754
1755 return HAL_TIMEOUT;
1756 }
1757 }
1758 }
1759 /* Save formatted counter into the scratch buffer pScratch */
1760 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
1761 {
1762 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1763 }
1764 /* Reset bit 0 */
1765 hcryp->Init.pScratch[15] &= 0xfe;
1766
1767 /* Select payload phase once the header phase is performed */
1768 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
1769
1770 /* Flush FIFO */
1771 __HAL_CRYP_FIFO_FLUSH(hcryp);
1772
1773 /* Set the phase */
1774 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1775 }
1776
1777 if(Size != 0)
1778 {
1779 /* Enable Interrupts */
1780 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1781 /* Enable the CRYP peripheral */
1782 __HAL_CRYP_ENABLE(hcryp);
1783 }
1784 else
1785 {
1786 /* Change the CRYP state and phase */
1787 hcryp->State = HAL_CRYP_STATE_READY;
1788 }
1789
1790 /* Return function status */
1791 return HAL_OK;
1792 }
1793 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
1794 {
1795 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1796 /* Write the Input block in the IN FIFO */
1797 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1798 inputaddr+=4;
1799 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1800 inputaddr+=4;
1801 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1802 inputaddr+=4;
1803 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1804 hcryp->pCrypInBuffPtr += 16;
1805 hcryp->CrypInCount -= 16;
1806 if(hcryp->CrypInCount == 0)
1807 {
1808 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1809 /* Call Input transfer complete callback */
1810 HAL_CRYP_InCpltCallback(hcryp);
1811 }
1812 }
1813 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
1814 {
1815 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1816 /* Read the Output block from the Output FIFO */
1817 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1818 outputaddr+=4;
1819 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1820 outputaddr+=4;
1821 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1822 outputaddr+=4;
1823 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1824 hcryp->pCrypOutBuffPtr += 16;
1825 hcryp->CrypOutCount -= 16;
1826 if(hcryp->CrypOutCount == 0)
1827 {
1828 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1829 /* Process Unlocked */
1830 __HAL_UNLOCK(hcryp);
1831 /* Change the CRYP peripheral state */
1832 hcryp->State = HAL_CRYP_STATE_READY;
1833 /* Call Input transfer complete callback */
1834 HAL_CRYP_OutCpltCallback(hcryp);
1835 }
1836 }
1837
1838 /* Return function status */
1839 return HAL_OK;
1840 }
1841
1842 /**
1843 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using IT.
1844 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1845 * the configuration information for CRYP module
1846 * @param pCypherData: Pointer to the cyphertext buffer
1847 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
1848 * @param pPlainData: Pointer to the plaintext buffer
1849 * @retval HAL status
1850 */
1851 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
1852 {
1853 uint32_t tickstart = 0;
1854 uint32_t inputaddr;
1855 uint32_t outputaddr;
1856
1857 if(hcryp->State == HAL_CRYP_STATE_READY)
1858 {
1859 /* Process Locked */
1860 __HAL_LOCK(hcryp);
1861
1862 /* Get the buffer addresses and sizes */
1863 hcryp->CrypInCount = Size;
1864 hcryp->pCrypInBuffPtr = pCypherData;
1865 hcryp->pCrypOutBuffPtr = pPlainData;
1866 hcryp->CrypOutCount = Size;
1867
1868 /* Change the CRYP peripheral state */
1869 hcryp->State = HAL_CRYP_STATE_BUSY;
1870
1871 /* Check if initialization phase has already been performed */
1872 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1873 {
1874 /* Set the key */
1875 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1876
1877 /* Set the CRYP peripheral in AES GCM decryption mode */
1878 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
1879
1880 /* Set the Initialization Vector */
1881 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
1882
1883 /* Flush FIFO */
1884 __HAL_CRYP_FIFO_FLUSH(hcryp);
1885
1886 /* Enable CRYP to start the init phase */
1887 __HAL_CRYP_ENABLE(hcryp);
1888
1889 /* Get tick */
1890 tickstart = HAL_GetTick();
1891
1892 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1893 {
1894 /* Check for the Timeout */
1895 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1896 {
1897 /* Change state */
1898 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1899
1900 /* Process Unlocked */
1901 __HAL_UNLOCK(hcryp);
1902
1903 return HAL_TIMEOUT;
1904 }
1905 }
1906
1907 /* Set the header phase */
1908 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
1909 {
1910 return HAL_TIMEOUT;
1911 }
1912 /* Disable the CRYP peripheral */
1913 __HAL_CRYP_DISABLE(hcryp);
1914
1915 /* Select payload phase once the header phase is performed */
1916 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
1917
1918 /* Set the phase */
1919 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1920 }
1921
1922 if(Size != 0)
1923 {
1924 /* Enable Interrupts */
1925 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1926 /* Enable the CRYP peripheral */
1927 __HAL_CRYP_ENABLE(hcryp);
1928 }
1929 else
1930 {
1931 /* Process Locked */
1932 __HAL_UNLOCK(hcryp);
1933 /* Change the CRYP state and phase */
1934 hcryp->State = HAL_CRYP_STATE_READY;
1935 }
1936
1937 /* Return function status */
1938 return HAL_OK;
1939 }
1940 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
1941 {
1942 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1943 /* Write the Input block in the IN FIFO */
1944 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1945 inputaddr+=4;
1946 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1947 inputaddr+=4;
1948 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1949 inputaddr+=4;
1950 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1951 hcryp->pCrypInBuffPtr += 16;
1952 hcryp->CrypInCount -= 16;
1953 if(hcryp->CrypInCount == 0)
1954 {
1955 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1956 /* Call the Input data transfer complete callback */
1957 HAL_CRYP_InCpltCallback(hcryp);
1958 }
1959 }
1960 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
1961 {
1962 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1963 /* Read the Output block from the Output FIFO */
1964 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1965 outputaddr+=4;
1966 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1967 outputaddr+=4;
1968 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1969 outputaddr+=4;
1970 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1971 hcryp->pCrypOutBuffPtr += 16;
1972 hcryp->CrypOutCount -= 16;
1973 if(hcryp->CrypOutCount == 0)
1974 {
1975 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1976 /* Process Unlocked */
1977 __HAL_UNLOCK(hcryp);
1978 /* Change the CRYP peripheral state */
1979 hcryp->State = HAL_CRYP_STATE_READY;
1980 /* Call Input transfer complete callback */
1981 HAL_CRYP_OutCpltCallback(hcryp);
1982 }
1983 }
1984
1985 /* Return function status */
1986 return HAL_OK;
1987 }
1988
1989 /**
1990 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using interrupt
1991 * then decrypted pCypherData. The cypher data are available in pPlainData.
1992 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1993 * the configuration information for CRYP module
1994 * @param pCypherData: Pointer to the cyphertext buffer
1995 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1996 * @param pPlainData: Pointer to the plaintext buffer
1997 * @retval HAL status
1998 */
1999 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2000 {
2001 uint32_t inputaddr;
2002 uint32_t outputaddr;
2003 uint32_t tickstart = 0;
2004 uint32_t headersize = hcryp->Init.HeaderSize;
2005 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
2006 uint32_t loopcounter = 0;
2007 uint32_t bufferidx = 0;
2008 uint8_t blockb0[16] = {0};/* Block B0 */
2009 uint8_t ctr[16] = {0}; /* Counter */
2010 uint32_t b0addr = (uint32_t)blockb0;
2011
2012 if(hcryp->State == HAL_CRYP_STATE_READY)
2013 {
2014 /* Process Locked */
2015 __HAL_LOCK(hcryp);
2016
2017 hcryp->CrypInCount = Size;
2018 hcryp->pCrypInBuffPtr = pCypherData;
2019 hcryp->pCrypOutBuffPtr = pPlainData;
2020 hcryp->CrypOutCount = Size;
2021
2022 /* Change the CRYP peripheral state */
2023 hcryp->State = HAL_CRYP_STATE_BUSY;
2024
2025 /* Check if initialization phase has already been performed */
2026 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2027 {
2028 /************************ Formatting the header block *******************/
2029 if(headersize != 0)
2030 {
2031 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2032 if(headersize < 65280)
2033 {
2034 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
2035 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
2036 headersize += 2;
2037 }
2038 else
2039 {
2040 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2041 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
2042 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
2043 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
2044 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
2045 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
2046 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
2047 headersize += 6;
2048 }
2049 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2050 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
2051 {
2052 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2053 }
2054 /* Check if the header size is modulo 16 */
2055 if ((headersize % 16) != 0)
2056 {
2057 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2058 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
2059 {
2060 hcryp->Init.pScratch[loopcounter] = 0;
2061 }
2062 /* Set the header size to modulo 16 */
2063 headersize = ((headersize/16) + 1) * 16;
2064 }
2065 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2066 headeraddr = (uint32_t)hcryp->Init.pScratch;
2067 }
2068 /*********************** Formatting the block B0 ************************/
2069 if(headersize != 0)
2070 {
2071 blockb0[0] = 0x40;
2072 }
2073 /* Flags byte */
2074 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2075 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2076 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2077
2078 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
2079 {
2080 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
2081 }
2082 for ( ; loopcounter < 13; loopcounter++)
2083 {
2084 blockb0[loopcounter+1] = 0;
2085 }
2086
2087 blockb0[14] = (Size >> 8);
2088 blockb0[15] = (Size & 0xFF);
2089
2090 /************************* Formatting the initial counter ***************/
2091 /* Byte 0:
2092 Bits 7 and 6 are reserved and shall be set to 0
2093 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2094 blocks are distinct from B0
2095 Bits 0, 1, and 2 contain the same encoding of q as in B0
2096 */
2097 ctr[0] = blockb0[0] & 0x07;
2098 /* byte 1 to NonceSize is the IV (Nonce) */
2099 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
2100 {
2101 ctr[loopcounter] = blockb0[loopcounter];
2102 }
2103 /* Set the LSB to 1 */
2104 ctr[15] |= 0x01;
2105
2106 /* Set the key */
2107 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2108
2109 /* Set the CRYP peripheral in AES CCM mode */
2110 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
2111
2112 /* Set the Initialization Vector */
2113 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
2114
2115 /* Select init phase */
2116 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2117
2118 b0addr = (uint32_t)blockb0;
2119 /* Write the blockb0 block in the IN FIFO */
2120 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2121 b0addr+=4;
2122 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2123 b0addr+=4;
2124 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2125 b0addr+=4;
2126 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2127
2128 /* Enable the CRYP peripheral */
2129 __HAL_CRYP_ENABLE(hcryp);
2130
2131 /* Get tick */
2132 tickstart = HAL_GetTick();
2133
2134 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2135 {
2136 /* Check for the Timeout */
2137 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2138 {
2139 /* Change state */
2140 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2141
2142 /* Process Unlocked */
2143 __HAL_UNLOCK(hcryp);
2144
2145 return HAL_TIMEOUT;
2146 }
2147 }
2148 /***************************** Header phase *****************************/
2149 if(headersize != 0)
2150 {
2151 /* Select header phase */
2152 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
2153
2154 /* Enable Crypto processor */
2155 __HAL_CRYP_ENABLE(hcryp);
2156
2157 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
2158 {
2159 /* Get tick */
2160 tickstart = HAL_GetTick();
2161
2162 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
2163 {
2164 /* Check for the Timeout */
2165 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2166 {
2167 /* Change state */
2168 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2169
2170 /* Process Unlocked */
2171 __HAL_UNLOCK(hcryp);
2172
2173 return HAL_TIMEOUT;
2174 }
2175 }
2176 /* Write the header block in the IN FIFO */
2177 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2178 headeraddr+=4;
2179 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2180 headeraddr+=4;
2181 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2182 headeraddr+=4;
2183 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2184 headeraddr+=4;
2185 }
2186
2187 /* Get tick */
2188 tickstart = HAL_GetTick();
2189
2190 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2191 {
2192 /* Check for the Timeout */
2193 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2194 {
2195 /* Change state */
2196 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2197
2198 /* Process Unlocked */
2199 __HAL_UNLOCK(hcryp);
2200
2201 return HAL_TIMEOUT;
2202 }
2203 }
2204 }
2205 /* Save formatted counter into the scratch buffer pScratch */
2206 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
2207 {
2208 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2209 }
2210 /* Reset bit 0 */
2211 hcryp->Init.pScratch[15] &= 0xfe;
2212 /* Select payload phase once the header phase is performed */
2213 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2214
2215 /* Flush FIFO */
2216 __HAL_CRYP_FIFO_FLUSH(hcryp);
2217
2218 /* Set the phase */
2219 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2220 }
2221
2222 /* Enable Interrupts */
2223 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2224
2225 /* Enable the CRYP peripheral */
2226 __HAL_CRYP_ENABLE(hcryp);
2227
2228 /* Return function status */
2229 return HAL_OK;
2230 }
2231 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
2232 {
2233 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
2234 /* Write the Input block in the IN FIFO */
2235 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
2236 inputaddr+=4;
2237 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
2238 inputaddr+=4;
2239 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
2240 inputaddr+=4;
2241 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
2242 hcryp->pCrypInBuffPtr += 16;
2243 hcryp->CrypInCount -= 16;
2244 if(hcryp->CrypInCount == 0)
2245 {
2246 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
2247 /* Call the Input data transfer complete callback */
2248 HAL_CRYP_InCpltCallback(hcryp);
2249 }
2250 }
2251 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
2252 {
2253 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
2254 /* Read the Output block from the Output FIFO */
2255 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
2256 outputaddr+=4;
2257 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
2258 outputaddr+=4;
2259 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
2260 outputaddr+=4;
2261 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
2262 hcryp->pCrypOutBuffPtr += 16;
2263 hcryp->CrypOutCount -= 16;
2264 if(hcryp->CrypOutCount == 0)
2265 {
2266 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
2267 /* Process Unlocked */
2268 __HAL_UNLOCK(hcryp);
2269 /* Change the CRYP peripheral state */
2270 hcryp->State = HAL_CRYP_STATE_READY;
2271 /* Call Input transfer complete callback */
2272 HAL_CRYP_OutCpltCallback(hcryp);
2273 }
2274 }
2275
2276 /* Return function status */
2277 return HAL_OK;
2278 }
2279
2280 /**
2281 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using DMA.
2282 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2283 * the configuration information for CRYP module
2284 * @param pPlainData: Pointer to the plaintext buffer
2285 * @param Size: Length of the plaintext buffer, must be a multiple of 16
2286 * @param pCypherData: Pointer to the cyphertext buffer
2287 * @retval HAL status
2288 */
2289 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
2290 {
2291 uint32_t tickstart = 0;
2292 uint32_t inputaddr;
2293 uint32_t outputaddr;
2294
2295 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2296 {
2297 /* Process Locked */
2298 __HAL_LOCK(hcryp);
2299
2300 inputaddr = (uint32_t)pPlainData;
2301 outputaddr = (uint32_t)pCypherData;
2302
2303 /* Change the CRYP peripheral state */
2304 hcryp->State = HAL_CRYP_STATE_BUSY;
2305
2306 /* Check if initialization phase has already been performed */
2307 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2308 {
2309 /* Set the key */
2310 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2311
2312 /* Set the CRYP peripheral in AES GCM mode */
2313 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
2314
2315 /* Set the Initialization Vector */
2316 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
2317
2318 /* Flush FIFO */
2319 __HAL_CRYP_FIFO_FLUSH(hcryp);
2320
2321 /* Enable CRYP to start the init phase */
2322 __HAL_CRYP_ENABLE(hcryp);
2323
2324 /* Get tick */
2325 tickstart = HAL_GetTick();
2326
2327 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2328 {
2329 /* Check for the Timeout */
2330 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2331 {
2332 /* Change state */
2333 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2334
2335 /* Process Unlocked */
2336 __HAL_UNLOCK(hcryp);
2337
2338 return HAL_TIMEOUT;
2339 }
2340 }
2341 /* Flush FIFO */
2342 __HAL_CRYP_FIFO_FLUSH(hcryp);
2343
2344 /* Set the header phase */
2345 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
2346 {
2347 return HAL_TIMEOUT;
2348 }
2349 /* Disable the CRYP peripheral */
2350 __HAL_CRYP_DISABLE(hcryp);
2351
2352 /* Select payload phase once the header phase is performed */
2353 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2354
2355 /* Flush FIFO */
2356 __HAL_CRYP_FIFO_FLUSH(hcryp);
2357
2358 /* Set the phase */
2359 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2360 }
2361
2362 /* Set the input and output addresses and start DMA transfer */
2363 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2364
2365 /* Unlock process */
2366 __HAL_UNLOCK(hcryp);
2367
2368 /* Return function status */
2369 return HAL_OK;
2370 }
2371 else
2372 {
2373 return HAL_ERROR;
2374 }
2375 }
2376
2377 /**
2378 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
2379 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2380 * the configuration information for CRYP module
2381 * @param pPlainData: Pointer to the plaintext buffer
2382 * @param Size: Length of the plaintext buffer, must be a multiple of 16
2383 * @param pCypherData: Pointer to the cyphertext buffer
2384 * @retval HAL status
2385 */
2386 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
2387 {
2388 uint32_t tickstart = 0;
2389 uint32_t inputaddr;
2390 uint32_t outputaddr;
2391 uint32_t headersize;
2392 uint32_t headeraddr;
2393 uint32_t loopcounter = 0;
2394 uint32_t bufferidx = 0;
2395 uint8_t blockb0[16] = {0};/* Block B0 */
2396 uint8_t ctr[16] = {0}; /* Counter */
2397 uint32_t b0addr = (uint32_t)blockb0;
2398
2399 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2400 {
2401 /* Process Locked */
2402 __HAL_LOCK(hcryp);
2403
2404 inputaddr = (uint32_t)pPlainData;
2405 outputaddr = (uint32_t)pCypherData;
2406
2407 headersize = hcryp->Init.HeaderSize;
2408 headeraddr = (uint32_t)hcryp->Init.Header;
2409
2410 hcryp->CrypInCount = Size;
2411 hcryp->pCrypInBuffPtr = pPlainData;
2412 hcryp->pCrypOutBuffPtr = pCypherData;
2413 hcryp->CrypOutCount = Size;
2414
2415 /* Change the CRYP peripheral state */
2416 hcryp->State = HAL_CRYP_STATE_BUSY;
2417
2418 /* Check if initialization phase has already been performed */
2419 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2420 {
2421 /************************ Formatting the header block *******************/
2422 if(headersize != 0)
2423 {
2424 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2425 if(headersize < 65280)
2426 {
2427 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
2428 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
2429 headersize += 2;
2430 }
2431 else
2432 {
2433 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2434 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
2435 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
2436 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
2437 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
2438 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
2439 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
2440 headersize += 6;
2441 }
2442 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2443 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
2444 {
2445 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2446 }
2447 /* Check if the header size is modulo 16 */
2448 if ((headersize % 16) != 0)
2449 {
2450 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2451 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
2452 {
2453 hcryp->Init.pScratch[loopcounter] = 0;
2454 }
2455 /* Set the header size to modulo 16 */
2456 headersize = ((headersize/16) + 1) * 16;
2457 }
2458 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2459 headeraddr = (uint32_t)hcryp->Init.pScratch;
2460 }
2461 /*********************** Formatting the block B0 ************************/
2462 if(headersize != 0)
2463 {
2464 blockb0[0] = 0x40;
2465 }
2466 /* Flags byte */
2467 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2468 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2469 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2470
2471 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
2472 {
2473 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
2474 }
2475 for ( ; loopcounter < 13; loopcounter++)
2476 {
2477 blockb0[loopcounter+1] = 0;
2478 }
2479
2480 blockb0[14] = (Size >> 8);
2481 blockb0[15] = (Size & 0xFF);
2482
2483 /************************* Formatting the initial counter ***************/
2484 /* Byte 0:
2485 Bits 7 and 6 are reserved and shall be set to 0
2486 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2487 blocks are distinct from B0
2488 Bits 0, 1, and 2 contain the same encoding of q as in B0
2489 */
2490 ctr[0] = blockb0[0] & 0x07;
2491 /* byte 1 to NonceSize is the IV (Nonce) */
2492 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
2493 {
2494 ctr[loopcounter] = blockb0[loopcounter];
2495 }
2496 /* Set the LSB to 1 */
2497 ctr[15] |= 0x01;
2498
2499 /* Set the key */
2500 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2501
2502 /* Set the CRYP peripheral in AES CCM mode */
2503 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
2504
2505 /* Set the Initialization Vector */
2506 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
2507
2508 /* Select init phase */
2509 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2510
2511 b0addr = (uint32_t)blockb0;
2512 /* Write the blockb0 block in the IN FIFO */
2513 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2514 b0addr+=4;
2515 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2516 b0addr+=4;
2517 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2518 b0addr+=4;
2519 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2520
2521 /* Enable the CRYP peripheral */
2522 __HAL_CRYP_ENABLE(hcryp);
2523
2524 /* Get tick */
2525 tickstart = HAL_GetTick();
2526
2527 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2528 {
2529 /* Check for the Timeout */
2530 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2531 {
2532 /* Change state */
2533 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2534
2535 /* Process Unlocked */
2536 __HAL_UNLOCK(hcryp);
2537
2538 return HAL_TIMEOUT;
2539 }
2540 }
2541 /***************************** Header phase *****************************/
2542 if(headersize != 0)
2543 {
2544 /* Select header phase */
2545 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
2546
2547 /* Enable Crypto processor */
2548 __HAL_CRYP_ENABLE(hcryp);
2549
2550 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
2551 {
2552 /* Get tick */
2553 tickstart = HAL_GetTick();
2554
2555 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
2556 {
2557 /* Check for the Timeout */
2558 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2559 {
2560 /* Change state */
2561 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2562
2563 /* Process Unlocked */
2564 __HAL_UNLOCK(hcryp);
2565
2566 return HAL_TIMEOUT;
2567 }
2568 }
2569 /* Write the header block in the IN FIFO */
2570 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2571 headeraddr+=4;
2572 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2573 headeraddr+=4;
2574 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2575 headeraddr+=4;
2576 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2577 headeraddr+=4;
2578 }
2579
2580 /* Get tick */
2581 tickstart = HAL_GetTick();
2582
2583 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2584 {
2585 /* Check for the Timeout */
2586 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2587 {
2588 /* Change state */
2589 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2590
2591 /* Process Unlocked */
2592 __HAL_UNLOCK(hcryp);
2593
2594 return HAL_TIMEOUT;
2595 }
2596 }
2597 }
2598 /* Save formatted counter into the scratch buffer pScratch */
2599 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
2600 {
2601 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2602 }
2603 /* Reset bit 0 */
2604 hcryp->Init.pScratch[15] &= 0xfe;
2605
2606 /* Select payload phase once the header phase is performed */
2607 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2608
2609 /* Flush FIFO */
2610 __HAL_CRYP_FIFO_FLUSH(hcryp);
2611
2612 /* Set the phase */
2613 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2614 }
2615
2616 /* Set the input and output addresses and start DMA transfer */
2617 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2618
2619 /* Unlock process */
2620 __HAL_UNLOCK(hcryp);
2621
2622 /* Return function status */
2623 return HAL_OK;
2624 }
2625 else
2626 {
2627 return HAL_ERROR;
2628 }
2629 }
2630
2631 /**
2632 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using DMA.
2633 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2634 * the configuration information for CRYP module
2635 * @param pCypherData: Pointer to the cyphertext buffer.
2636 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
2637 * @param pPlainData: Pointer to the plaintext buffer
2638 * @retval HAL status
2639 */
2640 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2641 {
2642 uint32_t tickstart = 0;
2643 uint32_t inputaddr;
2644 uint32_t outputaddr;
2645
2646 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2647 {
2648 /* Process Locked */
2649 __HAL_LOCK(hcryp);
2650
2651 inputaddr = (uint32_t)pCypherData;
2652 outputaddr = (uint32_t)pPlainData;
2653
2654 /* Change the CRYP peripheral state */
2655 hcryp->State = HAL_CRYP_STATE_BUSY;
2656
2657 /* Check if initialization phase has already been performed */
2658 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2659 {
2660 /* Set the key */
2661 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2662
2663 /* Set the CRYP peripheral in AES GCM decryption mode */
2664 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
2665
2666 /* Set the Initialization Vector */
2667 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
2668
2669 /* Enable CRYP to start the init phase */
2670 __HAL_CRYP_ENABLE(hcryp);
2671
2672 /* Get tick */
2673 tickstart = HAL_GetTick();
2674
2675 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2676 {
2677 /* Check for the Timeout */
2678 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2679 {
2680 /* Change state */
2681 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2682
2683 /* Process Unlocked */
2684 __HAL_UNLOCK(hcryp);
2685
2686 return HAL_TIMEOUT;
2687 }
2688 }
2689
2690 /* Set the header phase */
2691 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
2692 {
2693 return HAL_TIMEOUT;
2694 }
2695 /* Disable the CRYP peripheral */
2696 __HAL_CRYP_DISABLE(hcryp);
2697
2698 /* Select payload phase once the header phase is performed */
2699 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2700
2701 /* Set the phase */
2702 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2703 }
2704
2705 /* Set the input and output addresses and start DMA transfer */
2706 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2707
2708 /* Unlock process */
2709 __HAL_UNLOCK(hcryp);
2710
2711 /* Return function status */
2712 return HAL_OK;
2713 }
2714 else
2715 {
2716 return HAL_ERROR;
2717 }
2718 }
2719
2720 /**
2721 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using DMA
2722 * then decrypted pCypherData. The cypher data are available in pPlainData.
2723 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2724 * the configuration information for CRYP module
2725 * @param pCypherData: Pointer to the cyphertext buffer
2726 * @param Size: Length of the plaintext buffer, must be a multiple of 16
2727 * @param pPlainData: Pointer to the plaintext buffer
2728 * @retval HAL status
2729 */
2730 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2731 {
2732 uint32_t tickstart = 0;
2733 uint32_t inputaddr;
2734 uint32_t outputaddr;
2735 uint32_t headersize;
2736 uint32_t headeraddr;
2737 uint32_t loopcounter = 0;
2738 uint32_t bufferidx = 0;
2739 uint8_t blockb0[16] = {0};/* Block B0 */
2740 uint8_t ctr[16] = {0}; /* Counter */
2741 uint32_t b0addr = (uint32_t)blockb0;
2742
2743 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2744 {
2745 /* Process Locked */
2746 __HAL_LOCK(hcryp);
2747
2748 inputaddr = (uint32_t)pCypherData;
2749 outputaddr = (uint32_t)pPlainData;
2750
2751 headersize = hcryp->Init.HeaderSize;
2752 headeraddr = (uint32_t)hcryp->Init.Header;
2753
2754 hcryp->CrypInCount = Size;
2755 hcryp->pCrypInBuffPtr = pCypherData;
2756 hcryp->pCrypOutBuffPtr = pPlainData;
2757 hcryp->CrypOutCount = Size;
2758
2759 /* Change the CRYP peripheral state */
2760 hcryp->State = HAL_CRYP_STATE_BUSY;
2761
2762 /* Check if initialization phase has already been performed */
2763 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2764 {
2765 /************************ Formatting the header block *******************/
2766 if(headersize != 0)
2767 {
2768 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2769 if(headersize < 65280)
2770 {
2771 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
2772 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
2773 headersize += 2;
2774 }
2775 else
2776 {
2777 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2778 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
2779 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
2780 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
2781 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
2782 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
2783 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
2784 headersize += 6;
2785 }
2786 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2787 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
2788 {
2789 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2790 }
2791 /* Check if the header size is modulo 16 */
2792 if ((headersize % 16) != 0)
2793 {
2794 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2795 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
2796 {
2797 hcryp->Init.pScratch[loopcounter] = 0;
2798 }
2799 /* Set the header size to modulo 16 */
2800 headersize = ((headersize/16) + 1) * 16;
2801 }
2802 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2803 headeraddr = (uint32_t)hcryp->Init.pScratch;
2804 }
2805 /*********************** Formatting the block B0 ************************/
2806 if(headersize != 0)
2807 {
2808 blockb0[0] = 0x40;
2809 }
2810 /* Flags byte */
2811 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2812 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2813 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2814
2815 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
2816 {
2817 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
2818 }
2819 for ( ; loopcounter < 13; loopcounter++)
2820 {
2821 blockb0[loopcounter+1] = 0;
2822 }
2823
2824 blockb0[14] = (Size >> 8);
2825 blockb0[15] = (Size & 0xFF);
2826
2827 /************************* Formatting the initial counter ***************/
2828 /* Byte 0:
2829 Bits 7 and 6 are reserved and shall be set to 0
2830 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2831 blocks are distinct from B0
2832 Bits 0, 1, and 2 contain the same encoding of q as in B0
2833 */
2834 ctr[0] = blockb0[0] & 0x07;
2835 /* byte 1 to NonceSize is the IV (Nonce) */
2836 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
2837 {
2838 ctr[loopcounter] = blockb0[loopcounter];
2839 }
2840 /* Set the LSB to 1 */
2841 ctr[15] |= 0x01;
2842
2843 /* Set the key */
2844 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2845
2846 /* Set the CRYP peripheral in AES CCM mode */
2847 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
2848
2849 /* Set the Initialization Vector */
2850 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
2851
2852 /* Select init phase */
2853 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2854
2855 b0addr = (uint32_t)blockb0;
2856 /* Write the blockb0 block in the IN FIFO */
2857 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2858 b0addr+=4;
2859 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2860 b0addr+=4;
2861 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2862 b0addr+=4;
2863 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2864
2865 /* Enable the CRYP peripheral */
2866 __HAL_CRYP_ENABLE(hcryp);
2867
2868 /* Get tick */
2869 tickstart = HAL_GetTick();
2870
2871 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2872 {
2873 /* Check for the Timeout */
2874
2875 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2876 {
2877 /* Change state */
2878 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2879
2880 /* Process Unlocked */
2881 __HAL_UNLOCK(hcryp);
2882
2883 return HAL_TIMEOUT;
2884
2885 }
2886 }
2887 /***************************** Header phase *****************************/
2888 if(headersize != 0)
2889 {
2890 /* Select header phase */
2891 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
2892
2893 /* Enable Crypto processor */
2894 __HAL_CRYP_ENABLE(hcryp);
2895
2896 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
2897 {
2898 /* Get tick */
2899 tickstart = HAL_GetTick();
2900
2901 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
2902 {
2903 /* Check for the Timeout */
2904 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2905 {
2906 /* Change state */
2907 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2908
2909 /* Process Unlocked */
2910 __HAL_UNLOCK(hcryp);
2911
2912 return HAL_TIMEOUT;
2913 }
2914 }
2915 /* Write the header block in the IN FIFO */
2916 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2917 headeraddr+=4;
2918 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2919 headeraddr+=4;
2920 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2921 headeraddr+=4;
2922 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2923 headeraddr+=4;
2924 }
2925
2926 /* Get tick */
2927 tickstart = HAL_GetTick();
2928
2929 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2930 {
2931 /* Check for the Timeout */
2932 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2933 {
2934 /* Change state */
2935 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2936
2937 /* Process Unlocked */
2938 __HAL_UNLOCK(hcryp);
2939
2940 return HAL_TIMEOUT;
2941 }
2942 }
2943 }
2944 /* Save formatted counter into the scratch buffer pScratch */
2945 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
2946 {
2947 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2948 }
2949 /* Reset bit 0 */
2950 hcryp->Init.pScratch[15] &= 0xfe;
2951 /* Select payload phase once the header phase is performed */
2952 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2953
2954 /* Flush FIFO */
2955 __HAL_CRYP_FIFO_FLUSH(hcryp);
2956
2957 /* Set the phase */
2958 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2959 }
2960 /* Set the input and output addresses and start DMA transfer */
2961 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2962
2963 /* Unlock process */
2964 __HAL_UNLOCK(hcryp);
2965
2966 /* Return function status */
2967 return HAL_OK;
2968 }
2969 else
2970 {
2971 return HAL_ERROR;
2972 }
2973 }
2974
2975 /**
2976 * @}
2977 */
2978
2979 /** @defgroup CRYPEx_Exported_Functions_Group2 CRYPEx IRQ handler management
2980 * @brief CRYPEx IRQ handler.
2981 *
2982 @verbatim
2983 ==============================================================================
2984 ##### CRYPEx IRQ handler management #####
2985 ==============================================================================
2986 [..] This section provides CRYPEx IRQ handler function.
2987
2988 @endverbatim
2989 * @{
2990 */
2991
2992 /**
2993 * @brief This function handles CRYPEx interrupt request.
2994 * @param hcryp: pointer to a CRYPEx_HandleTypeDef structure that contains
2995 * the configuration information for CRYP module
2996 * @retval None
2997 */
2998 void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp)
2999 {
3000 switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION)
3001 {
3002 case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT:
3003 HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp, NULL, 0, NULL);
3004 break;
3005
3006 case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT:
3007 HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp, NULL, 0, NULL);
3008 break;
3009
3010 case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT:
3011 HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp, NULL, 0, NULL);
3012 break;
3013
3014 case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT:
3015 HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp, NULL, 0, NULL);
3016 break;
3017
3018 default:
3019 break;
3020 }
3021 }
3022
3023 /**
3024 * @}
3025 */
3026
3027 /**
3028 * @}
3029 */
3030 #endif /* HAL_CRYP_MODULE_ENABLED */
3031
3032 /**
3033 * @}
3034 */
3035 #endif /* STM32F756xx || STM32F777xx || STM32F779xx */
3036 /**
3037 * @}
3038 */
3039
3040 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/