summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c344
1 files changed, 344 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c
new file mode 100644
index 00000000..510ad426
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c
@@ -0,0 +1,344 @@
+/** @file
+ Implement TPM2 help.
+
+Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.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_ERROR, "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_ERROR, "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 ((EFI_D_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;
+}