Я пытаюсь реализовать приложение UEFI для команды CreatePrimary TPM. Я понимаю, что мне нужно упаковать параметры команды каноническим способом и поменять порядок байтов на 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 00 01 31 40 00 00 01 00 00 00 09 40 00 00 09 00 00 00 00 00 00 02 00 00 00 00 00 0 C 00 01 00 04 00 03 04 60 00 00 00 06 00 30 00 43 00 10 00 30 00 00 00 00 00 00 00 01 00 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_ret.ObjectHandle [0x00000000] CreatePrimary_ret.ObjectHandle [0x00000000] CreatePrimary_ret.