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