MCUXpresso SDK Documentation

middleware/wireless/framework/services/SecLib_RNG/SecLib.c

middleware/wireless/framework/services/SecLib_RNG/SecLib.c#

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