1 /**
2 ******************************************************************************
3 * @file stm32l4xx_hal_cryp_ex.c
4 * @author MCD Application Team
5 * @brief CRYPEx HAL module driver.
6 * This file provides firmware functions to manage the extended
7 * functionalities of the Cryptography (CRYP) peripheral.
8 *
9 ******************************************************************************
10 * @attention
11 *
12 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 * 3. Neither the name of STMicroelectronics nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 ******************************************************************************
37 */
38
39 /* Includes ------------------------------------------------------------------*/
40 #include "stm32l4xx_hal.h"
41
42 #ifdef HAL_CRYP_MODULE_ENABLED
43
44 #if defined(AES)
45
46 /** @addtogroup STM32L4xx_HAL_Driver
47 * @{
48 */
49
50 /** @defgroup CRYPEx CRYPEx
51 * @brief CRYP Extended HAL module driver
52 * @{
53 */
54
55 /* Private typedef -----------------------------------------------------------*/
56 /* Private define ------------------------------------------------------------*/
57 /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants
58 * @{
59 */
60 #define CRYP_CCF_TIMEOUTVALUE 22000 /*!< CCF flag raising time-out value */
61 #define CRYP_BUSY_TIMEOUTVALUE 22000 /*!< BUSY flag reset time-out value */
62
63 #define CRYP_POLLING_OFF 0x0 /*!< No polling when padding */
64 #define CRYP_POLLING_ON 0x1 /*!< Polling when padding */
65
66 #if defined(AES_CR_NPBLB)
67 #define AES_POSITION_CR_NPBLB (uint32_t)POSITION_VAL(AES_CR_NPBLB) /*!< Required left shift to set background CLUT size */
68 #endif
69 /**
70 * @}
71 */
72
73 /* Private macro -------------------------------------------------------------*/
74 /* Private variables ---------------------------------------------------------*/
75 /* Private function prototypes -----------------------------------------------*/
76 /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions
77 * @{
78 */
79 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout);
80 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout);
81 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
82 static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
83 static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma);
84 static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma);
85 static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma);
86 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
87 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
88 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
89 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
90 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
91 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling);
92 /**
93 * @}
94 */
95
96 /* Exported functions ---------------------------------------------------------*/
97
98 /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions
99 * @{
100 */
101
102
103 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function
104 * @brief Extended callback functions.
105 *
106 @verbatim
107 ===============================================================================
108 ##### Extended callback functions #####
109 ===============================================================================
110 [..] This section provides callback function:
111 (+) Computation completed.
112
113 @endverbatim
114 * @{
115 */
116
117
118 /**
119 * @brief Computation completed callbacks.
120 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
121 * the configuration information for CRYP module
122 * @retval None
123 */
HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef * hcryp)124 __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp)
125 {
126 /* Prevent unused argument(s) compilation warning */
127 UNUSED(hcryp);
128
129 /* NOTE : This function should not be modified; when the callback is needed,
130 the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file
131 */
132 }
133
134 /**
135 * @}
136 */
137
138 /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions
139 * @brief Extended processing functions.
140 *
141 @verbatim
142 ==============================================================================
143 ##### AES extended processing functions #####
144 ==============================================================================
145 [..] This section provides functions allowing to:
146 (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes.
147 Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated
148 based on the processing type. Three processing types are available:
149 (++) Polling mode
150 (++) Interrupt mode
151 (++) DMA mode
152 (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES
153 algorithm in different chaining modes.
154 Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase
155 so that steps can be skipped if so required. Functions are only differentiated based on the processing type.
156 Three processing types are available:
157 (++) Polling mode
158 (++) Interrupt mode
159 (++) DMA mode
160
161 @endverbatim
162 * @{
163 */
164
165 /**
166 * @brief Carry out in polling mode the ciphering or deciphering operation according to
167 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
168 * chaining modes ECB, CBC and CTR are managed by this function in polling mode.
169 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
170 * the configuration information for CRYP module
171 * @param pInputData: Pointer to the plain text in case of encryption or cipher text in case of decryption
172 * or key derivation+decryption.
173 * Parameter is meaningless in case of key derivation.
174 * @param Size: Length of the input data buffer in bytes, must be a multiple of 16.
175 * Parameter is meaningless in case of key derivation.
176 * @param pOutputData: Pointer to the cipher text in case of encryption or plain text in case of
177 * decryption/key derivation+decryption, or pointer to the derivative keys in
178 * case of key derivation only.
179 * @param Timeout: Specify Timeout value
180 * @retval HAL status
181 */
HAL_CRYPEx_AES(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint16_t Size,uint8_t * pOutputData,uint32_t Timeout)182 HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout)
183 {
184
185 if (hcryp->State == HAL_CRYP_STATE_READY)
186 {
187 /* Check parameters setting */
188 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
189 {
190 if (pOutputData == NULL)
191 {
192 return HAL_ERROR;
193 }
194 }
195 else
196 {
197 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
198 {
199 return HAL_ERROR;
200 }
201 }
202
203 /* Process Locked */
204 __HAL_LOCK(hcryp);
205
206 /* Change the CRYP state */
207 hcryp->State = HAL_CRYP_STATE_BUSY;
208
209 /* Call CRYP_ReadKey() API if the operating mode is set to
210 key derivation, CRYP_ProcessData() otherwise */
211 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
212 {
213 if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK)
214 {
215 return HAL_TIMEOUT;
216 }
217 }
218 else
219 {
220 if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK)
221 {
222 return HAL_TIMEOUT;
223 }
224 }
225
226 /* If the state has not been set to SUSPENDED, set it to
227 READY, otherwise keep it as it is */
228 if (hcryp->State != HAL_CRYP_STATE_SUSPENDED)
229 {
230 hcryp->State = HAL_CRYP_STATE_READY;
231 }
232
233 /* Process Unlocked */
234 __HAL_UNLOCK(hcryp);
235
236 return HAL_OK;
237 }
238 else
239 {
240 return HAL_BUSY;
241 }
242 }
243
244
245
246 /**
247 * @brief Carry out in interrupt mode the ciphering or deciphering operation according to
248 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
249 * chaining modes ECB, CBC and CTR are managed by this function in interrupt mode.
250 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
251 * the configuration information for CRYP module
252 * @param pInputData: Pointer to the plain text in case of encryption or cipher text in case of decryption
253 * or key derivation+decryption.
254 * Parameter is meaningless in case of key derivation.
255 * @param Size: Length of the input data buffer in bytes, must be a multiple of 16.
256 * Parameter is meaningless in case of key derivation.
257 * @param pOutputData: Pointer to the cipher text in case of encryption or plain text in case of
258 * decryption/key derivation+decryption, or pointer to the derivative keys in
259 * case of key derivation only.
260 * @retval HAL status
261 */
HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint16_t Size,uint8_t * pOutputData)262 HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
263 {
264 uint32_t inputaddr;
265
266 if(hcryp->State == HAL_CRYP_STATE_READY)
267 {
268 /* Check parameters setting */
269 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
270 {
271 if (pOutputData == NULL)
272 {
273 return HAL_ERROR;
274 }
275 }
276 else
277 {
278 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
279 {
280 return HAL_ERROR;
281 }
282 }
283 /* Process Locked */
284 __HAL_LOCK(hcryp);
285
286 /* If operating mode is not limited to key derivation only,
287 get the buffers addresses and sizes */
288 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
289 {
290
291 hcryp->CrypInCount = Size;
292 hcryp->pCrypInBuffPtr = pInputData;
293 hcryp->pCrypOutBuffPtr = pOutputData;
294 hcryp->CrypOutCount = Size;
295 }
296 else
297 {
298 /* For key derivation, set output buffer only
299 (will point at derivated key) */
300 hcryp->pCrypOutBuffPtr = pOutputData;
301 }
302
303 /* Change the CRYP state */
304 hcryp->State = HAL_CRYP_STATE_BUSY;
305
306 /* Process Unlocked */
307 __HAL_UNLOCK(hcryp);
308
309 /* Enable Computation Complete Flag and Error Interrupts */
310 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
311
312
313 /* If operating mode is key derivation only, the input data have
314 already been entered during the initialization process. For
315 the other operating modes, they are fed to the CRYP hardware
316 block at this point. */
317 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
318 {
319 /* Initiate the processing under interrupt in entering
320 the first input data */
321 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
322 /* Increment/decrement instance pointer/counter */
323 hcryp->pCrypInBuffPtr += 16;
324 hcryp->CrypInCount -= 16U;
325 /* Write the first input block in the Data Input register */
326 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
327 inputaddr+=4U;
328 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
329 inputaddr+=4U;
330 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
331 inputaddr+=4U;
332 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
333 }
334
335 /* Return function status */
336 return HAL_OK;
337 }
338 else
339 {
340 return HAL_BUSY;
341 }
342 }
343
344
345
346
347
348 /**
349 * @brief Carry out in DMA mode the ciphering or deciphering operation according to
350 * hcryp->Init structure fields.
351 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
352 * the configuration information for CRYP module
353 * @param pInputData: Pointer to the plain text in case of encryption or cipher text in case of decryption
354 * or key derivation+decryption.
355 * @param Size: Length of the input data buffer in bytes, must be a multiple of 16.
356 * @param pOutputData: Pointer to the cipher text in case of encryption or plain text in case of
357 * decryption/key derivation+decryption.
358 * @note Chaining modes ECB, CBC and CTR are managed by this function in DMA mode.
359 * @note Supported operating modes are encryption, decryption and key derivation with decryption.
360 * @note No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx
361 * registers must be done by software.
362 * @note This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx
363 * registers must be done by software thru HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs.
364 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
365 * @retval HAL status
366 */
HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint16_t Size,uint8_t * pOutputData)367 HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
368 {
369 uint32_t inputaddr;
370 uint32_t outputaddr;
371
372 if (hcryp->State == HAL_CRYP_STATE_READY)
373 {
374 /* Check parameters setting */
375 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
376 {
377 /* no DMA channel is provided for key derivation operating mode,
378 access to AES_KEYRx registers must be done by software */
379 return HAL_ERROR;
380 }
381 else
382 {
383 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
384 {
385 return HAL_ERROR;
386 }
387 }
388
389
390 /* Process Locked */
391 __HAL_LOCK(hcryp);
392
393 inputaddr = (uint32_t)pInputData;
394 outputaddr = (uint32_t)pOutputData;
395
396 /* Change the CRYP state */
397 hcryp->State = HAL_CRYP_STATE_BUSY;
398
399 /* Set the input and output addresses and start DMA transfer */
400 CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
401
402 /* Process Unlocked */
403 __HAL_UNLOCK(hcryp);
404
405 /* Return function status */
406 return HAL_OK;
407 }
408 else
409 {
410 return HAL_BUSY;
411 }
412 }
413
414
415
416
417
418
419 /**
420 * @brief Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering
421 * operation according to hcryp->Init structure fields.
422 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
423 * the configuration information for CRYP module
424 * @param pInputData:
425 * - pointer to payload data in GCM or CCM payload phase,
426 * - pointer to B0 block in CMAC header phase,
427 * - pointer to C block in CMAC final phase.
428 * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
429 * @param Size:
430 * - length of the input payload data buffer in bytes in GCM or CCM payload phase,
431 * - length of B0 block (in bytes) in CMAC header phase,
432 * - length of C block (in bytes) in CMAC final phase.
433 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
434 * - Parameter is meaningless in case of CCM final phase.
435 * - Parameter is message length in bytes in case of GCM final phase.
436 * - Parameter must be set to zero in case of GMAC final phase.
437 * @param pOutputData:
438 * - pointer to plain or cipher text in GCM/CCM payload phase,
439 * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
440 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
441 * - Parameter is meaningless in case of CMAC header phase.
442 * @param Timeout: Specify Timeout value
443 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable.
444 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
445 * can be skipped by the user if so required.
446 * @retval HAL status
447 */
HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint64_t Size,uint8_t * pOutputData,uint32_t Timeout)448 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout)
449 {
450 uint32_t index ;
451 uint32_t inputaddr ;
452 uint32_t outputaddr ;
453 uint32_t tagaddr ;
454 uint64_t headerlength ;
455 uint64_t inputlength ;
456 uint64_t payloadlength ;
457 uint32_t difflength = 0;
458 uint32_t addhoc_process = 0;
459
460 if (hcryp->State == HAL_CRYP_STATE_READY)
461 {
462 /* input/output parameters check */
463 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
464 {
465 /* No processing required */
466 }
467 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
468 {
469 if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
470 ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
471 {
472 return HAL_ERROR;
473 }
474 #if defined(AES_CR_NPBLB)
475 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
476 #else
477 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
478 #endif
479 {
480 /* In case of CMAC or CCM (when applicable) header phase resumption, we can have pInputData = NULL and Size = 0 */
481 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
482 {
483 return HAL_ERROR;
484 }
485 }
486 }
487 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
488 {
489 if (((pInputData == NULL) && (Size != 0U)) || \
490 ((pInputData != NULL) && (Size == 0U)) || \
491 ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL)))
492 {
493 return HAL_ERROR;
494 }
495 }
496 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
497 {
498 if (pOutputData == NULL)
499 {
500 return HAL_ERROR;
501 }
502 #if !defined(AES_CR_NPBLB)
503 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
504 {
505 return HAL_ERROR;
506 }
507 #endif
508 }
509 else
510 {
511 /* Unspecified Phase */
512 return HAL_ERROR;
513 }
514
515
516 /* Process Locked */
517 __HAL_LOCK(hcryp);
518
519 /* Change the CRYP state */
520 hcryp->State = HAL_CRYP_STATE_BUSY;
521
522 /*==============================================*/
523 /* GCM/GMAC (or CCM when applicable) init phase */
524 /*==============================================*/
525 /* In case of init phase, the input data (Key and Initialization Vector) have
526 already been entered during the initialization process. Therefore, the
527 API just waits for the CCF flag to be set. */
528 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
529 {
530 /* just wait for hash computation */
531 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
532 {
533 hcryp->State = HAL_CRYP_STATE_READY;
534 __HAL_UNLOCK(hcryp);
535 return HAL_TIMEOUT;
536 }
537
538 /* Clear CCF Flag */
539 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
540 /* Mark that the initialization phase is over */
541 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
542 }
543 /*=======================================================*/
544 /* GCM/GMAC or (CCM / CMAC when applicable) header phase */
545 /*=======================================================*/
546 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
547 {
548 #if !defined(AES_CR_NPBLB)
549 /* Set header phase; for GCM or GMAC, set data-byte at this point */
550 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
551 {
552 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
553 }
554 else
555 #endif
556 {
557 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
558 }
559
560 /* Enable the Peripheral */
561 __HAL_CRYP_ENABLE(hcryp);
562
563 #if !defined(AES_CR_NPBLB)
564 /* in case of CMAC, enter B0 block in header phase, before the header itself. */
565 /* If Size = 0 (possible case of resumption after CMAC header phase suspension),
566 skip these steps and go directly to header buffer feeding to the HW */
567 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U))
568 {
569 uint64_t index_test;
570 inputaddr = (uint32_t)pInputData;
571
572 for(index=0U ; (index < Size); index += 16U)
573 {
574 /* Write the Input block in the Data Input register */
575 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
576 inputaddr+=4U;
577 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
578 inputaddr+=4U;
579 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
580 inputaddr+=4U;
581 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
582 inputaddr+=4U;
583
584 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
585 {
586 hcryp->State = HAL_CRYP_STATE_READY;
587 __HAL_UNLOCK(hcryp);
588 return HAL_TIMEOUT;
589 }
590 /* Clear CCF Flag */
591 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
592
593 /* If the suspension flag has been raised and if the processing is not about
594 to end, suspend processing */
595 index_test = (uint64_t)index + 16U;
596 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_test < Size))
597 {
598 /* reset SuspendRequest */
599 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
600 /* Change the CRYP state */
601 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
602 /* Mark that the header phase is over */
603 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
604
605 /* Save current reading and writing locations of Input and Output buffers */
606 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
607 /* Save the total number of bytes (B blocks + header) that remain to be
608 processed at this point */
609 hcryp->CrypInCount = (uint32_t) (hcryp->Init.HeaderSize + Size - index_test);
610
611 /* Process Unlocked */
612 __HAL_UNLOCK(hcryp);
613
614 return HAL_OK;
615 }
616 } /* for(index=0; (index < Size); index += 16) */
617 }
618 #endif /* !defined(AES_CR_NPBLB) */
619
620 /* Enter header */
621 inputaddr = (uint32_t)hcryp->Init.Header;
622 /* Local variable headerlength is a number of bytes multiple of 128 bits,
623 remaining header data (if any) are handled after this loop */
624 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
625 if ((hcryp->Init.HeaderSize % 16U) != 0U)
626 {
627 difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength);
628 }
629 for(index=0U ; index < headerlength; index += 16U)
630 {
631 uint64_t index_temp;
632 /* Write the Input block in the Data Input register */
633 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
634 inputaddr+=4U;
635 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
636 inputaddr+=4U;
637 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
638 inputaddr+=4U;
639 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
640 inputaddr+=4U;
641
642 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
643 {
644 hcryp->State = HAL_CRYP_STATE_READY;
645 __HAL_UNLOCK(hcryp);
646 return HAL_TIMEOUT;
647 }
648 /* Clear CCF Flag */
649 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
650
651 /* If the suspension flag has been raised and if the processing is not about
652 to end, suspend processing */
653 index_temp = (uint64_t)index + 16U;
654 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < headerlength))
655 {
656 /* reset SuspendRequest */
657 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
658 /* Change the CRYP state */
659 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
660 /* Mark that the header phase is over */
661 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
662
663 /* Save current reading and writing locations of Input and Output buffers */
664 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
665 /* Save the total number of bytes that remain to be processed at this point */
666 hcryp->CrypInCount = (uint32_t) (hcryp->Init.HeaderSize - index_temp);
667
668 /* Process Unlocked */
669 __HAL_UNLOCK(hcryp);
670
671 return HAL_OK;
672 }
673 }
674
675 /* Case header length is not a multiple of 16 bytes */
676 if (difflength != 0U)
677 {
678 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
679 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
680 }
681
682 /* Mark that the header phase is over */
683 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
684 }
685 /*============================================*/
686 /* GCM (or CCM when applicable) payload phase */
687 /*============================================*/
688 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
689 {
690
691 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
692
693 /* if the header phase has been bypassed, AES must be enabled again */
694 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
695 {
696 __HAL_CRYP_ENABLE(hcryp);
697 }
698
699 inputaddr = (uint32_t)pInputData;
700 outputaddr = (uint32_t)pOutputData;
701
702 /* Enter payload */
703 /* Specific handling to manage payload last block size less than 128 bits */
704 if ((Size % 16U) != 0U)
705 {
706 payloadlength = (Size/16U) * 16U;
707 difflength = (uint32_t) (Size - payloadlength);
708 addhoc_process = 1;
709 }
710 else
711 {
712 payloadlength = Size;
713 }
714
715 /* Feed payload */
716 for(index=0U ; index < payloadlength; index += 16U)
717 {
718 uint64_t index_temp;
719 /* Write the Input block in the Data Input register */
720 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
721 inputaddr+=4U;
722 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
723 inputaddr+=4U;
724 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
725 inputaddr+=4U;
726 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
727 inputaddr+=4U;
728
729 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
730 {
731 hcryp->State = HAL_CRYP_STATE_READY;
732 __HAL_UNLOCK(hcryp);
733 return HAL_TIMEOUT;
734 }
735
736 /* Clear CCF Flag */
737 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
738
739 /* Retrieve output data: read the output block
740 from the Data Output Register */
741 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
742 outputaddr+=4U;
743 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
744 outputaddr+=4U;
745 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
746 outputaddr+=4U;
747 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
748 outputaddr+=4U;
749
750 /* If the suspension flag has been raised and if the processing is not about
751 to end, suspend processing */
752 index_temp = (uint64_t)index + 16U;
753 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < payloadlength))
754 {
755 /* no flag waiting under IRQ handling */
756 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
757 {
758 /* Ensure that Busy flag is reset */
759 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
760 {
761 hcryp->State = HAL_CRYP_STATE_READY;
762 __HAL_UNLOCK(hcryp);
763 return HAL_TIMEOUT;
764 }
765 }
766 /* reset SuspendRequest */
767 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
768 /* Change the CRYP state */
769 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
770 /* Mark that the header phase is over */
771 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
772
773 /* Save current reading and writing locations of Input and Output buffers */
774 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
775 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
776 /* Save the number of bytes that remain to be processed at this point */
777 hcryp->CrypInCount = (uint32_t) (Size - index_temp);
778
779 /* Process Unlocked */
780 __HAL_UNLOCK(hcryp);
781
782 return HAL_OK;
783 }
784
785 }
786
787 /* Additional processing to manage GCM(/CCM) encryption and decryption cases when
788 payload last block size less than 128 bits */
789 if (addhoc_process == 1U)
790 {
791
792 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
793 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
794 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
795
796 } /* (addhoc_process == 1) */
797
798 /* Mark that the payload phase is over */
799 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
800 }
801 /*==================================*/
802 /* GCM/GMAC/CCM or CMAC final phase */
803 /*==================================*/
804 else
805 {
806 tagaddr = (uint32_t)pOutputData;
807
808 #if defined(AES_CR_NPBLB)
809 /* By default, clear NPBLB field */
810 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
811 #endif
812
813 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
814
815 /* if the header and payload phases have been bypassed, AES must be enabled again */
816 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
817 {
818 __HAL_CRYP_ENABLE(hcryp);
819 }
820
821 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
822 {
823 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
824 inputlength = Size * 8U; /* input length in bits */
825
826 #if !defined(AES_CR_NPBLB)
827 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
828 {
829 hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
830 hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
831 hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
832 hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
833 }
834 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
835 {
836 hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
837 hcryp->Instance->DINR = __REV((uint32_t)headerlength);
838 hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
839 hcryp->Instance->DINR = __REV((uint32_t)inputlength);
840 }
841 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
842 {
843 hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
844 hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
845 hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
846 hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
847 }
848 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
849 {
850 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
851 hcryp->Instance->DINR = (uint32_t)(headerlength);
852 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
853 hcryp->Instance->DINR = (uint32_t)(inputlength);
854 }
855 else
856 {
857 /* Unspecified Data Type */
858 return HAL_ERROR;
859 }
860 #else
861 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
862 hcryp->Instance->DINR = (uint32_t)(headerlength);
863 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
864 hcryp->Instance->DINR = (uint32_t)(inputlength);
865 #endif
866 }
867 #if !defined(AES_CR_NPBLB)
868 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
869 {
870 inputaddr = (uint32_t)pInputData;
871 /* Enter the last block made of a 128-bit value formatted
872 from the original B0 packet. */
873 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
874 inputaddr+=4U;
875 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
876 inputaddr+=4U;
877 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
878 inputaddr+=4U;
879 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
880 }
881 else
882 {
883 /* Unspecified Chaining Mode */
884 return HAL_ERROR;
885 }
886 #endif
887
888
889 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
890 {
891 hcryp->State = HAL_CRYP_STATE_READY;
892 __HAL_UNLOCK(hcryp);
893 return HAL_TIMEOUT;
894 }
895
896 /* Read the Auth TAG in the Data Out register */
897 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
898 tagaddr+=4U;
899 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
900 tagaddr+=4U;
901 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
902 tagaddr+=4U;
903 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
904
905
906 /* Clear CCF Flag */
907 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
908 /* Mark that the final phase is over */
909 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
910 /* Disable the Peripheral */
911 __HAL_CRYP_DISABLE(hcryp);
912 }
913
914 /* Change the CRYP state */
915 hcryp->State = HAL_CRYP_STATE_READY;
916
917 /* Process Unlocked */
918 __HAL_UNLOCK(hcryp);
919
920 return HAL_OK;
921 }
922 else
923 {
924 return HAL_BUSY;
925 }
926 }
927
928
929
930
931 /**
932 * @brief Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering
933 * operation according to hcryp->Init structure fields.
934 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
935 * the configuration information for CRYP module
936 * @param pInputData:
937 * - pointer to payload data in GCM or CCM payload phase,
938 * - pointer to B0 block in CMAC header phase,
939 * - pointer to C block in CMAC final phase.
940 * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
941 * @param Size:
942 * - length of the input payload data buffer in bytes in GCM or CCM payload phase,
943 * - length of B0 block (in bytes) in CMAC header phase,
944 * - length of C block (in bytes) in CMAC final phase.
945 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
946 * - Parameter is meaningless in case of CCM final phase.
947 * - Parameter is message length in bytes in case of GCM final phase.
948 * - Parameter must be set to zero in case of GMAC final phase.
949 * @param pOutputData:
950 * - pointer to plain or cipher text in GCM/CCM payload phase,
951 * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
952 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
953 * - Parameter is meaningless in case of CMAC header phase.
954 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
955 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
956 * can be skipped by the user if so required.
957 * @retval HAL status
958 */
HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint64_t Size,uint8_t * pOutputData)959 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
960 {
961
962 uint32_t inputaddr ;
963 uint64_t headerlength ;
964 uint64_t inputlength ;
965 uint32_t index ;
966 uint32_t addhoc_process = 0;
967 uint32_t difflength = 0;
968 uint32_t difflengthmod4 = 0;
969 uint32_t mask[4][3];
970
971 uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
972
973 mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */
974 mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */
975 mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */
976 mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */
977
978 if (hcryp->State == HAL_CRYP_STATE_READY)
979 {
980 /* input/output parameters check */
981 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
982 {
983 /* No processing required */
984 }
985 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
986 {
987 if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
988 ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
989 {
990 return HAL_ERROR;
991 }
992 #if defined(AES_CR_NPBLB)
993 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
994 #else
995 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
996 #endif
997 {
998 /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and Size = 0 */
999 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
1000 {
1001 return HAL_ERROR;
1002 }
1003 }
1004 }
1005 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
1006 {
1007 if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
1008 {
1009 return HAL_ERROR;
1010 }
1011 }
1012 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
1013 {
1014 if (pOutputData == NULL)
1015 {
1016 return HAL_ERROR;
1017 }
1018 #if !defined(AES_CR_NPBLB)
1019 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
1020 {
1021 return HAL_ERROR;
1022 }
1023 #endif
1024 }
1025 else
1026 {
1027 /* Unspecified Phase */
1028 return HAL_ERROR;
1029 }
1030
1031
1032 /* Process Locked */
1033 __HAL_LOCK(hcryp);
1034
1035 /* Change the CRYP state */
1036 hcryp->State = HAL_CRYP_STATE_BUSY;
1037
1038 /* Process Unlocked */
1039 __HAL_UNLOCK(hcryp);
1040
1041 /* Enable Computation Complete Flag and Error Interrupts */
1042 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
1043
1044
1045
1046 /*==============================================*/
1047 /* GCM/GMAC (or CCM when applicable) init phase */
1048 /*==============================================*/
1049 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
1050 {
1051 /* In case of init phase, the input data (Key and Initialization Vector) have
1052 already been entered during the initialization process. Therefore, the
1053 software just waits for the CCF interrupt to be raised and which will
1054 be handled by CRYP_AES_Auth_IT() API. */
1055 }
1056 /*===================================*/
1057 /* GCM/GMAC/CCM or CMAC header phase */
1058 /*===================================*/
1059 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
1060 {
1061
1062 #if defined(AES_CR_NPBLB)
1063 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
1064 #else
1065 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1066 #endif
1067 {
1068 /* In case of CMAC, B blocks are first entered, before the header.
1069 Therefore, B blocks and the header are entered back-to-back
1070 as if it was only one single block.
1071 However, in case of resumption after suspension, if all the
1072 B blocks have been entered (in that case, Size = 0), only the
1073 remainder of the non-processed header bytes are entered. */
1074 if (Size != 0U)
1075 {
1076 hcryp->CrypInCount = (uint32_t)(Size + hcryp->Init.HeaderSize);
1077 hcryp->pCrypInBuffPtr = pInputData;
1078 }
1079 else
1080 {
1081 hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
1082 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
1083 }
1084 }
1085 else
1086 {
1087 /* Get the header addresses and sizes */
1088 hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
1089 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
1090 }
1091
1092 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1093
1094
1095 #if !defined(AES_CR_NPBLB)
1096 /* Set header phase; for GCM or GMAC, set data-byte at this point */
1097 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
1098 {
1099 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
1100 }
1101 else
1102 #endif
1103 {
1104 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
1105 }
1106
1107 /* Enable the Peripheral */
1108 __HAL_CRYP_ENABLE(hcryp);
1109
1110 /* Increment/decrement instance pointer/counter */
1111 if (hcryp->CrypInCount == 0U)
1112 {
1113 /* Case of no header */
1114 hcryp->State = HAL_CRYP_STATE_READY;
1115 /* Mark that the header phase is over */
1116 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
1117 return HAL_OK;
1118 }
1119 else if (hcryp->CrypInCount < 16U)
1120 {
1121 hcryp->CrypInCount = 0;
1122 addhoc_process = 1;
1123 difflength = (uint32_t) (hcryp->Init.HeaderSize);
1124 difflengthmod4 = difflength%4U;
1125 }
1126 else
1127 {
1128 hcryp->pCrypInBuffPtr += 16;
1129 hcryp->CrypInCount -= 16U;
1130 }
1131
1132
1133 #if defined(AES_CR_NPBLB)
1134 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
1135 #else
1136 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1137 #endif
1138 {
1139 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
1140 {
1141 /* All B blocks will have been entered after the next
1142 four DINR writing, so point at header buffer for
1143 the next iteration */
1144 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
1145 }
1146 }
1147
1148 /* Enter header first block to initiate the process
1149 in the Data Input register */
1150 if (addhoc_process == 0U)
1151 {
1152 /* Header has size equal or larger than 128 bits */
1153 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1154 inputaddr+=4U;
1155 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1156 inputaddr+=4U;
1157 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1158 inputaddr+=4U;
1159 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1160 }
1161 else
1162 {
1163 /* Header has size less than 128 bits */
1164 /* Enter complete words when possible */
1165 for(index=0U ; index < (difflength/4U); index ++)
1166 {
1167 /* Write the Input block in the Data Input register */
1168 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1169 inputaddr+=4U;
1170 }
1171 /* Enter incomplete word padded with zeroes if applicable
1172 (case of header length not a multiple of 32-bits) */
1173 if (difflengthmod4 != 0U)
1174 {
1175 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
1176 }
1177 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
1178 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
1179 {
1180 hcryp->Instance->DINR = 0;
1181 }
1182
1183 }
1184 }
1185 /*============================================*/
1186 /* GCM (or CCM when applicable) payload phase */
1187 /*============================================*/
1188 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
1189 {
1190 /* Get the buffer addresses and sizes */
1191 hcryp->CrypInCount = (uint32_t)Size;
1192 hcryp->pCrypInBuffPtr = pInputData;
1193 hcryp->pCrypOutBuffPtr = pOutputData;
1194 hcryp->CrypOutCount = (uint32_t)Size;
1195
1196 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1197
1198 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
1199
1200 /* if the header phase has been bypassed, AES must be enabled again */
1201 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
1202 {
1203 __HAL_CRYP_ENABLE(hcryp);
1204 }
1205
1206 /* No payload case */
1207 if (pInputData == NULL)
1208 {
1209 hcryp->State = HAL_CRYP_STATE_READY;
1210 /* Mark that the header phase is over */
1211 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
1212 /* Process Unlocked */
1213 __HAL_UNLOCK(hcryp);
1214
1215 return HAL_OK;
1216 }
1217
1218 /* Specific handling to manage payload size less than 128 bits */
1219 if (Size < 16U)
1220 {
1221 difflength = (uint32_t) (Size);
1222 #if defined(AES_CR_NPBLB)
1223 /* In case of GCM encryption or CCM decryption, specify the number of padding
1224 bytes in last block of payload */
1225 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
1226 {
1227 uint32_t cr_temp = hcryp->Instance->CR;
1228
1229 if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
1230 || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
1231 {
1232 /* Set NPBLB field in writing the number of padding bytes
1233 for the last block of payload */
1234 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
1235 }
1236 }
1237 #else
1238 /* Software workaround applied to GCM encryption only */
1239 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
1240 {
1241 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
1242 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
1243 }
1244 #endif
1245
1246
1247 /* Set hcryp->CrypInCount to 0 (no more data to enter) */
1248 hcryp->CrypInCount = 0;
1249
1250 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes,
1251 to have a complete block of 128 bits */
1252 difflengthmod4 = difflength%4U;
1253 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
1254 to have a complete block of 128 bits */
1255 for(index=0U; index < (difflength/4U); index ++)
1256 {
1257 /* Write the Input block in the Data Input register */
1258 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1259 inputaddr+=4U;
1260 }
1261 /* If required, manage input data size not multiple of 32 bits */
1262 if (difflengthmod4 != 0U)
1263 {
1264 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
1265 }
1266 /* Wrap-up in padding with zero-words if applicable */
1267 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
1268 {
1269 hcryp->Instance->DINR = 0;
1270 }
1271 }
1272 else
1273 {
1274 /* Increment/decrement instance pointer/counter */
1275 hcryp->pCrypInBuffPtr += 16;
1276 hcryp->CrypInCount -= 16U;
1277
1278 /* Enter payload first block to initiate the process
1279 in the Data Input register */
1280 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1281 inputaddr+=4U;
1282 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1283 inputaddr+=4U;
1284 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1285 inputaddr+=4U;
1286 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1287 }
1288 }
1289 /*==================================*/
1290 /* GCM/GMAC/CCM or CMAC final phase */
1291 /*==================================*/
1292 else
1293 {
1294 hcryp->pCrypOutBuffPtr = pOutputData;
1295
1296 #if defined(AES_CR_NPBLB)
1297 /* By default, clear NPBLB field */
1298 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
1299 #endif
1300
1301 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
1302
1303 /* if the header and payload phases have been bypassed, AES must be enabled again */
1304 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
1305 {
1306 __HAL_CRYP_ENABLE(hcryp);
1307 }
1308
1309 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
1310 {
1311 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
1312 inputlength = Size * 8U; /* Input length in bits */
1313 /* Write the number of bits in the header on 64 bits followed by the number
1314 of bits in the payload on 64 bits as well */
1315
1316 #if !defined(AES_CR_NPBLB)
1317 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
1318 {
1319 hcryp->Instance->DINR = __RBIT((uint32_t)((headerlength)>>32));
1320 hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
1321 hcryp->Instance->DINR = __RBIT((uint32_t)((inputlength)>>32));
1322 hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
1323 }
1324 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
1325 {
1326 hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
1327 hcryp->Instance->DINR = __REV((uint32_t)headerlength);
1328 hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
1329 hcryp->Instance->DINR = __REV((uint32_t)inputlength);
1330 }
1331 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
1332 {
1333 hcryp->Instance->DINR = __ROR((uint32_t)((headerlength)>>32), 16);
1334 hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
1335 hcryp->Instance->DINR = __ROR((uint32_t)((inputlength)>>32), 16);
1336 hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
1337 }
1338 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
1339 {
1340 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
1341 hcryp->Instance->DINR = (uint32_t)(headerlength);
1342 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
1343 hcryp->Instance->DINR = (uint32_t)(inputlength);
1344 }
1345 else
1346 {
1347 /* Unspecified Data Type */
1348 return HAL_ERROR;
1349 }
1350 #else
1351 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
1352 hcryp->Instance->DINR = (uint32_t)(headerlength);
1353 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
1354 hcryp->Instance->DINR = (uint32_t)(inputlength);
1355 #endif
1356 }
1357 #if !defined(AES_CR_NPBLB)
1358 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1359 {
1360 inputaddr = (uint32_t)pInputData;
1361 /* Enter the last block made of a 128-bit value formatted
1362 from the original B0 packet. */
1363 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1364 inputaddr+=4U;
1365 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1366 inputaddr+=4U;
1367 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1368 inputaddr+=4U;
1369 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1370 }
1371 else
1372 {
1373 /* Unspecified Chaining Mode */
1374 return HAL_ERROR;
1375 }
1376 #endif
1377 }
1378
1379 return HAL_OK;
1380 }
1381 else
1382 {
1383 return HAL_BUSY;
1384 }
1385 }
1386
1387
1388
1389
1390 /**
1391 * @brief Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering
1392 * operation according to hcryp->Init structure fields.
1393 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1394 * the configuration information for CRYP module
1395 * @param pInputData:
1396 * - pointer to payload data in GCM or CCM payload phase,
1397 * - pointer to B0 block in CMAC header phase,
1398 * - pointer to C block in CMAC final phase.
1399 * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
1400 * @param Size:
1401 * - length of the input payload data buffer in bytes in GCM or CCM payload phase,
1402 * - length of B0 block (in bytes) in CMAC header phase,
1403 * - length of C block (in bytes) in CMAC final phase.
1404 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
1405 * - Parameter is meaningless in case of CCM final phase.
1406 * - Parameter is message length in bytes in case of GCM final phase.
1407 * - Parameter must be set to zero in case of GMAC final phase.
1408 * @param pOutputData:
1409 * - pointer to plain or cipher text in GCM/CCM payload phase,
1410 * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
1411 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
1412 * - Parameter is meaningless in case of CMAC header phase.
1413 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
1414 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
1415 * can be skipped by the user if so required.
1416 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
1417 * @retval HAL status
1418 */
HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint64_t Size,uint8_t * pOutputData)1419 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
1420 {
1421 uint32_t inputaddr ;
1422 uint32_t outputaddr ;
1423 uint32_t tagaddr ;
1424 uint64_t headerlength ;
1425 uint64_t inputlength ;
1426 uint64_t payloadlength ;
1427
1428
1429 if (hcryp->State == HAL_CRYP_STATE_READY)
1430 {
1431 /* input/output parameters check */
1432 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
1433 {
1434 /* No processing required */
1435 }
1436 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
1437 {
1438 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
1439 {
1440 return HAL_ERROR;
1441 }
1442 #if defined(AES_CR_NPBLB)
1443 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
1444 {
1445 /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and Size = 0 */
1446 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
1447 {
1448 return HAL_ERROR;
1449 }
1450 }
1451 #else
1452 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1453 {
1454 if ((pInputData == NULL) || (Size == 0U))
1455 {
1456 return HAL_ERROR;
1457 }
1458 }
1459 #endif
1460 }
1461 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
1462 {
1463 if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
1464 {
1465 return HAL_ERROR;
1466 }
1467 }
1468 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
1469 {
1470 if (pOutputData == NULL)
1471 {
1472 return HAL_ERROR;
1473 }
1474 #if !defined(AES_CR_NPBLB)
1475 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
1476 {
1477 return HAL_ERROR;
1478 }
1479 #endif
1480 }
1481 else
1482 {
1483 /* Unspecified Phase */
1484 return HAL_ERROR;
1485 }
1486
1487
1488 /* Process Locked */
1489 __HAL_LOCK(hcryp);
1490
1491 /* Change the CRYP state */
1492 hcryp->State = HAL_CRYP_STATE_BUSY;
1493
1494 /*==============================================*/
1495 /* GCM/GMAC (or CCM when applicable) init phase */
1496 /*==============================================*/
1497 /* In case of init phase, the input data (Key and Initialization Vector) have
1498 already been entered during the initialization process. No DMA transfer is
1499 required at that point therefore, the software just waits for the CCF flag
1500 to be raised. */
1501 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
1502 {
1503 /* just wait for hash computation */
1504 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1505 {
1506 hcryp->State = HAL_CRYP_STATE_READY;
1507 __HAL_UNLOCK(hcryp);
1508 return HAL_TIMEOUT;
1509 }
1510
1511 /* Clear CCF Flag */
1512 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1513 /* Mark that the initialization phase is over */
1514 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
1515 hcryp->State = HAL_CRYP_STATE_READY;
1516 }
1517 /*====================================*/
1518 /* GCM/GMAC/ CCM or CMAC header phase */
1519 /*====================================*/
1520 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
1521 {
1522 #if !defined(AES_CR_NPBLB)
1523 /* Set header phase; for GCM or GMAC, set data-byte at this point */
1524 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
1525 {
1526 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
1527 }
1528 else
1529 #endif
1530 {
1531 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
1532 }
1533
1534 /* Enable the CRYP peripheral */
1535 __HAL_CRYP_ENABLE(hcryp);
1536
1537 #if !defined(AES_CR_NPBLB)
1538 /* enter first B0 block in polling mode (no DMA transfer for B0) */
1539 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1540 {
1541 inputaddr = (uint32_t)pInputData;
1542 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1543 inputaddr+=4U;
1544 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1545 inputaddr+=4U;
1546 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1547 inputaddr+=4U;
1548 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1549
1550 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1551 {
1552 hcryp->State = HAL_CRYP_STATE_READY;
1553 __HAL_UNLOCK(hcryp);
1554 return HAL_TIMEOUT;
1555 }
1556 /* Clear CCF Flag */
1557 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1558 }
1559 #endif
1560
1561 /* No header case */
1562 if (hcryp->Init.Header == NULL)
1563 {
1564 hcryp->State = HAL_CRYP_STATE_READY;
1565 /* Mark that the header phase is over */
1566 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
1567 /* Process Unlocked */
1568 __HAL_UNLOCK(hcryp);
1569
1570 return HAL_OK;
1571 }
1572
1573 inputaddr = (uint32_t)hcryp->Init.Header;
1574 if ((hcryp->Init.HeaderSize % 16U) != 0U)
1575 {
1576
1577 if (hcryp->Init.HeaderSize < 16U)
1578 {
1579 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
1580 CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF);
1581
1582 hcryp->State = HAL_CRYP_STATE_READY;
1583 /* Mark that the header phase is over */
1584 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
1585
1586 /* CCF flag indicating header phase AES processing completion
1587 will be checked at the start of the next phase:
1588 - payload phase (GCM / CCM when applicable)
1589 - final phase (GMAC or CMAC when applicable). */
1590 }
1591 else
1592 {
1593 /* Local variable headerlength is a number of bytes multiple of 128 bits,
1594 remaining header data (if any) are handled after this loop */
1595 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
1596 /* Store the ending transfer point */
1597 hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength;
1598 hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */
1599
1600 /* Set the input and output addresses and start DMA transfer */
1601 /* (incomplete DMA transfer, will be wrapped up after completion of
1602 the first one (initiated here) with data padding */
1603 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)headerlength, 0);
1604 }
1605 }
1606 else
1607 {
1608 hcryp->CrypInCount = 0;
1609 /* Set the input address and start DMA transfer */
1610 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)hcryp->Init.HeaderSize, 0);
1611 }
1612 }
1613 /*============================================*/
1614 /* GCM (or CCM when applicable) payload phase */
1615 /*============================================*/
1616 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
1617 {
1618 /* Coming from header phase, wait for CCF flag to be raised
1619 if header present and fed to the IP in the previous phase */
1620 if (hcryp->Init.Header != NULL)
1621 {
1622 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1623 {
1624 hcryp->State = HAL_CRYP_STATE_READY;
1625 __HAL_UNLOCK(hcryp);
1626 return HAL_TIMEOUT;
1627 }
1628 }
1629 else
1630 {
1631 /* Enable the Peripheral since wasn't in header phase (no header case) */
1632 __HAL_CRYP_ENABLE(hcryp);
1633 }
1634 /* Clear CCF Flag */
1635 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1636
1637 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
1638
1639 /* No payload case */
1640 if (pInputData == NULL)
1641 {
1642 hcryp->State = HAL_CRYP_STATE_READY;
1643 /* Mark that the header phase is over */
1644 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
1645 /* Process Unlocked */
1646 __HAL_UNLOCK(hcryp);
1647
1648 return HAL_OK;
1649 }
1650
1651
1652 /* Specific handling to manage payload size less than 128 bits */
1653 if ((Size % 16U) != 0U)
1654 {
1655 inputaddr = (uint32_t)pInputData;
1656 outputaddr = (uint32_t)pOutputData;
1657 if (Size < 16U)
1658 {
1659 /* Block is now entered in polling mode, no actual gain in resorting to DMA */
1660 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
1661 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
1662
1663 CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON);
1664
1665 /* Change the CRYP state to ready */
1666 hcryp->State = HAL_CRYP_STATE_READY;
1667 /* Mark that the payload phase is over */
1668 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
1669
1670 /* Call output data transfer complete callback */
1671 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1672 hcryp->OutCpltCallback(hcryp);
1673 #else
1674 HAL_CRYP_OutCpltCallback(hcryp);
1675 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1676 }
1677 else
1678 {
1679 payloadlength = (Size/16U) * 16U;
1680
1681 /* Store the ending transfer points */
1682 hcryp->pCrypInBuffPtr = pInputData;
1683 hcryp->pCrypInBuffPtr += payloadlength;
1684 hcryp->pCrypOutBuffPtr = pOutputData;
1685 hcryp->pCrypOutBuffPtr += payloadlength;
1686 hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */
1687
1688 /* Set the input and output addresses and start DMA transfer */
1689 /* (incomplete DMA transfer, will be wrapped up with data padding
1690 after completion of the one initiated here) */
1691 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)payloadlength, outputaddr);
1692 }
1693 }
1694 else
1695 {
1696 hcryp->CrypInCount = 0;
1697 inputaddr = (uint32_t)pInputData;
1698 outputaddr = (uint32_t)pOutputData;
1699
1700 /* Set the input and output addresses and start DMA transfer */
1701 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)Size, outputaddr);
1702 }
1703 }
1704 /*==================================*/
1705 /* GCM/GMAC/CCM or CMAC final phase */
1706 /*==================================*/
1707 else
1708 {
1709 /* If coming from header phase (GMAC or CMAC case when applicable),
1710 wait for CCF flag to be raised */
1711 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE)
1712 {
1713 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1714 {
1715 hcryp->State = HAL_CRYP_STATE_READY;
1716 __HAL_UNLOCK(hcryp);
1717 return HAL_TIMEOUT;
1718 }
1719 /* Clear CCF Flag */
1720 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1721 }
1722
1723 tagaddr = (uint32_t)pOutputData;
1724
1725 #if defined(AES_CR_NPBLB)
1726 /* By default, clear NPBLB field */
1727 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
1728 #endif
1729 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
1730
1731 /* if the header and payload phases have been bypassed, AES must be enabled again */
1732 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
1733 {
1734 __HAL_CRYP_ENABLE(hcryp);
1735 }
1736
1737 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
1738 {
1739 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
1740 inputlength = Size * 8U; /* input length in bits */
1741 /* Write the number of bits in the header on 64 bits followed by the number
1742 of bits in the payload on 64 bits as well */
1743 #if !defined(AES_CR_NPBLB)
1744 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
1745 {
1746 hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
1747 hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
1748 hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
1749 hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
1750 }
1751 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
1752 {
1753 hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
1754 hcryp->Instance->DINR = __REV((uint32_t)headerlength);
1755 hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
1756 hcryp->Instance->DINR = __REV((uint32_t)inputlength);
1757 }
1758 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
1759 {
1760 hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
1761 hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
1762 hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
1763 hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
1764 }
1765 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
1766 {
1767 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
1768 hcryp->Instance->DINR = (uint32_t)(headerlength);
1769 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
1770 hcryp->Instance->DINR = (uint32_t)(inputlength);
1771 }
1772 else
1773 {
1774 /* Unspecified Data Type */
1775 return HAL_ERROR;
1776 }
1777 #else
1778 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
1779 hcryp->Instance->DINR = (uint32_t)(headerlength);
1780 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
1781 hcryp->Instance->DINR = (uint32_t)(inputlength);
1782 #endif
1783 }
1784 #if !defined(AES_CR_NPBLB)
1785 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1786 {
1787 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1788
1789 inputaddr = (uint32_t)pInputData;
1790 /* Enter the last block made of a 128-bit value formatted
1791 from the original B0 packet. */
1792 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1793 inputaddr+=4U;
1794 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1795 inputaddr+=4U;
1796 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1797 inputaddr+=4U;
1798 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1799 }
1800 else
1801 {
1802 /* Unspecified Chaining Mode */
1803 return HAL_ERROR;
1804 }
1805 #endif
1806
1807 /* No DMA transfer is required at that point therefore, the software
1808 just waits for the CCF flag to be raised. */
1809 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1810 {
1811 hcryp->State = HAL_CRYP_STATE_READY;
1812 __HAL_UNLOCK(hcryp);
1813 return HAL_TIMEOUT;
1814 }
1815
1816 /* Read the Auth TAG in the IN FIFO */
1817 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
1818 tagaddr+=4U;
1819 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
1820 tagaddr+=4U;
1821 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
1822 tagaddr+=4U;
1823 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
1824
1825 /* Clear CCF Flag */
1826 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1827
1828 /* Mark that the final phase is over */
1829 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
1830 hcryp->State = HAL_CRYP_STATE_READY;
1831 /* Disable the Peripheral */
1832 __HAL_CRYP_DISABLE(hcryp);
1833
1834 }
1835
1836 /* Process Unlocked */
1837 __HAL_UNLOCK(hcryp);
1838
1839 return HAL_OK;
1840 }
1841 else
1842 {
1843 return HAL_BUSY;
1844 }
1845 }
1846
1847 /**
1848 * @}
1849 */
1850
1851 /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions
1852 * @brief Extended processing functions.
1853 *
1854 @verbatim
1855 ==============================================================================
1856 ##### AES extended suspension and resumption functions #####
1857 ==============================================================================
1858 [..] This section provides functions allowing to:
1859 (+) save in memory the Initialization Vector, the Key registers, the Control register or
1860 the Suspend registers when a process is suspended by a higher priority message
1861 (+) write back in CRYP hardware block the saved values listed above when the suspended
1862 lower priority message processing is resumed.
1863
1864 @endverbatim
1865 * @{
1866 */
1867
1868
1869 /**
1870 * @brief In case of message processing suspension, read the Initialization Vector.
1871 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1872 * the configuration information for CRYP module.
1873 * @param Output: Pointer to the buffer containing the saved Initialization Vector.
1874 * @note This value has to be stored for reuse by writing the AES_IVRx registers
1875 * as soon as the interrupted processing has to be resumed.
1876 * Applicable to all chaining modes.
1877 * @note AES must be disabled when reading or resetting the IV values.
1878 * @retval None
1879 */
HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Output)1880 void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
1881 {
1882 uint32_t outputaddr = (uint32_t)Output;
1883
1884 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3);
1885 outputaddr+=4U;
1886 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2);
1887 outputaddr+=4U;
1888 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1);
1889 outputaddr+=4U;
1890 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0);
1891 }
1892
1893 /**
1894 * @brief In case of message processing resumption, rewrite the Initialization
1895 * Vector in the AES_IVRx registers.
1896 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1897 * the configuration information for CRYP module.
1898 * @param Input: Pointer to the buffer containing the saved Initialization Vector to
1899 * write back in the CRYP hardware block.
1900 * @note Applicable to all chaining modes.
1901 * @note AES must be disabled when reading or resetting the IV values.
1902 * @retval None
1903 */
HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Input)1904 void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
1905 {
1906 uint32_t ivaddr = (uint32_t)Input;
1907
1908 hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr));
1909 ivaddr+=4U;
1910 hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr));
1911 ivaddr+=4U;
1912 hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr));
1913 ivaddr+=4U;
1914 hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr));
1915 }
1916
1917
1918 /**
1919 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension,
1920 * read the Suspend Registers.
1921 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1922 * the configuration information for CRYP module.
1923 * @param Output: Pointer to the buffer containing the saved Suspend Registers.
1924 * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers
1925 * as soon as the interrupted processing has to be resumed.
1926 * @retval None
1927 */
HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Output)1928 void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
1929 {
1930 uint32_t outputaddr = (uint32_t)Output;
1931
1932 /* In case of GCM payload phase encryption, check that suspension can be carried out */
1933 if (READ_BIT(hcryp->Instance->CR, (AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT))
1934 {
1935 /* Ensure that Busy flag is reset */
1936 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
1937 {
1938 hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR;
1939 hcryp->State = HAL_CRYP_STATE_ERROR;
1940
1941 /* Process Unlocked */
1942 __HAL_UNLOCK(hcryp);
1943
1944 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1945 hcryp->ErrorCallback(hcryp);
1946 #else
1947 HAL_CRYP_ErrorCallback(hcryp);
1948 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1949 return ;
1950 }
1951 }
1952
1953 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R);
1954 outputaddr+=4U;
1955 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R);
1956 outputaddr+=4U;
1957 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R);
1958 outputaddr+=4U;
1959 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R);
1960 outputaddr+=4U;
1961 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R);
1962 outputaddr+=4U;
1963 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R);
1964 outputaddr+=4U;
1965 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R);
1966 outputaddr+=4U;
1967 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R);
1968 }
1969
1970 /**
1971 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Suspend
1972 * Registers in the AES_SUSPxR registers.
1973 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1974 * the configuration information for CRYP module.
1975 * @param Input: Pointer to the buffer containing the saved suspend registers to
1976 * write back in the CRYP hardware block.
1977 * @retval None
1978 */
HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Input)1979 void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
1980 {
1981 uint32_t ivaddr = (uint32_t)Input;
1982
1983 hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr));
1984 ivaddr+=4U;
1985 hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr));
1986 ivaddr+=4U;
1987 hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr));
1988 ivaddr+=4U;
1989 hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr));
1990 ivaddr+=4U;
1991 hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr));
1992 ivaddr+=4U;
1993 hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr));
1994 ivaddr+=4U;
1995 hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr));
1996 ivaddr+=4U;
1997 hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr));
1998 }
1999
2000
2001 /**
2002 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Key Registers.
2003 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2004 * the configuration information for CRYP module.
2005 * @param Output: Pointer to the buffer containing the saved Key Registers.
2006 * @param KeySize: Indicates the key size (128 or 256 bits).
2007 * @note These values have to be stored for reuse by writing back the AES_KEYRx registers
2008 * as soon as the interrupted processing has to be resumed.
2009 * @retval None
2010 */
HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Output,uint32_t KeySize)2011 void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize)
2012 {
2013 uint32_t keyaddr = (uint32_t)Output;
2014
2015 if (KeySize == CRYP_KEYSIZE_256B)
2016 {
2017 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7);
2018 keyaddr+=4U;
2019 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6);
2020 keyaddr+=4U;
2021 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5);
2022 keyaddr+=4U;
2023 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4);
2024 keyaddr+=4U;
2025 }
2026
2027 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3);
2028 keyaddr+=4U;
2029 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2);
2030 keyaddr+=4U;
2031 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1);
2032 keyaddr+=4U;
2033 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0);
2034 }
2035
2036 /**
2037 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key
2038 * Registers in the AES_KEYRx registers.
2039 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2040 * the configuration information for CRYP module.
2041 * @param Input: Pointer to the buffer containing the saved key registers to
2042 * write back in the CRYP hardware block.
2043 * @param KeySize: Indicates the key size (128 or 256 bits)
2044 * @retval None
2045 */
HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Input,uint32_t KeySize)2046 void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize)
2047 {
2048 uint32_t keyaddr = (uint32_t)Input;
2049
2050 if (KeySize == CRYP_KEYSIZE_256B)
2051 {
2052 hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr));
2053 keyaddr+=4U;
2054 hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr));
2055 keyaddr+=4U;
2056 hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr));
2057 keyaddr+=4U;
2058 hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr));
2059 keyaddr+=4U;
2060 }
2061
2062 hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr));
2063 keyaddr+=4U;
2064 hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr));
2065 keyaddr+=4U;
2066 hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr));
2067 keyaddr+=4U;
2068 hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr));
2069 }
2070
2071
2072 /**
2073 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Control Register.
2074 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2075 * the configuration information for CRYP module.
2076 * @param Output: Pointer to the buffer containing the saved Control Register.
2077 * @note This values has to be stored for reuse by writing back the AES_CR register
2078 * as soon as the interrupted processing has to be resumed.
2079 * @retval None
2080 */
HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef * hcryp,uint8_t * Output)2081 void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
2082 {
2083 *(uint32_t*)(void *)(Output) = hcryp->Instance->CR; /* Derogation MisraC2012 R.11.5 */
2084 }
2085
2086 /**
2087 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Control
2088 * Registers in the AES_CR register.
2089 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2090 * the configuration information for CRYP module.
2091 * @param Input: Pointer to the buffer containing the saved Control Register to
2092 * write back in the CRYP hardware block.
2093 * @retval None
2094 */
HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef * hcryp,uint8_t * Input)2095 void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
2096 {
2097 hcryp->Instance->CR = *(uint32_t*)(void *)(Input); /* Derogation MisraC2012 R.11.5 */
2098 /* At the same time, set handle state back to READY to be able to resume the AES calculations
2099 without the processing APIs returning HAL_BUSY when called. */
2100 hcryp->State = HAL_CRYP_STATE_READY;
2101 }
2102
2103 /**
2104 * @brief Request CRYP processing suspension when in polling or interruption mode.
2105 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2106 * the configuration information for CRYP module.
2107 * @note Set the handle field SuspendRequest to the appropriate value so that
2108 * the on-going CRYP processing is suspended as soon as the required
2109 * conditions are met.
2110 * @note It is advised not to suspend the CRYP processing when the DMA controller
2111 * is managing the data transfer
2112 * @retval None
2113 */
HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef * hcryp)2114 void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
2115 {
2116 /* Set Handle Suspend Request field */
2117 hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
2118 }
2119
2120 /**
2121 * @}
2122 */
2123
2124 /**
2125 * @}
2126 */
2127
2128 /** @addtogroup CRYPEx_Private_Functions
2129 * @{
2130 */
2131
2132 /**
2133 * @brief DMA CRYP Input Data process complete callback
2134 * for GCM, GMAC, CCM or CMAC chaining modes.
2135 * @note Specific setting of hcryp fields are required only
2136 * in the case of header phase where no output data DMA
2137 * transfer is on-going (only input data transfer is enabled
2138 * in such a case).
2139 * @param hdma: DMA handle.
2140 * @retval None
2141 */
CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef * hdma)2142 static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma)
2143 {
2144 uint32_t difflength;
2145 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
2146
2147 /* Disable the DMA transfer for input request */
2148 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
2149
2150 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
2151 {
2152
2153 if (hcryp->CrypInCount != 0U)
2154 {
2155 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
2156 difflength = hcryp->CrypInCount;
2157 hcryp->CrypInCount = 0;
2158
2159 CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF);
2160 }
2161 hcryp->State = HAL_CRYP_STATE_READY;
2162 /* Mark that the header phase is over */
2163 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
2164 }
2165 /* CCF flag indicating header phase AES processing completion
2166 will be checked at the start of the next phase:
2167 - payload phase (GCM or CCM when applicable)
2168 - final phase (GMAC or CMAC).
2169 This allows to avoid the Wait on Flag within the IRQ handling. */
2170
2171 /* Call input data transfer complete callback */
2172 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2173 hcryp->InCpltCallback(hcryp);
2174 #else
2175 HAL_CRYP_InCpltCallback(hcryp);
2176 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2177 }
2178
2179 /**
2180 * @brief DMA CRYP Output Data process complete callback
2181 * for GCM, GMAC, CCM or CMAC chaining modes.
2182 * @note This callback is called only in the payload phase.
2183 * @param hdma: DMA handle.
2184 * @retval None
2185 */
CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef * hdma)2186 static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma)
2187 {
2188 uint32_t difflength;
2189 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
2190
2191 /* Disable the DMA transfer for output request */
2192 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
2193
2194 /* Clear CCF Flag */
2195 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2196
2197 /* Initiate additional transfer to wrap-up data feeding to the IP */
2198 if (hcryp->CrypInCount != 0U)
2199 {
2200 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
2201 difflength = hcryp->CrypInCount;
2202 hcryp->CrypInCount = 0;
2203
2204 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
2205 }
2206
2207 /* Change the CRYP state to ready */
2208 hcryp->State = HAL_CRYP_STATE_READY;
2209 /* Mark that the payload phase is over */
2210 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
2211
2212 /* Call output data transfer complete callback */
2213 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2214 hcryp->OutCpltCallback(hcryp);
2215 #else
2216 HAL_CRYP_OutCpltCallback(hcryp);
2217 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2218 }
2219
2220 /**
2221 * @brief DMA CRYP communication error callback
2222 * for GCM, GMAC, CCM or CMAC chaining modes.
2223 * @param hdma: DMA handle
2224 * @retval None
2225 */
CRYP_Authentication_DMAError(DMA_HandleTypeDef * hdma)2226 static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma)
2227 {
2228 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
2229
2230 hcryp->State= HAL_CRYP_STATE_ERROR;
2231 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
2232 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2233 hcryp->ErrorCallback(hcryp);
2234 #else
2235 HAL_CRYP_ErrorCallback(hcryp);
2236 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2237 /* Clear Error Flag */
2238 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
2239 }
2240
2241
2242
2243 /**
2244 * @brief Handle CRYP block input/output data handling under interruption
2245 * for GCM, GMAC, CCM or CMAC chaining modes.
2246 * @note The function is called under interruption only, once
2247 * interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT().
2248 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2249 * the configuration information for CRYP module
2250 * @retval HAL status
2251 */
CRYP_AES_Auth_IT(CRYP_HandleTypeDef * hcryp)2252 HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp)
2253 {
2254 uint32_t inputaddr ;
2255 uint32_t outputaddr ;
2256 uint32_t index ;
2257 uint32_t addhoc_process = 0;
2258 uint32_t difflength = 0;
2259 uint32_t difflengthmod4 = 0;
2260 uint32_t mask[4][3] ;
2261 uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
2262 uint32_t intermediate_data[4] = {0};
2263
2264 mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */
2265 mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */
2266 mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */
2267 mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */
2268
2269 if(hcryp->State == HAL_CRYP_STATE_BUSY)
2270 {
2271 /*===========================*/
2272 /* GCM/GMAC(/CCM) init phase */
2273 /*===========================*/
2274 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
2275 {
2276 /* Clear Computation Complete Flag */
2277 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2278 /* Disable Computation Complete Flag and Errors Interrupts */
2279 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2280 /* Change the CRYP state */
2281 hcryp->State = HAL_CRYP_STATE_READY;
2282
2283 /* Mark that the initialization phase is over */
2284 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
2285
2286 /* Process Unlocked */
2287 __HAL_UNLOCK(hcryp);
2288 /* Call computation complete callback */
2289 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2290 hcryp->CompCpltCallback(hcryp);
2291 #else
2292 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2293 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2294 return HAL_OK;
2295 }
2296 /*========================================*/
2297 /* GCM/GMAC (or CCM or CMAC) header phase */
2298 /*========================================*/
2299 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
2300 {
2301 /* Check if all input header data have been entered */
2302 if (hcryp->CrypInCount == 0U)
2303 {
2304 /* Clear Computation Complete Flag */
2305 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2306 /* Disable Computation Complete Flag and Errors Interrupts */
2307 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2308 /* Change the CRYP state */
2309 hcryp->State = HAL_CRYP_STATE_READY;
2310 /* Mark that the header phase is over */
2311 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
2312
2313 /* Process Unlocked */
2314 __HAL_UNLOCK(hcryp);
2315
2316 /* Call computation complete callback */
2317 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2318 hcryp->CompCpltCallback(hcryp);
2319 #else
2320 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2321 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2322
2323 return HAL_OK;
2324 }
2325 /* If suspension flag has been raised, suspend processing */
2326 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
2327 {
2328 /* Clear CCF Flag */
2329 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2330
2331 /* reset SuspendRequest */
2332 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
2333 /* Disable Computation Complete Flag and Errors Interrupts */
2334 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2335 /* Change the CRYP state */
2336 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
2337 /* Mark that the header phase is suspended */
2338 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
2339
2340 /* Process Unlocked */
2341 __HAL_UNLOCK(hcryp);
2342
2343 return HAL_OK;
2344 }
2345 else /* Carry on feeding input data to the CRYP hardware block */
2346 {
2347 /* Clear Computation Complete Flag */
2348 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2349 /* Get the last Input data address */
2350 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
2351
2352 /* Increment/decrement instance pointer/counter */
2353 if (hcryp->CrypInCount < 16U)
2354 {
2355 difflength = hcryp->CrypInCount;
2356 hcryp->CrypInCount = 0;
2357 addhoc_process = 1;
2358 difflengthmod4 = difflength%4U;
2359 }
2360 else
2361 {
2362 hcryp->pCrypInBuffPtr += 16;
2363 hcryp->CrypInCount -= 16U;
2364 }
2365
2366 #if defined(AES_CR_NPBLB)
2367 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
2368 #else
2369 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
2370 #endif
2371 {
2372 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
2373 {
2374 /* All B blocks will have been entered after the next
2375 four DINR writing, so point at header buffer for
2376 the next iteration */
2377 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
2378 }
2379 }
2380
2381 /* Write the Input block in the Data Input register */
2382 if (addhoc_process == 0U)
2383 {
2384 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2385 inputaddr+=4U;
2386 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2387 inputaddr+=4U;
2388 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2389 inputaddr+=4U;
2390 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2391 }
2392 else
2393 {
2394 /* Header remainder has size less than 128 bits */
2395 /* Enter complete words when possible */
2396 for(index=0U ; index < (difflength/4U); index ++)
2397 {
2398 /* Write the Input block in the Data Input register */
2399 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2400 inputaddr+=4U;
2401 }
2402 /* Enter incomplete word padded with zeroes if applicable
2403 (case of header length not a multiple of 32-bits) */
2404 if (difflengthmod4 != 0U)
2405 {
2406 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
2407 }
2408 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
2409 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
2410 {
2411 hcryp->Instance->DINR = 0;
2412 }
2413 }
2414
2415 return HAL_OK;
2416 }
2417 }
2418 /*=======================*/
2419 /* GCM/CCM payload phase */
2420 /*=======================*/
2421 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
2422 {
2423 /* Get the last output data address */
2424 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
2425
2426 /* Specific handling to manage payload size less than 128 bits
2427 when GCM (or CCM when applicable) encryption or decryption is selected.
2428 Check here if the last block output data are read */
2429 #if defined(AES_CR_NPBLB)
2430 if ((hcryp->CrypOutCount < 16U) && \
2431 (hcryp->CrypOutCount > 0U))
2432 #else
2433 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
2434 (hcryp->CrypOutCount < 16U) && \
2435 (hcryp->CrypOutCount > 0U))
2436 #endif
2437 {
2438 difflength = hcryp->CrypOutCount;
2439 difflengthmod4 = difflength%4U;
2440 hcryp->CrypOutCount = 0; /* mark that no more output data will be needed */
2441 /* Retrieve intermediate data */
2442 for(index=0U ; index < 4U; index ++)
2443 {
2444 intermediate_data[index] = hcryp->Instance->DOUTR;
2445 }
2446 /* Retrieve last words of cyphered data */
2447 /* First, retrieve complete output words */
2448 for(index=0U ; index < (difflength/4U); index ++)
2449 {
2450 *(uint32_t*)(outputaddr) = intermediate_data[index];
2451 outputaddr+=4U;
2452 }
2453 /* Next, retrieve partial output word if applicable;
2454 at the same time, start masking intermediate data
2455 with a mask of zeros of same size than the padding
2456 applied to the last block of payload */
2457 if (difflengthmod4 != 0U)
2458 {
2459 intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
2460 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
2461 }
2462
2463 #if !defined(AES_CR_NPBLB)
2464 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
2465 {
2466 /* Change again CHMOD configuration to GCM mode */
2467 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);
2468
2469 /* Select FINAL phase */
2470 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
2471
2472 /* Before inserting the intermediate data, carry on masking operation
2473 with a mask of zeros of same size than the padding applied to the last block of payload */
2474 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
2475 {
2476 intermediate_data[((difflength+3U)/4U)+index] = 0;
2477 }
2478
2479 /* Insert intermediate data to trigger an additional DOUTR reading round */
2480 /* Clear Computation Complete Flag before entering new block */
2481 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2482 for(index=0U ; index < 4U; index ++)
2483 {
2484 hcryp->Instance->DINR = intermediate_data[index];
2485 }
2486 }
2487 else
2488 #endif
2489 {
2490 /* Payload phase is now over */
2491 /* Clear Computation Complete Flag */
2492 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2493 /* Disable Computation Complete Flag and Errors Interrupts */
2494 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2495 /* Change the CRYP state */
2496 hcryp->State = HAL_CRYP_STATE_READY;
2497 /* Mark that the payload phase is over */
2498 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
2499
2500 /* Process Unlocked */
2501 __HAL_UNLOCK(hcryp);
2502
2503 /* Call computation complete callback */
2504 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2505 hcryp->CompCpltCallback(hcryp);
2506 #else
2507 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2508 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2509 }
2510 return HAL_OK;
2511 }
2512 else
2513 {
2514 if (hcryp->CrypOutCount != 0U)
2515 {
2516 /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */
2517 /* Retrieve the last block available from the CRYP hardware block:
2518 read the output block from the Data Output Register */
2519 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2520 outputaddr+=4U;
2521 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2522 outputaddr+=4U;
2523 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2524 outputaddr+=4U;
2525 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2526
2527 /* Increment/decrement instance pointer/counter */
2528 hcryp->pCrypOutBuffPtr += 16;
2529 hcryp->CrypOutCount -= 16U;
2530 }
2531 #if !defined(AES_CR_NPBLB)
2532 else
2533 {
2534 /* Software work-around: additional DOUTR reading round to discard the data */
2535 for(index=0U ; index < 4U; index ++)
2536 {
2537 intermediate_data[index] = hcryp->Instance->DOUTR;
2538 }
2539 }
2540 #endif
2541 }
2542
2543 /* Check if all output text has been retrieved */
2544 if (hcryp->CrypOutCount == 0U)
2545 {
2546 /* Clear Computation Complete Flag */
2547 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2548 /* Disable Computation Complete Flag and Errors Interrupts */
2549 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2550 /* Change the CRYP state */
2551 hcryp->State = HAL_CRYP_STATE_READY;
2552 /* Mark that the payload phase is over */
2553 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
2554
2555 /* Process Unlocked */
2556 __HAL_UNLOCK(hcryp);
2557
2558 /* Call computation complete callback */
2559 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2560 hcryp->CompCpltCallback(hcryp);
2561 #else
2562 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2563 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2564
2565 return HAL_OK;
2566 }
2567 /* If suspension flag has been raised, suspend processing */
2568 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
2569 {
2570 /* Clear CCF Flag */
2571 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2572
2573 /* reset SuspendRequest */
2574 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
2575 /* Disable Computation Complete Flag and Errors Interrupts */
2576 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2577 /* Change the CRYP state */
2578 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
2579 /* Mark that the payload phase is suspended */
2580 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_SUSPENDED;
2581
2582 /* Process Unlocked */
2583 __HAL_UNLOCK(hcryp);
2584
2585 return HAL_OK;
2586 }
2587 else /* Output data are still expected, carry on feeding the CRYP
2588 hardware block with input data */
2589 {
2590 /* Clear Computation Complete Flag */
2591 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2592 /* Get the last Input data address */
2593 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
2594
2595 /* Usual input data feeding case */
2596 if (hcryp->CrypInCount < 16U)
2597 {
2598 difflength = (uint32_t) (hcryp->CrypInCount);
2599 difflengthmod4 = difflength%4U;
2600 hcryp->CrypInCount = 0;
2601
2602 #if defined(AES_CR_NPBLB)
2603 /* In case of GCM encryption or CCM decryption, specify the number of padding
2604 bytes in last block of payload */
2605 {
2606 uint32_t cr_temp = hcryp->Instance->CR;
2607
2608 if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
2609 || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
2610 {
2611 /* Set NPBLB field in writing the number of padding bytes
2612 for the last block of payload */
2613 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
2614 }
2615 }
2616 #else
2617 /* Software workaround applied to GCM encryption only */
2618 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
2619 {
2620 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
2621 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
2622 }
2623 #endif
2624
2625 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
2626 to have a complete block of 128 bits */
2627 for(index=0U ; index < (difflength/4U); index ++)
2628 {
2629 /* Write the Input block in the Data Input register */
2630 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2631 inputaddr+=4U;
2632 }
2633 /* If required, manage input data size not multiple of 32 bits */
2634 if (difflengthmod4 != 0U)
2635 {
2636 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
2637 }
2638 /* Wrap-up in padding with zero-words if applicable */
2639 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
2640 {
2641 hcryp->Instance->DINR = 0;
2642 }
2643
2644 }
2645 else
2646 {
2647 hcryp->pCrypInBuffPtr += 16;
2648 hcryp->CrypInCount -= 16U;
2649
2650 /* Write the Input block in the Data Input register */
2651 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2652 inputaddr+=4U;
2653 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2654 inputaddr+=4U;
2655 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2656 inputaddr+=4U;
2657 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2658 }
2659
2660
2661 return HAL_OK;
2662 }
2663 }
2664 /*=======================================*/
2665 /* GCM/GMAC (or CCM or CMAC) final phase */
2666 /*=======================================*/
2667 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
2668 {
2669 /* Clear Computation Complete Flag */
2670 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2671
2672 /* Get the last output data address */
2673 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
2674
2675 /* Retrieve the last expected data from the CRYP hardware block:
2676 read the output block from the Data Output Register */
2677 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2678 outputaddr+=4U;
2679 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2680 outputaddr+=4U;
2681 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2682 outputaddr+=4U;
2683 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2684
2685 /* Disable Computation Complete Flag and Errors Interrupts */
2686 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2687 /* Change the CRYP state */
2688 hcryp->State = HAL_CRYP_STATE_READY;
2689 /* Mark that the header phase is over */
2690 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
2691
2692 /* Disable the Peripheral */
2693 __HAL_CRYP_DISABLE(hcryp);
2694 /* Process Unlocked */
2695 __HAL_UNLOCK(hcryp);
2696
2697 /* Call computation complete callback */
2698 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2699 hcryp->CompCpltCallback(hcryp);
2700 #else
2701 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2702 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2703
2704 return HAL_OK;
2705 }
2706 else
2707 {
2708 /* Clear Computation Complete Flag */
2709 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2710 hcryp->State = HAL_CRYP_STATE_ERROR;
2711 __HAL_UNLOCK(hcryp);
2712 return HAL_ERROR;
2713 }
2714 }
2715 else
2716 {
2717 return HAL_BUSY;
2718 }
2719 }
2720
2721
2722
2723 /**
2724 * @brief Set the DMA configuration and start the DMA transfer
2725 * for GCM, GMAC, CCM or CMAC chaining modes.
2726 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2727 * the configuration information for CRYP module.
2728 * @param inputaddr: Address of the Input buffer.
2729 * @param Size: Size of the Input buffer un bytes, must be a multiple of 16.
2730 * @param outputaddr: Address of the Output buffer, null pointer when no output DMA stream
2731 * has to be configured.
2732 * @retval None
2733 */
CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size,uint32_t outputaddr)2734 static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2735 {
2736
2737 /* Set the input CRYP DMA transfer complete callback */
2738 hcryp->hdmain->XferCpltCallback = CRYP_Authentication_DMAInCplt;
2739 /* Set the DMA error callback */
2740 hcryp->hdmain->XferErrorCallback = CRYP_Authentication_DMAError;
2741
2742 if (outputaddr != 0U)
2743 {
2744 /* Set the output CRYP DMA transfer complete callback */
2745 hcryp->hdmaout->XferCpltCallback = CRYP_Authentication_DMAOutCplt;
2746 /* Set the DMA error callback */
2747 hcryp->hdmaout->XferErrorCallback = CRYP_Authentication_DMAError;
2748 }
2749
2750 /* Enable the CRYP peripheral */
2751 __HAL_CRYP_ENABLE(hcryp);
2752
2753 /* Enable the DMA input stream */
2754 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
2755 {
2756 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2757 hcryp->ErrorCallback(hcryp);
2758 #else
2759 HAL_CRYP_ErrorCallback(hcryp);
2760 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2761 }
2762
2763 /* Enable the DMA input request */
2764 SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
2765
2766
2767 if (outputaddr != 0U)
2768 {
2769 /* Enable the DMA output stream */
2770 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
2771 {
2772 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2773 hcryp->ErrorCallback(hcryp);
2774 #else
2775 HAL_CRYP_ErrorCallback(hcryp);
2776 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2777 }
2778
2779 /* Enable the DMA output request */
2780 SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
2781 }
2782 }
2783
2784
2785
2786 /**
2787 * @brief Write/read input/output data in polling mode.
2788 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2789 * the configuration information for CRYP module.
2790 * @param Input: Pointer to the Input buffer.
2791 * @param Ilength: Length of the Input buffer in bytes, must be a multiple of 16.
2792 * @param Output: Pointer to the returned buffer.
2793 * @param Timeout: Specify Timeout value.
2794 * @retval HAL status
2795 */
CRYP_ProcessData(CRYP_HandleTypeDef * hcryp,uint8_t * Input,uint16_t Ilength,uint8_t * Output,uint32_t Timeout)2796 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout)
2797 {
2798 uint32_t index;
2799 uint32_t inputaddr = (uint32_t)Input;
2800 uint32_t outputaddr = (uint32_t)Output;
2801
2802
2803 for(index=0U ; (index < Ilength); index += 16U)
2804 {
2805 /* Write the Input block in the Data Input register */
2806 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2807 inputaddr+=4U;
2808 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2809 inputaddr+=4U;
2810 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2811 inputaddr+=4U;
2812 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2813 inputaddr+=4U;
2814
2815 /* Wait for CCF flag to be raised */
2816 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2817 {
2818 hcryp->State = HAL_CRYP_STATE_READY;
2819 __HAL_UNLOCK(hcryp);
2820 return HAL_TIMEOUT;
2821 }
2822
2823 /* Clear CCF Flag */
2824 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2825
2826 /* Read the Output block from the Data Output Register */
2827 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2828 outputaddr+=4U;
2829 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2830 outputaddr+=4U;
2831 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2832 outputaddr+=4U;
2833 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2834 outputaddr+=4U;
2835
2836 /* If the suspension flag has been raised and if the processing is not about
2837 to end, suspend processing */
2838 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength))
2839 {
2840 /* Reset SuspendRequest */
2841 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
2842
2843 /* Save current reading and writing locations of Input and Output buffers */
2844 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
2845 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
2846 /* Save the number of bytes that remain to be processed at this point */
2847 hcryp->CrypInCount = Ilength - (index+16U);
2848
2849 /* Change the CRYP state */
2850 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
2851
2852 return HAL_OK;
2853 }
2854
2855
2856 }
2857 /* Return function status */
2858 return HAL_OK;
2859
2860 }
2861
2862
2863
2864
2865
2866 /**
2867 * @brief Read derivative key in polling mode when CRYP hardware block is set
2868 * in key derivation operating mode (mode 2).
2869 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2870 * the configuration information for CRYP module.
2871 * @param Output: Pointer to the returned buffer.
2872 * @param Timeout: Specify Timeout value.
2873 * @retval HAL status
2874 */
CRYP_ReadKey(CRYP_HandleTypeDef * hcryp,uint8_t * Output,uint32_t Timeout)2875 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout)
2876 {
2877 uint32_t outputaddr = (uint32_t)Output;
2878
2879 /* Wait for CCF flag to be raised */
2880 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2881 {
2882 hcryp->State = HAL_CRYP_STATE_READY;
2883 __HAL_UNLOCK(hcryp);
2884 return HAL_TIMEOUT;
2885 }
2886 /* Clear CCF Flag */
2887 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2888
2889 /* Read the derivative key from the AES_KEYRx registers */
2890 if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B)
2891 {
2892 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7);
2893 outputaddr+=4U;
2894 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6);
2895 outputaddr+=4U;
2896 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5);
2897 outputaddr+=4U;
2898 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4);
2899 outputaddr+=4U;
2900 }
2901
2902 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3);
2903 outputaddr+=4U;
2904 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2);
2905 outputaddr+=4U;
2906 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1);
2907 outputaddr+=4U;
2908 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0);
2909
2910
2911 /* Return function status */
2912 return HAL_OK;
2913 }
2914
2915 /**
2916 * @brief Set the DMA configuration and start the DMA transfer.
2917 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2918 * the configuration information for CRYP module.
2919 * @param inputaddr: Address of the Input buffer.
2920 * @param Size: Size of the Input buffer in bytes, must be a multiple of 16.
2921 * @param outputaddr: Address of the Output buffer.
2922 * @retval None
2923 */
CRYP_SetDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size,uint32_t outputaddr)2924 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2925 {
2926 /* Set the CRYP DMA transfer complete callback */
2927 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2928 /* Set the DMA error callback */
2929 hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2930
2931 /* Set the CRYP DMA transfer complete callback */
2932 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
2933 /* Set the DMA error callback */
2934 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
2935
2936 /* Enable the DMA input stream */
2937 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
2938 {
2939 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2940 hcryp->ErrorCallback(hcryp);
2941 #else
2942 HAL_CRYP_ErrorCallback(hcryp);
2943 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2944 }
2945
2946 /* Enable the DMA output stream */
2947 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
2948 {
2949 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2950 hcryp->ErrorCallback(hcryp);
2951 #else
2952 HAL_CRYP_ErrorCallback(hcryp);
2953 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2954 }
2955
2956 /* Enable In and Out DMA requests */
2957 SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
2958
2959 /* Enable the CRYP peripheral */
2960 __HAL_CRYP_ENABLE(hcryp);
2961 }
2962
2963
2964 /**
2965 * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
2966 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2967 * the configuration information for CRYP module.
2968 * @param Timeout: Timeout duration.
2969 * @retval HAL status
2970 */
CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp,uint32_t Timeout)2971 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
2972 {
2973 uint32_t tickstart;
2974
2975 /* Get timeout */
2976 tickstart = HAL_GetTick();
2977
2978 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
2979 {
2980 /* Check for the Timeout */
2981 if(Timeout != HAL_MAX_DELAY)
2982 {
2983 if((HAL_GetTick() - tickstart ) > Timeout)
2984 {
2985 return HAL_TIMEOUT;
2986 }
2987 }
2988 }
2989 return HAL_OK;
2990 }
2991
2992 /**
2993 * @brief Wait for Busy Flag to be reset during a GCM payload encryption process suspension.
2994 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2995 * the configuration information for CRYP module.
2996 * @param Timeout: Timeout duration.
2997 * @retval HAL status
2998 */
CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp,uint32_t Timeout)2999 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
3000 {
3001 uint32_t tickstart;
3002
3003 /* Get timeout */
3004 tickstart = HAL_GetTick();
3005
3006 while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY))
3007 {
3008 /* Check for the Timeout */
3009 if(Timeout != HAL_MAX_DELAY)
3010 {
3011 if((HAL_GetTick() - tickstart ) > Timeout)
3012 {
3013 return HAL_TIMEOUT;
3014 }
3015 }
3016 }
3017 return HAL_OK;
3018 }
3019
3020
3021 /**
3022 * @brief DMA CRYP Input Data process complete callback.
3023 * @param hdma: DMA handle.
3024 * @retval None
3025 */
CRYP_DMAInCplt(DMA_HandleTypeDef * hdma)3026 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
3027 {
3028 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
3029
3030 /* Disable the DMA transfer for input request */
3031 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
3032
3033 /* Call input data transfer complete callback */
3034 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3035 hcryp->InCpltCallback(hcryp);
3036 #else
3037 HAL_CRYP_InCpltCallback(hcryp);
3038 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3039 }
3040
3041 /**
3042 * @brief DMA CRYP Output Data process complete callback.
3043 * @param hdma: DMA handle.
3044 * @retval None
3045 */
CRYP_DMAOutCplt(DMA_HandleTypeDef * hdma)3046 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
3047 {
3048 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
3049
3050 /* Disable the DMA transfer for output request */
3051 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
3052
3053 /* Clear CCF Flag */
3054 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3055
3056 /* Disable CRYP */
3057 __HAL_CRYP_DISABLE(hcryp);
3058
3059 /* Change the CRYP state to ready */
3060 hcryp->State = HAL_CRYP_STATE_READY;
3061
3062 /* Call output data transfer complete callback */
3063 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3064 hcryp->OutCpltCallback(hcryp);
3065 #else
3066 HAL_CRYP_OutCpltCallback(hcryp);
3067 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3068 }
3069
3070 /**
3071 * @brief DMA CRYP communication error callback.
3072 * @param hdma: DMA handle.
3073 * @retval None
3074 */
CRYP_DMAError(DMA_HandleTypeDef * hdma)3075 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
3076 {
3077 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
3078
3079 hcryp->State= HAL_CRYP_STATE_ERROR;
3080 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
3081 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3082 hcryp->ErrorCallback(hcryp);
3083 #else
3084 HAL_CRYP_ErrorCallback(hcryp);
3085 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3086 /* Clear Error Flag */
3087 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
3088 }
3089
3090 /**
3091 * @brief Last header or payload block padding when size is not a multiple of 128 bits.
3092 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3093 * the configuration information for CRYP module.
3094 * @param difflength: size remainder after having fed all complete 128-bit blocks.
3095 * @param polling: specifies whether or not polling on CCF must be done after having
3096 * entered a complete block.
3097 * @retval None
3098 */
CRYP_Padding(CRYP_HandleTypeDef * hcryp,uint32_t difflength,uint32_t polling)3099 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling)
3100 {
3101 uint32_t index;
3102 uint32_t difflengthmod4 = difflength%4U;
3103 uint32_t inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
3104 uint32_t outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
3105 uint32_t mask[4][3];
3106 uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
3107
3108 uint32_t intermediate_data[4] = {0};
3109
3110 mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */
3111 mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */
3112 mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */
3113 mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */
3114
3115 #if defined(AES_CR_NPBLB)
3116 /* In case of GCM encryption or CCM decryption, specify the number of padding
3117 bytes in last block of payload */
3118 if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
3119 {
3120 uint32_t cr_temp = hcryp->Instance->CR;
3121
3122 if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
3123 || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
3124 {
3125 /* Set NPBLB field in writing the number of padding bytes
3126 for the last block of payload */
3127 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
3128 }
3129 }
3130 #else
3131 /* Software workaround applied to GCM encryption only */
3132 if ((hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) &&
3133 (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT))
3134 {
3135 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
3136 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
3137 }
3138 #endif
3139
3140 /* Wrap-up entering header or payload data */
3141 /* Enter complete words when possible */
3142 for(index=0U ; index < (difflength/4U); index ++)
3143 {
3144 /* Write the Input block in the Data Input register */
3145 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3146 inputaddr+=4U;
3147 }
3148 /* Enter incomplete word padded with zeroes if applicable
3149 (case of header length not a multiple of 32-bits) */
3150 if (difflengthmod4 != 0U)
3151 {
3152 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
3153 }
3154 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
3155 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
3156 {
3157 hcryp->Instance->DINR = 0;
3158 }
3159
3160 if (polling == (uint32_t)CRYP_POLLING_ON)
3161 {
3162 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
3163 {
3164 hcryp->State = HAL_CRYP_STATE_READY;
3165 __HAL_UNLOCK(hcryp);
3166 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3167 hcryp->ErrorCallback(hcryp);
3168 #else
3169 HAL_CRYP_ErrorCallback(hcryp);
3170 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3171 }
3172
3173 /* Clear CCF Flag */
3174 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3175 }
3176
3177 /* if payload */
3178 if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
3179 {
3180
3181 /* Retrieve intermediate data */
3182 for(index=0U ; index < 4U; index ++)
3183 {
3184 intermediate_data[index] = hcryp->Instance->DOUTR;
3185 }
3186 /* Retrieve last words of cyphered data */
3187 /* First, retrieve complete output words */
3188 for(index=0U ; index < (difflength/4U); index ++)
3189 {
3190 *(uint32_t*)(outputaddr) = intermediate_data[index];
3191 outputaddr+=4U;
3192 }
3193 /* Next, retrieve partial output word if applicable;
3194 at the same time, start masking intermediate data
3195 with a mask of zeros of same size than the padding
3196 applied to the last block of payload */
3197 if (difflengthmod4 != 0U)
3198 {
3199 intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
3200 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
3201 }
3202
3203
3204 #if !defined(AES_CR_NPBLB)
3205 /* Software workaround applied to GCM encryption only,
3206 applicable for AES IP v2 version (where NPBLB is not defined) */
3207 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
3208 {
3209 /* Change again CHMOD configuration to GCM mode */
3210 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);
3211
3212 /* Select FINAL phase */
3213 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
3214
3215 /* Before inserting the intermediate data, carry on masking operation
3216 with a mask of zeros of same size than the padding applied to the last block of payload */
3217 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
3218 {
3219 intermediate_data[((difflength+3U)/4U)+index] = 0;
3220 }
3221 /* Insert intermediate data */
3222 for(index=0U ; index < 4U; index ++)
3223 {
3224 hcryp->Instance->DINR = intermediate_data[index];
3225 }
3226
3227 /* Wait for completion, and read data on DOUT. This data is to discard. */
3228 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
3229 {
3230 hcryp->State = HAL_CRYP_STATE_READY;
3231 __HAL_UNLOCK(hcryp);
3232 HAL_CRYP_ErrorCallback(hcryp);
3233 }
3234
3235 /* Read data to discard */
3236 /* Clear CCF Flag */
3237 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3238 for(index=0U ; index < 4U; index ++)
3239 {
3240 intermediate_data[index] = hcryp->Instance->DOUTR;
3241 }
3242
3243 } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */
3244 #endif /* !defined(AES_CR_NPBLB) */
3245 } /* if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) */
3246
3247 }
3248
3249 /**
3250 * @}
3251 */
3252
3253 /**
3254 * @}
3255 */
3256
3257 /**
3258 * @}
3259 */
3260
3261 #endif /* AES */
3262
3263 #endif /* HAL_CRYP_MODULE_ENABLED */
3264 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
3265