You've already forked slimbootloader
mirror of
https://github.com/Dasharo/slimbootloader.git
synced 2026-03-06 15:26:20 -08:00
990e3e81e6
Convert the line endings stored for all text files in the repository to LF. The majority previously used DOS-style CRLF line endings. Add a .gitattributes file to enforce this and treat certain extensions as never being text files. Update PatchCheck.py to insist on LF line endings rather than CRLF. However, its other checks fail on this commit due to lots of pre-existing complaints that it only notices because the line endings have changed. Silicon/QemuSocPkg/FspBin/Patches/0001-Build-QEMU-FSP-2.0-binaries.patch needs to be treated as binary since it contains a mixture of line endings. This change has implications depending on the client platform you are using the repository from: * Windows The usual configuration for Git on Windows means that text files will be checked out to the work tree with DOS-style CRLF line endings. If that's not the case then you can configure Git to do so for the entire machine with: git config --global core.autocrlf true or for just the repository with: git config core.autocrlf true Line endings will be normalised to LF when they are committed to the repository. If you commit a text file with only LF line endings then it will be converted to CRLF line endings in your work tree. * Linux, MacOS and other Unices The usual configuration for Git on such platforms is to check files out of the repository with LF line endings. This is probably the right thing for you. In the unlikely even that you are using Git on Unix but editing or compiling on Windows for some reason then you may need to tweak your configuration to force the use of CRLF line endings as described above. * General For more information see https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings . Fixes: https://github.com/slimbootloader/slimbootloader/issues/1400 Signed-off-by: Mike Crowe <mac@mcrowe.com>
419 lines
14 KiB
C
419 lines
14 KiB
C
/** @file
|
|
Implement TPM2 Integrity related command.
|
|
|
|
Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <IndustryStandard/UefiTcgPlatform.h>
|
|
#include <Tpm2CommandLib.h>
|
|
#include <Tpm2DeviceLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
|
|
#pragma pack(1)
|
|
|
|
typedef struct {
|
|
TPM2_COMMAND_HEADER Header;
|
|
TPMI_DH_PCR PcrHandle;
|
|
UINT32 AuthorizationSize;
|
|
TPMS_AUTH_COMMAND AuthSessionPcr;
|
|
TPML_DIGEST_VALUES DigestValues;
|
|
} TPM2_PCR_EXTEND_COMMAND;
|
|
|
|
typedef struct {
|
|
TPM2_RESPONSE_HEADER Header;
|
|
UINT32 ParameterSize;
|
|
TPMS_AUTH_RESPONSE AuthSessionPcr;
|
|
} TPM2_PCR_EXTEND_RESPONSE;
|
|
|
|
typedef struct {
|
|
TPM2_COMMAND_HEADER Header;
|
|
TPMI_RH_PLATFORM AuthHandle;
|
|
UINT32 AuthSessionSize;
|
|
TPMS_AUTH_COMMAND AuthSession;
|
|
TPML_PCR_SELECTION PcrAllocation;
|
|
} TPM2_PCR_ALLOCATE_COMMAND;
|
|
|
|
typedef struct {
|
|
TPM2_RESPONSE_HEADER Header;
|
|
UINT32 AuthSessionSize;
|
|
TPMI_YES_NO AllocationSuccess;
|
|
UINT32 MaxPCR;
|
|
UINT32 SizeNeeded;
|
|
UINT32 SizeAvailable;
|
|
TPMS_AUTH_RESPONSE AuthSession;
|
|
} TPM2_PCR_ALLOCATE_RESPONSE;
|
|
|
|
#pragma pack()
|
|
|
|
/**
|
|
This command is used to cause an update to the indicated PCR.
|
|
The digests parameter contains one or more tagged digest value identified by an algorithm ID.
|
|
For each digest, the PCR associated with pcrHandle is Extended into the bank identified by the tag (hashAlg).
|
|
|
|
@param[in] PcrHandle Handle of the PCR
|
|
@param[in] Digests List of tagged digest values to be extended
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
Tpm2PcrExtend (
|
|
IN TPMI_DH_PCR PcrHandle,
|
|
IN TPML_DIGEST_VALUES *Digests
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
TPM2_PCR_EXTEND_COMMAND Cmd;
|
|
TPM2_PCR_EXTEND_RESPONSE Res;
|
|
UINT32 CmdSize;
|
|
UINT32 RespSize;
|
|
UINT32 ResultBufSize;
|
|
UINT8 *Buffer;
|
|
UINTN Index;
|
|
UINT32 SessionInfoSize;
|
|
UINT16 DigestSize;
|
|
|
|
Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
|
|
Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Extend);
|
|
Cmd.PcrHandle = SwapBytes32 (PcrHandle);
|
|
|
|
|
|
//
|
|
// Add in Auth session
|
|
//
|
|
Buffer = (UINT8 *)&Cmd.AuthSessionPcr;
|
|
|
|
// sessionInfoSize
|
|
SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);
|
|
Buffer += SessionInfoSize;
|
|
Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
|
|
|
|
//Digest Count
|
|
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Digests->count));
|
|
Buffer += sizeof (UINT32);
|
|
|
|
//Digest
|
|
for (Index = 0; Index < Digests->count; Index++) {
|
|
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Digests->digests[Index].hashAlg));
|
|
Buffer += sizeof (UINT16);
|
|
DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
|
|
if (DigestSize == 0) {
|
|
DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
CopyMem (
|
|
Buffer,
|
|
&Digests->digests[Index].digest,
|
|
DigestSize
|
|
);
|
|
Buffer += DigestSize;
|
|
}
|
|
|
|
CmdSize = (UINT32) ((UINTN)Buffer - (UINTN)&Cmd);
|
|
Cmd.Header.paramSize = SwapBytes32 (CmdSize);
|
|
|
|
ResultBufSize = sizeof (Res);
|
|
Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (ResultBufSize > sizeof (Res)) {
|
|
DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
//
|
|
// Validate response headers
|
|
//
|
|
RespSize = SwapBytes32 (Res.Header.paramSize);
|
|
if (RespSize > sizeof (Res)) {
|
|
DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
//
|
|
// Fail if command failed
|
|
//
|
|
if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
|
DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
//
|
|
// Unmarshal the response
|
|
//
|
|
|
|
// None
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This command is used to set the desired PCR allocation of PCR and algorithms.
|
|
|
|
@param[in] AuthHandle TPM_RH_PLATFORM+{PP}
|
|
@param[in] AuthSession Auth Session context
|
|
@param[in] PcrAllocation The requested allocation
|
|
@param[out] AllocationSuccess YES if the allocation succeeded
|
|
@param[out] MaxPCR maximum number of PCR that may be in a bank
|
|
@param[out] SizeNeeded number of octets required to satisfy the request
|
|
@param[out] SizeAvailable Number of octets available. Computed before the allocation
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
Tpm2PcrAllocate (
|
|
IN TPMI_RH_PLATFORM AuthHandle,
|
|
IN TPMS_AUTH_COMMAND *AuthSession,
|
|
IN TPML_PCR_SELECTION *PcrAllocation,
|
|
OUT TPMI_YES_NO *AllocationSuccess,
|
|
OUT UINT32 *MaxPCR,
|
|
OUT UINT32 *SizeNeeded,
|
|
OUT UINT32 *SizeAvailable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
TPM2_PCR_ALLOCATE_COMMAND Cmd;
|
|
TPM2_PCR_ALLOCATE_RESPONSE Res;
|
|
UINT32 CmdSize;
|
|
UINT32 RespSize;
|
|
UINT8 *Buffer;
|
|
UINT32 SessionInfoSize;
|
|
UINT8 *ResultBuf;
|
|
UINT32 ResultBufSize;
|
|
UINTN Index;
|
|
|
|
//
|
|
// Construct command
|
|
//
|
|
Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
|
|
Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));
|
|
Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Allocate);
|
|
Cmd.AuthHandle = SwapBytes32 (AuthHandle);
|
|
|
|
//
|
|
// Add in Auth session
|
|
//
|
|
Buffer = (UINT8 *)&Cmd.AuthSession;
|
|
|
|
// sessionInfoSize
|
|
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
|
Buffer += SessionInfoSize;
|
|
Cmd.AuthSessionSize = SwapBytes32 (SessionInfoSize);
|
|
|
|
// Count
|
|
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (PcrAllocation->count));
|
|
Buffer += sizeof (UINT32);
|
|
for (Index = 0; Index < PcrAllocation->count; Index++) {
|
|
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (PcrAllocation->pcrSelections[Index].hash));
|
|
Buffer += sizeof (UINT16);
|
|
* (UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;
|
|
Buffer++;
|
|
CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);
|
|
Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;
|
|
}
|
|
|
|
CmdSize = (UINT32) (Buffer - (UINT8 *)&Cmd);
|
|
Cmd.Header.paramSize = SwapBytes32 (CmdSize);
|
|
|
|
ResultBuf = (UINT8 *) &Res;
|
|
ResultBufSize = sizeof (Res);
|
|
|
|
//
|
|
// Call the TPM
|
|
//
|
|
Status = Tpm2SubmitCommand (
|
|
CmdSize,
|
|
(UINT8 *)&Cmd,
|
|
&ResultBufSize,
|
|
ResultBuf
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
goto Done;
|
|
}
|
|
|
|
if (ResultBufSize > sizeof (Res)) {
|
|
DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
|
Status = EFI_BUFFER_TOO_SMALL;
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// Validate response headers
|
|
//
|
|
RespSize = SwapBytes32 (Res.Header.paramSize);
|
|
if (RespSize > sizeof (Res)) {
|
|
DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
|
|
Status = EFI_BUFFER_TOO_SMALL;
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// Fail if command failed
|
|
//
|
|
if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
|
DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
|
|
Status = EFI_DEVICE_ERROR;
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// Return the response
|
|
//
|
|
*AllocationSuccess = Res.AllocationSuccess;
|
|
*MaxPCR = SwapBytes32 (Res.MaxPCR);
|
|
*SizeNeeded = SwapBytes32 (Res.SizeNeeded);
|
|
*SizeAvailable = SwapBytes32 (Res.SizeAvailable);
|
|
|
|
Done:
|
|
//
|
|
// Clear AuthSession Content
|
|
//
|
|
ZeroMem (&Cmd, sizeof (Cmd));
|
|
ZeroMem (&Res, sizeof (Res));
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Alloc PCR data.
|
|
|
|
@param[in] PlatformAuth platform auth value. NULL means no platform auth change.
|
|
@param[in] SupportedPCRBanks Supported PCR banks
|
|
@param[in] PCRBanks PCR banks
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
Tpm2PcrAllocateBanks (
|
|
IN TPM2B_AUTH *PlatformAuth, OPTIONAL
|
|
IN UINT32 SupportedPCRBanks,
|
|
IN UINT32 PCRBanks
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
TPMS_AUTH_COMMAND *AuthSession;
|
|
TPMS_AUTH_COMMAND LocalAuthSession;
|
|
TPML_PCR_SELECTION PcrAllocation;
|
|
TPMI_YES_NO AllocationSuccess;
|
|
UINT32 MaxPCR;
|
|
UINT32 SizeNeeded;
|
|
UINT32 SizeAvailable;
|
|
|
|
if (PlatformAuth == NULL) {
|
|
AuthSession = NULL;
|
|
} else {
|
|
AuthSession = &LocalAuthSession;
|
|
ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));
|
|
LocalAuthSession.sessionHandle = TPM_RS_PW;
|
|
LocalAuthSession.hmac.size = PlatformAuth->size;
|
|
CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
|
|
}
|
|
|
|
//
|
|
// Fill input
|
|
//
|
|
ZeroMem (&PcrAllocation, sizeof (PcrAllocation));
|
|
if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
|
|
if ((HASH_ALG_SHA1 & PCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
|
|
} else {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
|
|
}
|
|
PcrAllocation.count++;
|
|
}
|
|
if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
|
|
if ((HASH_ALG_SHA256 & PCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
|
|
} else {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
|
|
}
|
|
PcrAllocation.count++;
|
|
}
|
|
if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
|
|
if ((HASH_ALG_SHA384 & PCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
|
|
} else {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
|
|
}
|
|
PcrAllocation.count++;
|
|
}
|
|
if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
|
|
if ((HASH_ALG_SHA512 & PCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
|
|
} else {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
|
|
}
|
|
PcrAllocation.count++;
|
|
}
|
|
if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
|
|
if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
|
|
} else {
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
|
|
PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
|
|
}
|
|
PcrAllocation.count++;
|
|
}
|
|
Status = Tpm2PcrAllocate (
|
|
TPM_RH_PLATFORM,
|
|
AuthSession,
|
|
&PcrAllocation,
|
|
&AllocationSuccess,
|
|
&MaxPCR,
|
|
&SizeNeeded,
|
|
&SizeAvailable
|
|
);
|
|
DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
|
|
if (EFI_ERROR (Status)) {
|
|
goto Done;
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
|
|
DEBUG ((DEBUG_INFO, "MaxPCR - %08x\n", MaxPCR));
|
|
DEBUG ((DEBUG_INFO, "SizeNeeded - %08x\n", SizeNeeded));
|
|
DEBUG ((DEBUG_INFO, "SizeAvailable - %08x\n", SizeAvailable));
|
|
|
|
Done:
|
|
ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));
|
|
return Status;
|
|
}
|