这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K3XX】HSE KEY 管理服务

共1条 1/1 1 跳转至

【S32K3XX】HSE KEY 管理服务

高工
2026-04-25 14:33:07   被打赏 50 分(兑奖)     打赏

【简介】

S32K 的HSE core 被设计成芯片的安全相关的核心,相关加密算法对应的密钥管理也是在HSE中尽心管理的。我们今天看下HSE 的密钥管理都有哪些服务。HSE 的KEY 在配置前需要先进行格式化,以下代码是S32K Secure Boot 代码中对对key 进行格式的的代码。

hseSrvResponse_t HseFrm_Key_FormatCatalogs(const hseKeyGroupCfgEntry_t* pNvmCatalog, const hseKeyGroupCfgEntry_t* pRamCatalog)
{
    hseSrvResponse_t hseSrvResponse = 0xFFFFFFFF;
    hseSrvDescriptor_t hseSrvDesc ;
    hseSrvDescriptor_t* pHseSrvDesc = &hseSrvDesc;

    hseFormatKeyCatalogsSrv_t*  pFormatKeyCatalogsReq = &pHseSrvDesc->hseSrv.formatKeyCatalogsReq;

    MEMSET(pHseSrvDesc, 0, sizeof(hseSrvDescriptor_t));

    //Use the same default catalog configurations to re-format the NVM and RAM catalogs
    pHseSrvDesc->srvId = HSE_SRV_ID_FORMAT_KEY_CATALOGS;

    pFormatKeyCatalogsReq->pNvmKeyCatalogCfg= (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)pNvmCatalog);

    pFormatKeyCatalogsReq->pRamKeyCatalogCfg= (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)pRamCatalog);

    hseSrvResponse = gHsePort_HseIf.reqApi( pHseSrvDesc , NULL );

    return hseSrvResponse;
}

从上述代码可知格式化处理实际上是调用的HSE 的HSE_SRV_ID_FORMAT_KEY_CATALOGS 服务来根据传入Key 的信息进行格式化。

以下是HSE 接口文档对该服务的描述。

image.png

image.png

根据上述的描述,格式化key 服务需要用户构造NVM/RAM key 的格式化结构,将该结构传递给HSE来进行格式化,对应的成员结构如下:

/** @brief    The entry of the Key Catalog Configuration
 *  @details  The size of a key slot is computed internally based on keytype and maxKeyBitLen.
 *            @note A key group (catalog entry) contains keys that have the same key type and the keybitLen <= maxKeyBitLen.
 *  */
typedef struct
{
hseMuMask_t        muMask;          /**< @brief Specifies the MU Instance(s) for the key group. A key group can belong to one ore more MUs. */
hseKeyGroupOwner_t groupOwner;      /**< @brief Specifies the key group owner. */
hseKeyType_t       keyType;         /**< @brief The key type (see #hseKeyType_t). */
uint8_t            numOfKeySlots;   /**< @brief The number of key slots. */
uint16_t           maxKeyBitLen;    /**< @brief The maximum length of the key (in bits). All stored keys have keyBitLen <= maxKeyBitLen. */
uint8_t            hseReserved[2];  /**< @brief HSE reserved */
} hseKeyGroupCfgEntry_t;

   image.png

格式化key 完成后就可以使用HSE的服务来往slot中导入key了,以下代码是导入key对应的代码。

/*
  NVM keys:
    In empty slots, an encrypted key can be imported only authenticated, and a plain key
    can be imported with/without authentication (public keys must be imported in plain).
    In non-empty slots, NVM keys can be imported(overwritten) in plain/encrypted,
    but must authenticated
*/
hseSrvResponse_t HseMid_KeyMgmt_ImportKey(
hseKeyHandle_t keyHandle,
hseKeyInfo_t* pKeyElemInfo,
hseMid_ImportKeyVal_t* pKeyVal,
hseKeyFormat_t* pKeyFormat,
hseFrm_KeyCipher_t* pCipher, hseFrm_KeyAuth_t* pAuth,
boolean needErase, boolean keepCounter
)
{
hseSrvResponse_t hseSrvResponse = 0xFFFFFFFF;

hseKeyInfo_t* pKeyInfo = &gsImportKeyInfo;

_TRY_START;

/* keyInfo copy to non-cacheable */
MEMCPY( pKeyInfo , pKeyElemInfo, sizeof(hseKeyInfo_t) );

hseSrvResponse = HseMid_KeyMgmt_EraseOrKeepKeyCounter(keyHandle, needErase,keepCounter, &(pKeyInfo->keyCounter), 1 );
_THROW_DIFF( HSE_SRV_RSP_OK , hseSrvResponse );

hseSrvResponse = HseFrm_Key_Import(keyHandle, pKeyInfo, (hseFrm_Key_t*)pKeyVal, NULL, pKeyFormat, pCipher, pAuth);
_THROW_DIFF( HSE_SRV_RSP_OK , hseSrvResponse );

_TRY_END;

return hseSrvResponse ;
}


