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