tpm - TPM 命令 CreatePrimary UEFI 应用程序
问题描述
我正在尝试为 CreatePrimary TPM 命令实现 UEFI 应用程序。我知道我需要以规范的方式打包命令参数并将字节顺序交换为 Big Endiann。由于某种原因,我仍然收到错误响应代码。我在这里想念什么?
CreatePrimaryCmd()
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_TREE_PROTOCOL *TreeProtocol;
TPM2_CreatePrimary_COMMAND CreatePrimary_cmd;
TPM2_CreatePrimary_RESPONSE CreatePrimary_ret;
UINT32 i;
UINT32 CmdSize;
UINT8 *Buffer;
UINT8 *AuthSizeOffset;
UINT16 *SizeOffset;
TPM2B_AUTH NewAuth;
Status = gBS->LocateProtocol( &gEfiTreeProtocolGuid,
NULL,
(VOID **) &TreeProtocol);
if (EFI_ERROR (Status)) {
DebugPrint(EFI_D_ERROR,"Failed to locate EFI_TREE_PROTOCOL [%r]\n", Status);
return Status;
}
NewAuth.size = 0;
Tpm2HierarchyChangeAuth (TPM_RH_OWNER, NULL, &NewAuth);
ZeroMem(&CreatePrimary_cmd, sizeof(CreatePrimary_cmd));
CreatePrimary_cmd.Header.tag = (TPMI_ST_COMMAND_TAG)SwapBytes16(TPM_ST_SESSIONS);
CreatePrimary_cmd.Header.commandCode = TPM_H2NL(TPM_CC_CreatePrimary);
Buffer = (UINT8 *)&CreatePrimary_cmd.Header.commandCode;
Buffer += sizeof(UINT32);
//PrimaryHandle
*(UINT32 *)Buffer = TPM_H2NL(TPM_RH_OWNER);
Buffer += sizeof(UINT32);
//
// Add in Auth session
//
AuthSizeOffset = Buffer;
*(UINT32 *)Buffer = 0;
Buffer += sizeof(UINT32);
// authHandle
*(UINT32 *)Buffer = TPM_H2NL(TPM_RS_PW);
Buffer += sizeof(UINT32);
// nonce = nullNonce
*(UINT16 *)Buffer = 0;
Buffer += sizeof(UINT16);
// sessionAttributes = 0
*(UINT8 *)Buffer = 0;
Buffer += sizeof(UINT8);
// auth = nullAuth
*(UINT16 *)Buffer = 0;
Buffer += sizeof(UINT16);
// authorizationSize
*(UINT32 *)AuthSizeOffset = TPM_H2NL((UINT32)(Buffer - AuthSizeOffset - sizeof(UINT32)));
//InSensitive.size
*(UINT16 *)Buffer = TPM_H2NS(2);
Buffer += sizeof(UINT16);
//sensitive.userAuth.size
*(UINT16 *)Buffer = TPM_H2NS(0);
Buffer += sizeof(UINT16);
//sensitive.data.keySize
*(UINT16 *)Buffer = TPM_H2NS(0);
Buffer += sizeof(UINT16);
//InPublic.size will be set later
SizeOffset = (UINT16 *)Buffer;
Buffer += sizeof(UINT16);
//InPublic.publicArea.type
*(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_RSA);
Buffer += sizeof(UINT16);
//publicArea.nameAlg
*(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_SHA1);
Buffer += sizeof(UINT16);
/*
CreatePrimary_cmd.InPublic.publicArea.objectAttributes.stClear= CLEAR;
CreatePrimary_cmd.InPublic.publicArea.objectAttributes.fixedTPM = CLEAR;
CreatePrimary_cmd.InPublic.publicArea.objectAttributes.fixedParent = CLEAR;
CreatePrimary_cmd.InPublic.publicArea.objectAttributes.sensitiveDataOrigin = SET;
CreatePrimary_cmd.InPublic.publicArea.objectAttributes.userWithAuth = SET;
CreatePrimary_cmd.InPublic.publicArea.objectAttributes.adminWithPolicy = CLEAR;
CreatePrimary_cmd.InPublic.publicArea.objectAttributes.noDA = SET;
CreatePrimary_cmd.InPublic.publicArea.objectAttributes.restricted = SET;
CreatePrimary_cmd.InPublic.publicArea.objectAttributes.decrypt = SET;
*/
//publicArea.objectAttributes
*(UINT32 *)Buffer = TPM_H2NL(0x30460);
Buffer += sizeof(UINT32);
//publicArea.authPolicy.size
*(UINT16 *)Buffer = 0;
Buffer += sizeof(UINT16);
//InPublic.publicArea.parameters.rsaDetail.symmetric.algorithm
*(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_AES);
Buffer += sizeof(UINT16);
//InPublic.publicArea.parameters.rsaDetail.symmetric.keyBits
*(UINT16 *)Buffer = TPM_H2NS(48);
Buffer += sizeof(UINT16);
//publicArea.parameters.rsaDetail.symmetric.mode
*(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_CFB);
Buffer += sizeof(UINT16);
//InPublic.publicArea.parameters.rsaDetail.scheme.scheme
*(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_NULL);
Buffer += sizeof(UINT16);
//InPublic.publicArea.parameters.rsaDetail.keyBits
*(UINT16 *)Buffer = TPM_H2NS(48);
Buffer += sizeof(UINT16);
//InPublic.publicArea.parameters.rsaDetail.exponent
*(UINT32 *)Buffer = TPM_H2NL(0);
Buffer += sizeof(UINT32);
//InPublic.publicArea.unique.rsa.keySize
*(UINT16 *)Buffer = 0;
Buffer += sizeof(UINT16);
//InPublic.size
*SizeOffset = TPM_H2NS(((UINT16)((UINT16*)Buffer - SizeOffset - sizeof(UINT16))));
//OutsideInfo.size
*(UINT16 *)Buffer = TPM_H2NS(1);
Buffer += sizeof(UINT16);
//OutsideInfo.buffer
*(UINT8 *)Buffer = 0;
Buffer += sizeof(UINT8);
//CreationPCR.count
*(UINT32 *)Buffer = 0;
Buffer += sizeof(UINT32);
//CreatePrimary_cmd.CreationPCR.pcrSelections.hash
CmdSize = (UINT32)(Buffer - (UINT8*)&CreatePrimary_cmd);
DebugPrint(EFI_D_ERROR,"CmdSize [0x%x]\n",CmdSize);
CreatePrimary_cmd.Header.paramSize = TPM_H2NL(CmdSize);
printbuffer((UINT8*)&CreatePrimary_cmd,CmdSize);
Status = TreeProtocol->SubmitCommand( TreeProtocol,
CmdSize,
(UINT8*)&CreatePrimary_cmd,
sizeof (CreatePrimary_ret),
(UINT8*)&CreatePrimary_ret);
if (EFI_ERROR (Status)) {
DebugPrint(EFI_D_ERROR,"Failed to SubmitCommand [%d]\n", Status);
return Status;
}
DebugPrint(EFI_D_ERROR,"\nCreatePrimary_ret.Header.paramSize [0x%08x]\n", SwapBytes32(CreatePrimary_ret.Header.paramSize));
DebugPrint(EFI_D_ERROR,"CreatePrimary_ret.Header.responseCode [0x%08x]\n", SwapBytes32(CreatePrimary_ret.Header.responseCode));
DebugPrint(EFI_D_ERROR,"CreatePrimary_ret.Header.tag [0x%04x]\n", SwapBytes16(CreatePrimary_ret.Header.tag));
DebugPrint(EFI_D_ERROR,"CreatePrimary_ret.ObjectHandle [0x%08x]\n", SwapBytes32(CreatePrimary_ret.ObjectHandle));
DebugPrint(EFI_D_ERROR,"CreatePrimary_cmd.InPublic.publicArea.unique.rsa.size) [0x%08x]\n", SwapBytes16(CreatePrimary_cmd.InPublic.publicArea.unique.rsa.keySize));
DebugPrint(EFI_D_ERROR,"RSA Key\n");
for( i = 0 ; i < 256 ; ++i)
{
DebugPrint(EFI_D_ERROR,"%02x", CreatePrimary_cmd.InPublic.publicArea.unique.rsa.key[i]);
}
DebugPrint(EFI_D_ERROR,"\n");
return Status;
}
响应打印输出:
80 02 00 00 00 44 00 01 31 31 40 00 00 01 00 00 00 00 00 09 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000C 00 01 00 01 00 04 00 04 00 04 60 00 00 00 00 00 00 06 00 306 00 306 00 306 00 306 00 306 00 306 00 306 00 306 00 306 00 306 00 06 43 00 10 00 30 00 00 00 00 00 00 00 01 00 00 00 00 00
CreatePrimary_ret.Header.paramSize [0x0000000A] CreatePrimary_ret.Header.responseCode [0x000001D5] CreatePrimary_ret.Header.tag [0x8001] CreatePrimary_ret.ObjectHandle [0x00000000] CreatePrimary_cmd.InPublic.publicArea.unique.rsa.size) [0x00000000]
解决方案
推荐阅读
- python - 如何从 Python 函数返回多个变量
- php - 从 pdo 结果中获取值
- java - 将 if 语句转换为三元运算符 - 编译器抱怨它不是语句
- javascript - NetSuite SuiteScript 2.0:内联 HTML document.querySelector() 结果
- dns - Route 53 子域 www 未定向到站点
- python-3.x - 如何执行并行 psycopg2 copy_from?
- java - SecurityException - “调用者......不是范围委托阻止卸载的代表”(Android 8 - Java)
- wordpress - 在 WooCommerce 产品元变体产品中显示尺寸
- kotlin - 使用时间管理库构建 kotlin 多平台(js、jvm)
- python - 如何部署海量数据的 Dash App