TPM Command CreatePrimary UEFI App

1

I'm trying to implement a UEFI App for the CreatePrimary TPM Command. i understand i need to pack the command parameters in a canonical way and swap the byte order to Big Endiann. Still i get the an error response code for some reason. what am i missing here?

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;
}

The Response printouts:

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 0C 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

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]

tpm
uefi
asked on Stack Overflow Apr 30, 2020 by Azra

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0