SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c File Reference


Functions

VOID EFIAPI SecureBootHook (IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINTN DataSize, IN VOID *Data)
EFI_STATUS EFIAPI DxeImageVerificationLibImageRead (IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
UINT32 GetImageType (IN CONST EFI_DEVICE_PATH_PROTOCOL *File)
BOOLEAN HashPeImage (IN UINT32 HashAlg)
EFI_STATUS HashPeImageByType (IN UINT8 *AuthData, IN UINTN AuthDataSize)
UINTN GetImageExeInfoTableSize (EFI_IMAGE_EXECUTION_INFO_TABLE *ImageExeInfoTable)
VOID AddImageExeInfo (IN EFI_IMAGE_EXECUTION_ACTION Action, IN CHAR16 *Name, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN EFI_SIGNATURE_LIST *Signature, IN UINTN SignatureSize)
BOOLEAN IsCertHashFoundInDatabase (IN UINT8 *Certificate, IN UINTN CertSize, IN EFI_SIGNATURE_LIST *SignatureList, IN UINTN SignatureListSize, OUT EFI_TIME *RevocationTime)
BOOLEAN IsSignatureFoundInDatabase (IN CHAR16 *VariableName, IN UINT8 *Signature, IN EFI_GUID *CertType, IN UINTN SignatureSize)
BOOLEAN IsValidSignatureByTimestamp (IN EFI_TIME *SigningTime, IN EFI_TIME *RevocationTime)
BOOLEAN IsTimeZero (IN EFI_TIME *Time)
BOOLEAN PassTimestampCheck (IN UINT8 *AuthData, IN UINTN AuthDataSize, IN EFI_TIME *RevocationTime)
BOOLEAN IsForbiddenByDbx (IN UINT8 *AuthData, IN UINTN AuthDataSize)
BOOLEAN IsAllowedByDb (IN UINT8 *AuthData, IN UINTN AuthDataSize)
EFI_STATUS EFIAPI DxeImageVerificationHandler (IN UINT32 AuthenticationStatus, IN CONST EFI_DEVICE_PATH_PROTOCOL *File, IN VOID *FileBuffer, IN UINTN FileSize, IN BOOLEAN BootPolicy)
VOID EFIAPI OnReadyToBoot (IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI DxeImageVerificationLibConstructor (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)

Variables

EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader
UINT32 mPeCoffHeaderOffset
EFI_GUID mCertType
UINTN mImageSize
UINT8 * mImageBase = NULL
UINT8 mImageDigest [MAX_DIGEST_SIZE]
UINTN mImageDigestSize
CHAR16 mNotifyString1 [MAX_NOTIFY_STRING_LEN] = L"Image verification pass but not found in authorized database!"
CHAR16 mNotifyString2 [MAX_NOTIFY_STRING_LEN] = L"Launch this image anyway? (Yes/Defer/No)"
CONST UINT8 mRsaE [] = { 0x01, 0x00, 0x01 }
UINT8 mHashOidValue []
HASH_TABLE mHash []

Detailed Description

Implement image verification services for secure boot service

Caution: This file requires additional review when modified. This library will have external input - PE/COFF image. This external input must be validated carefully to avoid security issue like buffer overflow, integer overflow.

DxeImageVerificationLibImageRead() function will make sure the PE/COFF image content read is within the image buffer.

DxeImageVerificationHandler(), HashPeImageByType(), HashPeImage() function will accept untrusted PE/COFF image and validate its data structure within this image buffer before use.

Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.


Function Documentation

VOID AddImageExeInfo ( IN EFI_IMAGE_EXECUTION_ACTION  Action,
IN CHAR16 *  Name,
IN CONST EFI_DEVICE_PATH_PROTOCOL *  DevicePath,
IN EFI_SIGNATURE_LIST *  Signature,
IN UINTN  SignatureSize 
)

Create an Image Execution Information Table entry and add it to system configuration table.

Parameters:
[in] Action Describes the action taken by the firmware regarding this image.
[in] Name Input a null-terminated, user-friendly name.
[in] DevicePath Input device path pointer.
[in] Signature Input signature info in EFI_SIGNATURE_LIST data structure.
[in] SignatureSize Size of signature.

References GetImageExeInfoTableSize(), and UINTN().

Referenced by DxeImageVerificationHandler().

EFI_STATUS EFIAPI DxeImageVerificationHandler ( IN UINT32  AuthenticationStatus,
IN CONST EFI_DEVICE_PATH_PROTOCOL *  File,
IN VOID *  FileBuffer,
IN UINTN  FileSize,
IN BOOLEAN  BootPolicy 
)

Provide verification service for signed images, which include both signature validation and platform policy control. For signature types, both UEFI WIN_CERTIFICATE_UEFI_GUID and MSFT Authenticode type signatures are supported.

In this implementation, only verify external executables when in USER MODE. Executables from FV is bypass, so pass in AuthenticationStatus is ignored.

The image verification policy is: If the image is signed, At least one valid signature or at least one hash value of the image must match a record in the security database "db", and no valid signature nor any hash value of the image may be reflected in the security database "dbx". Otherwise, the image is not signed, The SHA256 hash value of the image must match a record in the security database "db", and not be reflected in the security data base "dbx".

Caution: This function may receive untrusted input. PE/COFF image is external input, so this function will validate its data structure within this image buffer before use.

Parameters:
[in] AuthenticationStatus This is the authentication status returned from the security measurement services for the input file.
[in] File This is a pointer to the device path of the file that is being dispatched. This will optionally be used for logging.
[in] FileBuffer File buffer matches the input file device path.
[in] FileSize Size of File buffer matches the input file device path.
[in] BootPolicy A boot policy that was used to call LoadImage() UEFI service.
Return values:
EFI_SUCCESS The file specified by DevicePath and non-NULL FileBuffer did authenticate, and the platform policy dictates that the DXE Foundation may use the file.
EFI_SUCCESS The device path specified by NULL device path DevicePath and non-NULL FileBuffer did authenticate, and the platform policy dictates that the DXE Foundation may execute the image in FileBuffer.
EFI_OUT_RESOURCE Fail to allocate memory.
EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and the platform policy dictates that File should be placed in the untrusted state. The image has been added to the file execution table.
EFI_ACCESS_DENIED The file specified by File and FileBuffer did not authenticate, and the platform policy dictates that the DXE Foundation many not use File.

References AddImageExeInfo(), ALIGN_SIZE, ALLOW_EXECUTE_ON_SECURITY_VIOLATION, ALWAYS_EXECUTE, WIN_CERTIFICATE_EFI_PKCS::CertData, DENY_EXECUTE_ON_SECURITY_VIOLATION, DxeImageVerificationLibImageRead(), EFI_STATUS(), GetImageType(), HASHALG_SHA256, HashPeImage(), HashPeImageByType(), WIN_CERTIFICATE_EFI_PKCS::Hdr, IMAGE_FROM_FIXED_MEDIA, IMAGE_FROM_FV, IMAGE_FROM_OPTION_ROM, IMAGE_FROM_REMOVABLE_MEDIA, IsAllowedByDb(), IsForbiddenByDbx(), IsSignatureFoundInDatabase(), mCertType, mImageBase, mImageDigest, mImageDigestSize, mImageSize, mNtHeader, mPeCoffHeaderOffset, NEVER_EXECUTE, QUERY_USER_ON_SECURITY_VIOLATION, TRUE, and UINTN().

Referenced by DxeImageVerificationLibConstructor().

EFI_STATUS EFIAPI DxeImageVerificationLibConstructor ( IN EFI_HANDLE  ImageHandle,
IN EFI_SYSTEM_TABLE *  SystemTable 
)

Register security measurement handler.

Parameters:
ImageHandle ImageHandle of the loaded driver.
SystemTable Pointer to the EFI System Table.
Return values:
EFI_SUCCESS The handlers were registered successfully.

References DxeImageVerificationHandler(), and OnReadyToBoot().

EFI_STATUS EFIAPI DxeImageVerificationLibImageRead ( IN VOID *  FileHandle,
IN UINTN  FileOffset,
IN OUT UINTN *  ReadSize,
OUT VOID *  Buffer 
)

Reads contents of a PE/COFF image in memory buffer.

Caution: This function may receive untrusted input. PE/COFF image is external input, so this function will make sure the PE/COFF image content read is within the image buffer.

Parameters:
FileHandle Pointer to the file handle to read the PE/COFF image.
FileOffset Offset into the PE/COFF image to begin the read operation.
ReadSize On input, the size in bytes of the requested read operation. On output, the number of bytes actually read.
Buffer Output buffer that contains the data read from the PE/COFF image.
Return values:
EFI_SUCCESS The specified portion of the PE/COFF image was read and the size

References mImageSize, and UINTN().

Referenced by DxeImageVerificationHandler().

UINTN GetImageExeInfoTableSize ( EFI_IMAGE_EXECUTION_INFO_TABLE *  ImageExeInfoTable  ) 

Returns the size of a given image execution info table in bytes.

This function returns the size, in bytes, of the image execution info table specified by ImageExeInfoTable. If ImageExeInfoTable is NULL, then 0 is returned.

Parameters:
ImageExeInfoTable A pointer to a image execution info table structure.
Return values:
0 If ImageExeInfoTable is NULL.
Others The size of a image execution info table in bytes.

References UINTN().

Referenced by AddImageExeInfo().

UINT32 GetImageType ( IN CONST EFI_DEVICE_PATH_PROTOCOL *  File  ) 

Get the image type.

Parameters:
[in] File This is a pointer to the device path of the file that is being dispatched.
Returns:
UINT32 Image Type

References EFI_STATUS(), IMAGE_FROM_FIXED_MEDIA, IMAGE_FROM_FV, IMAGE_FROM_OPTION_ROM, IMAGE_FROM_REMOVABLE_MEDIA, and IMAGE_UNKNOWN.

Referenced by DxeImageVerificationHandler().

BOOLEAN HashPeImage ( IN UINT32  HashAlg  ) 

Calculate hash of Pe/Coff image based on the authenticode image hashing in PE/COFF Specification 8.0 Appendix A

Caution: This function may receive untrusted input. PE/COFF image is external input, so this function will validate its data structure within this image buffer before use.

Parameters:
[in] HashAlg Hash algorithm type.
Return values:
TRUE Successfully hash image.
FALSE Fail in hash image.

References BOOLEAN(), HASH_TABLE::GetContextSize, HASHALG_MAX, HASHALG_SHA1, HASHALG_SHA256, HASHALG_SHA384, HASHALG_SHA512, HASH_TABLE::HashFinal, HASH_TABLE::HashInit, HASH_TABLE::HashUpdate, MAX_DIGEST_SIZE, mCertType, mImageBase, mImageDigest, mImageDigestSize, mImageSize, mNtHeader, mPeCoffHeaderOffset, SHA1_DIGEST_SIZE, SHA256_DIGEST_SIZE, SHA384_DIGEST_SIZE, SHA512_DIGEST_SIZE, and UINTN().

Referenced by DxeImageVerificationHandler(), EnrollImageSignatureToSigDB(), and HashPeImageByType().

EFI_STATUS HashPeImageByType ( IN UINT8 *  AuthData,
IN UINTN  AuthDataSize 
)

Recognize the Hash algorithm in PE/COFF Authenticode and calculate hash of Pe/Coff image based on the authenticode image hashing in PE/COFF Specification 8.0 Appendix A

Caution: This function may receive untrusted input. PE/COFF image is external input, so this function will validate its data structure within this image buffer before use.

Parameters:
[in] AuthData Pointer to the Authenticode Signature retrieved from signed image.
[in] AuthDataSize Size of the Authenticode Signature in bytes.
Return values:
EFI_UNSUPPORTED Hash algorithm is not supported.
EFI_SUCCESS Hash successfully.

References HASHALG_MAX, HashPeImage(), and TWO_BYTE_ENCODE.

Referenced by DxeImageVerificationHandler(), and EnrollImageSignatureToSigDB().

BOOLEAN IsAllowedByDb ( IN UINT8 *  AuthData,
IN UINTN  AuthDataSize 
)

Check whether the image signature can be verified by the trusted certificates in DB database.

Parameters:
[in] AuthData Pointer to the Authenticode signature retrieved from signed image.
[in] AuthDataSize Size of the Authenticode signature in bytes.
Return values:
TRUE Image passed verification using certificate in db.
FALSE Image didn't pass verification using certificate in db.

References BOOLEAN(), EFI_STATUS(), IsCertHashFoundInDatabase(), mImageDigest, mImageDigestSize, PassTimestampCheck(), SecureBootHook(), and UINTN().

Referenced by DxeImageVerificationHandler().

BOOLEAN IsCertHashFoundInDatabase ( IN UINT8 *  Certificate,
IN UINTN  CertSize,
IN EFI_SIGNATURE_LIST *  SignatureList,
IN UINTN  SignatureListSize,
OUT EFI_TIME *  RevocationTime 
)

Check whether the hash of an given X.509 certificate is in forbidden database (DBX).

Parameters:
[in] Certificate Pointer to X.509 Certificate that is searched for.
[in] CertSize Size of X.509 Certificate.
[in] SignatureList Pointer to the Signature List in forbidden database.
[in] SignatureListSize Size of Signature List.
[out] RevocationTime Return the time that the certificate was revoked.
Returns:
TRUE The certificate hash is found in the forbidden database.

FALSE The certificate hash is not found in the forbidden database.

References BOOLEAN(), HASHALG_MAX, HASHALG_SHA256, HASHALG_SHA384, HASHALG_SHA512, HASH_TABLE::HashFinal, HASH_TABLE::HashInit, HASH_TABLE::HashUpdate, MAX_DIGEST_SIZE, TRUE, and UINTN().

Referenced by IsAllowedByDb(), and IsForbiddenByDbx().

BOOLEAN IsForbiddenByDbx ( IN UINT8 *  AuthData,
IN UINTN  AuthDataSize 
)

Check whether the image signature is forbidden by the forbidden database (dbx). The image is forbidden to load if any certificates for signing are revoked before signing time.

Parameters:
[in] AuthData Pointer to the Authenticode signature retrieved from the signed image.
[in] AuthDataSize Size of the Authenticode signature in bytes.
Return values:
TRUE Image is forbidden by dbx.
FALSE Image is not forbidden by dbx.

References BOOLEAN(), EFI_STATUS(), IsCertHashFoundInDatabase(), mImageDigest, mImageDigestSize, PassTimestampCheck(), SecureBootHook(), TRUE, and UINTN().

Referenced by DxeImageVerificationHandler().

BOOLEAN IsSignatureFoundInDatabase ( IN CHAR16 *  VariableName,
IN UINT8 *  Signature,
IN EFI_GUID *  CertType,
IN UINTN  SignatureSize 
)

Check whether signature is in specified database.

Parameters:
[in] VariableName Name of database variable that is searched in.
[in] Signature Pointer to signature that is searched for.
[in] CertType Pointer to hash algrithom.
[in] SignatureSize Size of Signature.
Returns:
TRUE Found the signature in the variable database.

FALSE Not found the signature in the variable database.

References BOOLEAN(), EFI_STATUS(), SecureBootHook(), TRUE, and UINTN().

Referenced by DxeImageVerificationHandler(), and IsX509CertInDbx().

BOOLEAN IsTimeZero ( IN EFI_TIME *  Time  ) 

Check if the given time value is zero.

Parameters:
[in] Time Pointer of a time value.
Return values:
TRUE The Time is Zero.
FALSE The Time is not Zero.

References TRUE.

Referenced by IsValidTimestamp(), and PassTimestampCheck().

BOOLEAN IsValidSignatureByTimestamp ( IN EFI_TIME *  SigningTime,
IN EFI_TIME *  RevocationTime 
)

Check whether the timestamp is valid by comparing the signing time and the revocation time.

Parameters:
SigningTime A pointer to the signing time.
RevocationTime A pointer to the revocation time.
Return values:
TRUE The SigningTime is not later than the RevocationTime.
FALSE The SigningTime is later than the RevocationTime.

References BOOLEAN().

Referenced by PassTimestampCheck().

VOID EFIAPI OnReadyToBoot ( IN EFI_EVENT  Event,
IN VOID *  Context 
)

On Ready To Boot Services Event notification handler.

Add the image execution information table if it is not in system configuration table.

Parameters:
[in] Event Event whose notification function is being invoked
[in] Context Pointer to the notification function's context

References UINTN().

Referenced by DriverEntry(), DxeImageVerificationLibConstructor(), and MorDriverEntryPoint().

BOOLEAN PassTimestampCheck ( IN UINT8 *  AuthData,
IN UINTN  AuthDataSize,
IN EFI_TIME *  RevocationTime 
)

Check whether the timestamp signature is valid and the signing time is also earlier than the revocation time.

Parameters:
[in] AuthData Pointer to the Authenticode signature retrieved from signed image.
[in] AuthDataSize Size of the Authenticode signature in bytes.
[in] RevocationTime The time that the certificate was revoked.
Return values:
TRUE Timestamp signature is valid and signing time is no later than the revocation time.
FALSE Timestamp signature is not valid or the signing time is later than the revocation time.

References BOOLEAN(), EFI_STATUS(), IsTimeZero(), IsValidSignatureByTimestamp(), TRUE, and UINTN().

Referenced by IsAllowedByDb(), and IsForbiddenByDbx().

VOID EFIAPI SecureBootHook ( IN CHAR16 *  VariableName,
IN EFI_GUID *  VendorGuid,
IN UINTN  DataSize,
IN VOID *  Data 
)

SecureBoot Hook for processing image verification.

Parameters:
[in] VariableName Name of Variable to be found.
[in] VendorGuid Variable vendor GUID.
[in] DataSize Size of Data found. If size is less than the data, this value contains the required size.
[in] Data Data pointer.

References AddDataMeasured(), EFI_STATUS(), IsDataMeasured(), IsSecureAuthorityVariable(), and MeasureVariable().

Referenced by IsAllowedByDb(), IsForbiddenByDbx(), and IsSignatureFoundInDatabase().


Variable Documentation

EFI_GUID mCertType

Initial value:

 {
  { L"SHA1",   20, &mHashOidValue[0],  5, Sha1GetContextSize,   Sha1Init,   Sha1Update,   Sha1Final  },
  { L"SHA224", 28, &mHashOidValue[5],  9, NULL,                 NULL,       NULL,         NULL       },
  { L"SHA256", 32, &mHashOidValue[14], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final},
  { L"SHA384", 48, &mHashOidValue[23], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final},
  { L"SHA512", 64, &mHashOidValue[32], 9, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final}
}

UINT8 mHashOidValue[]

Initial value:

 {
  0x2B, 0x0E, 0x03, 0x02, 0x1A,                           
  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,   
  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,   
  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,   
  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,   
  }

UINT8* mImageBase = NULL

UINT8 mImageDigest[MAX_DIGEST_SIZE]

UINTN mImageSize

CHAR16 mNotifyString1[MAX_NOTIFY_STRING_LEN] = L"Image verification pass but not found in authorized database!"

CHAR16 mNotifyString2[MAX_NOTIFY_STRING_LEN] = L"Launch this image anyway? (Yes/Defer/No)"

EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader

CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 }


Generated on Thu Sep 24 23:44:24 2015 for SecurityPkg[ALL] by  doxygen 1.5.7.1