1/*
2 * Copyright (c) 2015 Freescale Semiconductor, Inc.
3 * Copyright 2016-2018, 2020-2026 NXP
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6/*! *********************************************************************************
7 * \file
8 *
9 * This is the source file for the security module.
10 *
11 ********************************************************************************** */
12
13/*! *********************************************************************************
14*************************************************************************************
15* Include
16*************************************************************************************
17********************************************************************************** */
18#include "FunctionLib.h"
19#include "SecLib.h"
20#include "fsl_device_registers.h"
21#include "fsl_os_abstraction.h"
22#include "fsl_component_mem_manager.h"
23#include "CryptoLibSW.h"
24
25/* header file to be included after fsl_device_registers.h as it potentially overwrites some feature MACROs
26 (FSL_FEATURE_SOC_LTC_COUNT) */
27#include "fwk_config.h"
28
29#if (defined(FSL_FEATURE_SOC_MMCAU_COUNT) && (FSL_FEATURE_SOC_MMCAU_COUNT > 0))
30
31#ifndef FREESCALE_MMCAU
32#define FREESCALE_MMCAU 1
33#endif
34
35#ifndef FREESCALE_MMCAU_SHA
36#define FREESCALE_MMCAU_SHA 1
37#endif
38
39#include "cau_api.h"
40#endif /* FSL_FEATURE_SOC_MMCAU_COUNT */
41
42#if (defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0))
43#include "fsl_ltc.h"
44#endif
45
46/*! *********************************************************************************
47*************************************************************************************
48* Private macros
49*************************************************************************************
50********************************************************************************** */
51
52/* AES constants */
53#define AES128 128U
54#define AES128_ROUNDS 10U
55
56#define AES192 192U
57#define AES192_ROUNDS 12U
58
59#define AES256 256U
60#define AES256_ROUNDS 14U
61
62/* Limit the size of the hashed stream so that the number of bits does not exceed 32 bit in size.
63 * This limitation is arbitrary
64 */
65#define MAX_SHA256_TOTAL_BYTES (UINT32_MAX / 8uL)
66#define MAX_SHA1_TOTAL_BYTES (UINT32_MAX / 8uL)
67
68#if ((defined(USE_RTOS) && (USE_RTOS > 0)) && \
69 ((defined FSL_FEATURE_SOC_LTC_COUNT && (FSL_FEATURE_SOC_LTC_COUNT > 0)) || \
70 (defined FSL_FEATURE_SOC_MMCAU_COUNT && (FSL_FEATURE_SOC_MMCAU_COUNT > 0)) || \
71 (defined FSL_FEATURE_SOC_AES_HW && (FSL_FEATURE_SOC_AES_HW > 0))))
72#define gSecLibUseMutex_c TRUE
73#else
74#define gSecLibUseMutex_c FALSE
75#endif
76
77secResultType_t SecLibMutexCreate(void);
78
79#if (defined(gSecLibUseMutex_c) && (gSecLibUseMutex_c > 0))
80
81#define SECLIB_MUTEX_LOCK() (void)SecLibMutexLock()
82#define SECLIB_MUTEX_UNLOCK() (void)SecLibMutexUnlock()
83#else
84#define SECLIB_MUTEX_LOCK()
85#define SECLIB_MUTEX_UNLOCK()
86#endif
87/*
88 * __DSP_PRESENT is defined in the device specific file, however avoid use of __DSP_PRESENT to avoid
89 * a dependency with SDK.
90 * It is likely to be present on all Core M33, Core M7 and Core M4 devices.
91 * Nonetheless RW61x was designed without ARM DSP extension, in which case avoid defining
92 * gSecLibUseDspExtension_d.
93 * gSecLibUseDspExtension_d follows __DSP_PRESENT definition unless overridden to 0
94 */
95
96#ifndef gSecLibUseDspExtension_d
97#define gSecLibUseDspExtension_d 0
98#endif
99
100#ifndef RAISE_ERROR
101#define RAISE_ERROR(x, code) \
102 { \
103 (x) = (code); \
104 break; \
105 }
106#endif
107
108#define AES_BLOCK_ALIGN_MASK (0x0000000fUL)
109/* Compute number of whole AES block bytes */
110#define AES_WHOLE_BLOCK_BYTES(_LEN_) ((uint32_t)(_LEN_) & ~AES_BLOCK_ALIGN_MASK)
111/* Compute number of residual bytes constituting a partial AES block */
112#define AES_PARTIAL_BLOCK_BYTES(_LEN_) ((uint32_t)(_LEN_)&AES_BLOCK_ALIGN_MASK)
113
114/*! *********************************************************************************
115*************************************************************************************
116* Private prototypes
117*************************************************************************************
118********************************************************************************** */
119
120/*! *********************************************************************************
121*************************************************************************************
122* Private type definitions
123*************************************************************************************
124********************************************************************************** */
125typedef union _uuint128_tag
126{
127 uint8_t u8[16];
128 uint64_t u64[2];
129} uuint128_t;
130
131#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES == 1))
132uint8_t AES128ECB_Enc_Id;
133uint8_t AES128ECB_Dec_Id;
134uint8_t AES128ECBB_Enc_Id;
135uint8_t AES128ECBB_Dec_Id;
136
137uint8_t AES128CTR_Enc_Id;
138uint8_t AES128CTR_Dec_Id;
139
140uint8_t AES128CMAC_Id;
141#endif
142
143#if (defined(FSL_FEATURE_SOC_MMCAU_COUNT) && (FSL_FEATURE_SOC_MMCAU_COUNT > 0))
144typedef struct mmcauAesContext_tag
145{
146 uint8_t keyExpansion[44 * 4];
147 uint8_t alignedIn[AES_BLOCK_SIZE];
148 uint8_t alignedOut[AES_BLOCK_SIZE];
149} mmcauAesContext_t;
150
151/*! MMCAU AES Context Buffer for both AES Encrypt and Decrypt operations.*/
152mmcauAesContext_t mmcauAesCtx;
153#endif /* FSL_FEATURE_SOC_MMCAU_COUNT */
154
155#if gSecLibUseMutex_c
156/*! Mutex used to protect the AES Context when an RTOS is used. */
157static OSA_MUTEX_HANDLE_DEFINE(mSecLibMutexId);
158#endif /* USE_RTOS */
159
160typedef struct sha256Context_tag
161{
162 uint32_t hash[SHA256_HASH_SIZE / sizeof(uint32_t)];
163 uint8_t buffer[SHA256_BLOCK_SIZE];
164 uint32_t totalBytes;
165 uint8_t bytes;
166} sha256Context_t;
167
168typedef struct HMAC_SHA256_context_tag
169{
170 sha256Context_t shaCtx;
171 uint8_t pad[SHA256_BLOCK_SIZE];
172} HMAC_SHA256_context_t;
173
174/************************************************************************************
175*************************************************************************************
176* Private memory declarations
177*************************************************************************************
178************************************************************************************/
179/*! Callback used to offload Security steps onto application message queue. When it is not set the
180 * multiplication is done using SecLib means */
181extern secLibCallback_t pfSecLibMultCallback;
182
183#if (gSecLibUseBleDebugKeys_d == 1)
184/*! Bluetooth LE debug keys as specified in section 2.3.5.6.1 vol. 3, part H of the Bluetooth Core specification version 5.4 */
185static const ecp256KeyPair_t mBleDebugKeyPair = {
186 .public_key.components_8bit.x = {0x20, 0xb0, 0x03, 0xd2, 0xf2, 0x97, 0xbe, 0x2c, 0x5e, 0x2c, 0x83,
187 0xa7, 0xe9, 0xf9, 0xa5, 0xb9, 0xef, 0xf4, 0x91, 0x11, 0xac, 0xf4,
188 0xfd, 0xdb, 0xcc, 0x03, 0x01, 0x48, 0x0e, 0x35, 0x9d, 0xe6},
189 .public_key.components_8bit.y = {0xdc, 0x80, 0x9c, 0x49, 0x65, 0x2a, 0xeb, 0x6d, 0x63, 0x32, 0x9a,
190 0xbf, 0x5a, 0x52, 0x15, 0x5c, 0x76, 0x63, 0x45, 0xc2, 0x8f, 0xed,
191 0x30, 0x24, 0x74, 0x1c, 0x8e, 0xd0, 0x15, 0x89, 0xd2, 0x8b},
192 .private_key.raw_8bit = {0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3,
193 0xe3, 0xd2, 0x10, 0x3f, 0x50, 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40,
194 0xb7, 0x99, 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd}};
195#endif /* gSecLibUseBleDebugKeys_d */
196
197/*! *********************************************************************************
198*************************************************************************************
199* Public prototypes
200*************************************************************************************
201********************************************************************************** */
202
203/*! *********************************************************************************
204*************************************************************************************
205* Private prototypes
206*************************************************************************************
207********************************************************************************** */
208static void SHA256_hash_n(const uint8_t *pData, uint32_t nBlk, uint32_t *pHash);
209static void AES_128_CMAC_Generate_Subkey(const uint8_t *key, uint8_t *K1, uint8_t *K2);
210static void SecLib_LeftShiftOneBit(uint8_t *input, uint8_t *output);
211static void SecLib_Xor128(const uint8_t *a, const uint8_t *b, uint8_t *out);
212
213static uint8_t SecLib_Padding(const uint8_t *lastb, uint8_t pad_block[AES_BLOCK_SIZE], uint8_t length);
214static uint8_t SecLib_DePadding(const uint8_t pad_block[AES_BLOCK_SIZE]);
215
216#if (defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT == 1U))
217#else
218static void AES_128_IncrementCounter(uint8_t *ctr);
219#endif
220
221#ifdef FSL_FEATURE_SOC_AES_HW
222static void AES_128_ECB_Enc_HW(AES_param_t *ECB_p);
223static void AES_128_ECB_Dec_HW(AES_param_t *ECB_p);
224static void AES_128_ECB_Block_Enc_HW(AES_param_t *ECBB_p);
225static void AES_128_ECB_Block_Dec_HW(AES_param_t *ECBB_p);
226
227static void AES_128_CTR_Enc_HW(AES_param_t *CTR_p);
228static void AES_128_CTR_Dec_HW(AES_param_t *CTR_p);
229
230static void AES_128_CMAC_HW(AES_param_t *CMAC_p);
231#endif
232
233/*! *********************************************************************************
234*************************************************************************************
235* Private functions
236*************************************************************************************
237********************************************************************************** */
238
239#if gSecLibUseDspExtension_d
240static bool ECP256_LePointValid(const ecp256Point_t *P)
241{
242 ecp256Point_t tmp;
243 ECP256_PointCopy_and_change_endianness(tmp.raw, P->raw);
244 return ECP256_PointValid(&tmp);
245}
246#else
247
248extern bool_t EcP256_IsPointOnCurve(const uint32_t *X, const uint32_t *Y);
249
250static bool ECP256_LePointValid(const ecp256Point_t *P)
251{
252 return EcP256_IsPointOnCurve((const uint32_t *)&P->components_32bit.x[0],
253 (const uint32_t *)&P->components_32bit.y[0]);
254}
255#endif
256
257/*! *********************************************************************************
258*************************************************************************************
259* Public functions
260*************************************************************************************
261********************************************************************************** */
262
263secResultType_t SecLibMutexCreate(void)
264{
265 secResultType_t st = gSecSuccess_c;
266#if gSecLibUseMutex_c
267 static bool seclib_mutex_created = false;
268 if (!seclib_mutex_created)
269 {
270 /*! Initialize the SecLib Mutex here. If not already done by RNG module */
271 osa_status_t ret = OSA_MutexCreate((osa_mutex_handle_t)mSecLibMutexId);
272
273 if (KOSA_StatusSuccess != ret)
274 {
275 st = gSecAllocError_c;
276 assert(false);
277 }
278 else
279 {
280 seclib_mutex_created = true;
281 }
282 }
283#endif
284 return st;
285}
286
287secResultType_t SecLibMutexLock(void)
288{
289#if gSecLibUseMutex_c
290 osa_status_t ret = OSA_MutexLock((osa_mutex_handle_t)mSecLibMutexId, osaWaitForever_c);
291 return (ret == KOSA_StatusSuccess) ? gSecSuccess_c : gSecError_c;
292#else
293 return gSecSuccess_c;
294#endif
295}
296
297secResultType_t SecLibMutexUnlock(void)
298{
299#if gSecLibUseMutex_c
300 osa_status_t ret = OSA_MutexUnlock((osa_mutex_handle_t)mSecLibMutexId);
301 return (ret == KOSA_StatusSuccess) ? gSecSuccess_c : gSecError_c;
302#else
303 return gSecSuccess_c;
304#endif
305}
306
307/*! *********************************************************************************
308 * \brief This function performs initialization of the cryptographic HW acceleration.
309 *
310 ********************************************************************************** */
311void SecLib_Init(void)
312{
313 static bool initialized = false;
314 if (!initialized)
315 {
316 initialized = true;
317#if (defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0))
318 LTC_Init(LTC0);
319#endif /* FSL_FEATURE_SOC_LTC_COUNT */
320
321#if gSecLibUseMutex_c
322 /*! Initialize the MMCAU AES Context Buffer Mutex here. */
323 (void)SecLibMutexCreate();
324#endif
325 }
326}
327
328/*! *********************************************************************************
329 * \brief This function performs initialization of the cryptographic HW acceleration.
330 *
331 ********************************************************************************** */
332void SecLib_ReInit(void)
333{
334 /* Nothing to do for Software implementation */
335}
336
337/*! *********************************************************************************
338 * \brief This function will allow reinitizialize the cryptographic HW acceleration
339 * next time we need it, typically after lowpower mode.
340 *
341 ********************************************************************************** */
342void SecLib_DeInit(void)
343{
344 /* Nothing to do for Software implementation */
345}
346
347#if !(defined(gSecLibUseDspExtension_d) && (gSecLibUseDspExtension_d > 0))
348/* In case the SecLib is using dsp extension the API from the Ultrafast library will be used,
349 * no need to offload elliptic curve multiplication.
350 * Otherwise the operation takes too long and multiplication must be segmented in multiple steps.
351 */
352/*! *********************************************************************************
353 * \brief This function performs initialization of the callback used to offload
354 * elliptic curve multiplication.
355 *
356 * \param[in] pfCallback Pointer to the function used to handle multiplication.
357 *
358 ********************************************************************************** */
359void SecLib_SetExternalMultiplicationCb(secLibCallback_t pfCallback)
360{
361 pfSecLibMultCallback = pfCallback;
362}
363
364/*! *********************************************************************************
365 * \brief This function performs calls the multiplication Callback.
366 *
367 * \param[in] pMsg Pointer to the data used in multiplication.
368 *
369 ********************************************************************************** */
370bool_t SecLib_ExecMultiplicationCb(computeDhKeyParam_t *pMsg)
371{
372 bool_t result = FALSE;
373
374 if (pfSecLibMultCallback != NULL)
375 {
376 pfSecLibMultCallback(pMsg);
377 result = TRUE;
378 }
379
380 return result;
381}
382#endif
383/*! *********************************************************************************
384 * \brief This function performs AES-128 encryption on a 16-byte block.
385 *
386 * \param[in] pInput Pointer to the location of the 16-byte plain text block.
387 *
388 * \param[in] pKey Pointer to the location of the 128-bit key.
389 *
390 * \param[out] pOutput Pointer to the location to store the 16-byte ciphered output.
391 *
392 * \pre All Input/Output pointers must refer to a memory address aligned to 4 bytes!
393 *
394 ********************************************************************************** */
395secResultType_t SecLib_AES_128_Encrypt(const uint8_t *pInput, const uint8_t *pKey, uint8_t *pOutput)
396{
397 secResultType_t result = gSecSuccess_c;
398 do
399 {
400 if ((pInput == NULL) || (pKey == NULL) || (pOutput == NULL))
401 {
402 result = gSecBadArgument_c;
403 break;
404 }
405
406#if (defined(FSL_FEATURE_SOC_MMCAU_COUNT) && (FSL_FEATURE_SOC_MMCAU_COUNT > 0))
407
408 mmcauAesContext_t *pCtx = &mmcauAesCtx;
409 uint8_t *pIn;
410 uint8_t *pOut;
411 SECLIB_MUTEX_LOCK();
412
413 /* Check if pKey is 4 bytes aligned */
414 if ((uint32_t)pKey & 0x00000003u)
415 {
416 FLib_MemCpy(pCtx->alignedIn, (uint8_t *)pKey, AES_BLOCK_SIZE);
417 pIn = pCtx->alignedIn;
418 }
419 else
420 {
421 pIn = (uint8_t *)pKey;
422 }
423
424 /* Expand Key */
425 mmcau_aes_set_key(pIn, AES128, pCtx->keyExpansion);
426
427 /* Check if pData is 4 bytes aligned */
428 if ((uint32_t)pInput & 0x00000003u)
429 {
430 FLib_MemCpy(pCtx->alignedIn, (uint8_t *)pInput, AES_BLOCK_SIZE);
431 pIn = pCtx->alignedIn;
432 }
433 else
434 {
435 pIn = (uint8_t *)pInput;
436 }
437 /* Check if pReturnData is 4 bytes aligned */
438 if ((uint32_t)pOutput & 0x00000003u)
439 {
440 pOut = pCtx->alignedOut;
441 }
442 else
443 {
444 pOut = pOutput;
445 }
446
447 /* Encrypt data */
448 mmcau_aes_encrypt(pIn, pCtx->keyExpansion, AES128_ROUNDS, pOut);
449
450 if (pOut == pCtx->alignedOut)
451 {
452 FLib_MemCpy(pOutput, pCtx->alignedOut, AES_BLOCK_SIZE);
453 }
454 SECLIB_MUTEX_UNLOCK();
455#endif /* MMCAU */
456#if (defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0))
457 SECLIB_MUTEX_LOCK();
458 (void)LTC_AES_EncryptEcb(LTC0, pInput, pOutput, AES_BLOCK_SIZE, pKey, AES_BLOCK_SIZE);
459 SECLIB_MUTEX_UNLOCK();
460#endif
461#if (defined FSL_FEATURE_SOC_AES_HW && (FSL_FEATURE_SOC_AES_HW > 0))
462 SECLIB_MUTEX_LOCK();
463 aes_enc_status_t hw_ase_status_flag;
464
465 do
466 {
467 while (*(uint8_t *)(0x04000168u + 76u) == true)
468 {
469 OSA_TaskYield();
470 }
471 __disable_irq();
472 hw_ase_status_flag = AES_128_Encrypt_HW(pInput, pKey, pOutput);
473 __enable_irq();
474 } while (hw_ase_status_flag == HW_AES_Previous_Enc_on_going);
475 SECLIB_MUTEX_UNLOCK();
476#else
477 sw_Aes128(pInput, pKey, 1, pOutput);
478#endif
479 } while (false);
480 return result;
481}
482
483/*! *********************************************************************************
484 * \brief This function performs AES-128 decryption on a 16-byte block.
485 *
486 * \param[in] pInput Pointer to the location of the 16-byte ciphered text block.
487 *
488 * \param[in] pKey Pointer to the location of the 128-bit key.
489 *
490 * \param[out] pOutput Pointer to the location to store the 16-byte plain text output.
491 *
492 * \pre All Input/Output pointers must refer to a memory address aligned to 4 bytes!
493 *
494 ********************************************************************************** */
495secResultType_t SecLib_AES_128_Decrypt(const uint8_t *pInput, const uint8_t *pKey, uint8_t *pOutput)
496{
497 secResultType_t result = gSecSuccess_c;
498 do
499 {
500 if ((pInput == NULL) || (pKey == NULL) || (pOutput == NULL))
501 {
502 result = gSecBadArgument_c;
503 break;
504 }
505#if (defined(FSL_FEATURE_SOC_MMCAU_COUNT) && (FSL_FEATURE_SOC_MMCAU_COUNT > 0))
506 mmcauAesContext_t *pCtx = &mmcauAesCtx;
507 uint8_t *pIn;
508 uint8_t *pOut;
509
510 SECLIB_MUTEX_LOCK();
511 /* Check if pKey is 4 bytes aligned */
512 if ((uint32_t)pKey & 0x00000003u)
513 {
514 FLib_MemCpy(pCtx->alignedIn, (uint8_t *)pKey, AES_BLOCK_SIZE);
515 pIn = pCtx->alignedIn;
516 }
517 else
518 {
519 pIn = (uint8_t *)pKey;
520 }
521
522 /* Expand Key */
523 mmcau_aes_set_key(pIn, AES128, pCtx->keyExpansion);
524
525 /* Check if pData is 4 bytes aligned */
526 if ((uint32_t)pInput & 0x00000003u)
527 {
528 FLib_MemCpy(pCtx->alignedIn, (uint8_t *)pInput, AES_BLOCK_SIZE);
529 pIn = pCtx->alignedIn;
530 }
531 else
532 {
533 pIn = (uint8_t *)pInput;
534 }
535
536 /* Check if pReturnData is 4 bytes aligned */
537 if ((uint32_t)pOutput & 0x00000003u)
538 {
539 pOut = pCtx->alignedOut;
540 }
541 else
542 {
543 pOut = pOutput;
544 }
545
546 /* Decrypt data */
547 mmcau_aes_decrypt(pIn, pCtx->keyExpansion, AES128_ROUNDS, pOut);
548
549 if (pOut == pCtx->alignedOut)
550 {
551 FLib_MemCpy(pOutput, pCtx->alignedOut, AES_BLOCK_SIZE);
552 }
553 SECLIB_MUTEX_UNLOCK();
554#elif (defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0))
555 SECLIB_MUTEX_LOCK();
556 (void)LTC_AES_DecryptEcb(LTC0, pInput, pOutput, AES_BLOCK_SIZE, pKey, AES_BLOCK_SIZE, kLTC_EncryptKey);
557 SECLIB_MUTEX_UNLOCK();
558
559#elif (defined FSL_FEATURE_SOC_AES_HW && (FSL_FEATURE_SOC_AES_HW > 0))
560
561 aes_enc_status_t hw_ase_status_flag;
562 SECLIB_MUTEX_LOCK();
563 do
564 {
565 while (*(uint8_t *)(0x04000168u + 76u) == true)
566 {
567 OSA_TaskYield();
568 }
569 __disable_irq();
570 hw_ase_status_flag = AES_128_Decrypt_HW(pInput, pKey, pOutput);
571 __enable_irq();
572
573 } while (hw_ase_status_flag == HW_AES_Previous_Enc_on_going);
574
575 SECLIB_MUTEX_UNLOCK();
576#else
577 sw_Aes128(pInput, pKey, 0, pOutput);
578#endif
579 } while (false);
580 return result;
581}
582
583/*! *********************************************************************************
584 * \brief This function performs AES-128-ECB encryption on a message block.
585 *
586 * \param[in] pInput Pointer to the location of the input message.
587 *
588 * \param[in] inputLen Input message length in bytes.
589 *
590 * \param[in] pKey Pointer to the location of the 128-bit key.
591 *
592 * \param[out] pOutput Pointer to the location to store the ciphered output.
593 *
594 * \pre All Input/Output pointers must refer to a memory address aligned to 4 bytes!
595 *
596 ********************************************************************************** */
597secResultType_t SecLib_AES_128_ECB_Encrypt(const uint8_t *pInput,
598 uint32_t inputLen,
599 const uint8_t *pKey,
600 uint8_t *pOutput)
601{
602 secResultType_t status;
603 do
604 {
605 if (pInput == NULL || pKey == NULL || pOutput == NULL || inputLen == 0)
606 {
607 RAISE_ERROR(status, gSecBadArgument_c);
608 }
609 if ((inputLen % AES_128_BLOCK_SIZE) != 0U)
610 {
611 RAISE_ERROR(status, gSecBadArgument_c);
612 }
613
614#ifdef FSL_FEATURE_SOC_AES_HW /* HW AES */
615 AES_param_t pAES;
616
617 pAES.CTR_counter = NULL;
618 pAES.Key = pKey;
619 pAES.Len = inputLen;
620 pAES.pCipher = pOutput;
621 pAES.pInitVector = NULL;
622 pAES.pPlain = pInput;
623 pAES.Blocks = 0;
624#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
625 AESM_InitType(&AES128ECB_Enc_Id, gAESMGR_ECB_Enc_c);
626 AESM_SetParam(AES128ECB_Enc_Id, pAES, AES_128_ECB_Enc_HW);
627 AESM_Start(AES128ECB_Enc_Id);
628#else
629 SECLIB_MUTEX_LOCK();
630 AES_128_ECB_Enc_HW(&pAES);
631 SECLIB_MUTEX_UNLOCK();
632#endif /* USE_TASK_FOR_HW_AES */
633 status = gSecSuccess_c;
634
635#else /* SW AES */
636 uint8_t tempBuffIn[AES_BLOCK_SIZE] = {0};
637 uint8_t tempBuffOut[AES_BLOCK_SIZE] = {0};
638
639 /* If remaining data bigger than one AES block size */
640 while (inputLen > AES_BLOCK_SIZE)
641 {
642 AES_128_Encrypt(pInput, pKey, pOutput);
643
644 pInput += AES_BLOCK_SIZE;
645 pOutput += AES_BLOCK_SIZE;
646 inputLen -= AES_BLOCK_SIZE;
647 }
648 /* If remaining data is smaller then one AES block size */
649 FLib_MemCpy(tempBuffIn, pInput, inputLen);
650 AES_128_Encrypt(tempBuffIn, pKey, tempBuffOut);
651 FLib_MemCpy(pOutput, tempBuffOut, inputLen);
652#endif
653 status = gSecSuccess_c;
654
655 } while (false);
656
657 return status;
658}
659
660/*! *********************************************************************************
661 * \brief This function performs AES-128-ECB decryption on a message block.
662 *
663 * \param[in] pInput Pointer to the location of the input message.
664 *
665 * \param[in] inputLen Input message length in bytes.
666 *
667 * \param[in] pKey Pointer to the location of the 128-bit key.
668 *
669 * \param[out] pOutput Pointer to the location to store the ciphered output.
670 *
671 * \pre All Input/Output pointers must refer to a memory address aligned to 4 bytes!
672 *
673 ********************************************************************************** */
674secResultType_t SecLib_AES_128_ECB_Decrypt(const uint8_t *pInput,
675 uint32_t inputLen,
676 const uint8_t *pKey,
677 uint8_t *pOutput)
678{
679 secResultType_t status;
680 do
681 {
682 if (pInput == NULL || pKey == NULL || pOutput == NULL || inputLen == 0)
683 {
684 RAISE_ERROR(status, gSecBadArgument_c);
685 }
686 if ((inputLen % AES_128_BLOCK_SIZE) != 0U)
687 {
688 RAISE_ERROR(status, gSecBadArgument_c);
689 }
690#ifdef FSL_FEATURE_SOC_AES_HW
691
692 AES_param_t pAES;
693
694 pAES.CTR_counter = NULL;
695 pAES.Key = pKey;
696 pAES.Len = inputLen;
697 pAES.pCipher = pInput;
698 pAES.pInitVector = NULL;
699 pAES.pPlain = pOutput;
700 pAES.Blocks = 0;
701#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
702 AESM_InitType(&AES128ECB_Dec_Id, gAESMGR_ECB_Dec_c);
703 AESM_SetParam(AES128ECB_Dec_Id, pAES, AES_128_ECB_Dec_HW);
704 AESM_Start(AES128ECB_Dec_Id);
705#else
706 SECLIB_MUTEX_LOCK();
707 AES_128_ECB_Dec_HW(&pAES);
708 SECLIB_MUTEX_UNLOCK();
709#endif /* USE_TASK_FOR_HW_AES */
710 status = gSecSuccess_c;
711
712#else /* SW AES */
713 uint8_t tempBuffIn[AES_BLOCK_SIZE] = {0};
714 uint8_t tempBuffOut[AES_BLOCK_SIZE] = {0};
715
716 /* If remaining data bigger than one AES block size */
717 while (inputLen > AES_BLOCK_SIZE)
718 {
719 AES_128_Decrypt(pInput, pKey, pOutput);
720
721 pInput += AES_BLOCK_SIZE;
722 pOutput += AES_BLOCK_SIZE;
723 inputLen -= AES_BLOCK_SIZE;
724 }
725 /* If remaining data is smaller then one AES block size */
726 FLib_MemCpy(tempBuffIn, pInput, inputLen);
727 AES_128_Decrypt(tempBuffIn, pKey, tempBuffOut);
728 FLib_MemCpy(pOutput, tempBuffOut, inputLen);
729#endif /* FSL_FEATURE_SOC_AES_HW */
730
731 status = gSecSuccess_c;
732
733 } while (false);
734 return status;
735}
736
737/*! *********************************************************************************
738 * \brief This function performs AES-128-CBC encryption on a message block.
739 *
740 *
741 * \param[in] pInput Pointer to the location of the input message.
742 *
743 * \param[in] inputLen Input message length in bytes - must be a multiple of AES_BLOCK_SIZE
744 *
745 * \param[in, out] pInitVector Pointer to the location of the 128-bit initialization vector.
746 * On exit the IV content is updated with ciphered output to be injected as next block IV.
747 * Because IV is modifiable, it cannot be RO (const).
748 *
749 * \param[in] pKey Pointer to the location of the 128-bit key.
750 *
751 * \param[out] pOutput Pointer to the location to store the ciphered output.
752 *
753 * \return : gSecSuccess_c if no error,
754 * gSecBadArgument_c in case of bad arguments,
755 * gSecError_c in case of internal error.
756 *
757 ********************************************************************************** */
758secResultType_t SecLib_AES_128_CBC_Encrypt(
759 const uint8_t *pInput, uint32_t inputLen, uint8_t *pInitVector, const uint8_t *pKey, uint8_t *pOutput)
760{
761 secResultType_t ret;
762
763 do
764 {
765 if ((pInput == NULL) || (pInitVector == NULL) || (pKey == NULL) || (pOutput == NULL) ||
766 /* If the input length is not a non zero multiple of AES 128 block size, return */
767 (inputLen < AES_BLOCK_SIZE) || (AES_PARTIAL_BLOCK_BYTES(inputLen) != 0U))
768 {
769 RAISE_ERROR(ret, gSecBadArgument_c);
770 }
771
772 /* LTC is capable of performing CBC operation natively */
773#if (defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0))
774 status_t st;
775 SECLIB_MUTEX_LOCK();
776 st = LTC_AES_EncryptCbc(LTC0, pInput, pOutput, inputLen, pInitVector, pKey, AES_128_KEY_BYTE_LEN);
777 SECLIB_MUTEX_UNLOCK();
778 if (st != kStatus_Success)
779 {
780 RAISE_ERROR(ret, gSecError_c);
781 }
782 /* Update IV with last ciphered block to be injected at next call */
783 /* Note that inputLen is greater than or equal to AES_BLOCK_SIZE, otherwise would have exited
784 with gSecBadArgument_c, so difference cannot be negative */
785 FLib_MemCpy(pInitVector, &pOutput[inputLen - AES_BLOCK_SIZE], AES_BLOCK_SIZE);
786#else
787 uint8_t tempBuffIn[AES_BLOCK_SIZE] = {0};
788
789 FLib_MemCpy(tempBuffIn, pInitVector, AES_BLOCK_SIZE);
790 /* If remaining data is bigger than one AES block size */
791 while (inputLen > 0u)
792 {
793 SecLib_XorN(tempBuffIn, pInput, AES_BLOCK_SIZE);
794 AES_128_Encrypt(tempBuffIn, pKey, pOutput);
795 FLib_MemCpy(tempBuffIn, pOutput, AES_BLOCK_SIZE);
796 pInput += AES_BLOCK_SIZE;
797 pOutput += AES_BLOCK_SIZE;
798 inputLen -= AES_BLOCK_SIZE;
799 }
800 FLib_MemCpy(pInitVector, tempBuffIn, AES_BLOCK_SIZE);
801#endif
802 ret = gSecSuccess_c;
803 } while (false);
804
805 return ret;
806}
807
808/*! *********************************************************************************
809 * \brief This function performs AES-128-CBC decryption on a message block.
810 *
811 * \param[in] pInput Pointer to the location of the input ciphered message.
812 *
813 * \param[in] inputLen Input message length in bytes - must be a multiple of AES_BLOCK_SIZE.
814 *
815 * \param[in, out] pInitVector Pointer to the location of the 128-bit initialization vector.
816 * On exit the IV content is updated with ciphered output to be injected as next block IV.
817 * Because IV is modifiable, it cannot be RO (const).
818 *
819 * \param[in] pKey Pointer to the location of the 128-bit key.
820 *
821 * \param[out] pOutput Pointer to the location to store the plain text output.
822 *
823 * \return : gSecSuccess_c if no error,
824 * gSecBadArgument_c in case of bad arguments,
825 * gSecError_c in case of internal error.
826 *
827 ********************************************************************************** */
828secResultType_t SecLib_AES_128_CBC_Decrypt(
829 const uint8_t *pInput, uint32_t inputLen, uint8_t *pInitVector, const uint8_t *pKey, uint8_t *pOutput)
830{
831 secResultType_t ret;
832
833 do
834 {
835 if ((pInput == NULL) || (pInitVector == NULL) || (pKey == NULL) || (pOutput == NULL) ||
836 /* If the input length is not a non zero multiple of AES 128 block size, return */
837 (inputLen < AES_BLOCK_SIZE) || (AES_PARTIAL_BLOCK_BYTES(inputLen) != 0U))
838 {
839 RAISE_ERROR(ret, gSecBadArgument_c);
840 }
841
842#if (defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0)) && \
843 (defined(LTC_KEY_REGISTER_READABLE) && (LTC_KEY_REGISTER_READABLE == 1))
844 status_t st;
845 SECLIB_MUTEX_LOCK();
846 st = LTC_AES_DecryptCbc(LTC0, pInput, pOutput, inputLen, pInitVector, pKey, AES_128_KEY_BYTE_LEN,
847 kLTC_DecryptKey);
848 SECLIB_MUTEX_UNLOCK();
849 if (st != kStatus_Success)
850 {
851 RAISE_ERROR(ret, gSecError_c);
852 }
853 /* Update IV with last ciphered block to be injected at next call */
854 /* Note that inputLen is greater than or equal to AES_BLOCK_SIZE, otherwise would have exited
855 with gSecBadArgument_c, so difference cannot be negative */
856 FLib_MemCpy(pInitVector, &pInput[inputLen - AES_BLOCK_SIZE], AES_BLOCK_SIZE);
857#else
858 uint8_t temp[AES_BLOCK_SIZE] = {0u};
859
860 while (inputLen > 0u)
861 {
862 FLib_MemCpy(temp, pInput, AES_BLOCK_SIZE);
863 AES_128_Decrypt(pInput, pKey, pOutput);
864 SecLib_XorN(pOutput, pInitVector, AES_BLOCK_SIZE);
865
866 FLib_MemCpy(pInitVector, temp, AES_BLOCK_SIZE);
867
868 pInput += AES_BLOCK_SIZE;
869 pOutput += AES_BLOCK_SIZE;
870 inputLen -= AES_BLOCK_SIZE;
871 }
872#endif
873 ret = gSecSuccess_c;
874
875 } while (false);
876
877 return ret;
878}
879
880/*! *********************************************************************************
881 * \brief This function performs AES-128-CBC encryption on a message block after
882 * padding until AES block completion.
883 *
884 * Padding scheme is ISO/IEC 7816-4: one 80h byte (1 bit), followed by as many 00h as
885 * required to fill a 128 bit block. Note that if the message length is a multiple of
886 * AES block size already, another block is appended to the original message.
887 *
888 * \param[in] pInput Pointer to the location of the input message.
889 *
890 * \param[in] inputLen Input message length in bytes - no specific constraint.
891 *
892 * IMPORTANT: User must make sure output buffer has at least inputLen + 16 bytes size.
893 * This constraint does not apply to input buffer (any longer).
894 *
895 * \param[in, out] pInitVector Pointer to the location of the 128-bit initialization vector.
896 * On exit the IV content is updated with ciphered output to be injected as next block IV.
897 * Because it is modifiable it cannot be RO (const).
898 *
899 * \param[in] pKey Pointer to the location of the 128-bit key.
900 *
901 * \param[out] pOutput Pointer to the location to store the ciphered output.
902 *
903 * \return size of output message after padding is appended.
904 *
905 ********************************************************************************** */
906uint32_t AES_128_CBC_Encrypt_And_Pad(
907 uint8_t *pInput, uint32_t inputLen, uint8_t *pInitVector, const uint8_t *pKey, uint8_t *pOutput)
908{
909 uint32_t roundedLen = 0u;
910
911 do
912 {
913 uint8_t last_blk_msg_sz;
914 uint8_t last_block[AES_BLOCK_SIZE]; /* Buffer used to generate last block containing padding */
915 /* compute new length */
916 roundedLen = AES_WHOLE_BLOCK_BYTES(inputLen);
917 last_blk_msg_sz = (uint8_t)(inputLen - roundedLen);
918 /* Perform AES-CBC operation on whole AES blocks */
919 if (SecLib_AES_128_CBC_Encrypt(pInput, roundedLen, pInitVector, pKey, pOutput) != gSecSuccess_c)
920 {
921 roundedLen = 0u;
922 break;
923 }
924 pInput += roundedLen;
925 pOutput += roundedLen;
926 /* There may be a remainder modulus 16 : copy it to last_block byte array (on stack).
927 * then add padding so as to fill the last_block array. The amount of padding is 16 bytes if already
928 * AES block aligned, or any size [0..15] to pad till AES block is full.
929 */
930 (void)SecLib_Padding(pInput, last_block, last_blk_msg_sz);
931 if (SecLib_AES_128_CBC_Encrypt(last_block, AES_BLOCK_SIZE, pInitVector, pKey, pOutput) != gSecSuccess_c)
932 {
933 roundedLen = 0u;
934 break;
935 }
936 roundedLen += AES_BLOCK_SIZE;
937 } while (false);
938
939 return roundedLen;
940}
941
942/*! *********************************************************************************
943 * \brief This function performs AES_128_CBC_Decrypt_And_Depad decryption on a message.
944 *
945 * \param[in] pInput Pointer to the location of the input ciphered message.
946 *
947 * \param[in] inputLen Input message length in bytes must be a multiple of AES block size
948 *
949 * \param[in] pInitVector Pointer to the location of the 128-bit initialization vector.
950 *
951 * \param[in] pKey Pointer to the location of the 128-bit key.
952 *
953 * \param[out] pOutput Pointer to the location to store the plain text output.
954 *
955 * \return size of output buffer (after depadding the 0x80 [0x00 .. ]. padding sequence)
956 *
957 ********************************************************************************** */
958uint32_t AES_128_CBC_Decrypt_And_Depad(
959 const uint8_t *pInput, uint32_t inputLen, uint8_t *pInitVector, const uint8_t *pKey, uint8_t *pOutput)
960{
961 uint32_t newLen = 0uL;
962
963 if (inputLen > 0u)
964 {
965 if (SecLib_AES_128_CBC_Decrypt(pInput, inputLen, pInitVector, pKey, pOutput) == gSecSuccess_c)
966 {
967 uint8_t padding_len;
968 /* If we are here inputLen is a non 0 multiple of AES_BLOCK_SIZE, otherwise AES_128_CBC_Decrypt would have
969 returned an error.
970 Yet the test below is to prevent a false MISRA error detection.
971 */
972 if ((inputLen >= AES_BLOCK_SIZE) && (AES_PARTIAL_BLOCK_BYTES(inputLen) == 0u))
973 {
974 uint8_t *p_last_block = &pOutput[inputLen - AES_BLOCK_SIZE];
975 padding_len = SecLib_DePadding(p_last_block);
976 if ((padding_len > 0u) && (padding_len <= AES_BLOCK_SIZE))
977 {
978 /* Safe: inputLen is a multiple of AES_BLOCK_SIZE and >= AES_BLOCK_SIZE,
979 padding_len is in [1..AES_BLOCK_SIZE], so subtraction cannot underflow */
980 newLen = inputLen - (uint32_t)padding_len;
981 }
982 }
983 }
984 }
985 /* coverity [return_overflow:FALSE] see above */
986 return newLen;
987}
988
989/*! *********************************************************************************
990 * \brief This function performs AES-128-CTR encryption on a message block.
991 *
992 * \param[in] pInput Pointer to the location of the input message.
993 *
994 * \param[in] inputLen Input message length in bytes.
995 *
996 * \param[in] pCounter Pointer to the location of the 128-bit counter.
997 *
998 * \param[in] pKey Pointer to the location of the 128-bit key.
999 *
1000 * \param[out] pOutput Pointer to the location to store the ciphered output.
1001 *
1002 ********************************************************************************** */
1003secResultType_t SecLib_AES_128_CTR(
1004 const uint8_t *pInput, uint32_t inputLen, uint8_t *pCounter, const uint8_t *pKey, uint8_t *pOutput)
1005{
1006 secResultType_t status = gSecError_c;
1007 do
1008 {
1009 if ((pInput == NULL) || (pOutput == NULL) || (pKey == NULL) || (pCounter == NULL) || (inputLen == 0UL))
1010 {
1011 RAISE_ERROR(status, gSecBadArgument_c);
1012 }
1013#ifdef FSL_FEATURE_SOC_AES_HW /* HW AES */
1014 AES_param_t pAES;
1015
1016 pAES.CTR_counter = pCounter;
1017 pAES.Key = pKey;
1018 pAES.Len = inputLen;
1019 pAES.pCipher = pOutput;
1020 pAES.pInitVector = NULL;
1021 pAES.pPlain = pInput;
1022 pAES.Blocks = 0;
1023#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
1024 AESM_InitType(&AES128CTR_Enc_Id, gAESMGR_CTR_Enc_c);
1025 AESM_SetParam(AES128CTR_Enc_Id, pAES, AES_128_CTR_Enc_HW);
1026 AESM_Start(AES128CTR_Enc_Id);
1027#else
1028 SECLIB_MUTEX_LOCK();
1029 AES_128_CTR_Enc_HW(&pAES);
1030 SECLIB_MUTEX_UNLOCK();
1031#endif /* USE_TASK_FOR_HW_AES */
1032 status = gSecSuccess_c;
1033#else /*FSL_FEATURE_SOC_AES_HW */
1034
1035#if (defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0))
1036 status_t st;
1037 SECLIB_MUTEX_LOCK();
1038 st = LTC_AES_EncryptCtr(LTC0, pInput, pOutput, inputLen, pCounter, pKey, AES_BLOCK_SIZE, (void *)NULL,
1039 (void *)NULL);
1040 SECLIB_MUTEX_UNLOCK();
1041 if (st != kStatus_Success)
1042 {
1043 RAISE_ERROR(ret, gSecError_c);
1044 }
1045#else
1046 uint8_t tempBuffIn[AES_BLOCK_SIZE] = {0};
1047 uint8_t encrCtr[AES_BLOCK_SIZE] = {0};
1048
1049 /* If remaining data bigger than one AES block size */
1050 while (inputLen > AES_BLOCK_SIZE)
1051 {
1052 FLib_MemCpy(tempBuffIn, pInput, AES_BLOCK_SIZE);
1053 AES_128_Encrypt(pCounter, pKey, encrCtr);
1054 SecLib_XorN(tempBuffIn, encrCtr, AES_BLOCK_SIZE);
1055 FLib_MemCpy(pOutput, tempBuffIn, AES_BLOCK_SIZE);
1056 pInput += AES_BLOCK_SIZE;
1057 pOutput += AES_BLOCK_SIZE;
1058 inputLen -= AES_BLOCK_SIZE;
1059 AES_128_IncrementCounter(pCounter);
1060 }
1061 /* If remaining data is smaller then one AES block size */
1062 FLib_MemCpy(tempBuffIn, pInput, inputLen);
1063 AES_128_Encrypt(pCounter, pKey, encrCtr);
1064 SecLib_XorN(tempBuffIn, encrCtr, AES_BLOCK_SIZE);
1065 FLib_MemCpy(pOutput, tempBuffIn, inputLen);
1066 AES_128_IncrementCounter(pCounter);
1067#endif /* FSL_FEATURE_SOC_LTC_COUNT */
1068#endif /* FSL_FEATURE_SOC_AES_HW */
1069 status = gSecSuccess_c;
1070 } while (false);
1071
1072 return status;
1073}
1074
1075/*! *********************************************************************************
1076 * \brief This function performs AES-128-CTR decryption on a message block.
1077 *
1078 * \param[in] pInput Pointer to the location of the input message.
1079 *
1080 * \param[in] inputLen Input message length in bytes.
1081 *
1082 * \param[in] pCounter Pointer to the location of the 128-bit counter.
1083 *
1084 * \param[in] pKey Pointer to the location of the 128-bit key.
1085 *
1086 * \param[out] pOutput Pointer to the location to store the ciphered output.
1087 *
1088 ********************************************************************************** */
1089#ifdef FSL_FEATURE_SOC_AES_HW
1090void AES_128_CTR_Decrypt(
1091 const uint8_t *pInput, uint32_t inputLen, uint8_t *pCounter, const uint8_t *pKey, uint8_t *pOutput)
1092{
1093 AES_param_t pAES;
1094
1095 pAES.CTR_counter = pCounter;
1096 pAES.Key = pKey;
1097 pAES.Len = inputLen;
1098 pAES.pCipher = pInput;
1099 pAES.pInitVector = NULL;
1100 pAES.pPlain = pOutput;
1101 pAES.Blocks = 0;
1102#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
1103 AESM_InitType(&AES128CTR_Dec_Id, gAESMGR_CTR_Dec_c);
1104 AESM_SetParam(AES128CTR_Dec_Id, pAES, AES_128_CTR_Dec_HW);
1105 AESM_Start(AES128CTR_Dec_Id);
1106#else
1107 SECLIB_MUTEX_LOCK();
1108 AES_128_CTR_Dec_HW(&pAES);
1109 SECLIB_MUTEX_UNLOCK();
1110#endif /* USE_TASK_FOR_HW_AES */
1111}
1112#endif /* FSL_FEATURE_SOC_AES_HW */
1113
1114/*! *********************************************************************************
1115 * \brief This function performs AES-128-CMAC on a message block.
1116 *
1117 * \param[in] pInput Pointer to the location of the input message.
1118 *
1119 * \param[in] inputLen Length of the input message in bytes. The input data must be provided MSB first.
1120 *
1121 * \param[in] pKey Pointer to the location of the 128-bit key. The key must be provided MSB first.
1122 *
1123 * \param[out] pOutput Pointer to the location to store the 16-byte authentication code. The code will be generated
1124 *MSB
1125 *first.
1126 *
1127 * \remarks This is public open source code! Terms of use must be checked before use!
1128 *
1129 ********************************************************************************** */
1130secResultType_t SecLib_AES_128_CMAC(const uint8_t *pInput,
1131 const uint32_t inputLen,
1132 const uint8_t *pKey,
1133 uint8_t *pOutput)
1134{
1135 secResultType_t status;
1136 do
1137 {
1138 if ((pInput == 0) || (pKey == NULL) || (pOutput == NULL))
1139 {
1140 RAISE_ERROR(status, gSecBadArgument_c);
1141 }
1142#ifdef FSL_FEATURE_SOC_AES_HW /* HW AES */
1143 AES_param_t pAES;
1144
1145 pAES.CTR_counter = NULL;
1146 pAES.Key = pKey;
1147 pAES.Len = inputLen;
1148 pAES.pCipher = pOutput;
1149 pAES.pInitVector = NULL;
1150 pAES.pPlain = pInput;
1151 pAES.Blocks = 0;
1152#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
1153 AESM_InitType(&AES128CMAC_Id, gAESMGR_CMAC_Enc_c);
1154 AESM_SetParam(AES128CMAC_Id, pAES, AES_128_CMAC_HW);
1155 AESM_Start(AES128CMAC_Id);
1156#else
1157 SECLIB_MUTEX_LOCK();
1158 AES_128_CMAC_HW(&pAES);
1159 SECLIB_MUTEX_UNLOCK();
1160#endif /* USE_TASK_FOR_HW_AES */
1161
1162#else /* SW AES */
1163
1164 uint8_t X[16];
1165 uint8_t Y[16];
1166 uint8_t M_last[16] = {0};
1167 uint8_t padded[16] = {0};
1168
1169 uint8_t K1[16] = {0};
1170 uint8_t K2[16] = {0};
1171
1172 uint16_t n;
1173 uint32_t i;
1174 uint8_t flag;
1175 uint8_t residual_len;
1176
1177 AES_128_CMAC_Generate_Subkey(pKey, K1, K2);
1178
1179 n = (uint16_t)((inputLen + (AES_BLOCK_SIZE - 1u)) / AES_BLOCK_SIZE); /* n is number of rounds */
1180 residual_len = (uint8_t)AES_PARTIAL_BLOCK_BYTES(inputLen);
1181
1182 if (n == 0u)
1183 {
1184 n = 1u;
1185 flag = 0u;
1186 }
1187 else
1188 {
1189 if (residual_len == 0u)
1190 { /* last block is a complete block */
1191 flag = 1u;
1192 }
1193 else
1194 { /* last block is not complete block */
1195 flag = 0u;
1196 }
1197 }
1198
1199 /* Process the last block - the last part the MSB first input data */
1200 if (flag > 0u)
1201 { /* last block is complete block */
1202 SecLib_Xor128(&pInput[AES_BLOCK_SIZE * (n - 1u)], K1, M_last);
1203 }
1204 else
1205 {
1206 (void)SecLib_Padding(&pInput[AES_BLOCK_SIZE * (n - 1u)], padded, residual_len);
1207 SecLib_Xor128(padded, K2, M_last);
1208 }
1209
1210 for (i = 0u; i < 16u; i++)
1211 {
1212 X[i] = 0u;
1213 }
1214
1215 for (i = 0u; i < (uint32_t)n - 1u; i++)
1216 {
1217 SecLib_Xor128(X, &pInput[AES_BLOCK_SIZE * i], Y); /* Y := Mi (+) X */
1218 AES_128_Encrypt(Y, pKey, X); /* X := AES-128(KEY, Y) */
1219 }
1220
1221 SecLib_Xor128(X, M_last, Y);
1222 AES_128_Encrypt(Y, pKey, X);
1223
1224 for (i = 0u; i < 16u; i++)
1225 {
1226 pOutput[i] = X[i];
1227 }
1228#endif /* FSL_FEATURE_SOC_AES_HW */
1229 status = gSecSuccess_c;
1230 } while (false);
1231
1232 return status;
1233}
1234
1235/*! *********************************************************************************
1236 * \brief This function performs AES-128-CMAC on a message block accepting input data
1237 * which is in LSB first format and computing the authentication code starting from the end of the data.
1238 *
1239 * \param[in] pInput Pointer to the location of the input message.
1240 *
1241 * \param[in] inputLen Length of the input message in bytes. The input data must be provided LSB first.
1242 *
1243 * \param[in] pKey Pointer to the location of the 128-bit key. The key must be provided MSB first.
1244 *
1245 * \param[out] pOutput Pointer to the location to store the 16-byte authentication code. The code will be generated
1246 *MSB
1247 *first.
1248 *
1249 ********************************************************************************** */
1250secResultType_t SecLib_AES_128_CMAC_LsbFirstInput(const uint8_t *pInput,
1251 uint32_t inputLen,
1252 const uint8_t *pKey,
1253 uint8_t *pOutput)
1254{
1255 secResultType_t status;
1256
1257 do
1258 {
1259 if ((pInput == NULL) || (pKey == NULL) || (pOutput == NULL))
1260 {
1261 RAISE_ERROR(status, gSecBadArgument_c);
1262 }
1263 uint8_t X[16];
1264 uint8_t Y[16];
1265 uint8_t M_last[16] = {0};
1266 uint8_t padded[16] = {0};
1267 uint8_t reversedBlock[16] = {0};
1268
1269 uint8_t K1[16] = {0};
1270 uint8_t K2[16] = {0};
1271
1272 uint16_t n;
1273 uint32_t i;
1274 uint8_t flag;
1275 uint8_t residual_len;
1276
1277 AES_128_CMAC_Generate_Subkey(pKey, K1, K2);
1278
1279 n = (uint16_t)(((inputLen + (AES_BLOCK_SIZE - 1u))) / AES_BLOCK_SIZE); /* n is number of rounds */
1280 residual_len = (uint8_t)AES_PARTIAL_BLOCK_BYTES(inputLen);
1281
1282 if (n == 0u)
1283 {
1284 n = 1u;
1285 flag = 0u;
1286 }
1287 else
1288 {
1289 if (residual_len == 0u) /* last block is a complete block */
1290 {
1291 flag = 1u;
1292 }
1293 else /* last block is not complete block */
1294 {
1295 flag = 0u;
1296 }
1297 }
1298
1299 /* Process the last block - the first part the LSB first input data */
1300 if (flag > 0u) /* last block is complete block */
1301 {
1302 FLib_MemCpyReverseOrder(reversedBlock, &pInput[0], AES_BLOCK_SIZE);
1303 SecLib_Xor128(reversedBlock, K1, M_last);
1304 }
1305 else
1306 {
1307 FLib_MemCpyReverseOrder(reversedBlock, &pInput[0], residual_len);
1308 (void)SecLib_Padding(reversedBlock, padded, residual_len);
1309 SecLib_Xor128(padded, K2, M_last);
1310 }
1311
1312 for (i = 0u; i < 16u; i++)
1313 {
1314 X[i] = 0u;
1315 }
1316
1317 for (i = 0u; i < (uint32_t)n - 1u; i++)
1318 {
1319 FLib_MemCpyReverseOrder(reversedBlock, &pInput[inputLen - AES_BLOCK_SIZE * (i + 1u)], AES_BLOCK_SIZE);
1320 SecLib_Xor128(X, reversedBlock, Y); /* Y := Mi (+) X */
1321 AES_128_Encrypt(Y, pKey, X); /* X := AES-128(KEY, Y) */
1322 }
1323
1324 SecLib_Xor128(X, M_last, Y);
1325 AES_128_Encrypt(Y, pKey, X);
1326
1327 for (i = 0u; i < 16u; i++)
1328 {
1329 pOutput[i] = X[i];
1330 }
1331 status = gSecSuccess_c;
1332 } while (false);
1333 return status;
1334}
1335
1336/*! *********************************************************************************
1337 * \brief This function performs AES 128 CMAC Pseudo-Random Function (AES-CMAC-PRF-128),
1338 * according to rfc4615, on a message block.
1339 *
1340 * \details The AES-CMAC-PRF-128 algorithm behaves similar to teh AES CMAC 128 algorithm
1341 * but removes 128 bit key size restriction.
1342 *
1343 * \param[in] pInput Pointer to the location of the input message.
1344 *
1345 * \param[in] inputLen Length of the input message in bytes.
1346 *
1347 * \param[in] pVarKey Pointer to the location of the variable length key.
1348 *
1349 * \param[in] varKeyLen Length of the input key in bytes
1350 *
1351 * \param[out] pOutput Pointer to the location to store the 16-byte pseudo random variable.
1352 *
1353 ********************************************************************************** */
1354secResultType_t SecLib_AES_CMAC_PRF_128(
1355 const uint8_t *pInput, uint32_t inputLen, const uint8_t *pVarKey, uint32_t varKeyLen, uint8_t *pOutput)
1356{
1357 secResultType_t status;
1358 do
1359 {
1360 uint8_t K[16]; /*!< Temporary key location to be used if the key length is not 16 bytes. */
1361 const uint8_t *pCmacKey = pVarKey; /*!< Pointer to the key used by the CMAC operation which generates the
1362 * output. */
1363 if ((pInput == NULL) || (pVarKey == NULL) || (pOutput == NULL))
1364 {
1365 RAISE_ERROR(status, gSecBadArgument_c);
1366 }
1367
1368 if (varKeyLen == 0u)
1369 {
1370 /* NIST SP 800‑38B and RFC 4493 allow empty message input.
1371 * RFC 4615 could mathematically accepts variable-length to be 0, nonetheless it is strongly discouraged
1372 * and ought to be rejected because of the lack of entropy. Using it could let the PRF be predictable
1373 * */
1374 RAISE_ERROR(status, gSecBadArgument_c);
1375 }
1376
1377 if (varKeyLen != 16u)
1378 {
1379 uint8_t K0[16] = {0x00u, 0x00, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
1380 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u};
1381 /*! Perform AES 128 CMAC on the variable key if it has a length which
1382 * is different from 16 bytes using a 128 bit key with all zeroes and
1383 * set the CMAC key to point to the result. */
1384
1385 status = SecLib_AES_128_CMAC(pVarKey, varKeyLen, K0, K);
1386 if (status != gSecSuccess_c)
1387 {
1388 break;
1389 }
1390 pCmacKey = K;
1391 }
1392
1393 /*! Perform the CMAC operation which generates the output using the local
1394 * key pointer whcih will be set to the initial key or the generated one. */
1395 status = SecLib_AES_128_CMAC(pInput, inputLen, pCmacKey, pOutput);
1396 } while (false);
1397 return status;
1398}
1399
1400/*! *********************************************************************************
1401 * \brief This function performs AES-128-CCM on a message block.
1402 *
1403 * \param[in] pInput Pointer to the location of the input message (plaintext or ciphertext).
1404 *
1405 * \param[in] inputLen Length of the input plaintext in bytes when encrypting.
1406 * Length of the input ciphertext without the MAC length when decrypting.
1407 *
1408 * \param[in] pAuthData Pointer to the additional authentication data.
1409 *
1410 * \param[in] authDataLen Length of additional authentication data.
1411 *
1412 * \param[in] pNonce Pointer to the Nonce.
1413 *
1414 * \param[in] nonceSize The size of the nonce (7-13).
1415 *
1416 * \param[in] pKey Pointer to the location of the 128-bit key.
1417 *
1418 * \param[out] pOutput Pointer to the location to store the plaintext data when decrypting.
1419 * Pointer to the location to store the ciphertext data when encrypting.
1420 *
1421 * \param[out] pCbcMac Pointer to the location to store the Message Authentication Code (MAC) when encrypting.
1422 * Pointer to the location where the received MAC can be found when decrypting.
1423 *
1424 * \param[out] macSize The size of the MAC.
1425 *
1426 * \param[out] flags Select encrypt/decrypt operations (gSecLib_CCM_Encrypt_c, gSecLib_CCM_Decrypt_c)
1427 *
1428 * \return 0 if encryption/decryption was successful; otherwise, error code for failed encryption/decryption
1429 *
1430 * \remarks At decryption, MIC fail is also signaled by returning a non-zero value.
1431 *
1432 ********************************************************************************** */
1433secResultType_t SecLib_AES_128_CCM(const uint8_t *pInput,
1434 uint16_t inputLen,
1435 const uint8_t *pAuthData,
1436 uint16_t authDataLen,
1437 const uint8_t *pNonce,
1438 uint8_t nonceSize,
1439 const uint8_t *pKey,
1440 uint8_t *pOutput,
1441 uint8_t *pCbcMac,
1442 uint8_t macSize,
1443 uint32_t flags)
1444{
1445 secResultType_t st = gSecError_c;
1446 uint8_t status;
1447
1448 if ((pInput == NULL) || (pAuthData == NULL) || (pNonce == NULL) || (pOutput == NULL) || (pKey == NULL) ||
1449 (pCbcMac == NULL))
1450 {
1451 return gSecBadArgument_c;
1452 }
1453
1454#if (defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT == 1))
1455 SECLIB_MUTEX_LOCK();
1456 if ((flags & gSecLib_CCM_Decrypt_c) == gSecLib_CCM_Decrypt_c)
1457 {
1458 status = (uint8_t)(LTC_AES_DecryptTagCcm(LTC0, pInput, pOutput, (uint32_t)inputLen, pNonce, (uint32_t)nonceSize,
1459 pAuthData, (uint32_t)authDataLen, pKey, AES_BLOCK_SIZE, pCbcMac,
1460 (uint32_t)macSize));
1461 }
1462 else
1463 {
1464 status = (uint8_t)(LTC_AES_EncryptTagCcm(LTC0, pInput, pOutput, (uint32_t)inputLen, pNonce, (uint32_t)nonceSize,
1465 pAuthData, (uint32_t)authDataLen, pKey, AES_BLOCK_SIZE, pCbcMac,
1466 (uint32_t)macSize));
1467 }
1468 SECLIB_MUTEX_UNLOCK();
1469
1470#else
1471 status = sw_AES128_CCM(pInput, inputLen, pAuthData, authDataLen, pNonce, nonceSize, pKey, pOutput, pCbcMac, macSize,
1472 flags);
1473#endif
1474 if (status == 0u)
1475 {
1476 st = gSecSuccess_c;
1477 }
1478
1479 return st;
1480}
1481
1482/*! *********************************************************************************
1483 * \brief This function calculates XOR of individual byte pairs in two uint8_t arrays.
1484 * pDst[i] := pDst[i] ^ pSrc[i] for i=0 to n-1
1485 *
1486 * \param[in, out] pDst First byte array operand for XOR and destination byte array
1487 *
1488 * \param[in] pSrc Second byte array operand for XOR
1489 *
1490 * \param[in] n Length of the byte arrays which will be XORed
1491 *
1492 ********************************************************************************** */
1493void SecLib_XorN(uint8_t *pDst, const uint8_t *pSrc, uint8_t n)
1494{
1495 while (n > 0u)
1496 {
1497 *pDst = *pDst ^ *pSrc;
1498 pDst = pDst + 1u;
1499 pSrc = pSrc + 1u;
1500 n--;
1501 }
1502}
1503
1504/*! *********************************************************************************
1505 * \brief This function allocates a memory buffer for a SHA256 context structure
1506 *
1507 * \return Address of the SHA256 context buffer
1508 * Deallocate using SHA256_FreeCtx()
1509 *
1510 ********************************************************************************** */
1511void *SecLib_SHA256_AllocCtx(void)
1512{
1513 void *sha256Ctx = MEM_BufferAlloc(sizeof(sha256Context_t));
1514
1515 return sha256Ctx;
1516}
1517
1518/*! *********************************************************************************
1519* \brief This function deallocates the memory buffer for the SHA256 context structure
1520*
1521
1522* \param [in] pContext Address of the SHA256 context buffer
1523*
1524********************************************************************************** */
1525void SecLib_SHA256_FreeCtx(void *pContext)
1526{
1527 (void)MEM_BufferFree(pContext);
1528}
1529
1530/*! *********************************************************************************
1531 * \brief This function clones SHA256 context.
1532 * Make sure the size of the allocated destination context buffer is appropriate.
1533 *
1534 * \param [in] pDestCtx Address of the destination SHA256 context
1535 * \param [in] pSourceCtx Address of the source SHA256 context
1536 *
1537 ********************************************************************************** */
1538void SecLib_SHA256_CloneCtx(void *pDestCtx, void *pSourceCtx)
1539{
1540 FLib_MemCpy(pDestCtx, pSourceCtx, sizeof(sha256Context_t));
1541}
1542
1543/*! *********************************************************************************
1544 * \brief This function initializes the SHA256 context data
1545 *
1546 * \param [in] pContext Pointer to the SHA256 context data
1547 * Allocated using SHA256_AllocCtx()
1548 *
1549 ********************************************************************************** */
1550secResultType_t SecLib_SHA256_Init(void *pContext)
1551{
1552 secResultType_t st = gSecBadArgument_c;
1553 sha256Context_t *context = (sha256Context_t *)pContext;
1554
1555 if (context != NULL)
1556 {
1557 context->bytes = 0u;
1558 context->totalBytes = 0u;
1559#if (defined(FSL_FEATURE_SOC_MMCAU_COUNT) && (FSL_FEATURE_SOC_MMCAU_COUNT > 0))
1560 SECLIB_MUTEX_LOCK();
1561 (void)mmcau_sha256_initialize_output((const unsigned int *)context->hash);
1562 SECLIB_MUTEX_UNLOCK();
1563
1564#else
1565 sw_sha256_initialize_output(context->hash);
1566#endif
1567 st = gSecSuccess_c;
1568 }
1569 return st;
1570}
1571
1572/*! *********************************************************************************
1573 * \brief This function performs SHA256 on multiple bytes and updates the context data
1574 *
1575 * \param [in] pContext Pointer to the SHA256 context data
1576 * Allocated using SHA256_AllocCtx()
1577 * \param [in] pData Pointer to the input data
1578 * \param [in] numBytes Number of bytes to hash
1579 * \return 0 if operation successful
1580 * -1 if context is NULL
1581 * -2 if bytes in context greater than 64
1582 * -3 if numBytes is about to let number of accumulated bytes of context exceeds 2^29.
1583 *
1584 ********************************************************************************** */
1585secResultType_t SecLib_SHA256_HashUpdate(void *pContext, const uint8_t *pData, uint32_t numBytes)
1586{
1587 uint32_t blocks;
1588 sha256Context_t *context = (sha256Context_t *)pContext;
1589 secResultType_t st;
1590 /* The Hash Finish operation needs space to convert in number of bits so must
1591 * be smaller than 2^29 */
1592 do
1593 {
1594 uint8_t copyBytes;
1595
1596 if ((context == NULL) || (pData == NULL))
1597 {
1598 RAISE_ERROR(st, gSecBadArgument_c);
1599 }
1600 assert(context->bytes < SHA256_BLOCK_SIZE);
1601 if (MAX_SHA256_TOTAL_BYTES - context->totalBytes < numBytes)
1602 {
1603 RAISE_ERROR(st, gSecError_c);
1604 }
1605 /* update total byte count */
1606 context->totalBytes += numBytes;
1607
1608 copyBytes = SHA256_BLOCK_SIZE - context->bytes;
1609
1610 if (numBytes < (uint32_t)copyBytes)
1611 {
1612 /* store bytes for later processing, a full block will not be accumulated yet */
1613 FLib_MemCpy(&context->buffer[context->bytes], pData, numBytes);
1614 context->bytes += (uint8_t)(numBytes & 0xffu);
1615 }
1616 else
1617 {
1618 /* Check for bytes leftover from previous update */
1619 if (context->bytes > 0u)
1620 {
1621 FLib_MemCpy(&context->buffer[context->bytes], pData, copyBytes);
1622 SHA256_hash_n(context->buffer, 1u, context->hash);
1623 pData += copyBytes;
1624 /* numBytes necessarily greater or equal to copyBytes in this branch */
1625 numBytes -= (uint32_t)copyBytes;
1626 context->bytes = 0u;
1627 }
1628 /* Hash 64 bytes blocks */
1629 blocks = (numBytes / SHA256_BLOCK_SIZE);
1630 SHA256_hash_n(pData, blocks, context->hash);
1631 numBytes -= blocks * SHA256_BLOCK_SIZE;
1632 pData += blocks * SHA256_BLOCK_SIZE; /* Check if we have at least 1 SHA256 block */
1633 /* Check for remaining bytes */
1634 if (numBytes > 0u)
1635 {
1636 context->bytes = (uint8_t)(numBytes & (uint32_t)(SHA256_BLOCK_SIZE - 1));
1637 FLib_MemCpy(context->buffer, pData, numBytes);
1638 }
1639 }
1640 st = gSecSuccess_c;
1641 } while (0);
1642
1643 return st;
1644}
1645
1646/*! *********************************************************************************
1647 * \brief This function finalizes the SHA256 hash computation and clears the context data.
1648 * The final hash value is stored at the provided output location.
1649 *
1650 * \param [in] pContext Pointer to the SHA256 context data
1651 * Allocated using SHA256_AllocCtx()
1652 * \param [out] pOutput Pointer to the output location
1653 *
1654 ********************************************************************************** */
1655secResultType_t SecLib_SHA256_HashFinish(void *pContext, uint8_t *pOutput)
1656{
1657 secResultType_t st;
1658
1659 sha256Context_t *context = (sha256Context_t *)pContext;
1660 /* The Hash Finish operation needs space to convert in number of bits so must
1661 * be smaller than 2^29 */
1662 do
1663 {
1664 uint32_t numBytes = context->bytes;
1665
1666 if ((context == NULL) || (pOutput == NULL))
1667 {
1668 RAISE_ERROR(st, gSecBadArgument_c);
1669 }
1670 assert(numBytes < SHA256_BLOCK_SIZE);
1671 assert(MAX_SHA256_TOTAL_BYTES - context->totalBytes >= numBytes);
1672
1673 /* Add 1 bit (a 0x80 byte) after the message to begin padding */
1674 context->buffer[numBytes++] = 0x80u;
1675 /* Check for space to fit an 8 byte length field plus the 0x80 */
1676 if (context->bytes >= (SHA256_BLOCK_SIZE - 8u))
1677 {
1678 /* Fill the rest of the chunk with zeros */
1679 FLib_MemSet(&context->buffer[numBytes], 0u, SHA256_BLOCK_SIZE - numBytes);
1680 SHA256_hash_n(context->buffer, 1u, context->hash);
1681 numBytes = 0u;
1682 }
1683 /* Fill the rest of the chunk with zeros */
1684 FLib_MemSet(&context->buffer[numBytes], 0, SHA256_BLOCK_SIZE - numBytes);
1685 /* Append the total length of the message(Big Endian), in bits (bytes << 3) */
1686 /* Conversion can be done safely on a 32 bit variable because we have ascertained that totalBytes remain
1687 * smaller than 2^29 */
1688 context->totalBytes <<= 3u;
1689 FLib_MemCpyReverseOrder(&context->buffer[SHA256_BLOCK_SIZE - (uint8_t)sizeof(uint32_t)], &context->totalBytes,
1690 sizeof(uint32_t));
1691 SHA256_hash_n(context->buffer, 1u, context->hash);
1692 /* Convert to Big Endian */
1693 for (uint32_t i = 0u; i < SHA256_HASH_SIZE / sizeof(uint32_t); i++)
1694 {
1695 uint32_t temp;
1696 temp = context->hash[i];
1697 FLib_MemCpyReverseOrder(&context->hash[i], &temp, sizeof(uint32_t));
1698 }
1699
1700 /* Copy the generated hash to the indicated output location */
1701 FLib_MemCpy(pOutput, (uint8_t *)(context->hash), SHA256_HASH_SIZE);
1702 st = gSecSuccess_c;
1703 } while (false);
1704
1705 return st;
1706}
1707
1708/*! *********************************************************************************
1709 * \brief This function performs all SHA256 steps on multiple bytes: initialize,
1710 * update and finish.
1711 * The final hash value is stored at the provided output location.
1712 *
1713 * \param [in] pData Pointer to the input data
1714 * \param [in] numBytes Number of bytes to hash
1715 * \param [out] pOutput Pointer to the output location
1716 *
1717 ********************************************************************************** */
1718secResultType_t SecLib_SHA256_Hash(const uint8_t *pData, uint32_t numBytes, uint8_t *pOutput)
1719{
1720 secResultType_t st;
1721 sha256Context_t context;
1722 do
1723 {
1724 (void)SecLib_SHA256_Init(&context);
1725 st = SecLib_SHA256_HashUpdate(&context, pData, numBytes);
1726 if (st != gSecSuccess_c)
1727 {
1728 break;
1729 }
1730 st = SecLib_SHA256_HashFinish(&context, pOutput);
1731 if (st != gSecSuccess_c)
1732 {
1733 break;
1734 }
1735 } while (false);
1736 return st;
1737}
1738
1739/*! *********************************************************************************
1740 * \brief This function allocates a memory buffer for a HMAC SHA256 context structure
1741 *
1742 * \return Address of the HMAC SHA256 context buffer
1743 * Deallocate using HMAC_SHA256_FreeCtx()
1744 *
1745 ********************************************************************************** */
1746void *SecLib_HMAC_SHA256_AllocCtx(void)
1747{
1748 void *hmacSha256Ctx = MEM_BufferAlloc(sizeof(HMAC_SHA256_context_t));
1749
1750 return hmacSha256Ctx;
1751}
1752
1753/*! *********************************************************************************
1754 * \brief This function deallocates the memory buffer for the HMAC SHA256 context structure
1755 *
1756 * \param [in] pContext Address of the HMAC SHA256 context buffer
1757 *
1758 ********************************************************************************** */
1759void SecLib_HMAC_SHA256_FreeCtx(void *pContext)
1760{
1761 (void)MEM_BufferFree(pContext);
1762}
1763
1764/*! *********************************************************************************
1765 * \brief This function performs the initialization of the HMAC SHA256 context data
1766 *
1767 * \param [in] pContext Pointer to the HMAC SHA256 context data
1768 * Allocated using HMAC_SHA256_AllocCtx()
1769 * \param [in] pKey Pointer to the HMAC key
1770 * \param [in] keyLen Length of the HMAC key in bytes
1771 *
1772 ********************************************************************************** */
1773secResultType_t SecLib_HMAC_SHA256_Init(void *pContext, const uint8_t *pKey, uint32_t keyLen)
1774{
1775 secResultType_t st;
1776
1777 do
1778 {
1779 uint8_t i;
1780 HMAC_SHA256_context_t *context = (HMAC_SHA256_context_t *)pContext;
1781 sha256Context_t *hash_ctx;
1782 uint8_t sha256HashKeyBuffer[SHA256_HASH_SIZE] = {0};
1783
1784 if ((context == NULL) || (pKey == NULL))
1785 {
1786 RAISE_ERROR(st, gSecBadArgument_c);
1787 }
1788 hash_ctx = &context->shaCtx;
1789
1790 if (keyLen > SHA256_BLOCK_SIZE)
1791 {
1792 st = SecLib_SHA256_Hash(pKey, keyLen, sha256HashKeyBuffer);
1793 if (st != gSecSuccess_c)
1794 {
1795 break;
1796 }
1797 pKey = sha256HashKeyBuffer;
1798 keyLen = SHA256_HASH_SIZE;
1799 }
1800 /* Create i_pad */
1801 for (i = 0u; i < keyLen; i++)
1802 {
1803 context->pad[i] = pKey[i] ^ gHmacIpad_c;
1804 }
1805
1806 for (i = (uint8_t)(keyLen & 0xffu); i < SHA256_BLOCK_SIZE; i++)
1807 {
1808 context->pad[i] = gHmacIpad_c;
1809 }
1810
1811 /* start hashing of the i_key_pad */
1812 st = SecLib_SHA256_Init(hash_ctx);
1813 if (st != gSecSuccess_c)
1814 {
1815 break;
1816 }
1817
1818 st = SecLib_SHA256_HashUpdate(hash_ctx, context->pad, SHA256_BLOCK_SIZE);
1819 if (st != gSecSuccess_c)
1820 {
1821 break;
1822 }
1823 /* create o_pad by xor-ing pad[i] with 0x36 ^ 0x5C: */
1824 for (i = 0u; i < SHA256_BLOCK_SIZE; i++)
1825 {
1826 context->pad[i] ^= (gHmacIpad_c ^ gHmacOpad_c);
1827 }
1828 } while (false);
1829 return st;
1830}
1831
1832/*! *********************************************************************************
1833 * \brief This function performs HMAC update with the input data.
1834 *
1835 * \param [in] pContext Pointer to the HMAC SHA256 context data
1836 * Allocated using HMAC_SHA256_AllocCtx()
1837 * \param [in] pData Pointer to the input data
1838 * \param [in] numBytes Number of bytes to hash
1839 *
1840 ********************************************************************************** */
1841secResultType_t SecLib_HMAC_SHA256_Update(void *pContext, const uint8_t *pData, uint32_t numBytes)
1842{
1843 HMAC_SHA256_context_t *context = (HMAC_SHA256_context_t *)pContext;
1844 sha256Context_t *sha_ctx = (context == NULL) ? NULL : &context->shaCtx;
1845 return SecLib_SHA256_HashUpdate(sha_ctx, pData, numBytes);
1846}
1847
1848/*! *********************************************************************************
1849 * \brief This function finalizes the HMAC SHA256 computation and clears the context data.
1850 * The final hash value is stored at the provided output location.
1851 *
1852 * \param [in] pContext Pointer to the HMAC SHA256 context data
1853 * Allocated using HMAC_SHA256_AllocCtx()
1854 * \param [in,out] pOutput Pointer to the output location
1855 *
1856 ********************************************************************************** */
1857secResultType_t SecLib_HMAC_SHA256_Finish(void *pContext, uint8_t *pOutput)
1858{
1859 secResultType_t st;
1860 do
1861 {
1862 HMAC_SHA256_context_t *context = (HMAC_SHA256_context_t *)pContext;
1863 sha256Context_t *sha_ctx = (context == NULL) ? NULL : &context->shaCtx;
1864 uint8_t hash1[SHA256_HASH_SIZE];
1865
1866 /* finalize the hash of the i_key_pad and message */
1867 st = SecLib_SHA256_HashFinish(sha_ctx, hash1);
1868 if (st != gSecSuccess_c)
1869 {
1870 break;
1871 }
1872 /* perform hash of the o_key_pad and hash1 */
1873 st = SecLib_SHA256_Init(sha_ctx);
1874 if (st != gSecSuccess_c)
1875 {
1876 break;
1877 }
1878 st = SecLib_SHA256_HashUpdate(sha_ctx, context->pad, SHA256_BLOCK_SIZE);
1879 if (st != gSecSuccess_c)
1880 {
1881 break;
1882 }
1883 st = SecLib_SHA256_HashUpdate(sha_ctx, hash1, SHA256_HASH_SIZE);
1884 if (st != gSecSuccess_c)
1885 {
1886 break;
1887 }
1888
1889 st = SecLib_SHA256_HashFinish(sha_ctx, pOutput);
1890
1891 } while (false);
1892 return st;
1893}
1894
1895/*! *********************************************************************************
1896 * \brief This function performs all HMAC SHA256 steps on multiple bytes: initialize,
1897 * update, finish, and update context data.
1898 * The final HMAC value is stored at the provided output location.
1899 *
1900 * \param [in] pKey Pointer to the HMAC key
1901 * \param [in] keyLen Length of the HMAC key in bytes
1902 * \param [in] pData Pointer to the input data
1903 * \param [in] numBytes Number of bytes to perform HMAC on
1904 * \param [in,out] pOutput Pointer to the output location
1905 *
1906 ********************************************************************************** */
1907secResultType_t SecLib_HMAC_SHA256(
1908 const uint8_t *pKey, uint32_t keyLen, const uint8_t *pData, uint32_t numBytes, uint8_t *pOutput)
1909{
1910 secResultType_t st;
1911 do
1912 {
1913 HMAC_SHA256_context_t context;
1914
1915 st = SecLib_HMAC_SHA256_Init(&context, pKey, keyLen);
1916 if (st != gSecSuccess_c)
1917 {
1918 break;
1919 }
1920 st = SecLib_HMAC_SHA256_Update(&context, pData, numBytes);
1921 if (st != gSecSuccess_c)
1922 {
1923 break;
1924 }
1925 st = SecLib_HMAC_SHA256_Finish(&context, pOutput);
1926 if (st != gSecSuccess_c)
1927 {
1928 break;
1929 }
1930 } while (false);
1931 return st;
1932}
1933
1934#if (defined(mDbgRevertKeys_d) && (mDbgRevertKeys_d > 0))
1935static ecdhPublicKey_t mReversedPublicKey;
1936static ecdhPrivateKey_t mReversedPrivateKey;
1937#endif /* mDbgRevertKeys_d */
1938
1939/* ECDH Sample Data Bluetooth specification V5.0 :
19407.1.2.1 P-256 Data Set 1
1941Private A: 3f49f6d4 a3c55f38 74c9b3e3 d2103f50 4aff607b eb40b799 5899b8a6 cd3c1abd
1942Private B: 55188b3d 32f6bb9a 900afcfb eed4e72a 59cb9ac2 f19d7cfb 6b4fdd49 f47fc5fd
1943Public A(x): 20b003d2 f297be2c 5e2c83a7 e9f9a5b9 eff49111 acf4fddb cc030148 0e359de6
1944Public A(y): dc809c49 652aeb6d 63329abf 5a52155c 766345c2 8fed3024 741c8ed0 1589d28b
1945Public B(x): 1ea1f0f0 1faf1d96 09592284 f19e4c00 47b58afd 8615a69f 559077b2 2faaa190
1946Public B(y): 4c55f33e 429dad37 7356703a 9ab85160 472d1130 e28e3676 5f89aff9 15b1214a
1947DHKey: ec0234a3 57c8ad05 341010a6 0a397d9b 99796b13 b4f866f1 868d34f3 73bfa698
19487.1.2.2 P-256 Data Set 2
1949Private A: 06a51669 3c9aa31a 6084545d 0c5db641 b48572b9 7203ddff b7ac73f7 d0457663
1950Private B: 529aa067 0d72cd64 97502ed4 73502b03 7e8803b5 c60829a5 a3caa219 505530ba
1951Public A(x): 2c31a47b 5779809e f44cb5ea af5c3e43 d5f8faad 4a8794cb 987e9b03 745c78dd
1952Public A(y): 91951218 3898dfbe cd52e240 8e43871f d0211091 17bd3ed4 eaf84377 43715d4f
1953Public B(x): f465e43f f23d3f1b 9dc7dfc0 4da87581 84dbc966 204796ec cf0d6cf5 e16500cc
1954Public B(y): 0201d048 bcbbd899 eeefc424 164e33c2 01c2b010 ca6b4d43 a8a155ca d8ecb279
1955DHKey: ab85843a 2f6d883f 62e5684b 38e30733 5fe6e194 5ecd1960 4105c6f2 3221eb69
1956*/
1957
1958/************************************************************************************
1959 * \brief Generates a public key from a scalar given as input
1960 *
1961 * This function performs the multiplication of the scalar by the EC P 256 G point.
1962 * The resulting point is the public key corresponding to the private key constituted by the scalar.
1963 * This calculation is also involved in the compute L stage if the SPAKE2+ not necessarily.
1964 *
1965 * \return gSecSuccess_c or error
1966 *
1967 ************************************************************************************/
1968secEcp256Status_t ECP256_GeneratePublicKey(uint8_t *pOutPublicKey,
1969 const uint8_t *pInPrivateKey,
1970 void *pMultiplicationBuffer)
1971{
1972 secEcp256Status_t ret = gSecEcp256BadParameters_c;
1973 if ((pOutPublicKey != NULL) && (pInPrivateKey != NULL))
1974 {
1975#if !(defined gSecLibUseDspExtension_d && (gSecLibUseDspExtension_d == 1))
1976 if (pMultiplicationBuffer != NULL)
1977 {
1978 big_int256_t privKey;
1979 ecp256Point_t out;
1980 FLib_MemCpyReverseOrder((uint8_t *)&privKey, pInPrivateKey, sizeof(big_int256_t));
1981 ret = ECP256_GeneratePublicKeySeg(&out.raw[0], (uint8_t *)&privKey, pMultiplicationBuffer);
1982 ECP256_PointCopy_and_change_endianness((uint8_t *)pOutPublicKey, &out.raw[0]);
1983 }
1984#else
1985 NOT_USED(pMultiplicationBuffer);
1986 ret = ECP256_GeneratePublicKeyUltraFast(pOutPublicKey, pInPrivateKey);
1987#endif
1988 }
1989 return ret;
1990}
1991/************************************************************************************
1992 * \brief Generates a new ECDH P256 Private/Public key pair
1993 *
1994 * \return gSecSuccess_c or error
1995 *
1996 ************************************************************************************/
1997secResultType_t ECDH_P256_GenerateKeys(ecdhPublicKey_t *pOutPublicKey, ecdhPrivateKey_t *pOutPrivateKey)
1998{
1999 secResultType_t result;
2000
2001 do
2002 {
2003 if ((pOutPublicKey == NULL) || (pOutPrivateKey == NULL))
2004 {
2005 result = gSecBadArgument_c;
2006 break;
2007 }
2008
2009#if !(defined(gSecLibUseBleDebugKeys_d) && (gSecLibUseBleDebugKeys_d > 0))
2010#if !(defined gSecLibUseDspExtension_d && (gSecLibUseDspExtension_d == 1))
2011 void *pMultiplicationBuffer = MEM_BufferAlloc(gEcP256_MultiplicationBufferSize_c);
2012 if (NULL == pMultiplicationBuffer)
2013 {
2014 result = gSecAllocError_c;
2015 break;
2016 }
2017#if (defined(mDbgRevertKeys_d) && (mDbgRevertKeys_d > 0))
2018 if (gSecEcp256Success_c !=
2019 ECP256_GenerateKeyPair(&mReversedPublicKey, &mReversedPrivateKey, pMultiplicationBuffer))
2020#else /* !mDbgRevertKeys_d */
2021 if (gSecEcp256Success_c != ECP256_GenerateKeyPair(pOutPublicKey, pOutPrivateKey, pMultiplicationBuffer))
2022#endif /* mDbgRevertKeys_d */
2023 {
2024 result = gSecError_c;
2025 break;
2026 }
2027 else
2028 {
2029 result = gSecSuccess_c;
2030#if (defined(mDbgRevertKeys_d) && (mDbgRevertKeys_d > 0))
2031 FLib_MemCpyReverseOrder(pOutPublicKey->components_8bit.x, mReversedPublicKey.components_8bit.x, 32);
2032 FLib_MemCpyReverseOrder(pOutPublicKey->components_8bit.y, mReversedPublicKey.components_8bit.y, 32);
2033 FLib_MemCpyReverseOrder(pOutPrivateKey->raw_8bit, mReversedPrivateKey.raw_8bit, 32);
2034#endif /* mDbgRevertKeys_d */
2035 result = gSecSuccess_c;
2036
2037 (void)MEM_BufferFree(pMultiplicationBuffer);
2038 }
2039#else
2040 ecp256KeyPair_t KeyPair;
2041 if (gSecEcp256Success_c != ECP256_GenerateKeyPairUltraFast(&KeyPair.public_key, &KeyPair.private_key))
2042 {
2043 result = gSecError_c;
2044 break;
2045 }
2046
2047 result = gSecSuccess_c;
2048 /* The NCCL output is BE and BLE expected LE */
2049 ECP256_PointCopy_and_change_endianness((uint8_t *)pOutPublicKey, (const uint8_t *)&KeyPair.public_key);
2050 ECP256_coordinate_copy_and_change_endianness((uint8_t *)pOutPrivateKey, (const uint8_t *)&KeyPair.private_key);
2051#endif
2052#else /* gSecLibUseBleDebugKeys_d */
2053 /* The NCCL output is BE and BLE expected LE */
2054 ECP256_PointCopy_and_change_endianness((uint8_t *)pOutPublicKey, (const uint8_t *)&mBleDebugKeyPair.public_key);
2055 ECP256_coordinate_copy_and_change_endianness((uint8_t *)pOutPrivateKey,
2056 (const uint8_t *)&mBleDebugKeyPair.private_key);
2057 result = gSecSuccess_c;
2058#endif /* gSecLibUseBleDebugKeys_d */
2059 } while (false);
2060 return result;
2061}
2062
2063/************************************************************************************
2064 * \brief Generates a new ECDH P256 Private/Public key pair. This function starts the
2065 * ECDH generate procedure. The pDhKeyData must be allocated and kept
2066 * allocated for the time of the computation procedure.
2067 * When the result is gSecResultPending_c the memory should be kept until the
2068 * last step.
2069 * In any other result messages the data shall be cleared after this call.
2070 *
2071 * \param[in] pDhKeyData Pointer to the structure holding information about the
2072 * multiplication
2073 *
2074 * \return gSecSuccess_c, gSecResultPending_c or error
2075 *
2076 ************************************************************************************/
2077secResultType_t ECDH_P256_GenerateKeysSeg(computeDhKeyParam_t *pDhKeyData)
2078{
2079 secResultType_t result;
2080
2081 do
2082 {
2083 if (pDhKeyData == NULL)
2084 {
2085 RAISE_ERROR(result, gSecBadArgument_c);
2086 }
2087 /* The callback is NULL when there is no async ECDH */
2088 if (pfSecLibMultCallback == NULL)
2089 {
2090 result = ECDH_P256_GenerateKeys(&pDhKeyData->outPoint, &pDhKeyData->privateKey);
2091 }
2092 else
2093 {
2094 void *pMultiplicationBuffer = MEM_BufferAlloc(gEcP256_MultiplicationBufferSize_c);
2095
2096 if (NULL == pMultiplicationBuffer)
2097 {
2098 RAISE_ERROR(result, gSecAllocError_c);
2099 }
2100
2101 pDhKeyData->pWorkBuffer = pMultiplicationBuffer;
2102 if (gSecEcdhSuccess_c != Ecdh_GenerateNewKeysSeg(pDhKeyData))
2103 {
2104 (void)MEM_BufferFree(pDhKeyData->pWorkBuffer);
2105 pDhKeyData->pWorkBuffer = NULL;
2106 RAISE_ERROR(result, gSecError_c);
2107 }
2108 result = gSecResultPending_c;
2109 }
2110 } while (false);
2111 return result;
2112}
2113
2114/************************************************************************************
2115 * \brief Function used to create the mac key and LTK using Bluetooth F5 algorithm
2116 *
2117 * \param [out] pMacKey 128 bit MacKey output location (pointer)
2118 * \param [out] pLtk 128 bit LTK output location (pointer)
2119 * \param [in] pW 256 bit W (pointer) (DHKey)
2120 * \param [in] pN1 128 bit N1 (pointer) (Na)
2121 * \param [in] pN2 128 bit N2 (pointer) (Nb)
2122 * \param [in] a1at 8 bit A1 address type, 0 = Public, 1 = Random
2123 * \param [in] pA1 48 bit A1 (pointer) (A)
2124 * \param [in] a2at 8 bit A2 address type, 0 = Public, 1 = Random
2125 * \param [in] pA2 48 bit A2 (pointer) (B)
2126 *
2127 * \retval gSecSuccess_c operation succeeded
2128 * \retval gSecError_c operation failed
2129 ************************************************************************************/
2130secResultType_t SecLib_GenerateBluetoothF5Keys(uint8_t *pMacKey,
2131 uint8_t *pLtk,
2132 const uint8_t *pW,
2133 const uint8_t *pN1,
2134 const uint8_t *pN2,
2135 const uint8_t a1at,
2136 const uint8_t *pA1,
2137 const uint8_t a2at,
2138 const uint8_t *pA2)
2139{
2140 secResultType_t result = gSecError_c;
2141 const uint8_t f5KeyId[4] = {0x62, 0x74, 0x6c, 0x65}; /*!< Big Endian, "btle" */
2142 uint8_t f5CmacBuffer[1 + 4 + 16 + 16 + 7 + 7 + 2];
2143 /* Counter[1] || keyId[4] || N1[16] || N2[16] || A1[7] || A2[7] || Length[2] = 53 */
2144
2145 uint8_t f5T[16] = {0};
2146 const uint8_t f5Salt[16] = {0x6C, 0x88, 0x83, 0x91, 0xAA, 0xF5, 0xA5, 0x38,
2147 0x60, 0x37, 0x0B, 0xDB, 0x5A, 0x60, 0x83, 0xBE}; /*!< Big endian */
2148 do
2149 {
2150 uint8_t tempOut[16];
2151
2152 /*! Check for NULL output pointers and return with proper status if this is the case. */
2153 if ((NULL == pMacKey) || (NULL == pLtk) || (NULL == pW) || (NULL == pN1) || (NULL == pN2) || (NULL == pA1) ||
2154 (NULL == pA2))
2155 {
2156#if defined(gSmDebugEnabled_d) && (gSmDebugEnabled_d == 1U)
2157 SmDebug_Log(gSmDebugFileSmCrypto_c, __LINE__, smDebugLogTypeError_c, 0);
2158#endif /* gSmDebugEnabled_d */
2159 RAISE_ERROR(result, gSecBadArgument_c);
2160 }
2161
2162 /*! Compute the f5 function key T using the predefined salt as key for AES-128-CAMC */
2163 AES_128_CMAC_LsbFirstInput((const uint8_t *)pW, 32, (const uint8_t *)f5Salt, f5T);
2164
2165 /*! Build the most significant part of the f5 input data to compute the MacKey */
2166 f5CmacBuffer[0] = 0; /* Counter = 0 */
2167 FLib_MemCpy(&f5CmacBuffer[1], (const uint8_t *)f5KeyId, 4);
2168 FLib_MemCpyReverseOrder(&f5CmacBuffer[5], (const uint8_t *)pN1, 16);
2169 FLib_MemCpyReverseOrder(&f5CmacBuffer[21], (const uint8_t *)pN2, 16);
2170 f5CmacBuffer[37] = 0x01U & a1at;
2171 FLib_MemCpyReverseOrder(&f5CmacBuffer[38], (const uint8_t *)pA1, 6);
2172 f5CmacBuffer[44] = 0x01U & a2at;
2173 FLib_MemCpyReverseOrder(&f5CmacBuffer[45], (const uint8_t *)pA2, 6);
2174 f5CmacBuffer[51] = 0x01; /* Length msB big endian = 0x01, Length = 256 */
2175 f5CmacBuffer[52] = 0x00; /* Length lsB big endian = 0x00, Length = 256 */
2176
2177 /*! Compute the MacKey into the temporary buffer. */
2178 result = SecLib_AES_128_CMAC(f5CmacBuffer, sizeof(f5CmacBuffer), f5T, tempOut);
2179 if (result != gSecSuccess_c)
2180 {
2181 break;
2182 }
2183 /*! Copy the MacKey to the output location
2184 * in reverse order. The CMAC result is generated MSB first. */
2185 FLib_MemCpyReverseOrder(pMacKey, (const uint8_t *)tempOut, 16);
2186
2187 /*! Build the least significant part of the f5 input data to compute the MacKey.
2188 * It is identical to the most significant part with the exception of the counter. */
2189 f5CmacBuffer[0] = 1; /* Counter = 1 */
2190
2191 /*! Compute the LTK into the temporary buffer. */
2192 result = SecLib_AES_128_CMAC(f5CmacBuffer, sizeof(f5CmacBuffer), f5T, tempOut);
2193 if (result != gSecSuccess_c)
2194 {
2195 break;
2196 }
2197
2198 /*! Copy the LTK to the output location
2199 * in reverse order. The CMAC result is generated MSB first. */
2200 FLib_MemCpyReverseOrder(pLtk, (const uint8_t *)tempOut, 16);
2201
2202 result = gSecSuccess_c;
2203
2204 } while (false);
2205
2206 return result;
2207}
2208
2209#if (defined(mDbgRevertKeys_d) && (mDbgRevertKeys_d > 0))
2210static ecdhDhKey_t mReversedEcdhKey;
2211#endif /* mDbgRevertKeys_d */
2212
2213secResultType_t ECDH_P256_ComputeDhKey(const ecdhPrivateKey_t *pInPrivateKey,
2214 const ecdhPublicKey_t *pInPeerPublicKey,
2215 ecdhDhKey_t *pOutDhKey,
2216 const bool_t keepBlobDhKey)
2217{
2218 secResultType_t result = gSecSuccess_c;
2219 secEcdhStatus_t ecdhStatus;
2220 NOT_USED(keepBlobDhKey);
2221 do
2222 {
2223 if ((pInPrivateKey == NULL) || (pInPeerPublicKey == NULL) || (pOutDhKey == NULL))
2224 {
2225 RAISE_ERROR(result, gSecBadArgument_c);
2226 }
2227 if (!ECP256_LePointValid(pInPeerPublicKey))
2228 {
2229 RAISE_ERROR(result, gSecInvalidPublicKey_c);
2230 }
2231#if !(defined gSecLibUseDspExtension_d && (gSecLibUseDspExtension_d == 1))
2232
2233 void *pMultiplicationBuffer = MEM_BufferAlloc(gEcP256_MultiplicationBufferSize_c);
2234 if (NULL == pMultiplicationBuffer)
2235 {
2236 RAISE_ERROR(result, gSecAllocError_c);
2237 }
2238
2239#if (defined(mDbgRevertKeys_d) && (mDbgRevertKeys_d > 0))
2240 FLib_MemCpyReverseOrder(mReversedPublicKey.components_8bit.x, pInPeerPublicKey->components_8bit.x, 32);
2241 FLib_MemCpyReverseOrder(mReversedPublicKey.components_8bit.y, pInPeerPublicKey->components_8bit.y, 32);
2242 FLib_MemCpyReverseOrder(mReversedPrivateKey.raw_8bit, pInPrivateKey->raw_8bit, 32);
2243#endif /* mDbgRevertKeys_d */
2244
2245#if (defined(mDbgRevertKeys_d) && (mDbgRevertKeys_d > 0))
2246 ecdhStatus =
2247 Ecdh_ComputeDhKey(&mReversedPrivateKey, &mReversedPublicKey, &mReversedEcdhKey, pMultiplicationBuffer);
2248#else /* !mDbgRevertKeys_d */
2249 ecdhStatus = Ecdh_ComputeDhKey(pInPrivateKey, pInPeerPublicKey, pOutDhKey, pMultiplicationBuffer);
2250#endif /* mDbgRevertKeys_d */
2251 if (gSecEcdhInvalidPublicKey_c == ecdhStatus)
2252 {
2253 RAISE_ERROR(result, gSecInvalidPublicKey_c);
2254 }
2255 else if (gSecEcdhSuccess_c != ecdhStatus)
2256 {
2257 RAISE_ERROR(result, gSecError_c);
2258 }
2259 else
2260 {
2261#if (defined(mDbgRevertKeys_d) && (mDbgRevertKeys_d > 0))
2262 FLib_MemCpyReverseOrder(pOutDhKey->components_8bit.x, mReversedEcdhKey.components_8bit.x, 32);
2263 FLib_MemCpyReverseOrder(pOutDhKey->components_8bit.y, mReversedEcdhKey.components_8bit.y, 32);
2264#endif /* mDbgRevertKeys_d */
2265 }
2266
2267 (void)MEM_BufferFree(pMultiplicationBuffer);
2268
2269#else
2270 ecp256Point_t peer_public_key;
2271 ecp256Coordinate_t self_private_key;
2272 ecp256Point_t dh_secret;
2273 ECP256_PointCopy_and_change_endianness(&peer_public_key.raw[0], (const uint8_t *)pInPeerPublicKey);
2274 ECP256_coordinate_copy_and_change_endianness(&self_private_key.raw_8bit[0], (const uint8_t *)pInPrivateKey);
2275 ecdhStatus = Ecdh_ComputeDhKeyUltraFast(&self_private_key, &peer_public_key, &dh_secret);
2276 if (ecdhStatus == gSecEcdhSuccess_c)
2277 {
2278 ECP256_PointCopy_and_change_endianness(&pOutDhKey->raw[0], (const uint8_t *)&dh_secret);
2279 }
2280 else
2281 {
2282 RAISE_ERROR(result, gSecError_c);
2283 }
2284#endif
2285 } while (false);
2286 return result;
2287}
2288
2289/************************************************************************************
2290 * \brief Checks whether a public key is valid (point is on the curve).
2291 *
2292 * \return TRUE if valid, FALSE if not
2293 *
2294 ************************************************************************************/
2295bool_t ECP256_IsKeyValid(const ecp256Point_t *pKey)
2296{
2297 bool_t ret = false;
2298
2299 if (ECP256_LePointValid(pKey))
2300 {
2301 ret = true;
2302 }
2303
2304 return ret;
2305}
2306
2307/*! *********************************************************************************
2308 * \brief This function implements the SMP ah cryptographic toolbox function which calculates the
2309 * hash part of a Resolvable Private Address.
2310 * The key is kept in plaintext.
2311 *
2312 * \param[out] pHash Pointer where the 24 bit hash value will be written.
2313 * 24 bit hash field of a Resolvable Private Address (output)
2314 *
2315 * \param[in] pKey Pointer to the 128 bit key.
2316 *
2317 * \param[in] pR Pointer to the 24 bit random value (Prand).
2318 * The most significant bits of this field must be 0b01 for Resolvable Private Addresses.
2319 *
2320 * \retval gSecSuccess_c All operations were successful.
2321 * \retval gSecError_c The call failed.
2322 *
2323 ********************************************************************************** */
2324secResultType_t SecLib_VerifyBluetoothAh(uint8_t *pHash, const uint8_t *pKey, const uint8_t *pR)
2325{
2326 secResultType_t result = gSecError_c;
2327 uint8_t tempAddrPart[16] = {0};
2328 uint8_t tempOutHash[16];
2329 uint8_t tempKey[16];
2330 do
2331 {
2332 /*! Check for NULL output pointers and return with proper status if this is the case. */
2333 if ((NULL == pHash) || (NULL == pKey) || (NULL == pR))
2334 {
2335 RAISE_ERROR(result, gSecBadArgument_c);
2336 }
2337 /* Initialize the r' value in the temporary location. 3 bytes of ramdom value.
2338 * Initialize it reversed for AES.
2339 */
2340 for (int i = 0; i < 3; i++)
2341 {
2342 tempAddrPart[15 - i] = pR[i];
2343 }
2344 /* Regular operation with plaintext key */
2345 /*! Reverse the Key and place it in a temporary location. */
2346 FLib_MemCpyReverseOrder(tempKey, (const uint8_t *)pKey, 16);
2347
2348 /*! Compute the hash. */
2349 AES_128_Encrypt(tempAddrPart, tempKey, tempOutHash);
2350
2351 /*! Copy the relevant bytes to the output. */
2352 pHash[0] = tempOutHash[15];
2353 pHash[1] = tempOutHash[14];
2354 pHash[2] = tempOutHash[13];
2355
2356 result = gSecSuccess_c;
2357
2358 } while (false);
2359
2360 return result;
2361}
2362
2363/************************************************************************************
2364 * \brief Computes the Diffie-Hellman Key for an ECDH P256 key pair. This function
2365 * starts the ECDH key pair generate procedure. The pDhKeyData must be
2366 * allocated and kept allocated for the time of the computation procedure.
2367 * When the result is gSecResultPending_c the memory should be kept until the
2368 * last step, when it can be safely freed.
2369 * In any other result messages the data shall be cleared after this call.
2370 *
2371 * \param[in] pDhKeyData Pointer to the structure holding information about the
2372 * multiplication
2373 *
2374 * \return gSecSuccess_c or error
2375 *
2376 ************************************************************************************/
2377secResultType_t ECDH_P256_ComputeDhKeySeg(computeDhKeyParam_t *pDhKeyData)
2378{
2379 secResultType_t result;
2380#if !(defined gSecLibUseDspExtension_d && (gSecLibUseDspExtension_d == 1))
2381 do
2382 {
2383 secEcdhStatus_t ecdhStatus;
2384 void *pMultiplicationBuffer;
2385
2386 if (pDhKeyData == NULL)
2387 {
2388 RAISE_ERROR(result, gSecBadArgument_c);
2389 }
2390
2391 if (pfSecLibMultCallback == NULL)
2392 {
2393 /* One shot operation */
2394 result = ECDH_P256_ComputeDhKey(&pDhKeyData->privateKey, &pDhKeyData->peerPublicKey, &pDhKeyData->outPoint,
2395 FALSE);
2396 break;
2397 }
2398
2399 pMultiplicationBuffer = MEM_BufferAlloc(gEcP256_MultiplicationBufferSize_c);
2400 if (NULL == pMultiplicationBuffer)
2401 {
2402 RAISE_ERROR(result, gSecAllocError_c);
2403 }
2404 else
2405 {
2406 pDhKeyData->pWorkBuffer = pMultiplicationBuffer;
2407 ecdhStatus = Ecdh_ComputeDhKeySeg(pDhKeyData);
2408 result = gSecResultPending_c;
2409
2410 if (gSecEcdhInvalidPublicKey_c == ecdhStatus)
2411 {
2412 result = gSecInvalidPublicKey_c;
2413 }
2414 else if (gSecEcdhSuccess_c != ecdhStatus)
2415 {
2416 result = gSecError_c;
2417 }
2418 if (result != gSecResultPending_c)
2419 {
2420 (void)MEM_BufferFree(pDhKeyData->pWorkBuffer);
2421 pDhKeyData->pWorkBuffer = NULL;
2422 }
2423 }
2424 } while (false);
2425#else
2426 result = ECDH_P256_ComputeDhKey(&pDhKeyData->privateKey, &pDhKeyData->peerPublicKey, &pDhKeyData->outPoint, FALSE);
2427#endif
2428 return result;
2429}
2430
2431#if !(defined gSecLibUseDspExtension_d && (gSecLibUseDspExtension_d == 1))
2432/************************************************************************************
2433 * \brief Handle one step of ECDH multiplication depending on the number of steps at
2434 * a time according to gSecLibEcStepsAtATime. After the last step is completed
2435 * the function returns TRUE and the upper layer is responsible for clearing
2436 * pData.
2437 *
2438 * \param[in] pData Pointer to the structure holding information about the
2439 * multiplication
2440 *
2441 * \return TRUE if the multiplication is completed
2442 * FALSE when the function needs to be called again
2443 *
2444 ************************************************************************************/
2445bool_t SecLib_HandleMultiplyStep(computeDhKeyParam_t *pData)
2446{
2447 bool_t result = FALSE;
2448 const uint8_t steps = ((255U + 1U) / gSecLibEcStepsAtATime);
2449
2450 /* Intermediate step */
2451 if (pData->procStep < steps)
2452 {
2453 /* Compute step */
2454 Ecdh_ComputeJacobiChunk(255U - (pData->procStep * gSecLibEcStepsAtATime), gSecLibEcStepsAtATime, pData);
2455 /* Go to the next step */
2456 pData->procStep++;
2457 pData->result = gSecResultPending_c;
2458 result = FALSE;
2459 }
2460 /* Final step was completed -> resume SecLib procedure */
2461 else
2462 {
2463 Ecdh_JacobiCompleteMult(pData);
2464
2465#if (defined(mDbgRevertKeys_d) && (mDbgRevertKeys_d > 0))
2466 {
2467 FLib_MemCpyReverseOrder(mReversedEcdhKey.components_8bit.x, pData->outX,
2468 sizeof(mReversedEcdhKey.components_8bit.x));
2469 FLib_MemCpyReverseOrder(mReversedEcdhKey.components_8bit.y, pData->outY,
2470 sizeof(mReversedEcdhKey.components_8bit.y));
2471 FLib_MemCpyReverseOrder(pData->outX, mReversedEcdhKey.components_8bit.x, sizeof(pData->outX));
2472 FLib_MemCpyReverseOrder(pData->outY, mReversedEcdhKey.components_8bit.y, sizeof(pData->outY));
2473 }
2474#endif /* mDbgRevertKeys_d */
2475 pData->result = gSecSuccess_c;
2476 result = TRUE;
2477 }
2478 return result;
2479}
2480#endif
2481
2482secResultType_t SecLib_GenerateBluetoothF5KeysSecure(uint8_t *pMacKey,
2483 uint8_t *pLtk,
2484 const uint8_t *pW,
2485 const uint8_t *pN1,
2486 const uint8_t *pN2,
2487 const uint8_t a1at,
2488 const uint8_t *pA1,
2489 const uint8_t a2at,
2490 const uint8_t *pA2)
2491{
2492 NOT_USED(pMacKey);
2493 NOT_USED(pLtk);
2494 NOT_USED(pW);
2495 NOT_USED(pN1);
2496 NOT_USED(pN2);
2497 NOT_USED(a1at);
2498 NOT_USED(pA1);
2499 NOT_USED(a2at);
2500 NOT_USED(pA2);
2501 return gSecError_c;
2502}
2503
2504/************************************************************************************
2505 * \brief Converts a plaintext symmetric key into a blob of blobType. Reverses key beforehand.
2506 *
2507 * \param[in] pKey Pointer to the key.
2508 *
2509 * \param[out] pBlob Pointer to the blob (shall be allocated, 40 or 16, depending on blobType)
2510 *
2511 * \param[in] blobType Blob type.
2512 *
2513 * \return gSecSuccess_c or error
2514 *
2515 ************************************************************************************/
2516secResultType_t SecLib_ObfuscateKeySecure(const uint8_t *pKey, uint8_t *pBlob, const uint8_t blobType)
2517{
2518 NOT_USED(pKey);
2519 NOT_USED(pBlob);
2520 NOT_USED(blobType);
2521 return gSecError_c;
2522}
2523
2524/************************************************************************************
2525 * \brief Converts a blob of a symmetric key into the plaintext. Reverses key afterwards.
2526 *
2527 * \param[in] pBlob Pointer to the blob.
2528 *
2529 * \param[out] pKey Pointer to the key.
2530 *
2531 * \return gSecSuccess_c or error
2532 *
2533 ************************************************************************************/
2534secResultType_t SecLib_DeobfuscateKeySecure(const uint8_t *pBlob, uint8_t *pKey)
2535{
2536 NOT_USED(pBlob);
2537 NOT_USED(pKey);
2538 return gSecError_c;
2539}
2540
2541/************************************************************************************
2542 * \brief Function used to derive the Bluetooth SKD used in LL encryption.
2543 * Available on EdgeLock (SSS only)
2544 *
2545 * \param [in] pInSKD pointer to the received SKD (16-byte array)
2546 * \param [in] pLtkBlob pointer to the blob (40-byte array)
2547 * \param [in] bOpenKey if TRUE sends derived key to NBU
2548 * \param [out] pOutSKD pointer to the resulted SKD (16-byte array)
2549 *
2550 * \retval gSecSuccess_c operation succeeded
2551 * \retval gSecError_c operation failed / not implemented
2552 ************************************************************************************/
2553secResultType_t SecLib_DeriveBluetoothSKDSecure(const uint8_t *pInSKD,
2554 const uint8_t *pLtkBlob,
2555 bool_t bOpenKey,
2556 uint8_t *pOutSKD)
2557{
2558 NOT_USED(pInSKD);
2559 NOT_USED(pLtkBlob);
2560 NOT_USED(bOpenKey);
2561 NOT_USED(pOutSKD);
2562
2563 return gSecError_c;
2564}
2565
2566secResultType_t SecLib_GenerateSymmetricKey(const uint32_t keySize, const bool_t blobOutput, void *pOut)
2567{
2568 NOT_USED(keySize);
2569 NOT_USED(blobOutput);
2570 NOT_USED(pOut);
2571 return gSecError_c;
2572}
2573
2574secResultType_t SecLib_GenerateBluetoothEIRKBlobSecure(const void *pIRK,
2575 const bool_t blobInput,
2576 const bool_t generateDKeyIRK,
2577 uint8_t *pOutEIRKblob)
2578{
2579 NOT_USED(pIRK);
2580 NOT_USED(blobInput);
2581 NOT_USED(generateDKeyIRK);
2582 NOT_USED(pOutEIRKblob);
2583 return gSecError_c;
2584}
2585secResultType_t ECDH_P256_ComputeA2BKeySecure(const ecdhPublicKey_t *pInPeerPublicKey, ecdhDhKey_t *pOutE2EKey)
2586{
2587 NOT_USED(pInPeerPublicKey);
2588 NOT_USED(pOutE2EKey);
2589 return gSecError_c;
2590}
2591
2592secResultType_t SecLib_ExportA2BBlobSecure(const void *pKey, const secInputKeyType_t keyType, uint8_t *pOutKey)
2593{
2594 NOT_USED(pKey);
2595 NOT_USED(keyType);
2596 NOT_USED(pOutKey);
2597 return gSecError_c;
2598}
2599
2600void ECDH_P256_FreeDhKeyDataSecure(computeDhKeyParam_t *pDhKeyData)
2601{
2602 NOT_USED(pDhKeyData);
2603}
2604
2605secResultType_t SecLib_ImportA2BBlobSecure(const uint8_t *pKey, const secInputKeyType_t keyType, uint8_t *pOutKey)
2606{
2607 NOT_USED(pKey);
2608 NOT_USED(keyType);
2609 NOT_USED(pOutKey);
2610 return gSecError_c;
2611}
2612
2613secResultType_t ECDH_P256_FreeE2EKeyDataSecure(ecdhDhKey_t *pE2EKeyData)
2614{
2615 NOT_USED(pE2EKeyData);
2616 return gSecError_c;
2617}
2618
2619secResultType_t SecLib_VerifyBluetoothAhSecure(uint8_t *pHash, const uint8_t *pKey, const uint8_t *pR)
2620{
2621 NOT_USED(pHash);
2622 NOT_USED(pKey);
2623 NOT_USED(pR);
2624 return gSecError_c;
2625}
2626
2627/*! *********************************************************************************
2628*************************************************************************************
2629* Private functions
2630*************************************************************************************
2631********************************************************************************** */
2632
2633/*! *********************************************************************************
2634 * \brief This function performs SHA256 on multiple blocks
2635 *
2636 * \param [in] pData Pointer to the input data
2637 * \param [in] nBlk Number of SHA256 blocks to hash
2638 * \param [in] context Pointer to the SHA256 context data
2639 *
2640 ********************************************************************************** */
2641static void SHA256_hash_n(const uint8_t *pData, uint32_t nBlk, uint32_t *pHash)
2642{
2643 if (nBlk < (UINT32_MAX / SHA256_BLOCK_SIZE))
2644 {
2645#if (defined(FSL_FEATURE_SOC_MMCAU_COUNT) && (FSL_FEATURE_SOC_MMCAU_COUNT > 0))
2646 SECLIB_MUTEX_LOCK();
2647 mmcau_sha256_hash_n(pData, nBlk, (unsigned int *)pHash);
2648 SECLIB_MUTEX_UNLOCK();
2649#else
2650 sw_sha256_hash_n(pData, nBlk, pHash);
2651#endif
2652 }
2653 else
2654 {
2655 assert(0);
2656 }
2657}
2658
2659#if (defined FSL_FEATURE_SOC_AES_HW && (FSL_FEATURE_SOC_AES_HW > 0))
2660/*! *********************************************************************************
2661 * \brief This function performs hardware AES-128 ECB encryption
2662 *
2663 * \param [in] ECB_p Pointer to AES parameter structure
2664 *
2665 ********************************************************************************** */
2666static void AES_128_ECB_Enc_HW(AES_param_t *ECB_p)
2667{
2668 uint8_t tempBuffIn[AES_BLOCK_SIZE] = {0};
2669 uint8_t tempBuffOut[AES_BLOCK_SIZE] = {0};
2670
2671 /* If remaining data bigger than one AES block size */
2672 while (ECB_p->Len > AES_BLOCK_SIZE)
2673 {
2674 AES_128_Encrypt(ECB_p->pPlain, ECB_p->Key, ECB_p->pCipher);
2675 ECB_p->pPlain += AES_BLOCK_SIZE;
2676 ECB_p->pCipher += AES_BLOCK_SIZE;
2677 ECB_p->Len -= AES_BLOCK_SIZE;
2678 }
2679
2680 /* If remaining data is smaller then one AES block size */
2681 FLib_MemCpy(tempBuffIn, ECB_p->pPlain, ECB_p->Len);
2682 AES_128_Encrypt(tempBuffIn, ECB_p->Key, tempBuffOut);
2683 FLib_MemCpy(ECB_p->pCipher, tempBuffOut, AES_BLOCK_SIZE);
2684#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
2685 AESM_Complete(AES128ECB_Enc_Id);
2686#endif
2687}
2688
2689/*! *********************************************************************************
2690 * \brief This function performs hardware AES-128 ECB decryption
2691 *
2692 * \param [in] ECB_p Pointer to AES parameter structure
2693 *
2694 ********************************************************************************** */
2695static void AES_128_ECB_Dec_HW(AES_param_t *ECB_p)
2696{
2697 uint8_t tempBuffIn[AES_BLOCK_SIZE] = {0};
2698 uint8_t tempBuffOut[AES_BLOCK_SIZE] = {0};
2699
2700 /* If remaining data bigger than one AES block size */
2701 while (ECB_p->Len > AES_BLOCK_SIZE)
2702 {
2703 AES_128_Decrypt(ECB_p->pCipher, ECB_p->Key, ECB_p->pPlain);
2704 ECB_p->pPlain += AES_BLOCK_SIZE;
2705 ECB_p->pCipher += AES_BLOCK_SIZE;
2706 ECB_p->Len -= AES_BLOCK_SIZE;
2707 }
2708
2709 /* If remaining data is smaller then one AES block size */
2710 FLib_MemCpy(tempBuffIn, ECB_p->pCipher, ECB_p->Len);
2711 AES_128_Decrypt(tempBuffIn, ECB_p->Key, tempBuffOut);
2712 FLib_MemCpy(ECB_p->pPlain, tempBuffOut, ECB_p->Len);
2713#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
2714 AESM_Complete(AES128ECB_Dec_Id);
2715#endif /* USE_TASK_FOR_HW_AES */
2716}
2717
2718/*! *********************************************************************************
2719 * \brief This function performs hardware AES-128 ECB block encryption
2720 *
2721 * \param [in] ECB_p Pointer to AES parameter structure
2722 *
2723 ********************************************************************************** */
2724static void AES_128_ECB_Block_Enc_HW(AES_param_t *ECBB_p)
2725{
2726 while (ECBB_p->Blocks > 0u)
2727 {
2728 AES_128_Encrypt(ECBB_p->pPlain, ECBB_p->Key, ECBB_p->pCipher);
2729 ECBB_p->Blocks--;
2730 ECBB_p->pPlain += AES_BLOCK_SIZE;
2731 ECBB_p->pCipher += AES_BLOCK_SIZE;
2732 }
2733#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
2734 AESM_Complete(AES128ECBB_Enc_Id);
2735#endif
2736}
2737
2738/*! *********************************************************************************
2739 * \brief This function performs hardware AES-128 ECB block decryption
2740 *
2741 * \param [in] ECB_p Pointer to AES parameter structure
2742 *
2743 ********************************************************************************** */
2744static void AES_128_ECB_Block_Dec_HW(AES_param_t *ECBB_p)
2745{
2746 while (ECBB_p->Blocks > 0u)
2747 {
2748 AES_128_Decrypt(ECBB_p->pCipher, ECBB_p->Key, ECBB_p->pPlain);
2749 ECBB_p->Blocks--;
2750 ECBB_p->pPlain += AES_BLOCK_SIZE;
2751 ECBB_p->pCipher += AES_BLOCK_SIZE;
2752 }
2753#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
2754 AESM_Complete(AES128ECBB_Dec_Id);
2755#endif
2756}
2757
2758/*! *********************************************************************************
2759 * \brief This function performs hardware AES-128 CTR encryption
2760 *
2761 * \param [in] CTR_p Pointer to AES parameter structure
2762 *
2763 ********************************************************************************** */
2764static void AES_128_CTR_Enc_HW(AES_param_t *CTR_p)
2765{
2766 uint8_t tempBuffIn[AES_BLOCK_SIZE] = {0};
2767 uint8_t encrCtr[AES_BLOCK_SIZE] = {0};
2768
2769 /* If remaining data bigger than one AES block size */
2770 while (CTR_p->Len > AES_BLOCK_SIZE)
2771 {
2772 FLib_MemCpy(tempBuffIn, CTR_p->pPlain, AES_BLOCK_SIZE);
2773 AES_128_Encrypt(CTR_p->CTR_counter, CTR_p->Key, encrCtr);
2774 SecLib_XorN(tempBuffIn, encrCtr, AES_BLOCK_SIZE);
2775 FLib_MemCpy(CTR_p->pCipher, tempBuffIn, AES_BLOCK_SIZE);
2776 CTR_p->pPlain += AES_BLOCK_SIZE;
2777 CTR_p->pCipher += AES_BLOCK_SIZE;
2778 CTR_p->Len -= AES_BLOCK_SIZE;
2779 AES_128_IncrementCounter(CTR_p->CTR_counter);
2780 }
2781
2782 /* If remaining data is smaller then one AES block size */
2783 FLib_MemCpy(tempBuffIn, CTR_p->pPlain, CTR_p->Len);
2784 SecLib_AES_128_Encrypt(CTR_p->CTR_counter, CTR_p->Key, encrCtr);
2785 SecLib_XorN(tempBuffIn, encrCtr, AES_BLOCK_SIZE);
2786 FLib_MemCpy(CTR_p->pCipher, tempBuffIn, CTR_p->Len);
2787 AES_128_IncrementCounter(CTR_p->CTR_counter);
2788#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
2789 AESM_Complete(AES128CTR_Enc_Id);
2790#endif
2791}
2792
2793/*! *********************************************************************************
2794 * \brief This function performs hardware AES-128 CTR decryption
2795 *
2796 * \param [in] CTR_p Pointer to AES parameter structure
2797 *
2798 ********************************************************************************** */
2799static void AES_128_CTR_Dec_HW(AES_param_t *CTR_p)
2800{
2801 uint8_t tempBuffIn[AES_BLOCK_SIZE] = {0};
2802 uint8_t encrCtr[AES_BLOCK_SIZE] = {0};
2803
2804 /* If remaining data bigger than one AES block size */
2805 while (CTR_p->Len > AES_BLOCK_SIZE)
2806 {
2807 FLib_MemCpy(tempBuffIn, CTR_p->pCipher, AES_BLOCK_SIZE);
2808 AES_128_Encrypt(CTR_p->CTR_counter, CTR_p->Key, encrCtr);
2809 SecLib_XorN(tempBuffIn, encrCtr, AES_BLOCK_SIZE);
2810 FLib_MemCpy(CTR_p->pPlain, tempBuffIn, AES_BLOCK_SIZE);
2811 CTR_p->pPlain += AES_BLOCK_SIZE;
2812 CTR_p->pCipher += AES_BLOCK_SIZE;
2813 CTR_p->Len -= AES_BLOCK_SIZE;
2814 AES_128_IncrementCounter(CTR_p->CTR_counter);
2815 }
2816
2817 /* If remaining data is smaller then one AES block size */
2818 FLib_MemCpy(tempBuffIn, CTR_p->pCipher, CTR_p->Len);
2819 SecLib_AES_128_Encrypt(CTR_p->CTR_counter, CTR_p->Key, encrCtr);
2820 SecLib_XorN(tempBuffIn, encrCtr, AES_BLOCK_SIZE);
2821 FLib_MemCpy(CTR_p->pPlain, tempBuffIn, CTR_p->Len);
2822 AES_128_IncrementCounter(CTR_p->CTR_counter);
2823#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
2824 AESM_Complete(AES128CTR_Dec_Id);
2825#endif
2826}
2827
2828/*! *********************************************************************************
2829 * \brief This function performs hardware AES-128 CMAC encryption
2830 *
2831 * \param [in] CMAC_p Pointer to AES parameter structure
2832 *
2833 ********************************************************************************** */
2834static void AES_128_CMAC_HW(AES_param_t *CMAC_p)
2835{
2836 uint8_t X[16];
2837 uint8_t Y[16];
2838 uint8_t M_last[16] = {0};
2839 uint8_t padded[16] = {0};
2840
2841 uint8_t K1[16] = {0};
2842 uint8_t K2[16] = {0};
2843
2844 uint8_t n;
2845 uint32_t i;
2846 uint8_t flag;
2847 uint8_t n;
2848 uint8_t residual_len;
2849
2850 AES_128_CMAC_Generate_Subkey(CMAC_p->Key, K1, K2);
2851
2852 n = (uint8_t)((CMAC_p->Len + (AES_BLOCK_SIZE - 1u)) / AES_BLOCK_SIZE); /* n is number of rounds */
2853 residual_len = (uint8_t)(AES_PARTIAL_BLOCK_BYTES(CMAC_p->Len));
2854
2855 if (n == 0u)
2856 {
2857 n = 1u;
2858 flag = 0u;
2859 }
2860 else
2861 {
2862 if (residual_len == 0u)
2863 { /* last block is a complete block */
2864 flag = 1u;
2865 }
2866 else
2867 { /* last block is not complete block */
2868 flag = 0u;
2869 }
2870 }
2871
2872 /* Process the last block - the last part the MSB first input data */
2873 if (flag > 0u)
2874 { /* last block is complete block */
2875 SecLib_Xor128(&CMAC_p->pPlain[16u * (n - 1u)], K1, M_last);
2876 }
2877 else
2878 {
2879 (void)SecLib_Padding(&CMAC_p->pPlain[AES_BLOCK_SIZE * (n - 1u)], padded, residual_len);
2880 SecLib_Xor128(padded, K2, M_last);
2881 }
2882
2883 for (i = 0u; i < 16u; i++)
2884 {
2885 X[i] = 0u;
2886 }
2887
2888 for (i = 0u; i < n - 1u; i++)
2889 {
2890 SecLib_Xor128(X, &CMAC_p->pPlain[AES_BLOCK_SIZE * i], Y); /* Y := Mi (+) X */
2891 AES_128_Encrypt(Y, CMAC_p->Key, X); /* X := AES-128(KEY, Y) */
2892 }
2893
2894 SecLib_Xor128(X, M_last, Y);
2895 AES_128_Encrypt(Y, CMAC_p->Key, X);
2896
2897 for (i = 0u; i < 16u; i++)
2898 {
2899 CMAC_p->pCipher[i] = X[i];
2900 }
2901#if (defined(USE_TASK_FOR_HW_AES) && (USE_TASK_FOR_HW_AES > 0))
2902 AESM_Complete(AES128CMAC_Id);
2903#endif
2904}
2905
2906#endif /* FSL_FEATURE_SOC_AES_HW */
2907
2908/*! *********************************************************************************
2909 * \brief This function pads an incomplete 16 byte block of data, where padding is
2910 * the concatenation of x and a single '1',
2911 * followed by the minimum number of '0's, so that the total length is equal to 128 bits.
2912 * Padding scheme is ISO/IEC 7816-4: one 80h byte (1 bit), followed by as many 00h as
2913 * required to fill a 128 bit block.
2914 *
2915 * \param[in, out] lastb Pointer to the last block of message to be padded
2916 *
2917 * \param[in] pad_block Padded block destination
2918 *
2919 * \param[in] length Number of message bytes in the block to be padded : must be in [0..AES_BLOCK_SIZE-1]
2920 *
2921 * \return length of padding [1..AES_BLOCK_SIZE] if ok, 0 otherwise
2922 *
2923 ********************************************************************************** */
2924static uint8_t SecLib_Padding(const uint8_t *lastb, uint8_t pad_block[AES_BLOCK_SIZE], uint8_t length)
2925{
2926 uint8_t padding_sz = 0;
2927 uint32_t j;
2928 if (length < AES_BLOCK_SIZE)
2929 {
2930 for (j = 0u; j < AES_BLOCK_SIZE; j++)
2931 {
2932 /* there may be 0 bytes to copy if message was a multiple of AES_BLOCK_SIZE */
2933 if (j < length)
2934 {
2935 /* original last block */
2936 pad_block[j] = lastb[j];
2937 }
2938 else if (j == length)
2939 {
2940 pad_block[j] = 0x80u;
2941 }
2942 else
2943 {
2944 pad_block[j] = 0x00u;
2945 }
2946 }
2947 padding_sz = AES_BLOCK_SIZE - length;
2948 }
2949 return padding_sz;
2950}
2951/*! *********************************************************************************
2952 * \brief This function removes padding from an octet string (at most 16 bytes of data).
2953 *
2954 * \param[in] pIn Pointer to start of last AES block of a message to be depadded
2955 *
2956 * \return if > 0 Final size of padding to be removed : must be in [1..AES_BLOCK_SIZE].
2957 * if 0 : error occurred the last block does not contain expected padding patter.
2958 *
2959 ********************************************************************************** */
2960static uint8_t SecLib_DePadding(const uint8_t pad_block[AES_BLOCK_SIZE])
2961{
2962 uint8_t padding_sz = 0u;
2963
2964 for (uint8_t i = AES_BLOCK_SIZE; i > 0u; i--)
2965 {
2966 uint8_t ch = pad_block[i - 1u];
2967 if (ch == 0x80u)
2968 {
2969 padding_sz = AES_BLOCK_SIZE - i + 1u;
2970 break;
2971 }
2972 else if (ch != 0x00u)
2973 {
2974 /* not padding */
2975 padding_sz = 0u;
2976 break;
2977 }
2978 else
2979 {
2980 /* MISRA rule 15.7 but useless */
2981 continue;
2982 }
2983 }
2984 return padding_sz;
2985}
2986
2987/*! *********************************************************************************
2988 * \brief This function Xors 2 blocks of 128 bits and copies the result to a set destination
2989 *
2990 * \param [in] a Pointer to the first block to XOR
2991 *
2992 * \param [in] b Pointer to the second block to XOR.
2993 *
2994 * \param [out] out Destination pointer
2995 *
2996 * \remarks This is public open source code! Terms of use must be checked before use!
2997 *
2998 ********************************************************************************** */
2999static void SecLib_Xor128(const uint8_t *a, const uint8_t *b, uint8_t *out)
3000{
3001 uint32_t i;
3002
3003 for (i = 0u; i < AES_BLOCK_SIZE; i++)
3004 {
3005 out[i] = a[i] ^ b[i];
3006 }
3007}
3008/*! *********************************************************************************
3009*************************************************************************************
3010* Private functions
3011*************************************************************************************
3012********************************************************************************** */
3013
3014#if (!defined(FSL_FEATURE_SOC_LTC_COUNT) || (FSL_FEATURE_SOC_LTC_COUNT == 0))
3015/*! *********************************************************************************
3016 * \brief Increments the value of a given counter vector.
3017 *
3018 * \param [in,out] ctr Counter.
3019 *
3020 * \remarks used for AES CTR
3021 *
3022 ********************************************************************************** */
3023static void AES_128_IncrementCounter(uint8_t *ctr)
3024{
3025 uint32_t i;
3026 uint64_t tempLow;
3027 uuint128_t tempCtr;
3028
3029 for (i = 0u; i < AES_BLOCK_SIZE; i++)
3030 {
3031 tempCtr.u8[AES_BLOCK_SIZE - i - 1u] = ctr[i];
3032 }
3033
3034 tempLow = tempCtr.u64[0];
3035 tempCtr.u64[0]++;
3036
3037 if (tempLow > tempCtr.u64[0])
3038 {
3039 tempCtr.u64[1]++;
3040 }
3041
3042 for (i = 0u; i < AES_BLOCK_SIZE; i++)
3043 {
3044 ctr[i] = tempCtr.u8[AES_BLOCK_SIZE - i - 1u];
3045 }
3046}
3047#endif /* !(FSL_FEATURE_SOC_LTC_COUNT) */
3048
3049/*! *********************************************************************************
3050 * \brief Generates the two subkeys that correspond to an AES key
3051 *
3052 * \param [in] key AES Key.
3053 *
3054 * \param [out] K1 First subkey.
3055 *
3056 * \param [out] K2 Second subkey.
3057 *
3058 * \remarks This is public open source code! Terms of use must be checked before use!
3059 *
3060 ********************************************************************************** */
3061static void AES_128_CMAC_Generate_Subkey(const uint8_t *key, uint8_t *K1, uint8_t *K2)
3062{
3063 uint8_t const_Rb[16] = {0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
3064 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x87u};
3065 uint8_t L[16];
3066 uint8_t Z[16];
3067 uint8_t tmp[16] = {0};
3068 uint32_t i;
3069
3070 for (i = 0u; i < 16u; i++)
3071 {
3072 Z[i] = 0u;
3073 }
3074
3075 AES_128_Encrypt(Z, key, L);
3076
3077 if ((L[0] & 0x80u) == 0u)
3078 {
3079 /* If MSB(L) = 0, then K1 = L << 1 */
3080 SecLib_LeftShiftOneBit(L, K1);
3081 }
3082 else
3083 {
3084 /* Else K1 = ( L << 1 ) (+) Rb */
3085 SecLib_LeftShiftOneBit(L, tmp);
3086 SecLib_Xor128(tmp, const_Rb, K1);
3087 }
3088
3089 if ((K1[0] & 0x80u) == 0u)
3090 {
3091 SecLib_LeftShiftOneBit(K1, K2);
3092 }
3093 else
3094 {
3095 SecLib_LeftShiftOneBit(K1, tmp);
3096 SecLib_Xor128(tmp, const_Rb, K2);
3097 }
3098}
3099
3100/*! *********************************************************************************
3101 * \brief Shifts a given vector to the left with one bit.
3102 *
3103 * \param [in] input Input vector.
3104 *
3105 * \param [out] output Output vector.
3106 *
3107 * \remarks This is public open source code! Terms of use must be checked before use!
3108 *
3109 ********************************************************************************** */
3110static void SecLib_LeftShiftOneBit(uint8_t *input, uint8_t *output)
3111{
3112 int32_t i;
3113 uint8_t overflow = 0u;
3114
3115 for (i = 15; i >= 0; i--)
3116 {
3117 output[i] = input[i] << 1u;
3118 output[i] |= overflow;
3119 overflow = ((input[i] & 0x80u) > 0u) ? 1u : 0u;
3120 }
3121}