我尝试在 UEFI 中使用 EFI_TCG2_PROTOCOL 来访问 TPM 功能。 我以这种方式使用 TSS API 在用户空间中创建持久密钥:
// We will make a key in the "null hierarchy".
TPMT_PUBLIC primTempl(TPM_ALG_ID::SHA1,
TPMA_OBJECT::decrypt | TPMA_OBJECT::userWithAuth | TPMA_OBJECT::sensitiveDataOrigin,
null, // No policy
TPMS_RSA_PARMS(null, TPMS_SCHEME_OAEP(TPM_ALG_ID::SHA1), 2048, 65537),
TPM2B_PUBLIC_KEY_RSA());
// Create the key
auto storagePrimary = tpm.CreatePrimary(TPM_RH::OWNER, null, primTempl, null, null);
TPM_HANDLE& keyHandle = storagePrimary.handle;
// We can put the primary key into NV with EvictControl
TPM_HANDLE persistentHandle = TPM_HANDLE::Persistent(1000); //offset 1000
// First delete anything that might already be there
tpm._AllowErrors().EvictControl(TPM_RH::OWNER, persistentHandle, persistentHandle);
// Make our primary persistent
tpm.EvictControl(TPM_RH::OWNER, storagePrimary.handle, persistentHandle);
//// Flush the old one
tpm.FlushContext(storagePrimary.handle);
它工作得很好,即使在重新启动后我也可以访问这个密钥,因此密钥被保存到非易失性存储器中,并且可以在以后重复使用。 但是,当我尝试从 UEFI 访问此密钥时,使用 EFI_TCG2_PROTOCOL 例如为该密钥调用函数 TPM_CC_ReadPublic ,它不会返回错误代码,但响应似乎不正确。示例:
struct TPM2_Read_Public_Command {
TPMI_ST_COMMAND_TAG tag;
UINT32 commandSize;
TPM_CC commandCode;
TPMI_DH_OBJECT objectHandle;
};
struct TPM2_Read_Public_Response {
TPM_ST tag;
UINT32 responseSize;
TPM_RC responseCode;
TPM2B_PUBLIC outPublic;
TPM2B_NAME name;
TPM2B_NAME qualifiedName;
};
...
TPMI_DH_OBJECT hKeyHandle = PERSISTENT_FIRST + 1000; //offset 1000
struct TPM2_Read_Public_Command readPublicCmd = { 0 };
struct TPM2_Read_Public_Response readPublicResponse = { 0 };
...
readPublicCmd.tag = SwapBytes16(TPM_ST_NO_SESSIONS); //x86 is little endian, TPM2 is big-endian, use bswap to convert!)
readPublicCmd.commandSize = SwapBytes32(sizeof(struct TPM2_Read_Public_Command));
readPublicCmd.commandCode = SwapBytes32(TPM_CC_ReadPublic);
readPublicCmd.objectHandle = SwapBytes32(hKeyHandle);
Status = tcg2_protocol->SubmitCommand(
tcg2_protocol,
sizeof(struct TPM2_Read_Public_Command), (UINT8*)&readPublicCmd,
sizeof(struct TPM2_Read_Public_Response), (UINT8*)&readPublicResponse
);
if (EFI_ERROR(Status))
{
Print(L"keyReadPublicBuffer() FAILED, error = 0x%llX!\n", Status);
//return Status;
}
else
{
Print(L"keyReadPublicBuffer() SUCCESS!\n", Status);
for (i = 0; i < SwapBytes16(OutPublic.publicArea.unique.rsa.size); i++)
{
Print(L"%X", OutPublic.publicArea.unique.rsa.buffer[0]);
}
Print(L"\nkeyReadPublicBuffer() SUCCESS!\n", Status);
}
我在这里做错了什么吗?
我能够从 tpm 获取 EK 公钥。我想要使用 UEFI 中的 EK 密钥创建 RK 密钥。 我知道有一个 tpm 属性 TPM2_Create 来创建密钥..但是如何使用它任何想法或参考代码?