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