mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 02:19:12 +00:00 
			
		
		
		
	REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the SecurityPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
		
			
				
	
	
		
			1499 lines
		
	
	
		
			53 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1499 lines
		
	
	
		
			53 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Pkcs7Verify Driver to produce the UEFI PKCS7 Verification Protocol.
 | 
						|
 | 
						|
  The driver will produce the UEFI PKCS7 Verification Protocol which is used to
 | 
						|
  verify data signed using PKCS7 structure. The PKCS7 data to be verified must
 | 
						|
  be ASN.1 (DER) encoded.
 | 
						|
 | 
						|
Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Library/BaseCryptLib.h>
 | 
						|
#include <Protocol/Pkcs7Verify.h>
 | 
						|
 | 
						|
#define MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
 | 
						|
 | 
						|
/**
 | 
						|
  Calculates the hash of the given data based on the specified hash GUID.
 | 
						|
 | 
						|
  @param[in]  Data      Pointer to the data buffer to be hashed.
 | 
						|
  @param[in]  DataSize  The size of data buffer in bytes.
 | 
						|
  @param[in]  CertGuid  The GUID to identify the hash algorithm to be used.
 | 
						|
  @param[out] HashValue Pointer to a buffer that receives the hash result.
 | 
						|
 | 
						|
  @retval TRUE          Data hash calculation succeeded.
 | 
						|
  @retval FALSE         Data hash calculation failed.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
CalculateDataHash (
 | 
						|
  IN  VOID      *Data,
 | 
						|
  IN  UINTN     DataSize,
 | 
						|
  IN  EFI_GUID  *CertGuid,
 | 
						|
  OUT UINT8     *HashValue
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOOLEAN  Status;
 | 
						|
  VOID     *HashCtx;
 | 
						|
  UINTN    CtxSize;
 | 
						|
 | 
						|
  Status  = FALSE;
 | 
						|
  HashCtx = NULL;
 | 
						|
 | 
						|
  if (CompareGuid (CertGuid, &gEfiCertSha1Guid)) {
 | 
						|
    //
 | 
						|
    // SHA-1 Hash
 | 
						|
    //
 | 
						|
    CtxSize = Sha1GetContextSize ();
 | 
						|
    HashCtx = AllocatePool (CtxSize);
 | 
						|
    if (HashCtx == NULL) {
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = Sha1Init (HashCtx);
 | 
						|
    Status = Sha1Update (HashCtx, Data, DataSize);
 | 
						|
    Status = Sha1Final (HashCtx, HashValue);
 | 
						|
  } else if (CompareGuid (CertGuid, &gEfiCertSha256Guid)) {
 | 
						|
    //
 | 
						|
    // SHA256 Hash
 | 
						|
    //
 | 
						|
    CtxSize = Sha256GetContextSize ();
 | 
						|
    HashCtx = AllocatePool (CtxSize);
 | 
						|
    if (HashCtx == NULL) {
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = Sha256Init (HashCtx);
 | 
						|
    Status = Sha256Update (HashCtx, Data, DataSize);
 | 
						|
    Status = Sha256Final (HashCtx, HashValue);
 | 
						|
  } else if (CompareGuid (CertGuid, &gEfiCertSha384Guid)) {
 | 
						|
    //
 | 
						|
    // SHA384 Hash
 | 
						|
    //
 | 
						|
    CtxSize = Sha384GetContextSize ();
 | 
						|
    HashCtx = AllocatePool (CtxSize);
 | 
						|
    if (HashCtx == NULL) {
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = Sha384Init (HashCtx);
 | 
						|
    Status = Sha384Update (HashCtx, Data, DataSize);
 | 
						|
    Status = Sha384Final (HashCtx, HashValue);
 | 
						|
  } else if (CompareGuid (CertGuid, &gEfiCertSha512Guid)) {
 | 
						|
    //
 | 
						|
    // SHA512 Hash
 | 
						|
    //
 | 
						|
    CtxSize = Sha512GetContextSize ();
 | 
						|
    HashCtx = AllocatePool (CtxSize);
 | 
						|
    if (HashCtx == NULL) {
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = Sha512Init (HashCtx);
 | 
						|
    Status = Sha512Update (HashCtx, Data, DataSize);
 | 
						|
    Status = Sha512Final (HashCtx, HashValue);
 | 
						|
  }
 | 
						|
 | 
						|
_Exit:
 | 
						|
  if (HashCtx != NULL) {
 | 
						|
    FreePool (HashCtx);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the hash of data content is revoked by the revocation database.
 | 
						|
 | 
						|
  @param[in]  Hash          Pointer to the hash that is searched for.
 | 
						|
  @param[in]  HashSize      The size of the hash in bytes.
 | 
						|
  @param[in]  RevokedDb     Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                            structure which contains list of X.509 certificates
 | 
						|
                            of revoked signers and revoked content hashes.
 | 
						|
 | 
						|
  @return TRUE   The matched content hash is found in the revocation database.
 | 
						|
  @return FALSE  The matched content hash is not found in the revocation database.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsContentHashRevokedByHash (
 | 
						|
  IN  UINT8               *Hash,
 | 
						|
  IN  UINTN               HashSize,
 | 
						|
  IN  EFI_SIGNATURE_LIST  **RevokedDb
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_SIGNATURE_LIST  *SigList;
 | 
						|
  EFI_SIGNATURE_DATA  *SigData;
 | 
						|
  UINTN               Index;
 | 
						|
  UINTN               EntryIndex;
 | 
						|
  UINTN               EntryCount;
 | 
						|
  BOOLEAN             Status;
 | 
						|
 | 
						|
  if (RevokedDb == NULL) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = FALSE;
 | 
						|
  //
 | 
						|
  // Check if any hash matching content hash can be found in RevokedDB
 | 
						|
  //
 | 
						|
  for (Index = 0; ; Index++) {
 | 
						|
    SigList = (EFI_SIGNATURE_LIST *)(RevokedDb[Index]);
 | 
						|
 | 
						|
    //
 | 
						|
    // The list is terminated by a NULL pointer.
 | 
						|
    //
 | 
						|
    if (SigList == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Search the signature database to search the revoked content hash
 | 
						|
    //
 | 
						|
    SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
                                     SigList->SignatureHeaderSize);
 | 
						|
    EntryCount = (SigList->SignatureListSize - SigList->SignatureHeaderSize -
 | 
						|
                  sizeof (EFI_SIGNATURE_LIST)) / SigList->SignatureSize;
 | 
						|
    for (EntryIndex = 0; EntryIndex < EntryCount; EntryIndex++) {
 | 
						|
      //
 | 
						|
      // The problem case.  There's a revocation hash but the sizes
 | 
						|
      // don't match, meaning it's a different hash algorithm and we
 | 
						|
      // can't tell if it's revoking our binary or not.  Assume not.
 | 
						|
      //
 | 
						|
      if (SigList->SignatureSize - sizeof (EFI_GUID) == HashSize) {
 | 
						|
        //
 | 
						|
        // Compare Data Hash with Signature Data
 | 
						|
        //
 | 
						|
        if (CompareMem (SigData->SignatureData, Hash, HashSize) == 0) {
 | 
						|
          Status = TRUE;
 | 
						|
          goto _Exit;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigData + SigList->SignatureSize);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
_Exit:
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the hash of data content is revoked by the revocation database.
 | 
						|
 | 
						|
  @param[in]  Content       Pointer to the content buffer that is searched for.
 | 
						|
  @param[in]  ContentSize   The size of data content in bytes.
 | 
						|
  @param[in]  RevokedDb     Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                            structure which contains list of X.509 certificates
 | 
						|
                            of revoked signers and revoked content hashes.
 | 
						|
 | 
						|
  @return TRUE   The matched content hash is found in the revocation database.
 | 
						|
  @return FALSE  The matched content hash is not found in the revocation database.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsContentHashRevoked (
 | 
						|
  IN  UINT8               *Content,
 | 
						|
  IN  UINTN               ContentSize,
 | 
						|
  IN  EFI_SIGNATURE_LIST  **RevokedDb
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_SIGNATURE_LIST  *SigList;
 | 
						|
  EFI_SIGNATURE_DATA  *SigData;
 | 
						|
  UINTN               Index;
 | 
						|
  UINT8               HashVal[MAX_DIGEST_SIZE];
 | 
						|
  UINTN               EntryIndex;
 | 
						|
  UINTN               EntryCount;
 | 
						|
  BOOLEAN             Status;
 | 
						|
 | 
						|
  if (RevokedDb == NULL) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = FALSE;
 | 
						|
  //
 | 
						|
  // Check if any hash matching content hash can be found in RevokedDB
 | 
						|
  //
 | 
						|
  for (Index = 0; ; Index++) {
 | 
						|
    SigList = (EFI_SIGNATURE_LIST *)(RevokedDb[Index]);
 | 
						|
 | 
						|
    //
 | 
						|
    // The list is terminated by a NULL pointer.
 | 
						|
    //
 | 
						|
    if (SigList == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Calculate the digest of supplied data based on the signature hash type.
 | 
						|
    //
 | 
						|
    if (!CalculateDataHash (Content, ContentSize, &SigList->SignatureType, HashVal)) {
 | 
						|
      //
 | 
						|
      // Un-matched Hash GUID or other failure.
 | 
						|
      //
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Search the signature database to search the revoked content hash
 | 
						|
    //
 | 
						|
    SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
                                     SigList->SignatureHeaderSize);
 | 
						|
    EntryCount = (SigList->SignatureListSize - SigList->SignatureHeaderSize -
 | 
						|
                  sizeof (EFI_SIGNATURE_LIST)) / SigList->SignatureSize;
 | 
						|
    for (EntryIndex = 0; EntryIndex < EntryCount; EntryIndex++) {
 | 
						|
      //
 | 
						|
      // Compare Data Hash with Signature Data
 | 
						|
      //
 | 
						|
      if (CompareMem (SigData->SignatureData, HashVal, (SigList->SignatureSize - sizeof (EFI_GUID))) == 0) {
 | 
						|
        Status = TRUE;
 | 
						|
        goto _Exit;
 | 
						|
      }
 | 
						|
 | 
						|
      SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigData + SigList->SignatureSize);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
_Exit:
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the hash of an given certificate is revoked by the revocation database.
 | 
						|
 | 
						|
  @param[in]  Certificate     Pointer to the certificate that is searched for.
 | 
						|
  @param[in]  CertSize        Size of certificate in bytes.
 | 
						|
  @param[in]  RevokedDb       Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                              structures which contains list of X.509 certificate
 | 
						|
                              of revoked signers and revoked content hashes.
 | 
						|
  @param[out] RevocationTime  Return the time that the certificate was revoked.
 | 
						|
 | 
						|
  @return TRUE   The certificate hash is found in the revocation database.
 | 
						|
  @return FALSE  The certificate hash is not found in the revocation database.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsCertHashRevoked (
 | 
						|
  IN  UINT8               *Certificate,
 | 
						|
  IN  UINTN               CertSize,
 | 
						|
  IN  EFI_SIGNATURE_LIST  **RevokedDb,
 | 
						|
  OUT EFI_TIME            *RevocationTime
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOOLEAN             Status;
 | 
						|
  EFI_SIGNATURE_LIST  *SigList;
 | 
						|
  EFI_SIGNATURE_DATA  *SigData;
 | 
						|
  UINT8               *TBSCert;
 | 
						|
  UINTN               TBSCertSize;
 | 
						|
  UINTN               Index;
 | 
						|
  UINTN               EntryIndex;
 | 
						|
  UINTN               EntryCount;
 | 
						|
  UINT8               CertHashVal[MAX_DIGEST_SIZE];
 | 
						|
 | 
						|
  if ((RevocationTime == NULL) || (RevokedDb == NULL)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Retrieve the TBSCertificate from the X.509 Certificate for hash calculation
 | 
						|
  //
 | 
						|
  if (!X509GetTBSCert (Certificate, CertSize, &TBSCert, &TBSCertSize)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = FALSE;
 | 
						|
  for (Index = 0; ; Index++) {
 | 
						|
    SigList = (EFI_SIGNATURE_LIST *)(RevokedDb[Index]);
 | 
						|
    //
 | 
						|
    // The list is terminated by a NULL pointer.
 | 
						|
    //
 | 
						|
    if (SigList == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Determine Hash Algorithm based on the entry type in revocation database, and
 | 
						|
    // calculate the certificate hash.
 | 
						|
    //
 | 
						|
    if (CompareGuid (&SigList->SignatureType, &gEfiCertX509Sha256Guid)) {
 | 
						|
      Status = CalculateDataHash (TBSCert, TBSCertSize, &gEfiCertSha256Guid, CertHashVal);
 | 
						|
    } else if (CompareGuid (&SigList->SignatureType, &gEfiCertX509Sha384Guid)) {
 | 
						|
      Status = CalculateDataHash (TBSCert, TBSCertSize, &gEfiCertSha384Guid, CertHashVal);
 | 
						|
    } else if (CompareGuid (&SigList->SignatureType, &gEfiCertX509Sha512Guid)) {
 | 
						|
      Status = CalculateDataHash (TBSCert, TBSCertSize, &gEfiCertSha512Guid, CertHashVal);
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Un-matched Cert Hash GUID
 | 
						|
      //
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!Status) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
                                     SigList->SignatureHeaderSize);
 | 
						|
    EntryCount = (SigList->SignatureListSize - SigList->SignatureHeaderSize -
 | 
						|
                  sizeof (EFI_SIGNATURE_LIST)) / SigList->SignatureSize;
 | 
						|
    for (EntryIndex = 0; EntryIndex < EntryCount; Index++) {
 | 
						|
      //
 | 
						|
      // Check if the Certificate Hash is revoked.
 | 
						|
      //
 | 
						|
      if (CompareMem (
 | 
						|
            SigData->SignatureData,
 | 
						|
            CertHashVal,
 | 
						|
            SigList->SignatureSize - sizeof (EFI_GUID) - sizeof (EFI_TIME)
 | 
						|
            ) == 0)
 | 
						|
      {
 | 
						|
        Status = TRUE;
 | 
						|
        //
 | 
						|
        // Return the revocation time of this revoked certificate.
 | 
						|
        //
 | 
						|
        CopyMem (
 | 
						|
          RevocationTime,
 | 
						|
          (EFI_TIME *)((UINT8 *)SigData + SigList->SignatureSize - sizeof (EFI_TIME)),
 | 
						|
          sizeof (EFI_TIME)
 | 
						|
          );
 | 
						|
        goto _Exit;
 | 
						|
      }
 | 
						|
 | 
						|
      SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigData + SigList->SignatureSize);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
_Exit:
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check if the given time value is zero.
 | 
						|
 | 
						|
  @param[in]  Time      Pointer of a time value.
 | 
						|
 | 
						|
  @retval     TRUE      The Time is Zero.
 | 
						|
  @retval     FALSE     The Time is not Zero.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsTimeZero (
 | 
						|
  IN EFI_TIME  *Time
 | 
						|
  )
 | 
						|
{
 | 
						|
  if ((Time->Year == 0) && (Time->Month == 0) &&  (Time->Day == 0) &&
 | 
						|
      (Time->Hour == 0) && (Time->Minute == 0) && (Time->Second == 0))
 | 
						|
  {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the timestamp is valid by comparing the signing time and the revocation time.
 | 
						|
 | 
						|
  @param SigningTime     Pointer to the signing time.
 | 
						|
  @param RevocationTime  Pointer to the revocation time.
 | 
						|
 | 
						|
  @retval  TRUE          The SigningTime is not later than the RevocationTime.
 | 
						|
  @retval  FALSE         The SigningTime is later than the RevocationTime.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
CompareTimestamp (
 | 
						|
  IN EFI_TIME  *SigningTime,
 | 
						|
  IN EFI_TIME  *RevocationTime
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (SigningTime->Year != RevocationTime->Year) {
 | 
						|
    return (BOOLEAN)(SigningTime->Year < RevocationTime->Year);
 | 
						|
  } else if (SigningTime->Month != RevocationTime->Month) {
 | 
						|
    return (BOOLEAN)(SigningTime->Month < RevocationTime->Month);
 | 
						|
  } else if (SigningTime->Day != RevocationTime->Day) {
 | 
						|
    return (BOOLEAN)(SigningTime->Day < RevocationTime->Day);
 | 
						|
  } else if (SigningTime->Hour != RevocationTime->Hour) {
 | 
						|
    return (BOOLEAN)(SigningTime->Hour < RevocationTime->Hour);
 | 
						|
  } else if (SigningTime->Minute != RevocationTime->Minute) {
 | 
						|
    return (BOOLEAN)(SigningTime->Minute < RevocationTime->Minute);
 | 
						|
  }
 | 
						|
 | 
						|
  return (BOOLEAN)(SigningTime->Second <= RevocationTime->Second);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the timestamp signature embedded in PKCS7 signedData is valid and
 | 
						|
  the signing time is also earlier than the revocation time.
 | 
						|
 | 
						|
  @param[in]  SignedData        Pointer to the PKCS#7 signedData.
 | 
						|
  @param[in]  SignedDataSize    Size of SignedData in bytes.
 | 
						|
  @param[in]  TimeStampDb       Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                                structures which is used to pass a list of X.509
 | 
						|
                                certificates of trusted timestamp signers.
 | 
						|
  @param[in]  RevocationTime    The time that the certificate was revoked.
 | 
						|
 | 
						|
  @retval TRUE      Timestamp signature is valid and the signing time is no later
 | 
						|
                    than the revocation time.
 | 
						|
  @retval FALSE     Timestamp signature is not valid or the signing time is later
 | 
						|
                    than the revocation time.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidTimestamp (
 | 
						|
  IN UINT8               *SignedData,
 | 
						|
  IN UINTN               SignedDataSize,
 | 
						|
  IN EFI_SIGNATURE_LIST  **TimeStampDb,
 | 
						|
  IN EFI_TIME            *RevocationTime
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOOLEAN             Status;
 | 
						|
  EFI_SIGNATURE_LIST  *SigList;
 | 
						|
  EFI_SIGNATURE_DATA  *SigData;
 | 
						|
  UINT8               *TsaCert;
 | 
						|
  UINTN               TsaCertSize;
 | 
						|
  UINTN               Index;
 | 
						|
  EFI_TIME            SigningTime;
 | 
						|
 | 
						|
  //
 | 
						|
  // If no supplied database for verification or RevocationTime is zero,
 | 
						|
  // the certificate shall be considered to always be revoked.
 | 
						|
  //
 | 
						|
  if ((TimeStampDb == NULL) || (IsTimeZero (RevocationTime))) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = FALSE;
 | 
						|
  //
 | 
						|
  // RevocationTime is non-zero, the certificate should be considered to be revoked
 | 
						|
  // from that time and onwards.
 | 
						|
  //
 | 
						|
  for (Index = 0; ; Index++) {
 | 
						|
    SigList = (EFI_SIGNATURE_LIST *)(TimeStampDb[Index]);
 | 
						|
 | 
						|
    //
 | 
						|
    // The list is terminated by a NULL pointer.
 | 
						|
    //
 | 
						|
    if (SigList == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Ignore any non-X509-format entry in the list
 | 
						|
    //
 | 
						|
    if (!CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid)) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
                                     SigList->SignatureHeaderSize);
 | 
						|
    TsaCert     = SigData->SignatureData;
 | 
						|
    TsaCertSize = SigList->SignatureSize - sizeof (EFI_GUID);
 | 
						|
 | 
						|
    //
 | 
						|
    // Each TSA Certificate will normally be in a separate EFI_SIGNATURE_LIST
 | 
						|
    // Leverage ImageTimestampVerify interface for Timestamp counterSignature Verification
 | 
						|
    //
 | 
						|
    if (ImageTimestampVerify (SignedData, SignedDataSize, TsaCert, TsaCertSize, &SigningTime)) {
 | 
						|
      //
 | 
						|
      // The signer signature is valid only when the signing time is earlier than revocation time.
 | 
						|
      //
 | 
						|
      if (CompareTimestamp (&SigningTime, RevocationTime)) {
 | 
						|
        Status = TRUE;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the PKCS7 signedData is revoked by verifying with the revoked
 | 
						|
  certificates database, and if the signedData is timestamped, the embedded timestamp
 | 
						|
  counterSignature will be checked with the supplied timestamp database.
 | 
						|
 | 
						|
  @param[in]  SignedData      Pointer to buffer containing ASN.1 DER-encoded PKCS7
 | 
						|
                              signature.
 | 
						|
  @param[in]  SignedDataSize  The size of SignedData buffer in bytes.
 | 
						|
  @param[in]  InHash          Pointer to the buffer containing the hash of the message data
 | 
						|
                              previously signed and to be verified.
 | 
						|
  @param[in]  InHashSize      The size of InHash buffer in bytes.
 | 
						|
  @param[in]  RevokedDb       Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                              structure which contains list of X.509 certificates
 | 
						|
                              of revoked signers and revoked content hashes.
 | 
						|
  @param[in]  TimeStampDb     Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                              structures which is used to pass a list of X.509
 | 
						|
                              certificates of trusted timestamp signers.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS             The PKCS7 signedData is revoked.
 | 
						|
  @retval  EFI_SECURITY_VIOLATION  Fail to verify the signature in PKCS7 signedData.
 | 
						|
  @retval  EFI_INVALID_PARAMETER   SignedData is NULL or SignedDataSize is zero.
 | 
						|
                                   AllowedDb is NULL.
 | 
						|
                                   Content is not NULL and ContentSize is NULL.
 | 
						|
  @retval  EFI_NOT_FOUND           Content not found because InData is NULL and no
 | 
						|
                                   content embedded in PKCS7 signedData.
 | 
						|
  @retval  EFI_UNSUPPORTED         The PKCS7 signedData was not correctly formatted.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
P7CheckRevocationByHash (
 | 
						|
  IN UINT8               *SignedData,
 | 
						|
  IN UINTN               SignedDataSize,
 | 
						|
  IN UINT8               *InHash,
 | 
						|
  IN UINTN               InHashSize,
 | 
						|
  IN EFI_SIGNATURE_LIST  **RevokedDb,
 | 
						|
  IN EFI_SIGNATURE_LIST  **TimeStampDb
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  EFI_SIGNATURE_LIST  *SigList;
 | 
						|
  EFI_SIGNATURE_DATA  *SigData;
 | 
						|
  UINT8               *RevokedCert;
 | 
						|
  UINTN               RevokedCertSize;
 | 
						|
  UINTN               Index;
 | 
						|
  UINT8               *CertBuffer;
 | 
						|
  UINTN               BufferLength;
 | 
						|
  UINT8               *TrustedCert;
 | 
						|
  UINTN               TrustedCertLength;
 | 
						|
  UINT8               CertNumber;
 | 
						|
  UINT8               *CertPtr;
 | 
						|
  UINT8               *Cert;
 | 
						|
  UINTN               CertSize;
 | 
						|
  EFI_TIME            RevocationTime;
 | 
						|
 | 
						|
  Status          = EFI_SECURITY_VIOLATION;
 | 
						|
  SigData         = NULL;
 | 
						|
  RevokedCert     = NULL;
 | 
						|
  RevokedCertSize = 0;
 | 
						|
  CertBuffer      = NULL;
 | 
						|
  TrustedCert     = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // The signedData is revoked if the hash of content existed in RevokedDb
 | 
						|
  //
 | 
						|
  if (IsContentHashRevokedByHash (InHash, InHashSize, RevokedDb)) {
 | 
						|
    Status = EFI_SUCCESS;
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if the signer's certificate can be found in Revoked database
 | 
						|
  //
 | 
						|
  for (Index = 0; ; Index++) {
 | 
						|
    SigList = (EFI_SIGNATURE_LIST *)(RevokedDb[Index]);
 | 
						|
 | 
						|
    //
 | 
						|
    // The list is terminated by a NULL pointer.
 | 
						|
    //
 | 
						|
    if (SigList == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Ignore any non-X509-format entry in the list.
 | 
						|
    //
 | 
						|
    if (!CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid)) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
                                     SigList->SignatureHeaderSize);
 | 
						|
 | 
						|
    RevokedCert     = SigData->SignatureData;
 | 
						|
    RevokedCertSize = SigList->SignatureSize - sizeof (EFI_GUID);
 | 
						|
 | 
						|
    //
 | 
						|
    // Verifying the PKCS#7 SignedData with the revoked certificate in RevokedDb
 | 
						|
    //
 | 
						|
    if (AuthenticodeVerify (SignedData, SignedDataSize, RevokedCert, RevokedCertSize, InHash, InHashSize)) {
 | 
						|
      //
 | 
						|
      // The signedData was verified by one entry in Revoked Database
 | 
						|
      //
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // The signedData was revoked, since it was hit by RevokedDb
 | 
						|
    //
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Now we will continue to check the X.509 Certificate Hash & Possible Timestamp
 | 
						|
  //
 | 
						|
  if ((TimeStampDb == NULL) || (*TimeStampDb == NULL)) {
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  Pkcs7GetSigners (SignedData, SignedDataSize, &CertBuffer, &BufferLength, &TrustedCert, &TrustedCertLength);
 | 
						|
  if ((BufferLength == 0) || (CertBuffer == NULL)) {
 | 
						|
    Status = EFI_SUCCESS;
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if any hash of certificates embedded in P7 data is in the revoked database.
 | 
						|
  //
 | 
						|
  CertNumber = (UINT8)(*CertBuffer);
 | 
						|
  CertPtr    = CertBuffer + 1;
 | 
						|
  for (Index = 0; Index < CertNumber; Index++) {
 | 
						|
    //
 | 
						|
    // Retrieve the Certificate data
 | 
						|
    //
 | 
						|
    CertSize = (UINTN)ReadUnaligned32 ((UINT32 *)CertPtr);
 | 
						|
    Cert     = (UINT8 *)CertPtr + sizeof (UINT32);
 | 
						|
 | 
						|
    if (IsCertHashRevoked (Cert, CertSize, RevokedDb, &RevocationTime)) {
 | 
						|
      //
 | 
						|
      // Check the timestamp signature and signing time to determine if p7 data can be trusted.
 | 
						|
      //
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      if (IsValidTimestamp (SignedData, SignedDataSize, TimeStampDb, &RevocationTime)) {
 | 
						|
        //
 | 
						|
        // Use EFI_NOT_READY to identify the P7Data is not revoked, because the timestamping
 | 
						|
        // occurred prior to the time of certificate revocation.
 | 
						|
        //
 | 
						|
        Status = EFI_NOT_READY;
 | 
						|
      }
 | 
						|
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    CertPtr = CertPtr + sizeof (UINT32) + CertSize;
 | 
						|
  }
 | 
						|
 | 
						|
_Exit:
 | 
						|
  Pkcs7FreeSigners (CertBuffer);
 | 
						|
  Pkcs7FreeSigners (TrustedCert);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the PKCS7 signedData is revoked by verifying with the revoked
 | 
						|
  certificates database, and if the signedData is timestamped, the embedded timestamp
 | 
						|
  counterSignature will be checked with the supplied timestamp database.
 | 
						|
 | 
						|
  @param[in]  SignedData      Pointer to buffer containing ASN.1 DER-encoded PKCS7
 | 
						|
                              signature.
 | 
						|
  @param[in]  SignedDataSize  The size of SignedData buffer in bytes.
 | 
						|
  @param[in]  InData          Pointer to the buffer containing the raw message data
 | 
						|
                              previously signed and to be verified.
 | 
						|
  @param[in]  InDataSize      The size of InData buffer in bytes.
 | 
						|
  @param[in]  RevokedDb       Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                              structure which contains list of X.509 certificates
 | 
						|
                              of revoked signers and revoked content hashes.
 | 
						|
  @param[in]  TimeStampDb     Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                              structures which is used to pass a list of X.509
 | 
						|
                              certificates of trusted timestamp signers.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS             The PKCS7 signedData is revoked.
 | 
						|
  @retval  EFI_SECURITY_VIOLATION  Fail to verify the signature in PKCS7 signedData.
 | 
						|
  @retval  EFI_INVALID_PARAMETER   SignedData is NULL or SignedDataSize is zero.
 | 
						|
                                   AllowedDb is NULL.
 | 
						|
                                   Content is not NULL and ContentSize is NULL.
 | 
						|
  @retval  EFI_NOT_FOUND           Content not found because InData is NULL and no
 | 
						|
                                   content embedded in PKCS7 signedData.
 | 
						|
  @retval  EFI_UNSUPPORTED         The PKCS7 signedData was not correctly formatted.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
P7CheckRevocation (
 | 
						|
  IN UINT8               *SignedData,
 | 
						|
  IN UINTN               SignedDataSize,
 | 
						|
  IN UINT8               *InData,
 | 
						|
  IN UINTN               InDataSize,
 | 
						|
  IN EFI_SIGNATURE_LIST  **RevokedDb,
 | 
						|
  IN EFI_SIGNATURE_LIST  **TimeStampDb
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  EFI_SIGNATURE_LIST  *SigList;
 | 
						|
  EFI_SIGNATURE_DATA  *SigData;
 | 
						|
  UINT8               *RevokedCert;
 | 
						|
  UINTN               RevokedCertSize;
 | 
						|
  UINTN               Index;
 | 
						|
  UINT8               *CertBuffer;
 | 
						|
  UINTN               BufferLength;
 | 
						|
  UINT8               *TrustedCert;
 | 
						|
  UINTN               TrustedCertLength;
 | 
						|
  UINT8               CertNumber;
 | 
						|
  UINT8               *CertPtr;
 | 
						|
  UINT8               *Cert;
 | 
						|
  UINTN               CertSize;
 | 
						|
  EFI_TIME            RevocationTime;
 | 
						|
 | 
						|
  Status          = EFI_UNSUPPORTED;
 | 
						|
  SigData         = NULL;
 | 
						|
  RevokedCert     = NULL;
 | 
						|
  RevokedCertSize = 0;
 | 
						|
  CertBuffer      = NULL;
 | 
						|
  TrustedCert     = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // The signedData is revoked if the hash of content existed in RevokedDb
 | 
						|
  //
 | 
						|
  if (IsContentHashRevoked (InData, InDataSize, RevokedDb)) {
 | 
						|
    Status = EFI_SUCCESS;
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if the signer's certificate can be found in Revoked database
 | 
						|
  //
 | 
						|
  for (Index = 0; ; Index++) {
 | 
						|
    SigList = (EFI_SIGNATURE_LIST *)(RevokedDb[Index]);
 | 
						|
 | 
						|
    //
 | 
						|
    // The list is terminated by a NULL pointer.
 | 
						|
    //
 | 
						|
    if (SigList == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Ignore any non-X509-format entry in the list.
 | 
						|
    //
 | 
						|
    if (!CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid)) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
                                     SigList->SignatureHeaderSize);
 | 
						|
 | 
						|
    RevokedCert     = SigData->SignatureData;
 | 
						|
    RevokedCertSize = SigList->SignatureSize - sizeof (EFI_GUID);
 | 
						|
 | 
						|
    //
 | 
						|
    // Verifying the PKCS#7 SignedData with the revoked certificate in RevokedDb
 | 
						|
    //
 | 
						|
    if (Pkcs7Verify (SignedData, SignedDataSize, RevokedCert, RevokedCertSize, InData, InDataSize)) {
 | 
						|
      //
 | 
						|
      // The signedData was verified by one entry in Revoked Database
 | 
						|
      //
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // The signedData was revoked, since it was hit by RevokedDb
 | 
						|
    //
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Now we will continue to check the X.509 Certificate Hash & Possible Timestamp
 | 
						|
  //
 | 
						|
  if ((TimeStampDb == NULL) || (*TimeStampDb == NULL)) {
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  Pkcs7GetSigners (SignedData, SignedDataSize, &CertBuffer, &BufferLength, &TrustedCert, &TrustedCertLength);
 | 
						|
  if ((BufferLength == 0) || (CertBuffer == NULL)) {
 | 
						|
    Status = EFI_SUCCESS;
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if any hash of certificates embedded in P7 data is in the revoked database.
 | 
						|
  //
 | 
						|
  CertNumber = (UINT8)(*CertBuffer);
 | 
						|
  CertPtr    = CertBuffer + 1;
 | 
						|
  for (Index = 0; Index < CertNumber; Index++) {
 | 
						|
    //
 | 
						|
    // Retrieve the Certificate data
 | 
						|
    //
 | 
						|
    CertSize = (UINTN)ReadUnaligned32 ((UINT32 *)CertPtr);
 | 
						|
    Cert     = (UINT8 *)CertPtr + sizeof (UINT32);
 | 
						|
 | 
						|
    if (IsCertHashRevoked (Cert, CertSize, RevokedDb, &RevocationTime)) {
 | 
						|
      //
 | 
						|
      // Check the timestamp signature and signing time to determine if p7 data can be trusted.
 | 
						|
      //
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      if (IsValidTimestamp (SignedData, SignedDataSize, TimeStampDb, &RevocationTime)) {
 | 
						|
        //
 | 
						|
        // Use EFI_NOT_READY to identify the P7Data is not revoked, because the timestamping
 | 
						|
        // occurred prior to the time of certificate revocation.
 | 
						|
        //
 | 
						|
        Status = EFI_NOT_READY;
 | 
						|
      }
 | 
						|
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    CertPtr = CertPtr + sizeof (UINT32) + CertSize;
 | 
						|
  }
 | 
						|
 | 
						|
_Exit:
 | 
						|
  Pkcs7FreeSigners (CertBuffer);
 | 
						|
  Pkcs7FreeSigners (TrustedCert);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the PKCS7 signedData can be verified by the trusted certificates
 | 
						|
  database, and return the content of the signedData if requested.
 | 
						|
 | 
						|
  @param[in]  SignedData      Pointer to buffer containing ASN.1 DER-encoded PKCS7
 | 
						|
                              signature.
 | 
						|
  @param[in]  SignedDataSize  The size of SignedData buffer in bytes.
 | 
						|
  @param[in]  InHash          Pointer to the buffer containing the hash of the message data
 | 
						|
                              previously signed and to be verified.
 | 
						|
  @param[in]  InHashSize      The size of InHash buffer in bytes.
 | 
						|
  @param[in]  AllowedDb       Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                              structures which contains lists of X.509 certificates
 | 
						|
                              of approved signers.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS             The PKCS7 signedData is trusted.
 | 
						|
  @retval  EFI_SECURITY_VIOLATION  Fail to verify the signature in PKCS7 signedData.
 | 
						|
  @retval  EFI_INVALID_PARAMETER   SignedData is NULL or SignedDataSize is zero.
 | 
						|
                                   AllowedDb is NULL.
 | 
						|
                                   Content is not NULL and ContentSize is NULL.
 | 
						|
  @retval  EFI_NOT_FOUND           Content not found because InData is NULL and no
 | 
						|
                                   content embedded in PKCS7 signedData.
 | 
						|
  @retval  EFI_UNSUPPORTED         The PKCS7 signedData was not correctly formatted.
 | 
						|
  @retval  EFI_BUFFER_TOO_SMALL    The size of buffer indicated by ContentSize is too
 | 
						|
                                   small to hold the content. ContentSize updated to
 | 
						|
                                   the required size.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
P7CheckTrustByHash (
 | 
						|
  IN UINT8               *SignedData,
 | 
						|
  IN UINTN               SignedDataSize,
 | 
						|
  IN UINT8               *InHash,
 | 
						|
  IN UINTN               InHashSize,
 | 
						|
  IN EFI_SIGNATURE_LIST  **AllowedDb
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  EFI_SIGNATURE_LIST  *SigList;
 | 
						|
  EFI_SIGNATURE_DATA  *SigData;
 | 
						|
  UINT8               *TrustCert;
 | 
						|
  UINTN               TrustCertSize;
 | 
						|
  UINTN               Index;
 | 
						|
 | 
						|
  Status        = EFI_SECURITY_VIOLATION;
 | 
						|
  SigData       = NULL;
 | 
						|
  TrustCert     = NULL;
 | 
						|
  TrustCertSize = 0;
 | 
						|
 | 
						|
  if (AllowedDb == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Build Certificate Stack with all valid X509 certificates in the supplied
 | 
						|
  // Signature List for PKCS7 Verification.
 | 
						|
  //
 | 
						|
  for (Index = 0; ; Index++) {
 | 
						|
    SigList = (EFI_SIGNATURE_LIST *)(AllowedDb[Index]);
 | 
						|
 | 
						|
    //
 | 
						|
    // The list is terminated by a NULL pointer.
 | 
						|
    //
 | 
						|
    if (SigList == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Ignore any non-X509-format entry in the list.
 | 
						|
    //
 | 
						|
    if (!CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid)) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
                                     SigList->SignatureHeaderSize);
 | 
						|
 | 
						|
    TrustCert     = SigData->SignatureData;
 | 
						|
    TrustCertSize = SigList->SignatureSize - sizeof (EFI_GUID);
 | 
						|
 | 
						|
    //
 | 
						|
    // Verifying the PKCS#7 SignedData with the trusted certificate from AllowedDb
 | 
						|
    //
 | 
						|
    if (AuthenticodeVerify (SignedData, SignedDataSize, TrustCert, TrustCertSize, InHash, InHashSize)) {
 | 
						|
      //
 | 
						|
      // The SignedData was verified successfully by one entry in Trusted Database
 | 
						|
      //
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the PKCS7 signedData can be verified by the trusted certificates
 | 
						|
  database, and return the content of the signedData if requested.
 | 
						|
 | 
						|
  @param[in]  SignedData      Pointer to buffer containing ASN.1 DER-encoded PKCS7
 | 
						|
                              signature.
 | 
						|
  @param[in]  SignedDataSize  The size of SignedData buffer in bytes.
 | 
						|
  @param[in]  InData          Pointer to the buffer containing the raw message data
 | 
						|
                              previously signed and to be verified.
 | 
						|
  @param[in]  InDataSize      The size of InData buffer in bytes.
 | 
						|
  @param[in]  AllowedDb       Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                              structures which contains lists of X.509 certificates
 | 
						|
                              of approved signers.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS             The PKCS7 signedData is trusted.
 | 
						|
  @retval  EFI_SECURITY_VIOLATION  Fail to verify the signature in PKCS7 signedData.
 | 
						|
  @retval  EFI_INVALID_PARAMETER   SignedData is NULL or SignedDataSize is zero.
 | 
						|
                                   AllowedDb is NULL.
 | 
						|
                                   Content is not NULL and ContentSize is NULL.
 | 
						|
  @retval  EFI_NOT_FOUND           Content not found because InData is NULL and no
 | 
						|
                                   content embedded in PKCS7 signedData.
 | 
						|
  @retval  EFI_UNSUPPORTED         The PKCS7 signedData was not correctly formatted.
 | 
						|
  @retval  EFI_BUFFER_TOO_SMALL    The size of buffer indicated by ContentSize is too
 | 
						|
                                   small to hold the content. ContentSize updated to
 | 
						|
                                   the required size.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
P7CheckTrust (
 | 
						|
  IN UINT8               *SignedData,
 | 
						|
  IN UINTN               SignedDataSize,
 | 
						|
  IN UINT8               *InData,
 | 
						|
  IN UINTN               InDataSize,
 | 
						|
  IN EFI_SIGNATURE_LIST  **AllowedDb
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  EFI_SIGNATURE_LIST  *SigList;
 | 
						|
  EFI_SIGNATURE_DATA  *SigData;
 | 
						|
  UINT8               *TrustCert;
 | 
						|
  UINTN               TrustCertSize;
 | 
						|
  UINTN               Index;
 | 
						|
 | 
						|
  Status        = EFI_SECURITY_VIOLATION;
 | 
						|
  SigData       = NULL;
 | 
						|
  TrustCert     = NULL;
 | 
						|
  TrustCertSize = 0;
 | 
						|
 | 
						|
  if (AllowedDb == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Build Certificate Stack with all valid X509 certificates in the supplied
 | 
						|
  // Signature List for PKCS7 Verification.
 | 
						|
  //
 | 
						|
  for (Index = 0; ; Index++) {
 | 
						|
    SigList = (EFI_SIGNATURE_LIST *)(AllowedDb[Index]);
 | 
						|
 | 
						|
    //
 | 
						|
    // The list is terminated by a NULL pointer.
 | 
						|
    //
 | 
						|
    if (SigList == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Ignore any non-X509-format entry in the list.
 | 
						|
    //
 | 
						|
    if (!CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid)) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    SigData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
                                     SigList->SignatureHeaderSize);
 | 
						|
 | 
						|
    TrustCert     = SigData->SignatureData;
 | 
						|
    TrustCertSize = SigList->SignatureSize - sizeof (EFI_GUID);
 | 
						|
 | 
						|
    //
 | 
						|
    // Verifying the PKCS#7 SignedData with the trusted certificate from AllowedDb
 | 
						|
    //
 | 
						|
    if (Pkcs7Verify (SignedData, SignedDataSize, TrustCert, TrustCertSize, InData, InDataSize)) {
 | 
						|
      //
 | 
						|
      // The SignedData was verified successfully by one entry in Trusted Database
 | 
						|
      //
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Processes a buffer containing binary DER-encoded PKCS7 signature.
 | 
						|
  The signed data content may be embedded within the buffer or separated. Function
 | 
						|
  verifies the signature of the content is valid and signing certificate was not
 | 
						|
  revoked and is contained within a list of trusted signers.
 | 
						|
 | 
						|
  @param[in]     This                 Pointer to EFI_PKCS7_VERIFY_PROTOCOL instance.
 | 
						|
  @param[in]     SignedData           Points to buffer containing ASN.1 DER-encoded PKCS7
 | 
						|
                                      signature.
 | 
						|
  @param[in]     SignedDataSize       The size of SignedData buffer in bytes.
 | 
						|
  @param[in]     InData               In case of detached signature, InData points to
 | 
						|
                                      buffer containing the raw message data previously
 | 
						|
                                      signed and to be verified by function. In case of
 | 
						|
                                      SignedData containing embedded data, InData must be
 | 
						|
                                      NULL.
 | 
						|
  @param[in]     InDataSize           When InData is used, the size of InData buffer in
 | 
						|
                                      bytes. When InData is NULL. This parameter must be
 | 
						|
                                      0.
 | 
						|
  @param[in]     AllowedDb            Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                                      structures. The list is terminated by a null
 | 
						|
                                      pointer. The EFI_SIGNATURE_LIST structures contain
 | 
						|
                                      lists of X.509 certificates of approved signers.
 | 
						|
                                      Function recognizes signer certificates of type
 | 
						|
                                      EFI_CERT_X509_GUID. Any hash certificate in AllowedDb
 | 
						|
                                      list is ignored by this function. Function returns
 | 
						|
                                      success if signer of the buffer is within this list
 | 
						|
                                      (and not within RevokedDb). This parameter is
 | 
						|
                                      required.
 | 
						|
  @param[in]     RevokedDb            Optional pointer to a list of pointers to
 | 
						|
                                      EFI_SIGNATURE_LIST structures. The list is terminated
 | 
						|
                                      by a null pointer. List of X.509 certificates of
 | 
						|
                                      revoked signers and revoked file hashes. Except as
 | 
						|
                                      noted in description of TimeStampDb signature
 | 
						|
                                      verification will always fail if the signer of the
 | 
						|
                                      file or the hash of the data component of the buffer
 | 
						|
                                      is in RevokedDb list. This list is optional and
 | 
						|
                                      caller may pass Null or pointer to NULL if not
 | 
						|
                                      required.
 | 
						|
  @param[in]     TimeStampDb          Optional pointer to a list of pointers to
 | 
						|
                                      EFI_SIGNATURE_LIST structures. The list is terminated
 | 
						|
                                      by a null pointer. This parameter can be used to pass
 | 
						|
                                      a list of X.509 certificates of trusted time stamp
 | 
						|
                                      signers. This list is optional and caller must pass
 | 
						|
                                      Null or pointer to NULL if not required.
 | 
						|
  @param[out]    Content              On input, points to an optional caller-allocated
 | 
						|
                                      buffer into which the function will copy the content
 | 
						|
                                      portion of the file after verification succeeds.
 | 
						|
                                      This parameter is optional and if NULL, no copy of
 | 
						|
                                      content from file is performed.
 | 
						|
  @param[in,out] ContentSize          On input, points to the size in bytes of the optional
 | 
						|
                                      buffer Content previously allocated by caller. On
 | 
						|
                                      output, if the verification succeeds, the value
 | 
						|
                                      referenced by ContentSize will contain the actual
 | 
						|
                                      size of the content from signed file. If ContentSize
 | 
						|
                                      indicates the caller-allocated buffer is too small
 | 
						|
                                      to contain content, an error is returned, and
 | 
						|
                                      ContentSize will be updated with the required size.
 | 
						|
                                      This parameter must be 0 if Content is Null.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS                 Content signature was verified against hash of
 | 
						|
                                      content, the signer's certificate was not found in
 | 
						|
                                      RevokedDb, and was found in AllowedDb or if in signer
 | 
						|
                                      is found in both AllowedDb and RevokedDb, the
 | 
						|
                                      signing was allowed by reference to TimeStampDb as
 | 
						|
                                      described above, and no hash matching content hash
 | 
						|
                                      was found in RevokedDb.
 | 
						|
  @retval EFI_SECURITY_VIOLATION      The SignedData buffer was correctly formatted but
 | 
						|
                                      signer was in RevokedDb or not in AllowedDb. Also
 | 
						|
                                      returned if matching content hash found in RevokedDb.
 | 
						|
  @retval EFI_COMPROMISED_DATA        Calculated hash differs from signed hash.
 | 
						|
  @retval EFI_INVALID_PARAMETER       SignedData is NULL or SignedDataSize is zero.
 | 
						|
                                      AllowedDb is NULL.
 | 
						|
  @retval EFI_INVALID_PARAMETER       Content is not NULL and ContentSize is NULL.
 | 
						|
  @retval EFI_ABORTED                 Unsupported or invalid format in TimeStampDb,
 | 
						|
                                      RevokedDb or AllowedDb list contents was detected.
 | 
						|
  @retval EFI_NOT_FOUND               Content not found because InData is NULL and no
 | 
						|
                                      content embedded in SignedData.
 | 
						|
  @retval EFI_UNSUPPORTED             The SignedData buffer was not correctly formatted
 | 
						|
                                      for processing by the function.
 | 
						|
  @retval EFI_UNSUPPORTED             Signed data embedded in SignedData but InData is not
 | 
						|
                                      NULL.
 | 
						|
  @retval EFI_BUFFER_TOO_SMALL        The size of buffer indicated by ContentSize is too
 | 
						|
                                      small to hold the content. ContentSize updated to
 | 
						|
                                      required size.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
VerifyBuffer (
 | 
						|
  IN EFI_PKCS7_VERIFY_PROTOCOL  *This,
 | 
						|
  IN VOID                       *SignedData,
 | 
						|
  IN UINTN                      SignedDataSize,
 | 
						|
  IN VOID                       *InData          OPTIONAL,
 | 
						|
  IN UINTN                      InDataSize,
 | 
						|
  IN EFI_SIGNATURE_LIST         **AllowedDb,
 | 
						|
  IN EFI_SIGNATURE_LIST         **RevokedDb      OPTIONAL,
 | 
						|
  IN EFI_SIGNATURE_LIST         **TimeStampDb    OPTIONAL,
 | 
						|
  OUT VOID                      *Content         OPTIONAL,
 | 
						|
  IN OUT UINTN                  *ContentSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  EFI_SIGNATURE_LIST  *SigList;
 | 
						|
  UINTN               Index;
 | 
						|
  UINT8               *AttachedData;
 | 
						|
  UINTN               AttachedDataSize;
 | 
						|
  UINT8               *DataPtr;
 | 
						|
  UINTN               DataSize;
 | 
						|
 | 
						|
  //
 | 
						|
  // Parameters Checking
 | 
						|
  //
 | 
						|
  if ((SignedData == NULL) || (SignedDataSize == 0) || (AllowedDb == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((Content != NULL) && (ContentSize == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if any invalid entry format in AllowedDb list contents
 | 
						|
  //
 | 
						|
  for (Index = 0; ; Index++) {
 | 
						|
    SigList = (EFI_SIGNATURE_LIST *)(AllowedDb[Index]);
 | 
						|
 | 
						|
    if (SigList == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (SigList->SignatureListSize < sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
        SigList->SignatureHeaderSize +
 | 
						|
        SigList->SignatureSize)
 | 
						|
    {
 | 
						|
      return EFI_ABORTED;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if any invalid entry format in RevokedDb list contents
 | 
						|
  //
 | 
						|
  if (RevokedDb != NULL) {
 | 
						|
    for (Index = 0; ; Index++) {
 | 
						|
      SigList = (EFI_SIGNATURE_LIST *)(RevokedDb[Index]);
 | 
						|
 | 
						|
      if (SigList == NULL) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      if (SigList->SignatureListSize < sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
          SigList->SignatureHeaderSize +
 | 
						|
          SigList->SignatureSize)
 | 
						|
      {
 | 
						|
        return EFI_ABORTED;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if any invalid entry format in TimeStampDb list contents
 | 
						|
  //
 | 
						|
  if (TimeStampDb != NULL) {
 | 
						|
    for (Index = 0; ; Index++) {
 | 
						|
      SigList = (EFI_SIGNATURE_LIST *)(TimeStampDb[Index]);
 | 
						|
 | 
						|
      if (SigList == NULL) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      if (SigList->SignatureListSize < sizeof (EFI_SIGNATURE_LIST) +
 | 
						|
          SigList->SignatureHeaderSize +
 | 
						|
          SigList->SignatureSize)
 | 
						|
      {
 | 
						|
        return EFI_ABORTED;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Try to retrieve the attached content from PKCS7 signedData
 | 
						|
  //
 | 
						|
  AttachedData     = NULL;
 | 
						|
  AttachedDataSize = 0;
 | 
						|
  if (!Pkcs7GetAttachedContent (
 | 
						|
         SignedData,
 | 
						|
         SignedDataSize,
 | 
						|
         (VOID **)&AttachedData,
 | 
						|
         &AttachedDataSize
 | 
						|
         ))
 | 
						|
  {
 | 
						|
    //
 | 
						|
    // The SignedData buffer was not correctly formatted for processing
 | 
						|
    //
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  if (AttachedData != NULL) {
 | 
						|
    if (InData != NULL) {
 | 
						|
      //
 | 
						|
      // The embedded content is found in SignedData but InData is not NULL
 | 
						|
      //
 | 
						|
      Status = EFI_UNSUPPORTED;
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // PKCS7-formatted signedData with attached content; Use the embedded
 | 
						|
    // content for verification
 | 
						|
    //
 | 
						|
    DataPtr  = AttachedData;
 | 
						|
    DataSize = AttachedDataSize;
 | 
						|
  } else if (InData != NULL) {
 | 
						|
    //
 | 
						|
    // PKCS7-formatted signedData with detached content; Use the user-supplied
 | 
						|
    // input data for verification
 | 
						|
    //
 | 
						|
    DataPtr  = (UINT8 *)InData;
 | 
						|
    DataSize = InDataSize;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Content not found because InData is NULL and no content attached in SignedData
 | 
						|
    //
 | 
						|
    Status = EFI_NOT_FOUND;
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = EFI_UNSUPPORTED;
 | 
						|
 | 
						|
  //
 | 
						|
  // Verify PKCS7 SignedData with Revoked database
 | 
						|
  //
 | 
						|
  if (RevokedDb != NULL) {
 | 
						|
    Status = P7CheckRevocation (
 | 
						|
               SignedData,
 | 
						|
               SignedDataSize,
 | 
						|
               DataPtr,
 | 
						|
               DataSize,
 | 
						|
               RevokedDb,
 | 
						|
               TimeStampDb
 | 
						|
               );
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // The PKCS7 SignedData is revoked
 | 
						|
      //
 | 
						|
      Status = EFI_SECURITY_VIOLATION;
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Verify PKCS7 SignedData with AllowedDB
 | 
						|
  //
 | 
						|
  Status = P7CheckTrust (
 | 
						|
             SignedData,
 | 
						|
             SignedDataSize,
 | 
						|
             DataPtr,
 | 
						|
             DataSize,
 | 
						|
             AllowedDb
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // Verification failed with AllowedDb
 | 
						|
    //
 | 
						|
    goto _Exit;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Copy the content portion after verification succeeds
 | 
						|
  //
 | 
						|
  if (Content != NULL) {
 | 
						|
    if (*ContentSize < DataSize) {
 | 
						|
      //
 | 
						|
      // Caller-allocated buffer is too small to contain content
 | 
						|
      //
 | 
						|
      *ContentSize = DataSize;
 | 
						|
      Status       = EFI_BUFFER_TOO_SMALL;
 | 
						|
    } else {
 | 
						|
      *ContentSize = DataSize;
 | 
						|
      CopyMem (Content, DataPtr, DataSize);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
_Exit:
 | 
						|
  if (AttachedData != NULL) {
 | 
						|
    FreePool (AttachedData);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Processes a buffer containing binary DER-encoded detached PKCS7 signature.
 | 
						|
  The hash of the signed data content is calculated and passed by the caller. Function
 | 
						|
  verifies the signature of the content is valid and signing certificate was not revoked
 | 
						|
  and is contained within a list of trusted signers.
 | 
						|
 | 
						|
  Note: because this function uses hashes and the specification contains a variety of
 | 
						|
        hash choices, you should be aware that the check against the RevokedDb list
 | 
						|
        will improperly succeed if the signature is revoked using a different hash
 | 
						|
        algorithm.  For this reason, you should either cycle through all UEFI supported
 | 
						|
        hashes to see if one is forbidden, or rely on a single hash choice only if the
 | 
						|
        UEFI signature authority only signs and revokes with a single hash (at time
 | 
						|
        of writing, this hash choice is SHA256).
 | 
						|
 | 
						|
  @param[in]     This                 Pointer to EFI_PKCS7_VERIFY_PROTOCOL instance.
 | 
						|
  @param[in]     Signature            Points to buffer containing ASN.1 DER-encoded PKCS
 | 
						|
                                      detached signature.
 | 
						|
  @param[in]     SignatureSize        The size of Signature buffer in bytes.
 | 
						|
  @param[in]     InHash               InHash points to buffer containing the caller
 | 
						|
                                      calculated hash of the data. The parameter may not
 | 
						|
                                      be NULL.
 | 
						|
  @param[in]     InHashSize           The size in bytes of InHash buffer.
 | 
						|
  @param[in]     AllowedDb            Pointer to a list of pointers to EFI_SIGNATURE_LIST
 | 
						|
                                      structures. The list is terminated by a null
 | 
						|
                                      pointer. The EFI_SIGNATURE_LIST structures contain
 | 
						|
                                      lists of X.509 certificates of approved signers.
 | 
						|
                                      Function recognizes signer certificates of type
 | 
						|
                                      EFI_CERT_X509_GUID. Any hash certificate in AllowedDb
 | 
						|
                                      list is ignored by this function. Function returns
 | 
						|
                                      success if signer of the buffer is within this list
 | 
						|
                                      (and not within RevokedDb). This parameter is
 | 
						|
                                      required.
 | 
						|
  @param[in]     RevokedDb            Optional pointer to a list of pointers to
 | 
						|
                                      EFI_SIGNATURE_LIST structures. The list is terminated
 | 
						|
                                      by a null pointer. List of X.509 certificates of
 | 
						|
                                      revoked signers and revoked file hashes. Signature
 | 
						|
                                      verification will always fail if the signer of the
 | 
						|
                                      file or the hash of the data component of the buffer
 | 
						|
                                      is in RevokedDb list. This parameter is optional
 | 
						|
                                      and caller may pass Null if not required.
 | 
						|
  @param[in]     TimeStampDb          Optional pointer to a list of pointers to
 | 
						|
                                      EFI_SIGNATURE_LIST structures. The list is terminated
 | 
						|
                                      by a null pointer. This parameter can be used to pass
 | 
						|
                                      a list of X.509 certificates of trusted time stamp
 | 
						|
                                      counter-signers.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS                 Signed hash was verified against caller-provided
 | 
						|
                                      hash of content, the signer's certificate was not
 | 
						|
                                      found in RevokedDb, and was found in AllowedDb or
 | 
						|
                                      if in signer is found in both AllowedDb and
 | 
						|
                                      RevokedDb, the signing was allowed by reference to
 | 
						|
                                      TimeStampDb as described above, and no hash matching
 | 
						|
                                      content hash was found in RevokedDb.
 | 
						|
  @retval EFI_SECURITY_VIOLATION      The SignedData buffer was correctly formatted but
 | 
						|
                                      signer was in RevokedDb or not in AllowedDb. Also
 | 
						|
                                      returned if matching content hash found in RevokedDb.
 | 
						|
  @retval EFI_COMPROMISED_DATA        Caller provided hash differs from signed hash. Or,
 | 
						|
                                      caller and encrypted hash are different sizes.
 | 
						|
  @retval EFI_INVALID_PARAMETER       Signature is NULL or SignatureSize is zero. InHash
 | 
						|
                                      is NULL or InHashSize is zero. AllowedDb is NULL.
 | 
						|
  @retval EFI_ABORTED                 Unsupported or invalid format in TimeStampDb,
 | 
						|
                                      RevokedDb or AllowedDb list contents was detected.
 | 
						|
  @retval EFI_UNSUPPORTED             The Signature buffer was not correctly formatted
 | 
						|
                                      for processing by the function.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
VerifySignature (
 | 
						|
  IN EFI_PKCS7_VERIFY_PROTOCOL  *This,
 | 
						|
  IN VOID                       *Signature,
 | 
						|
  IN UINTN                      SignatureSize,
 | 
						|
  IN VOID                       *InHash,
 | 
						|
  IN UINTN                      InHashSize,
 | 
						|
  IN EFI_SIGNATURE_LIST         **AllowedDb,
 | 
						|
  IN EFI_SIGNATURE_LIST         **RevokedDb       OPTIONAL,
 | 
						|
  IN EFI_SIGNATURE_LIST         **TimeStampDb     OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // Parameters Checking
 | 
						|
  //
 | 
						|
  if (  (Signature == NULL) || (SignatureSize == 0) || (AllowedDb == NULL)
 | 
						|
     || (InHash == NULL) || (InHashSize == 0))
 | 
						|
  {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Verify PKCS7 SignedData with Revoked database
 | 
						|
  //
 | 
						|
  if (RevokedDb != NULL) {
 | 
						|
    Status = P7CheckRevocationByHash (
 | 
						|
               Signature,
 | 
						|
               SignatureSize,
 | 
						|
               InHash,
 | 
						|
               InHashSize,
 | 
						|
               RevokedDb,
 | 
						|
               TimeStampDb
 | 
						|
               );
 | 
						|
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // The PKCS7 SignedData is revoked
 | 
						|
      //
 | 
						|
      return EFI_SECURITY_VIOLATION;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Verify PKCS7 SignedData with AllowedDB
 | 
						|
  //
 | 
						|
  Status = P7CheckTrustByHash (
 | 
						|
             Signature,
 | 
						|
             SignatureSize,
 | 
						|
             InHash,
 | 
						|
             InHashSize,
 | 
						|
             AllowedDb
 | 
						|
             );
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// The PKCS7 Verification Protocol
 | 
						|
//
 | 
						|
EFI_PKCS7_VERIFY_PROTOCOL  mPkcs7Verify = {
 | 
						|
  VerifyBuffer,
 | 
						|
  VerifySignature
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  The user Entry Point for the PKCS7 Verification driver.
 | 
						|
 | 
						|
  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
 | 
						|
  @param[in] SystemTable    A pointer to the EFI System Table.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The entry point is executed successfully.
 | 
						|
  @retval EFI_NOT_SUPPORTED Platform does not support PKCS7 Verification.
 | 
						|
  @retval Other             Some error occurs when executing this entry point.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
Pkcs7VerifyDriverEntry (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                 Status;
 | 
						|
  EFI_HANDLE                 Handle;
 | 
						|
  EFI_PKCS7_VERIFY_PROTOCOL  Useless;
 | 
						|
 | 
						|
  //
 | 
						|
  // Avoid loading a second copy if this is built as an external module
 | 
						|
  //
 | 
						|
  Status = gBS->LocateProtocol (&gEfiPkcs7VerifyProtocolGuid, NULL, (VOID **)&Useless);
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Install UEFI Pkcs7 Verification Protocol
 | 
						|
  //
 | 
						|
  Handle = NULL;
 | 
						|
  Status = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                  &Handle,
 | 
						|
                  &gEfiPkcs7VerifyProtocolGuid,
 | 
						|
                  &mPkcs7Verify,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 |