hseSrvResponse_t HseFrm_Key_Import
(
hseKeyHandle_t targetKeyHandle,
hseKeyInfo_t* pKeyInfo,
hseFrm_Key_t* pKey,
hseFrm_KeyLen_t* pKeyLen,
hseKeyFormat_t* pKeyFormat,
hseFrm_KeyCipher_t *pCipher,
hseFrm_KeyAuth_t *pAuth
)
{
hseSrvResponse_t hseSrvResponse = 0xFFFFFFFF;
hseSrvDescriptor_t hseSrvDesc ;
hseSrvDescriptor_t* pHseSrvDesc = &hseSrvDesc;
hseImportKeySrv_t* pImportKeyReq = &pHseSrvDesc->hseSrv.importKeyReq;

MEMSET(pHseSrvDesc, 0, sizeof(hseSrvDescriptor_t));

pHseSrvDesc->srvId = HSE_SRV_ID_IMPORT_KEY;

pImportKeyReq->targetKeyHandle = targetKeyHandle;

pImportKeyReq->pKeyInfo = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)(pKeyInfo));

pImportKeyReq->pKey[0] = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)(pKey->pKey[0]));
pImportKeyReq->pKey[1] = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)(pKey->pKey[1]));
pImportKeyReq->pKey[2] = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)(pKey->pKey[2]));

if( NULL != pKeyFormat )
{
MEMCPY( &(pImportKeyReq->keyFormat),  pKeyFormat, sizeof(hseKeyFormat_t) );
}

if( NULL != pKeyLen )
{
pImportKeyReq->keyLen[0] = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)(pKeyLen->keyLen[0]));
pImportKeyReq->keyLen[1] = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)(pKeyLen->keyLen[1]));
pImportKeyReq->keyLen[2] = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)(pKeyLen->keyLen[2]));
}
else
{
HseFrm_Key_SetKeyLen( (hseKeyInfo_t*)pKeyInfo, (uint16_t*)( &(pImportKeyReq->keyLen[0]) ), &(pImportKeyReq->keyFormat) );
}

/* plain */
pImportKeyReq->cipher.cipherKeyHandle = HSE_INVALID_KEY_HANDLE;
pImportKeyReq->keyContainer.authKeyHandle = HSE_INVALID_KEY_HANDLE;

/* key import with/without encrypted/authenticated */

/* encrypted/authenticated */

if( NULL != pCipher)
{
/* encrypted */
pImportKeyReq->cipher.cipherKeyHandle = pCipher->keyHandle;
pImportKeyReq->cipher.cipherScheme = pCipher->cipherScheme;
}

if( NULL != pAuth)
{
/* authenticated */
pImportKeyReq->keyContainer.pKeyContainer = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)pAuth->pKeyContainer);
pImportKeyReq->keyContainer.keyContainerLen = pAuth->keyContainerLen;

pImportKeyReq->keyContainer.authKeyHandle = pAuth->authKeyHandle;
pImportKeyReq->keyContainer.authScheme = pAuth->authScheme;

pImportKeyReq->keyContainer.authLen[0] = (uint16_t) *(pAuth->pAuthLen[0]);
pImportKeyReq->keyContainer.authLen[1] = (uint16_t) *(pAuth->pAuthLen[1]);

pImportKeyReq->keyContainer.pAuth[0] = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)pAuth->pAuth[0]);
pImportKeyReq->keyContainer.pAuth[1] = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)pAuth->pAuth[1]);

/* When a key container is defined by the host, it must be ensured that the key values pointed by pKey[] are
            within the key container, that means (for i between 0 and 2) addresses pKey[i] and (pKey[i] + *pKeyLen[i])
            must be between keyContainer.pKeyContainer and (keyContainer.pKeyContainer +
            keyContainer.keyContainerLen - 1) */
/* key import with auth, pKeyInfo and pKey point to pKeyContainer */
pImportKeyReq->pKeyInfo     = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)( pAuth->pKeyContainer + 0 )) ;

pImportKeyReq->pKey[0]      = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)( pAuth->pKeyContainer + sizeof(hseKeyInfo_t) )) ;
pImportKeyReq->pKey[1]      = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)( pAuth->pKeyContainer + sizeof(hseKeyInfo_t) + pImportKeyReq->keyLen[0] )) ;
pImportKeyReq->pKey[2]      = (HOST_ADDR)hsePort_Mem_AddrHandler((HOST_ADDR)( pAuth->pKeyContainer + sizeof(hseKeyInfo_t) + pImportKeyReq->keyLen[0] + pImportKeyReq->keyLen[1] )) ;
}

/* encrypted and authenticated */

hseSrvResponse = gHsePort_HseIf.reqApi( pHseSrvDesc , NULL );

return hseSrvResponse;
}

对应的 HSE_SRV_ID_IMPORT_KEY 服务可以导入key.

image.png

image.png

通过上述服务就可以通知HSE core 来格式化处理KEY数据。

           


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]