/* * Copyright 2020 - 2021,2024 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * */ #include #include "fusemap.h" #include "fsl_loader_utils.h" #include "life_cycle.h" #include "fsl_ocotp.h" /******************************************************************************* * Definitions ******************************************************************************/ #define NBOOT_HAL_PRINTF(...) /******************************************************************************* * Prototype ******************************************************************************/ /*! * @brief Get the root security parameters. * * Read the root security configurations from OTP. * * @param context NBOOT context. * @param parms Root security parameters. * @retval kStatus_NBOOT_Fail Operate successfully. * @retval kStatus_NBOOT_InvalidArgument Invalid values of the parms * @retval kStatus_NBOOT_Fail Failed to operate. */ static fsl_nboot_status_t nboot_hal_get_root_auth_parms(fsl_nboot_context_t *context, fsl_nboot_rot_auth_parms_t *parms); /*! * @brief Get the ROTK revoke settings. * * Read the OTP_ROTK_REVOKE. * * @param rotkRevoke ROTK revoke state. * @param rotkCnt ROTK count. * @retval kStatus_NBOOT_Fail Operate successfully. * @retval kStatus_NBOOT_Fail Failed to operate. */ static inline fsl_nboot_status_t nboot_hal_get_rotk_revoke(fsl_nboot_root_key_revocation_t *rotkRevoke, uint32_t rotkCnt); /*! * @brief Get the ROTKH. * * Read the IFR_ROTKH. * * @param rotkh ROTKH value. * @param rotkhSize ROTKH size in bytes. * @retval kStatus_NBOOT_Fail Operate successfully. * @retval kStatus_NBOOT_Fail Failed to operate. */ static fsl_nboot_status_t nboot_hal_get_rotkh(uint32_t *rotkh, uint32_t rotkhSize); /*! * @brief Get the type of the root keys. * * Get the root key type * * @param rootKeyType Type of the root keys. * @retval kStatus_NBOOT_Fail Operate successfully. * @retval kStatus_NBOOT_Fail Failed to operate. */ static inline fsl_nboot_status_t nboot_hal_get_root_key_type(fsl_nboot_root_key_type_and_length_t *rootKeyType); /*! * @brief Get the Part Common Key(PCK). * * Read the IFR_PCK_BLOB. * * @param pckBlob PCK blob. * @param pckBlobSize PCK blob size in byte. * @retval kStatus_NBOOT_Fail Operate successfully. * @retval kStatus_NBOOT_Fail Failed to operate. */ static inline fsl_nboot_status_t nboot_hal_get_pck_blob(uint8_t *pckBlob, uint32_t pckBlobSize); /******************************************************************************* * Codes ******************************************************************************/ static inline uint32_t set_antipole(uint32_t value) { return (value & 0xFFFFu) | (~(value & 0xFFFFu) << 16); } static fsl_nboot_status_t nboot_hal_get_root_auth_parms(fsl_nboot_context_t *context, fsl_nboot_rot_auth_parms_t *parms) { if ((NULL == context) || (NULL == parms)) { return kStatus_NBOOT_InvalidArgument; } fsl_nboot_status_t status = kStatus_NBOOT_Fail; do { status = nboot_hal_get_rotk_revoke(&parms->soc_rootKeyRevocation[0], sizeof(parms->soc_rootKeyRevocation) / sizeof(parms->soc_rootKeyRevocation[0])); if (status != kStatus_NBOOT_Success) { break; } status = nboot_hal_get_rotkh(&parms->soc_rkh[0], sizeof(parms->soc_rkh)); if (status != kStatus_NBOOT_Success) { break; } parms->soc_numberOfRootKeys = 0u; parms->soc_rootKeyUsage[1] = kNBOOT_RootKeyUsage_Unused; parms->soc_rootKeyUsage[2] = kNBOOT_RootKeyUsage_Unused; parms->soc_rootKeyUsage[3] = kNBOOT_RootKeyUsage_Unused; for (size_t i = 0; i < (sizeof(parms->soc_rootKeyUsage) / sizeof(parms->soc_rootKeyUsage[0])); i++) { if ((parms->soc_rootKeyUsage[i] & OTP_ROTK0_USAGE_FUSE_MASK) != kNBOOT_RootKeyUsage_Unused) { parms->soc_numberOfRootKeys++; } } status = nboot_hal_get_root_key_type(&parms->soc_rootKeyTypeAndLength); if (status != kStatus_NBOOT_Success) { break; } parms->soc_lifecycle = (fsl_nboot_soc_lifecycle_t)set_antipole(get_lifecycle_state()); status = kStatus_NBOOT_Success; } while (false); if (status != kStatus_NBOOT_Success) { (void)memset(parms, 0, sizeof(*parms)); } return status; } static inline fsl_nboot_status_t nboot_hal_get_rotk_revoke(fsl_nboot_root_key_revocation_t *rotkRevoke, uint32_t rotkCnt) { /* No need to check the input arguments for this inline functions. */ assert(rotkRevoke); assert(rotkCnt == NBOOT_ROOT_CERT_COUNT); /* Set all root key to 'revoked' state */ for (uint32_t i = 0u; i < rotkCnt; i++) { rotkRevoke[i] = kNBOOT_RootKey_Enabled; } return kStatus_NBOOT_Success; } static fsl_nboot_status_t nboot_hal_get_rotkh(uint32_t *rotkh, uint32_t rotkhSize) { /* No need to check the input arguments for this inline functions. */ assert(rotkh); assert(rotkhSize == (uint32_t)NBOOT_ROOT_ROTKH_SIZE_IN_BYTE); fsl_nboot_status_t status = kStatus_NBOOT_Success; /* root key hash fixed in Flash memory */ #ifdef USE_ENG_CERTIFICATE rotkh[0] = 0xd0cfb419U; rotkh[1] = 0x4037ee3cU; rotkh[2] = 0xde74393eU; rotkh[3] = 0x0156d0a3U; rotkh[4] = 0x373b8677U; rotkh[5] = 0x6b6aee3dU; rotkh[6] = 0x619b459eU; rotkh[7] = 0xfa33f31dU; rotkh[8] = 0x00000000U; rotkh[9] = 0x00000000U; rotkh[10] = 0x00000000U; rotkh[11] = 0x00000000U; #else if ((get_chip_revision() == 0U)) { rotkh[0] = 0x60DFBEE6U; rotkh[1] = 0x8799305FU; rotkh[2] = 0xBA9E4AE6U; rotkh[3] = 0x1908394FU; rotkh[4] = 0x7AC4F934U; rotkh[5] = 0xEF76BF41U; rotkh[6] = 0x2E27796EU; rotkh[7] = 0x94DB19A0U; rotkh[8] = 0x00000000U; rotkh[9] = 0x00000000U; rotkh[10] = 0x00000000U; rotkh[11] = 0x00000000U; } else if ((get_chip_revision() == 1U)) { rotkh[0] = 0x9C758C58U; rotkh[1] = 0x0A5CCEAAU; rotkh[2] = 0x850DAD41U; rotkh[3] = 0x1371EEBAU; rotkh[4] = 0xB7874851U; rotkh[5] = 0x53C5BA44U; rotkh[6] = 0xF236F964U; rotkh[7] = 0x3320ECDFU; rotkh[8] = 0x00000000U; rotkh[9] = 0x00000000U; rotkh[10] = 0x00000000U; rotkh[11] = 0x00000000U; } else if ((get_chip_revision() == 2U)) { rotkh[0] = 0xE7C7E9BBU; rotkh[1] = 0x12C8C535U; rotkh[2] = 0x37E61148U; rotkh[3] = 0x2BE7F18CU; rotkh[4] = 0x8F0E3094U; rotkh[5] = 0xB2BA7F32U; rotkh[6] = 0xEC9B4ECBU; rotkh[7] = 0xAD9FC941U; rotkh[8] = 0x00000000U; rotkh[9] = 0x00000000U; rotkh[10] = 0x00000000U; rotkh[11] = 0x00000000U; } else { ; /* none to do */ } #endif return status; } static inline fsl_nboot_status_t nboot_hal_get_root_key_type(fsl_nboot_root_key_type_and_length_t *rootKeyType) { /* No need to check the input arguments for this inline functions. */ assert(rootKeyType); *rootKeyType = kNBOOT_RootKey_Ecdsa_P256; return kStatus_NBOOT_Success; } static inline fsl_nboot_status_t nboot_hal_get_pck_blob(uint8_t *pckBlob, uint32_t pckBlobSize) { /* No need to check the input arguments for this inline functions. */ assert(pckBlob); assert(pckBlobSize == (uint32_t)NBOOT_PCK_BLOB_SIZE_IN_BYTE); fsl_nboot_status_t status = kStatus_NBOOT_Fail; status_t otpStatus = kStatus_Fail; do { uint32_t fuseIdxStart = OTP_NXP_WIFI_SK_MK_31_0_FUSE_IDX; for (int i = 0; i < (NBOOT_PCK_BLOB_SIZE_IN_BYTE / 4); i++) { otpStatus = OCOTP_OtpFuseRead(fuseIdxStart, (uint32_t *)(&pckBlob[4 * i])); if (otpStatus != kStatus_Success) { return kStatus_NBOOT_Fail; } ++fuseIdxStart; } status = kStatus_NBOOT_Success; } while (false); return status; } fsl_nboot_status_t nboot_hal_get_sb3_manifest_params(fsl_nboot_context_t *context, fsl_nboot_sb3_load_manifest_parms_t *parms) { if ((NULL == context) || (NULL == parms)) { return kStatus_NBOOT_InvalidArgument; } fsl_nboot_status_t status = kStatus_NBOOT_Fail; do { status = nboot_hal_get_root_auth_parms(context, &parms->soc_RoTNVM); if (status != kStatus_NBOOT_Success) { break; } status = nboot_hal_get_pck_blob(&parms->pckBlob[0], sizeof(parms->pckBlob)); if (status != kStatus_NBOOT_Success) { break; } status = kStatus_NBOOT_Success; } while (false); if (status != kStatus_NBOOT_Success) { (void)memset(parms, 0, sizeof(*parms)); } return status; }