You've already forked slimbootloader
mirror of
https://github.com/Dasharo/slimbootloader.git
synced 2026-03-06 15:26:20 -08:00
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>
426 lines
10 KiB
C
426 lines
10 KiB
C
/** @file
|
|
Implement TPM2 help.
|
|
|
|
Copyright (c) 2013 - 2017, 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>
|
|
#include <Library/CryptoLib.h>
|
|
|
|
typedef struct {
|
|
TPMI_ALG_HASH HashAlgo;
|
|
UINT16 HashSize;
|
|
UINT32 HashMask;
|
|
} INTERNAL_HASH_INFO;
|
|
|
|
STATIC INTERNAL_HASH_INFO mHashInfo[] = {
|
|
{TPM_ALG_SHA1, SHA1_DIGEST_SIZE, HASH_ALG_SHA1},
|
|
{TPM_ALG_SHA256, SHA256_DIGEST_SIZE, HASH_ALG_SHA256},
|
|
{TPM_ALG_SM3_256, SM3_256_DIGEST_SIZE, HASH_ALG_SM3_256},
|
|
{TPM_ALG_SHA384, SHA384_DIGEST_SIZE, HASH_ALG_SHA384},
|
|
{TPM_ALG_SHA512, SHA512_DIGEST_SIZE, HASH_ALG_SHA512},
|
|
};
|
|
|
|
/**
|
|
Return size of digest.
|
|
|
|
@param[in] HashAlgo Hash algorithm
|
|
|
|
@return size of digest
|
|
**/
|
|
UINT16
|
|
EFIAPI
|
|
GetHashSizeFromAlgo (
|
|
IN TPMI_ALG_HASH HashAlgo
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < sizeof (mHashInfo) / sizeof (mHashInfo[0]); Index++) {
|
|
if (mHashInfo[Index].HashAlgo == HashAlgo) {
|
|
return mHashInfo[Index].HashSize;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
Get hash mask from algorithm.
|
|
|
|
@param[in] HashAlgo Hash algorithm
|
|
|
|
@return Hash mask
|
|
**/
|
|
UINT32
|
|
EFIAPI
|
|
GetHashMaskFromAlgo (
|
|
IN TPMI_ALG_HASH HashAlgo
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < sizeof (mHashInfo) / sizeof (mHashInfo[0]); Index++) {
|
|
if (mHashInfo[Index].HashAlgo == HashAlgo) {
|
|
return mHashInfo[Index].HashMask;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
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 - (UINTN)AuthSessionOut);
|
|
}
|
|
|
|
/**
|
|
Copy AuthSessionIn from TPM2 response buffer.
|
|
|
|
@param [in] AuthSessionIn Input AuthSession data in TPM2 response buffer
|
|
@param [out] AuthSessionOut Output AuthSession data
|
|
|
|
@return 0 copy failed
|
|
else AuthSession size
|
|
**/
|
|
UINT32
|
|
EFIAPI
|
|
CopyAuthSessionResponse (
|
|
IN UINT8 *AuthSessionIn,
|
|
OUT TPMS_AUTH_RESPONSE *AuthSessionOut OPTIONAL
|
|
)
|
|
{
|
|
UINT8 *Buffer;
|
|
TPMS_AUTH_RESPONSE LocalAuthSessionOut;
|
|
|
|
if (AuthSessionOut == NULL) {
|
|
AuthSessionOut = &LocalAuthSessionOut;
|
|
}
|
|
|
|
Buffer = (UINT8 *)AuthSessionIn;
|
|
|
|
// nonce
|
|
AuthSessionOut->nonce.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
|
|
Buffer += sizeof (UINT16);
|
|
if (AuthSessionOut->nonce.size > sizeof(TPMU_HA)) {
|
|
DEBUG ((DEBUG_VERBOSE, "CopyAuthSessionResponse - nonce.size error %x\n", AuthSessionOut->nonce.size));
|
|
return 0;
|
|
}
|
|
|
|
CopyMem (AuthSessionOut->nonce.buffer, Buffer, AuthSessionOut->nonce.size);
|
|
Buffer += AuthSessionOut->nonce.size;
|
|
|
|
// sessionAttributes
|
|
* (UINT8 *)&AuthSessionOut->sessionAttributes = * (UINT8 *)Buffer;
|
|
Buffer++;
|
|
|
|
// hmac
|
|
AuthSessionOut->hmac.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
|
|
Buffer += sizeof (UINT16);
|
|
if (AuthSessionOut->hmac.size > sizeof(TPMU_HA)) {
|
|
DEBUG ((DEBUG_VERBOSE, "CopyAuthSessionResponse - hmac.size error %x\n", AuthSessionOut->hmac.size));
|
|
return 0;
|
|
}
|
|
|
|
CopyMem (AuthSessionOut->hmac.buffer, Buffer, AuthSessionOut->hmac.size);
|
|
Buffer += AuthSessionOut->hmac.size;
|
|
|
|
return (UINT32) ((UINTN)Buffer - (UINTN)AuthSessionIn);
|
|
}
|
|
|
|
/**
|
|
Return if hash alg is supported in HashAlgorithmMask.
|
|
|
|
@param HashAlg Hash algorithm to be checked.
|
|
@param HashAlgorithmMask Bitfield of allowed hash algorithms.
|
|
|
|
@retval TRUE Hash algorithm is supported.
|
|
@retval FALSE Hash algorithm is not supported.
|
|
**/
|
|
BOOLEAN
|
|
EFIAPI
|
|
IsHashAlgSupportedInHashAlgorithmMask (
|
|
IN TPMI_ALG_HASH HashAlg,
|
|
IN UINT32 HashAlgorithmMask
|
|
)
|
|
{
|
|
switch (HashAlg) {
|
|
case TPM_ALG_SHA1:
|
|
if ((HashAlgorithmMask & HASH_ALG_SHA1) != 0) {
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case TPM_ALG_SHA256:
|
|
if ((HashAlgorithmMask & HASH_ALG_SHA256) != 0) {
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case TPM_ALG_SHA384:
|
|
if ((HashAlgorithmMask & HASH_ALG_SHA384) != 0) {
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case TPM_ALG_SHA512:
|
|
if ((HashAlgorithmMask & HASH_ALG_SHA512) != 0) {
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case TPM_ALG_SM3_256:
|
|
if ((HashAlgorithmMask & HASH_ALG_SM3_256) != 0) {
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Copy TPML_DIGEST_VALUES into a buffer
|
|
|
|
@param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
|
|
@param[in] DigestList TPML_DIGEST_VALUES to be copied.
|
|
@param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
|
|
|
|
@return The end of buffer to hold TPML_DIGEST_VALUES.
|
|
**/
|
|
VOID *
|
|
EFIAPI
|
|
CopyDigestListToBuffer (
|
|
IN OUT VOID *Buffer,
|
|
IN TPML_DIGEST_VALUES *DigestList,
|
|
IN UINT32 HashAlgorithmMask
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINT16 DigestSize;
|
|
UINT32 DigestListCount;
|
|
UINT32 *DigestListCountPtr;
|
|
|
|
DigestListCountPtr = (UINT32 *) Buffer;
|
|
DigestListCount = 0;
|
|
Buffer = (UINT8 *)Buffer + sizeof (DigestList->count);
|
|
for (Index = 0; Index < DigestList->count; Index++) {
|
|
if (!IsHashAlgSupportedInHashAlgorithmMask (DigestList->digests[Index].hashAlg, HashAlgorithmMask)) {
|
|
DEBUG ((DEBUG_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n",
|
|
DigestList->digests[Index].hashAlg));
|
|
continue;
|
|
}
|
|
CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof (DigestList->digests[Index].hashAlg));
|
|
Buffer = (UINT8 *)Buffer + sizeof (DigestList->digests[Index].hashAlg);
|
|
DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);
|
|
CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);
|
|
Buffer = (UINT8 *)Buffer + DigestSize;
|
|
DigestListCount++;
|
|
}
|
|
WriteUnaligned32 (DigestListCountPtr, DigestListCount);
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
/**
|
|
Get TPML_DIGEST_VALUES data size.
|
|
|
|
@param[in] DigestList TPML_DIGEST_VALUES data.
|
|
|
|
@return TPML_DIGEST_VALUES data size.
|
|
**/
|
|
UINT32
|
|
EFIAPI
|
|
GetDigestListSize (
|
|
IN TPML_DIGEST_VALUES *DigestList
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINT16 DigestSize;
|
|
UINT32 TotalSize;
|
|
|
|
TotalSize = sizeof (DigestList->count);
|
|
for (Index = 0; Index < DigestList->count; Index++) {
|
|
DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);
|
|
TotalSize += sizeof (DigestList->digests[Index].hashAlg) + DigestSize;
|
|
}
|
|
|
|
return TotalSize;
|
|
}
|
|
|
|
/**
|
|
This function get digest from digest list.
|
|
|
|
@param[in] HashAlg Digest algorithm
|
|
@param[in] DigestList Digest list
|
|
@param[out] Digest Digest
|
|
|
|
@retval EFI_SUCCESS Digest is found and returned.
|
|
@retval EFI_NOT_FOUND Digest is not found.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetDigestFromDigestList (
|
|
IN TPMI_ALG_HASH HashAlg,
|
|
IN TPML_DIGEST_VALUES *DigestList,
|
|
OUT VOID *Digest
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINT16 DigestSize;
|
|
|
|
DigestSize = GetHashSizeFromAlgo (HashAlg);
|
|
for (Index = 0; Index < DigestList->count; Index++) {
|
|
if (DigestList->digests[Index].hashAlg == HashAlg) {
|
|
CopyMem (
|
|
Digest,
|
|
&DigestList->digests[Index].digest,
|
|
DigestSize
|
|
);
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
|
|
/**
|
|
Generates requested random bytes using RDRAND instruction.
|
|
|
|
@param[out] Buffer Buffer to populate with random bytes.
|
|
@param[in] Len length of random bytes required.
|
|
|
|
@retval 0 if SUCCESS, 1 if error.
|
|
**/
|
|
UINT32
|
|
EFIAPI
|
|
GetRandomBytes (
|
|
OUT UINT8 *Buffer,
|
|
IN UINT32 Len
|
|
)
|
|
{
|
|
UINT32 Rand32;
|
|
INT32 CurBlocks;
|
|
INT32 RemainingBytes;
|
|
INT32 TotalBlocks;
|
|
|
|
CurBlocks = 0;
|
|
RemainingBytes = 0;
|
|
TotalBlocks = Len / sizeof(Rand32);
|
|
|
|
if (TotalBlocks != 0) {
|
|
while( CurBlocks < TotalBlocks) {
|
|
if (AsmRdRand32 (&Rand32)) {
|
|
CopyMem(Buffer + (CurBlocks*sizeof(Rand32)), (UINT8*)&Rand32, sizeof(Rand32));
|
|
} else {
|
|
goto err;
|
|
}
|
|
|
|
CurBlocks++;
|
|
}
|
|
}
|
|
|
|
RemainingBytes = Len - (CurBlocks * sizeof(Rand32));
|
|
if (RemainingBytes != 0) {
|
|
if (AsmRdRand32 (&Rand32)){
|
|
CopyMem(Buffer + (CurBlocks*sizeof(Rand32)), (UINT8*)&Rand32, RemainingBytes);
|
|
} else {
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
|
|
err:
|
|
DEBUG ((DEBUG_ERROR, "RDRAND32 error\n"));
|
|
return 1;
|
|
}
|
|
|
|
|
|
/**
|
|
It attempts to wipe sensitive data from memory.
|
|
|
|
@param[in] Buffer Buffer to sanitize.
|
|
@param[in] Val Update buffer with this value.
|
|
@param[in] Len Size of above buffer.
|
|
|
|
@retval the sanitized input buffer.
|
|
**/
|
|
VOID *
|
|
EFIAPI
|
|
SecureZeroMem (
|
|
IN VOID *Buffer,
|
|
IN UINT8 Val,
|
|
IN UINT32 Len
|
|
)
|
|
{
|
|
volatile UINT8 *Ptr;
|
|
Ptr = Buffer;
|
|
while (Len-- != 0) {
|
|
*Ptr++ = Val;
|
|
}
|
|
return Buffer;
|
|
}
|