/** Send TPM_Startup command to TPM. @param[in] PeiServices Describes the list of possible PEI Services. @param[in] TpmHandle TPM handle. @param[in] BootMode Boot mode. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_TIMEOUT The register can't run into the expected status in time. @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS TpmCommStartup ( IN EFI_PEI_SERVICES **PeiServices, IN TIS_TPM_HANDLE TpmHandle, IN EFI_BOOT_MODE BootMode ) { EFI_STATUS Status; TPM_STARTUP_TYPE TpmSt; UINT32 TpmRecvSize; UINT32 TpmSendSize; TPM_CMD_START_UP SendBuffer; UINT8 RecvBuffer[20]; TpmSt = TPM_ST_CLEAR; if (BootMode == BOOT_ON_S3_RESUME) { TpmSt = TPM_ST_STATE; } // // send Tpm command TPM_ORD_Startup // TpmRecvSize = 20; TpmSendSize = sizeof (TPM_CMD_START_UP); SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize); SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_Startup); SendBuffer.TpmSt = SwapBytes16 (TpmSt); Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize); return Status; }
/** Send Shutdown command to TPM2. @param[in] ShutdownType TPM_SU_CLEAR or TPM_SU_STATE. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm2Shutdown ( IN TPM_SU ShutdownType ) { EFI_STATUS Status; TPM2_SHUTDOWN_COMMAND Cmd; TPM2_SHUTDOWN_RESPONSE Res; UINT32 ResultBufSize; Cmd.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd)); Cmd.Header.commandCode = SwapBytes32(TPM_CC_Shutdown); Cmd.ShutdownType = SwapBytes16(ShutdownType); ResultBufSize = sizeof(Res); Status = Tpm2SubmitCommand (sizeof(Cmd), (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res); if (EFI_ERROR(Status)) { return Status; } if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) { DEBUG ((EFI_D_ERROR, "Tpm2Shutdown: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode))); return EFI_DEVICE_ERROR; } return EFI_SUCCESS; }
/** This command returns Returns a list of TPMS_ALG_PROPERTIES. Each entry is an algorithm ID and a set of properties of the algorithm. This function parse the value got from TPM2_GetCapability and return the list. @param[out] AlgList List of algorithm. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI Tpm2GetCapabilitySupportedAlg ( OUT TPML_ALG_PROPERTY *AlgList ) { TPMS_CAPABILITY_DATA TpmCap; TPMI_YES_NO MoreData; UINTN Index; EFI_STATUS Status; Status = Tpm2GetCapability ( TPM_CAP_ALGS, 1, MAX_CAP_ALGS, &MoreData, &TpmCap ); if (EFI_ERROR (Status)) { return Status; } CopyMem (AlgList, &TpmCap.data.algorithms, sizeof (TPML_ALG_PROPERTY)); AlgList->count = SwapBytes32 (AlgList->count); for (Index = 0; Index < AlgList->count; Index++) { AlgList->algProperties[Index].alg = SwapBytes16 (AlgList->algProperties[Index].alg); WriteUnaligned32 ((UINT32 *)&AlgList->algProperties[Index].algProperties, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&AlgList->algProperties[Index].algProperties))); } return EFI_SUCCESS; }
RETURN_STATUS EFIAPI ArmVirtTimerFdtClientLibConstructor ( VOID ) { EFI_STATUS Status; FDT_CLIENT_PROTOCOL *FdtClient; CONST INTERRUPT_PROPERTY *InterruptProp; UINT32 PropSize; INT32 SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum; RETURN_STATUS PcdStatus; Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, (VOID **)&FdtClient); ASSERT_EFI_ERROR (Status); Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,armv7-timer", "interrupts", (CONST VOID **)&InterruptProp, &PropSize); if (Status == EFI_NOT_FOUND) { Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,armv8-timer", "interrupts", (CONST VOID **)&InterruptProp, &PropSize); } if (EFI_ERROR (Status)) { return Status; } // // - interrupts : Interrupt list for secure, non-secure, virtual and // hypervisor timers, in that order. // ASSERT (PropSize == 36 || PropSize == 48); SecIntrNum = SwapBytes32 (InterruptProp[0].Number) + (InterruptProp[0].Type ? 16 : 0); IntrNum = SwapBytes32 (InterruptProp[1].Number) + (InterruptProp[1].Type ? 16 : 0); VirtIntrNum = SwapBytes32 (InterruptProp[2].Number) + (InterruptProp[2].Type ? 16 : 0); HypIntrNum = PropSize < 48 ? 0 : SwapBytes32 (InterruptProp[3].Number) + (InterruptProp[3].Type ? 16 : 0); DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n", SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum)); PcdStatus = PcdSet32S (PcdArmArchTimerSecIntrNum, SecIntrNum); ASSERT_RETURN_ERROR (PcdStatus); PcdStatus = PcdSet32S (PcdArmArchTimerIntrNum, IntrNum); ASSERT_RETURN_ERROR (PcdStatus); PcdStatus = PcdSet32S (PcdArmArchTimerVirtIntrNum, VirtIntrNum); ASSERT_RETURN_ERROR (PcdStatus); PcdStatus = PcdSet32S (PcdArmArchTimerHypIntrNum, HypIntrNum); ASSERT_RETURN_ERROR (PcdStatus); return EFI_SUCCESS; }
/** Read a TPM PCR. @param[in] PcrIndex The PCR to be read. @param[out] PcrValue PCR value. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_TIMEOUT The register can't run into the expected status in time. @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm12PcrRead ( IN TPM_PCRINDEX PcrIndex, OUT TPM_DIGEST *PcrValue ) { EFI_STATUS Status; TPM_CMD_PCR_READ Command; TPM_RSP_PCR_READ Response; UINT32 Length; // // send Tpm command TPM_ORD_PcrRead // Command.Hdr.tag = SwapBytes16(TPM_TAG_RQU_COMMAND); Command.Hdr.paramSize = SwapBytes32(sizeof(Command)); Command.Hdr.ordinal = SwapBytes32(TPM_ORD_PcrRead); Command.PcrIndex = SwapBytes32(PcrIndex); Length = sizeof(Response); Status = Tpm12SubmitCommand(sizeof(Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response); if (EFI_ERROR(Status)) { return Status; } if (Response.Hdr.returnCode != 0) { return EFI_DEVICE_ERROR; } if (PcrValue != NULL) { CopyMem(PcrValue, &Response.TpmDigest, sizeof(*PcrValue)); } return Status; }
/** Extend a TPM PCR. @param[in] DigestToExtend The 160 bit value representing the event to be recorded. @param[in] PcrIndex The PCR to be updated. @param[out] NewPcrValue New PCR value after extend. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_TIMEOUT The register can't run into the expected status in time. @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm12Extend ( IN TPM_DIGEST *DigestToExtend, IN TPM_PCRINDEX PcrIndex, OUT TPM_DIGEST *NewPcrValue ) { EFI_STATUS Status; TPM_CMD_EXTEND Command; TPM_RSP_EXTEND Response; UINT32 Length; // // send Tpm command TPM_ORD_Extend // Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); Command.Hdr.paramSize = SwapBytes32 (sizeof (Command)); Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_Extend); Command.PcrIndex = SwapBytes32 (PcrIndex); CopyMem (&Command.TpmDigest, DigestToExtend, sizeof (Command.TpmDigest)); Length = sizeof (Response); Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response); if (EFI_ERROR (Status)) { return Status; } if (NewPcrValue != NULL) { CopyMem (NewPcrValue, &Response.TpmDigest, sizeof (*NewPcrValue)); } return Status; }
/** Send ForceClear command to TPM1.2. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm12ForceClear ( VOID ) { EFI_STATUS Status; TPM_RQU_COMMAND_HDR Command; TPM_RSP_COMMAND_HDR Response; UINT32 Length; // // send Tpm command TPM_ORD_ForceClear // Command.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); Command.paramSize = SwapBytes32 (sizeof (Command)); Command.ordinal = SwapBytes32 (TPM_ORD_ForceClear); Length = sizeof (Response); Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response); if (EFI_ERROR (Status)) { return Status; } switch (SwapBytes32 (Response.returnCode)) { case TPM_SUCCESS: return EFI_SUCCESS; default: return EFI_DEVICE_ERROR; } }
/** Send ForceClear command to TPM1.2. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm12ForceClear ( VOID ) { EFI_STATUS Status; UINT32 TpmRecvSize; UINT32 TpmSendSize; TPM_CMD_FORCE_CLEAR SendBuffer; TPM_RSP_FORCE_CLEAR RecvBuffer; UINT32 ReturnCode; // // send Tpm command TPM_ORD_ForceClear // TpmRecvSize = sizeof (TPM_RSP_FORCE_CLEAR); TpmSendSize = sizeof (TPM_CMD_FORCE_CLEAR); SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize); SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_ForceClear); Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer); if (EFI_ERROR (Status)) { return Status; } ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode); switch (ReturnCode) { case TPM_SUCCESS: return EFI_SUCCESS; default: return EFI_DEVICE_ERROR; } }
/** Execute READ CAPACITY command to request information regarding the capacity of the installed medium of the device. This function executes READ CAPACITY command to get the capacity of the USB mass storage media, including the presence, block size, and last block number. @param UsbMass The device to retireve disk gemotric. @retval EFI_SUCCESS The disk geometry is successfully retrieved. @retval EFI_NOT_READY The returned block size is zero. @retval Other READ CAPACITY command execution failed. **/ EFI_STATUS UsbBootReadCapacity ( IN USB_MASS_DEVICE *UsbMass ) { USB_BOOT_READ_CAPACITY_CMD CapacityCmd; USB_BOOT_READ_CAPACITY_DATA CapacityData; EFI_BLOCK_IO_MEDIA *Media; EFI_STATUS Status; UINT32 BlockSize; Media = &UsbMass->BlockIoMedia; ZeroMem (&CapacityCmd, sizeof (USB_BOOT_READ_CAPACITY_CMD)); ZeroMem (&CapacityData, sizeof (USB_BOOT_READ_CAPACITY_DATA)); CapacityCmd.OpCode = USB_BOOT_READ_CAPACITY_OPCODE; CapacityCmd.Lun = (UINT8) (USB_BOOT_LUN (UsbMass->Lun)); Status = UsbBootExecCmdWithRetry ( UsbMass, &CapacityCmd, (UINT8) sizeof (USB_BOOT_READ_CAPACITY_CMD), EfiUsbDataIn, &CapacityData, sizeof (USB_BOOT_READ_CAPACITY_DATA), USB_BOOT_GENERAL_CMD_TIMEOUT ); if (EFI_ERROR (Status)) { return Status; } // // Get the information on media presence, block size, and last block number // from READ CAPACITY data. // Media->MediaPresent = TRUE; Media->LastBlock = SwapBytes32 (ReadUnaligned32 ((CONST UINT32 *) CapacityData.LastLba)); BlockSize = SwapBytes32 (ReadUnaligned32 ((CONST UINT32 *) CapacityData.BlockLen)); if (BlockSize == 0) { // // Get sense data // return UsbBootRequestSense (UsbMass); } else { Media->BlockSize = BlockSize; } if (Media->LastBlock == 0xFFFFFFFF) { Status = UsbBootReadCapacity16 (UsbMass); if (!EFI_ERROR (Status)) { UsbMass->Cdb16Byte = TRUE; } } return Status; }
/** Get TPM physical presence permanent flags. @param[in] TcgProtocol EFI TCG Protocol instance. @param[out] LifetimeLock physicalPresenceLifetimeLock permanent flag. @param[out] CmdEnable physicalPresenceCMDEnable permanent flag. @retval EFI_SUCCESS Flags were returns successfully. @retval other Failed to locate EFI TCG Protocol. **/ EFI_STATUS GetTpmCapability ( IN EFI_TCG_PROTOCOL *TcgProtocol, OUT BOOLEAN *LifetimeLock, OUT BOOLEAN *CmdEnable ) { EFI_STATUS Status; TPM_RQU_COMMAND_HDR *TpmRqu; TPM_RSP_COMMAND_HDR *TpmRsp; UINT32 *SendBufPtr; UINT8 SendBuffer[sizeof (*TpmRqu) + sizeof (UINT32) * 3]; TPM_PERMANENT_FLAGS *TpmPermanentFlags; UINT8 RecvBuffer[40]; // // Fill request header // TpmRsp = (TPM_RSP_COMMAND_HDR*)RecvBuffer; TpmRqu = (TPM_RQU_COMMAND_HDR*)SendBuffer; TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); TpmRqu->paramSize = SwapBytes32 (sizeof (SendBuffer)); TpmRqu->ordinal = SwapBytes32 (TPM_ORD_GetCapability); // // Set request parameter // SendBufPtr = (UINT32*)(TpmRqu + 1); WriteUnaligned32 (SendBufPtr++, SwapBytes32 (TPM_CAP_FLAG)); WriteUnaligned32 (SendBufPtr++, SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT))); WriteUnaligned32 (SendBufPtr, SwapBytes32 (TPM_CAP_FLAG_PERMANENT)); Status = TcgProtocol->PassThroughToTpm ( TcgProtocol, sizeof (SendBuffer), (UINT8*)TpmRqu, sizeof (RecvBuffer), (UINT8*)&RecvBuffer ); ASSERT_EFI_ERROR (Status); ASSERT (TpmRsp->tag == SwapBytes16 (TPM_TAG_RSP_COMMAND)); ASSERT (TpmRsp->returnCode == 0); TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)]; if (LifetimeLock != NULL) { *LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock; } if (CmdEnable != NULL) { *CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable; } return Status; }
/** Copy AuthSessionIn to TPM2 command buffer. @param [in] AuthSessionIn Input AuthSession data @param [out] AuthSessionOut Output AuthSession data in TPM2 command buffer @return AuthSession size **/ UINT32 EFIAPI CopyAuthSessionCommand ( IN TPMS_AUTH_COMMAND *AuthSessionIn, OPTIONAL OUT UINT8 *AuthSessionOut ) { UINT8 *Buffer; Buffer = (UINT8 *)AuthSessionOut; // // Add in Auth session // if (AuthSessionIn != NULL) { // sessionHandle WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(AuthSessionIn->sessionHandle)); Buffer += sizeof(UINT32); // nonce WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->nonce.size)); Buffer += sizeof(UINT16); CopyMem (Buffer, AuthSessionIn->nonce.buffer, AuthSessionIn->nonce.size); Buffer += AuthSessionIn->nonce.size; // sessionAttributes *(UINT8 *)Buffer = *(UINT8 *)&AuthSessionIn->sessionAttributes; Buffer++; // hmac WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->hmac.size)); Buffer += sizeof(UINT16); CopyMem (Buffer, AuthSessionIn->hmac.buffer, AuthSessionIn->hmac.size); Buffer += AuthSessionIn->hmac.size; } else { // sessionHandle WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(TPM_RS_PW)); Buffer += sizeof(UINT32); // nonce = nullNonce WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(0)); Buffer += sizeof(UINT16); // sessionAttributes = 0 *(UINT8 *)Buffer = 0x00; Buffer++; // hmac = nullAuth WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(0)); Buffer += sizeof(UINT16); } return (UINT32)(UINTN)(Buffer - (UINT8 *)AuthSessionOut); }
/** This command returns the current policyDigest of the session. This command allows the TPM to be used to perform the actions required to precompute the authPolicy for an object. @param[in] PolicySession Handle for the policy session. @param[out] PolicyHash the current value of the policyHash of policySession. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI Tpm2PolicyGetDigest ( IN TPMI_SH_POLICY PolicySession, OUT TPM2B_DIGEST *PolicyHash ) { EFI_STATUS Status; TPM2_POLICY_GET_DIGEST_COMMAND SendBuffer; TPM2_POLICY_GET_DIGEST_RESPONSE RecvBuffer; UINT32 SendBufferSize; UINT32 RecvBufferSize; // // Construct command // SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyGetDigest); SendBuffer.PolicySession = SwapBytes32 (PolicySession); SendBufferSize = (UINT32) sizeof (SendBuffer); SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize); // // send Tpm command // RecvBufferSize = sizeof (RecvBuffer); Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer); if (EFI_ERROR (Status)) { return Status; } if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) { DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - RecvBufferSize Error - %x\n", RecvBufferSize)); return EFI_DEVICE_ERROR; } if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) { DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); return EFI_DEVICE_ERROR; } // // Return the response // PolicyHash->size = SwapBytes16 (RecvBuffer.PolicyHash.size); if (PolicyHash->size > sizeof(TPMU_HA)) { DEBUG ((DEBUG_ERROR, "Tpm2PolicyGetDigest - PolicyHash->size error %x\n", PolicyHash->size)); return EFI_DEVICE_ERROR; } CopyMem (PolicyHash->buffer, &RecvBuffer.PolicyHash.buffer, PolicyHash->size); return EFI_SUCCESS; }
/** This command returns various information regarding the TPM and its current state. The capability parameter determines the category of data returned. The property parameter selects the first value of the selected category to be returned. If there is no property that corresponds to the value of property, the next higher value is returned, if it exists. The moreData parameter will have a value of YES if there are more values of the requested type that were not returned. If no next capability exists, the TPM will return a zero-length list and moreData will have a value of NO. NOTE: To simplify this function, leave returned CapabilityData for caller to unpack since there are many capability categories and only few categories will be used in firmware. It means the caller need swap the byte order for the feilds in CapabilityData. @param[in] Capability Group selection; determines the format of the response. @param[in] Property Further definition of information. @param[in] PropertyCount Number of properties of the indicated type to return. @param[out] MoreData Flag to indicate if there are more values of this type. @param[out] CapabilityData The capability data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI Tpm2GetCapability ( IN TPM_CAP Capability, IN UINT32 Property, IN UINT32 PropertyCount, OUT TPMI_YES_NO *MoreData, OUT TPMS_CAPABILITY_DATA *CapabilityData ) { EFI_STATUS Status; TPM2_GET_CAPABILITY_COMMAND SendBuffer; TPM2_GET_CAPABILITY_RESPONSE RecvBuffer; UINT32 SendBufferSize; UINT32 RecvBufferSize; // // Construct command // SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_GetCapability); SendBuffer.Capability = SwapBytes32 (Capability); SendBuffer.Property = SwapBytes32 (Property); SendBuffer.PropertyCount = SwapBytes32 (PropertyCount); SendBufferSize = (UINT32) sizeof (SendBuffer); SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize); // // send Tpm command // RecvBufferSize = sizeof (RecvBuffer); Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer ); if (EFI_ERROR (Status)) { return Status; } if (RecvBufferSize <= sizeof (TPM2_RESPONSE_HEADER) + sizeof (UINT8)) { return EFI_DEVICE_ERROR; } // // Return the response // *MoreData = RecvBuffer.MoreData; // // Does not unpack all possiable property here, the caller should unpack it and note the byte order. // CopyMem (CapabilityData, &RecvBuffer.CapabilityData, RecvBufferSize - sizeof (TPM2_RESPONSE_HEADER) - sizeof (UINT8)); return EFI_SUCCESS; }
CHAR8 *devprop_generate_string(DevPropString *StringBuf) { UINTN len = StringBuf->length * 2; INT32 i = 0; UINT32 x = 0; CHAR8 *buffer = (CHAR8*)AllocatePool(len + 1); CHAR8 *ptr = buffer; // DBG("devprop_generate_string\n"); if(!buffer) return NULL; AsciiSPrint(buffer, len, "%08x%08x%04x%04x", SwapBytes32(StringBuf->length), StringBuf->WHAT2, SwapBytes16(StringBuf->numentries), StringBuf->WHAT3); buffer += 24; while(i < StringBuf->numentries) { UINT8 *dataptr = StringBuf->entries[i]->data; AsciiSPrint(buffer, len, "%08x%04x%04x", SwapBytes32(StringBuf->entries[i]->length), SwapBytes16(StringBuf->entries[i]->numentries), StringBuf->entries[i]->WHAT2); //FIXME: wrong buffer sizes! buffer += 16; AsciiSPrint(buffer, len, "%02x%02x%04x%08x%08x", StringBuf->entries[i]->acpi_dev_path.type, StringBuf->entries[i]->acpi_dev_path.subtype, SwapBytes16(StringBuf->entries[i]->acpi_dev_path.length), SwapBytes32(StringBuf->entries[i]->acpi_dev_path._HID), SwapBytes32(StringBuf->entries[i]->acpi_dev_path._UID)); buffer += 24; for(x = 0; x < StringBuf->entries[i]->num_pci_devpaths; x++) { AsciiSPrint(buffer, len, "%02x%02x%04x%02x%02x", StringBuf->entries[i]->pci_dev_path[x].type, StringBuf->entries[i]->pci_dev_path[x].subtype, SwapBytes16(StringBuf->entries[i]->pci_dev_path[x].length), StringBuf->entries[i]->pci_dev_path[x].function, StringBuf->entries[i]->pci_dev_path[x].device); buffer += 12; } AsciiSPrint(buffer, len, "%02x%02x%04x", StringBuf->entries[i]->path_end.type, StringBuf->entries[i]->path_end.subtype, SwapBytes16(StringBuf->entries[i]->path_end.length)); buffer += 8; for(x = 0; x < (StringBuf->entries[i]->length) - (24 + (6 * StringBuf->entries[i]->num_pci_devpaths)); x++) { AsciiSPrint(buffer, len, "%02x", *dataptr++); buffer += 2; } i++; } return ptr; }
/** This command returns the information of TPM PCRs. This function parse the value got from TPM2_GetCapability and return the PcrSelection. @param[out] Pcrs The Pcr Selection @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI Tpm2GetCapabilityPcrs ( OUT TPML_PCR_SELECTION *Pcrs ) { TPMS_CAPABILITY_DATA TpmCap; TPMI_YES_NO MoreData; EFI_STATUS Status; UINTN Index; Status = Tpm2GetCapability ( TPM_CAP_PCRS, 0, 1, &MoreData, &TpmCap ); if (EFI_ERROR (Status)) { return Status; } Pcrs->count = SwapBytes32 (TpmCap.data.assignedPCR.count); for (Index = 0; Index < Pcrs->count; Index++) { Pcrs->pcrSelections[Index].hash = SwapBytes16 (TpmCap.data.assignedPCR.pcrSelections[Index].hash); Pcrs->pcrSelections[Index].sizeofSelect = TpmCap.data.assignedPCR.pcrSelections[Index].sizeofSelect; CopyMem (Pcrs->pcrSelections[Index].pcrSelect, TpmCap.data.assignedPCR.pcrSelections[Index].pcrSelect, Pcrs->pcrSelections[Index].sizeofSelect); } return EFI_SUCCESS; }
/** Calculate the prefix length of the IPv4 subnet mask. @param[in] SubnetMask The IPv4 subnet mask. @return The prefix length of the subnet mask. @retval 0 Other errors as indicated. **/ UINT8 GetSubnetMaskPrefixLength ( IN EFI_IPv4_ADDRESS *SubnetMask ) { UINT8 Len; UINT32 ReverseMask; // // The SubnetMask is in network byte order. // ReverseMask = SwapBytes32 (*(UINT32 *)&SubnetMask[0]); // // Reverse it. // ReverseMask = ~ReverseMask; if ((ReverseMask & (ReverseMask + 1)) != 0) { return 0; } Len = 0; while (ReverseMask != 0) { ReverseMask = ReverseMask >> 1; Len++; } return (UINT8) (32 - Len); }
/** Read some blocks from the device by SCSI 16 byte cmd. @param UsbMass The USB mass storage device to read from @param Lba The start block number @param TotalBlock Total block number to read @param Buffer The buffer to read to @retval EFI_SUCCESS Data are read into the buffer @retval Others Failed to read all the data **/ EFI_STATUS UsbBootReadBlocks16 ( IN USB_MASS_DEVICE *UsbMass, IN UINT64 Lba, IN UINTN TotalBlock, OUT UINT8 *Buffer ) { UINT8 ReadCmd[16]; EFI_STATUS Status; UINT16 Count; UINT32 BlockSize; UINT32 ByteSize; UINT32 Timeout; BlockSize = UsbMass->BlockIoMedia.BlockSize; Status = EFI_SUCCESS; while (TotalBlock > 0) { // // Split the total blocks into smaller pieces. // Count = (UINT16)((TotalBlock < USB_BOOT_IO_BLOCKS) ? TotalBlock : USB_BOOT_IO_BLOCKS); ByteSize = (UINT32)Count * BlockSize; // // USB command's upper limit timeout is 5s. [USB2.0-9.2.6.1] // Timeout = (UINT32) USB_BOOT_GENERAL_CMD_TIMEOUT; // // Fill in the command then execute // ZeroMem (ReadCmd, sizeof (ReadCmd)); ReadCmd[0] = EFI_SCSI_OP_READ16; ReadCmd[1] = (UINT8) ((USB_BOOT_LUN (UsbMass->Lun) & 0xE0)); WriteUnaligned64 ((UINT64 *) &ReadCmd[2], SwapBytes64 (Lba)); WriteUnaligned32 ((UINT32 *) &ReadCmd[10], SwapBytes32 (Count)); Status = UsbBootExecCmdWithRetry ( UsbMass, ReadCmd, (UINT8) sizeof (ReadCmd), EfiUsbDataIn, Buffer, ByteSize, Timeout ); if (EFI_ERROR (Status)) { return Status; } DEBUG ((EFI_D_BLKIO, "UsbBootReadBlocks16: LBA (0x%lx), Blk (0x%x)\n", Lba, Count)); Lba += Count; Buffer += Count * BlockSize; TotalBlock -= Count; } return Status; }
/** Send TPM_ContinueSelfTest command to TPM. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_TIMEOUT The register can't run into the expected status in time. @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm12ContinueSelfTest ( VOID ) { TPM_RQU_COMMAND_HDR Command; TPM_RSP_COMMAND_HDR Response; UINT32 Length; // // send Tpm command TPM_ORD_ContinueSelfTest // Command.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); Command.paramSize = SwapBytes32 (sizeof (Command)); Command.ordinal = SwapBytes32 (TPM_ORD_ContinueSelfTest); return Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response); }
/** This command causes all context associated with a loaded object or session to be removed from TPM memory. @param[in] FlushHandle The handle of the item to flush. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI Tpm2FlushContext ( IN TPMI_DH_CONTEXT FlushHandle ) { EFI_STATUS Status; TPM2_FLUSH_CONTEXT_COMMAND SendBuffer; TPM2_FLUSH_CONTEXT_RESPONSE RecvBuffer; UINT32 SendBufferSize; UINT32 RecvBufferSize; // // Construct command // SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_FlushContext); SendBuffer.FlushHandle = SwapBytes32 (FlushHandle); SendBufferSize = (UINT32) sizeof (SendBuffer); SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize); // // send Tpm command // RecvBufferSize = sizeof (RecvBuffer); Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer); if (EFI_ERROR (Status)) { return Status; } if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) { DEBUG ((EFI_D_ERROR, "Tpm2FlushContext - RecvBufferSize Error - %x\n", RecvBufferSize)); return EFI_DEVICE_ERROR; } if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) { DEBUG ((EFI_D_ERROR, "Tpm2FlushContext - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); return EFI_DEVICE_ERROR; } return EFI_SUCCESS; }
/** Send NV ReadValue command to TPM1.2. @param NvIndex The index of the area to set. @param Offset The offset into the area. @param DataSize The size of the data area. @param Data The data to set the area to. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm12NvReadValue ( IN TPM_NV_INDEX NvIndex, IN UINT32 Offset, IN OUT UINT32 *DataSize, OUT UINT8 *Data ) { EFI_STATUS Status; TPM_CMD_NV_READ_VALUE Command; TPM_RSP_NV_READ_VALUE Response; UINT32 Length; // // send Tpm command TPM_ORD_NV_ReadValue // Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); Command.Hdr.paramSize = SwapBytes32 (sizeof (Command)); Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_ReadValue); Command.NvIndex = SwapBytes32 (NvIndex); Command.Offset = SwapBytes32 (Offset); Command.DataSize = SwapBytes32 (*DataSize); Length = sizeof (Response); Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response); if (EFI_ERROR (Status)) { return Status; } DEBUG ((DEBUG_INFO, "Tpm12NvReadValue - ReturnCode = %x\n", SwapBytes32 (Response.Hdr.returnCode))); switch (SwapBytes32 (Response.Hdr.returnCode)) { case TPM_SUCCESS: break; default: return EFI_DEVICE_ERROR; } // // Return the response // if (SwapBytes32 (Response.DataSize) > *DataSize) { return EFI_BUFFER_TOO_SMALL; } *DataSize = SwapBytes32 (Response.DataSize); ZeroMem (Data, *DataSize); CopyMem (Data, &Response.Data, *DataSize); return EFI_SUCCESS; }
STATIC VOID EfiGuidToRfc4122Uuid ( OUT RFC4122_UUID *Rfc4122Uuid, IN EFI_GUID *Guid ) { Rfc4122Uuid->Data1 = SwapBytes32 (Guid->Data1); Rfc4122Uuid->Data2 = SwapBytes16 (Guid->Data2); Rfc4122Uuid->Data3 = SwapBytes16 (Guid->Data3); CopyMem (Rfc4122Uuid->Data4, Guid->Data4, sizeof (Rfc4122Uuid->Data4)); }
/** This command causes the TPM to perform a test of its capabilities. If the fullTest is YES, the TPM will test all functions. If fullTest = NO, the TPM will only test those functions that have not previously been tested. @param[in] FullTest YES if full test to be performed NO if only test of untested functions required @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm2SelfTest ( IN TPMI_YES_NO FullTest ) { EFI_STATUS Status; TPM2_SELF_TEST_COMMAND Cmd; TPM2_SELF_TEST_RESPONSE Res; UINT32 ResultBufSize; Cmd.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd)); Cmd.Header.commandCode = SwapBytes32(TPM_CC_SelfTest); Cmd.FullTest = FullTest; ResultBufSize = sizeof(Res); Status = Tpm2SubmitCommand (sizeof(Cmd), (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res); return Status; }
/** Send NV DefineSpace command to TPM1.2. @param PubInfo The public parameters of the NV area. @param EncAuth The encrypted AuthData, only valid if the attributes require subsequent authorization. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm12NvDefineSpace ( IN TPM12_NV_DATA_PUBLIC *PubInfo, IN TPM_ENCAUTH *EncAuth ) { EFI_STATUS Status; UINT32 TpmRecvSize; UINT32 TpmSendSize; TPM_CMD_NV_DEFINE_SPACE SendBuffer; TPM_RSP_NV_DEFINE_SPACE RecvBuffer; UINT32 ReturnCode; // // send Tpm command TPM_ORD_NV_DefineSpace // TpmRecvSize = sizeof (TPM_RSP_NV_DEFINE_SPACE); TpmSendSize = sizeof (TPM_CMD_NV_DEFINE_SPACE); SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); SendBuffer.Hdr.paramSize = SwapBytes32 (sizeof(TPM_CMD_NV_DEFINE_SPACE)); SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_DefineSpace); SendBuffer.PubInfo.tag = SwapBytes16 (PubInfo->tag); SendBuffer.PubInfo.nvIndex = SwapBytes32 (PubInfo->nvIndex); SendBuffer.PubInfo.pcrInfoRead.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoRead.pcrSelection.sizeOfSelect); SendBuffer.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[0]; SendBuffer.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[1]; SendBuffer.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[2]; SendBuffer.PubInfo.pcrInfoRead.localityAtRelease = PubInfo->pcrInfoRead.localityAtRelease; CopyMem (&SendBuffer.PubInfo.pcrInfoRead.digestAtRelease, &PubInfo->pcrInfoRead.digestAtRelease, sizeof(PubInfo->pcrInfoRead.digestAtRelease)); SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoWrite.pcrSelection.sizeOfSelect); SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[0]; SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[1]; SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[2]; SendBuffer.PubInfo.pcrInfoWrite.localityAtRelease = PubInfo->pcrInfoWrite.localityAtRelease; CopyMem (&SendBuffer.PubInfo.pcrInfoWrite.digestAtRelease, &PubInfo->pcrInfoWrite.digestAtRelease, sizeof(PubInfo->pcrInfoWrite.digestAtRelease)); SendBuffer.PubInfo.permission.tag = SwapBytes16 (PubInfo->permission.tag); SendBuffer.PubInfo.permission.attributes = SwapBytes32 (PubInfo->permission.attributes); SendBuffer.PubInfo.bReadSTClear = PubInfo->bReadSTClear; SendBuffer.PubInfo.bWriteSTClear = PubInfo->bWriteSTClear; SendBuffer.PubInfo.bWriteDefine = PubInfo->bWriteDefine; SendBuffer.PubInfo.dataSize = SwapBytes32 (PubInfo->dataSize); CopyMem (&SendBuffer.EncAuth, EncAuth, sizeof(*EncAuth)); Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer); if (EFI_ERROR (Status)) { return Status; } ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode); DEBUG ((DEBUG_INFO, "Tpm12NvDefineSpace - ReturnCode = %x\n", ReturnCode)); switch (ReturnCode) { case TPM_SUCCESS: break; default: return EFI_DEVICE_ERROR; } return EFI_SUCCESS; }
void dng_stream::Put_uint32 (uint32 x) { if (fSwapBytes) { x = SwapBytes32 (x); } Put (&x, 4); }
/** This command returns the information of the maximum value for commandSize and responseSize in a command. This function parse the value got from TPM2_GetCapability and return the max command size and response size @param[out] MaxCommandSize The maximum value for commandSize in a command. @param[out] MaxResponseSize The maximum value for responseSize in a command. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI Tpm2GetCapabilityMaxCommandResponseSize ( OUT UINT32 *MaxCommandSize, OUT UINT32 *MaxResponseSize ) { TPMS_CAPABILITY_DATA TpmCap; TPMI_YES_NO MoreData; EFI_STATUS Status; Status = Tpm2GetCapability ( TPM_CAP_TPM_PROPERTIES, TPM_PT_MAX_COMMAND_SIZE, 1, &MoreData, &TpmCap ); if (EFI_ERROR (Status)) { return Status; } *MaxCommandSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value); Status = Tpm2GetCapability ( TPM_CAP_TPM_PROPERTIES, TPM_PT_MAX_RESPONSE_SIZE, 1, &MoreData, &TpmCap ); if (EFI_ERROR (Status)) { return Status; } *MaxResponseSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value); return EFI_SUCCESS; }
/** Issue TSC_PhysicalPresence command to TPM. @param[in] TcgProtocol EFI TCG Protocol instance. @param[in] PhysicalPresence The state to set the TPM's Physical Presence flags. @retval EFI_SUCCESS TPM executed the command successfully. @retval EFI_SECURITY_VIOLATION TPM returned error when executing the command. @retval other Failed to locate EFI TCG Protocol. **/ EFI_STATUS TpmPhysicalPresence ( IN EFI_TCG_PROTOCOL *TcgProtocol, IN TPM_PHYSICAL_PRESENCE PhysicalPresence ) { EFI_STATUS Status; TPM_RQU_COMMAND_HDR *TpmRqu; TPM_PHYSICAL_PRESENCE *TpmPp; TPM_RSP_COMMAND_HDR TpmRsp; UINT8 Buffer[sizeof (*TpmRqu) + sizeof (*TpmPp)]; TpmRqu = (TPM_RQU_COMMAND_HDR*)Buffer; TpmPp = (TPM_PHYSICAL_PRESENCE*)(TpmRqu + 1); TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); TpmRqu->paramSize = SwapBytes32 (sizeof (Buffer)); TpmRqu->ordinal = SwapBytes32 (TSC_ORD_PhysicalPresence); WriteUnaligned16 (TpmPp, (TPM_PHYSICAL_PRESENCE) SwapBytes16 (PhysicalPresence)); Status = TcgProtocol->PassThroughToTpm ( TcgProtocol, sizeof (Buffer), (UINT8*)TpmRqu, sizeof (TpmRsp), (UINT8*)&TpmRsp ); ASSERT_EFI_ERROR (Status); ASSERT (TpmRsp.tag == SwapBytes16 (TPM_TAG_RSP_COMMAND)); if (TpmRsp.returnCode != 0) { // // If it fails, some requirements may be needed for this command. // return EFI_SECURITY_VIOLATION; } return Status; }
/** Send TPM_ContinueSelfTest command to TPM. @param[in] PeiServices Describes the list of possible PEI Services. @param[in] TpmHandle TPM handle. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_TIMEOUT The register can't run into the expected status in time. @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS TpmCommContinueSelfTest ( IN EFI_PEI_SERVICES **PeiServices, IN TIS_TPM_HANDLE TpmHandle ) { EFI_STATUS Status; UINT32 TpmRecvSize; UINT32 TpmSendSize; TPM_CMD_SELF_TEST SendBuffer; UINT8 RecvBuffer[20]; // // send Tpm command TPM_ORD_ContinueSelfTest // TpmRecvSize = 20; TpmSendSize = sizeof (TPM_CMD_SELF_TEST); SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize); SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_ContinueSelfTest); Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize); return Status; }
/** Send Startup command to TPM1.2. @param TpmSt Startup Type. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm12Startup ( IN TPM_STARTUP_TYPE TpmSt ) { EFI_STATUS Status; UINT32 TpmRecvSize; UINT32 TpmSendSize; TPM_CMD_START_UP SendBuffer; TPM_RSP_START_UP RecvBuffer; UINT32 ReturnCode; // // send Tpm command TPM_ORD_Startup // TpmRecvSize = sizeof (TPM_RSP_START_UP); TpmSendSize = sizeof (TPM_CMD_START_UP); SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize); SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_Startup); SendBuffer.TpmSt = SwapBytes16 (TpmSt); Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer); if (EFI_ERROR (Status)) { return Status; } ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode); switch (ReturnCode) { case TPM_SUCCESS: case TPM_INVALID_POSTINIT: // In warm reset, TPM may response TPM_INVALID_POSTINIT return EFI_SUCCESS; default: return EFI_DEVICE_ERROR; } }
/** Send Startup command to TPM2. @param[in] StartupType TPM_SU_CLEAR or TPM_SU_STATE @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm2Startup ( IN TPM_SU StartupType ) { EFI_STATUS Status; TPM2_STARTUP_COMMAND Cmd; TPM2_STARTUP_RESPONSE Res; UINT32 ResultBufSize; TPM_RC ResponseCode; Cmd.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS); Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd)); Cmd.Header.commandCode = SwapBytes32(TPM_CC_Startup); Cmd.StartupType = SwapBytes16(StartupType); ResultBufSize = sizeof(Res); Status = Tpm2SubmitCommand (sizeof(Cmd), (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res); if (EFI_ERROR(Status)) { return Status; } ResponseCode = SwapBytes32(Res.Header.responseCode); switch (ResponseCode) { case TPM_RC_SUCCESS: DEBUG ((DEBUG_INFO, "TPM2Startup: TPM_RC_SUCCESS\n")); return EFI_SUCCESS; case TPM_RC_INITIALIZE: // TPM_RC_INITIALIZE can be returned if Tpm2Startup is not required. DEBUG ((DEBUG_INFO, "TPM2Startup: TPM_RC_INITIALIZE\n")); return EFI_SUCCESS; default: DEBUG ((EFI_D_ERROR, "Tpm2Startup: Response Code error! 0x%08x\r\n", ResponseCode)); return EFI_DEVICE_ERROR; } }
/** Starts a new ComPacket in the Data structure. @param [in/out] CreateStruct Structure used to add Tcg Packet @param[in] Tsn Packet Tper session number @param[in] Hsn Packet Host session number @param[in] SeqNumber Packet Sequence Number @param[in] AckType Packet Acknowledge Type @param[in] Ack Packet Acknowledge **/ TCG_RESULT EFIAPI TcgStartPacket( TCG_CREATE_STRUCT *CreateStruct, UINT32 Tsn, UINT32 Hsn, UINT32 SeqNumber, UINT16 AckType, UINT32 Ack ) { UINT32 AddedSize; NULL_CHECK(CreateStruct); AddedSize = 0; if (CreateStruct->ComPacket == NULL || CreateStruct->CurPacket != NULL || CreateStruct->CurSubPacket != NULL ) { DEBUG ((DEBUG_INFO, "unexpected state: ComPacket=%p CurPacket=%p CurSubPacket=%p\n", CreateStruct->ComPacket, CreateStruct->CurPacket, CreateStruct->CurSubPacket)); return (TcgResultFailureInvalidAction); } // update TCG_COM_PACKET and packet lengths AddedSize = sizeof(TCG_PACKET); if ((SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize) > CreateStruct->BufferSize) { DEBUG ((DEBUG_INFO, "BufferSize=0x%X\n", CreateStruct->BufferSize)); return (TcgResultFailureBufferTooSmall); } CreateStruct->CurPacket = (TCG_PACKET*)(CreateStruct->ComPacket->Payload + SwapBytes32(CreateStruct->ComPacket->LengthBE)); CreateStruct->CurPacket->TperSessionNumberBE = SwapBytes32( Tsn ); CreateStruct->CurPacket->HostSessionNumberBE = SwapBytes32( Hsn ); CreateStruct->CurPacket->SequenceNumberBE = SwapBytes32( SeqNumber ); CreateStruct->CurPacket->AckTypeBE = SwapBytes16( AckType ); CreateStruct->CurPacket->AcknowledgementBE = SwapBytes32( Ack ); CreateStruct->CurPacket->LengthBE = 0; // update TCG_COM_PACKET Length for next pointer CreateStruct->ComPacket->LengthBE = SwapBytes32( SwapBytes32(CreateStruct->ComPacket->LengthBE) + AddedSize ); return (TcgResultSuccess); }