source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

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