// Caution: This is used by a function which may receive untrusted input.\r
// These global variables hold PE/COFF image data, and they should be validated before use.\r
//\r
-EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader;\r
-UINT32 mPeCoffHeaderOffset;\r
-EFI_GUID mCertType;\r
+EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader;\r
+UINT32 mPeCoffHeaderOffset;\r
+EFI_GUID mCertType;\r
\r
//\r
// Information on current PE/COFF image\r
//\r
-UINTN mImageSize;\r
-UINT8 *mImageBase = NULL;\r
-UINT8 mImageDigest[MAX_DIGEST_SIZE];\r
-UINTN mImageDigestSize;\r
+UINTN mImageSize;\r
+UINT8 *mImageBase = NULL;\r
+UINT8 mImageDigest[MAX_DIGEST_SIZE];\r
+UINTN mImageDigestSize;\r
\r
//\r
// Notify string for authorization UI.\r
//\r
// Public Exponent of RSA Key.\r
//\r
-CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };\r
-\r
+CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };\r
\r
//\r
// OID ASN.1 Value for Hash Algorithms\r
//\r
-UINT8 mHashOidValue[] = {\r
- 0x2B, 0x0E, 0x03, 0x02, 0x1A, // OBJ_sha1\r
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, // OBJ_sha224\r
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, // OBJ_sha256\r
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, // OBJ_sha384\r
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, // OBJ_sha512\r
- };\r
-\r
-HASH_TABLE mHash[] = {\r
- { L"SHA1", 20, &mHashOidValue[0], 5, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final },\r
- { L"SHA224", 28, &mHashOidValue[5], 9, NULL, NULL, NULL, NULL },\r
- { L"SHA256", 32, &mHashOidValue[14], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final},\r
- { L"SHA384", 48, &mHashOidValue[23], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final},\r
- { L"SHA512", 64, &mHashOidValue[32], 9, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final}\r
+UINT8 mHashOidValue[] = {\r
+ 0x2B, 0x0E, 0x03, 0x02, 0x1A, // OBJ_sha1\r
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, // OBJ_sha224\r
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, // OBJ_sha256\r
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, // OBJ_sha384\r
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, // OBJ_sha512\r
+};\r
+\r
+HASH_TABLE mHash[] = {\r
+ #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES\r
+ { L"SHA1", 20, &mHashOidValue[0], 5, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final },\r
+ #else\r
+ { L"SHA1", 20, &mHashOidValue[0], 5, NULL, NULL, NULL, NULL },\r
+ #endif\r
+ { L"SHA224", 28, &mHashOidValue[5], 9, NULL, NULL, NULL, NULL },\r
+ { L"SHA256", 32, &mHashOidValue[14], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final },\r
+ { L"SHA384", 48, &mHashOidValue[23], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final },\r
+ { L"SHA512", 64, &mHashOidValue[32], 9, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final }\r
};\r
\r
-EFI_STRING mHashTypeStr;\r
+EFI_STRING mHashTypeStr;\r
\r
/**\r
SecureBoot Hook for processing image verification.\r
VOID\r
EFIAPI\r
SecureBootHook (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN UINTN DataSize,\r
- IN VOID *Data\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINTN DataSize,\r
+ IN VOID *Data\r
);\r
\r
/**\r
EFI_STATUS\r
EFIAPI\r
DxeImageVerificationLibImageRead (\r
- IN VOID *FileHandle,\r
- IN UINTN FileOffset,\r
- IN OUT UINTN *ReadSize,\r
- OUT VOID *Buffer\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINTN *ReadSize,\r
+ OUT VOID *Buffer\r
)\r
{\r
- UINTN EndPosition;\r
+ UINTN EndPosition;\r
\r
- if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) {\r
+ if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
*ReadSize = 0;\r
}\r
\r
- CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);\r
+ CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize);\r
\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Get the image type.\r
\r
**/\r
UINT32\r
GetImageType (\r
- IN CONST EFI_DEVICE_PATH_PROTOCOL *File\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *File\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_HANDLE DeviceHandle;\r
- EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
- EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE DeviceHandle;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
\r
if (File == NULL) {\r
return IMAGE_UNKNOWN;\r
//\r
// First check to see if File is from a Firmware Volume\r
//\r
- DeviceHandle = NULL;\r
- TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) File;\r
- Status = gBS->LocateDevicePath (\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- &TempDevicePath,\r
- &DeviceHandle\r
- );\r
+ DeviceHandle = NULL;\r
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ &TempDevicePath,\r
+ &DeviceHandle\r
+ );\r
if (!EFI_ERROR (Status)) {\r
Status = gBS->OpenProtocol (\r
DeviceHandle,\r
// Next check to see if File is from a Block I/O device\r
//\r
DeviceHandle = NULL;\r
- TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) File;\r
- Status = gBS->LocateDevicePath (\r
- &gEfiBlockIoProtocolGuid,\r
- &TempDevicePath,\r
- &DeviceHandle\r
- );\r
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiBlockIoProtocolGuid,\r
+ &TempDevicePath,\r
+ &DeviceHandle\r
+ );\r
if (!EFI_ERROR (Status)) {\r
BlockIo = NULL;\r
- Status = gBS->OpenProtocol (\r
- DeviceHandle,\r
- &gEfiBlockIoProtocolGuid,\r
- (VOID **) &BlockIo,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status) && BlockIo != NULL) {\r
+ Status = gBS->OpenProtocol (\r
+ DeviceHandle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ (VOID **)&BlockIo,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status) && (BlockIo != NULL)) {\r
if (BlockIo->Media != NULL) {\r
if (BlockIo->Media->RemovableMedia) {\r
//\r
// the device path supports the Simple File System Protocol.\r
//\r
DeviceHandle = NULL;\r
- TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) File;\r
- Status = gBS->LocateDevicePath (\r
- &gEfiSimpleFileSystemProtocolGuid,\r
- &TempDevicePath,\r
- &DeviceHandle\r
- );\r
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiSimpleFileSystemProtocolGuid,\r
+ &TempDevicePath,\r
+ &DeviceHandle\r
+ );\r
if (!EFI_ERROR (Status)) {\r
//\r
// Simple File System is present without Block I/O, so assume media is fixed.\r
// File is not from an FV, Block I/O or Simple File System, so the only options\r
// left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC.\r
//\r
- TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) File;\r
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
while (!IsDevicePathEndType (TempDevicePath)) {\r
switch (DevicePathType (TempDevicePath)) {\r
+ case MEDIA_DEVICE_PATH:\r
+ if (DevicePathSubType (TempDevicePath) == MEDIA_RELATIVE_OFFSET_RANGE_DP) {\r
+ return IMAGE_FROM_OPTION_ROM;\r
+ }\r
\r
- case MEDIA_DEVICE_PATH:\r
- if (DevicePathSubType (TempDevicePath) == MEDIA_RELATIVE_OFFSET_RANGE_DP) {\r
- return IMAGE_FROM_OPTION_ROM;\r
- }\r
- break;\r
+ break;\r
\r
- case MESSAGING_DEVICE_PATH:\r
- if (DevicePathSubType(TempDevicePath) == MSG_MAC_ADDR_DP) {\r
- return IMAGE_FROM_REMOVABLE_MEDIA;\r
- }\r
- break;\r
+ case MESSAGING_DEVICE_PATH:\r
+ if (DevicePathSubType (TempDevicePath) == MSG_MAC_ADDR_DP) {\r
+ return IMAGE_FROM_REMOVABLE_MEDIA;\r
+ }\r
\r
- default:\r
- break;\r
+ break;\r
+\r
+ default:\r
+ break;\r
}\r
+\r
TempDevicePath = NextDevicePathNode (TempDevicePath);\r
}\r
+\r
return IMAGE_UNKNOWN;\r
}\r
\r
**/\r
BOOLEAN\r
HashPeImage (\r
- IN UINT32 HashAlg\r
+ IN UINT32 HashAlg\r
)\r
{\r
BOOLEAN Status;\r
ZeroMem (mImageDigest, MAX_DIGEST_SIZE);\r
\r
switch (HashAlg) {\r
- case HASHALG_SHA1:\r
- mImageDigestSize = SHA1_DIGEST_SIZE;\r
- mCertType = gEfiCertSha1Guid;\r
- break;\r
-\r
- case HASHALG_SHA256:\r
- mImageDigestSize = SHA256_DIGEST_SIZE;\r
- mCertType = gEfiCertSha256Guid;\r
- break;\r
-\r
- case HASHALG_SHA384:\r
- mImageDigestSize = SHA384_DIGEST_SIZE;\r
- mCertType = gEfiCertSha384Guid;\r
- break;\r
-\r
- case HASHALG_SHA512:\r
- mImageDigestSize = SHA512_DIGEST_SIZE;\r
- mCertType = gEfiCertSha512Guid;\r
- break;\r
-\r
- default:\r
- return FALSE;\r
+ #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES\r
+ case HASHALG_SHA1:\r
+ mImageDigestSize = SHA1_DIGEST_SIZE;\r
+ mCertType = gEfiCertSha1Guid;\r
+ break;\r
+ #endif\r
+\r
+ case HASHALG_SHA256:\r
+ mImageDigestSize = SHA256_DIGEST_SIZE;\r
+ mCertType = gEfiCertSha256Guid;\r
+ break;\r
+\r
+ case HASHALG_SHA384:\r
+ mImageDigestSize = SHA384_DIGEST_SIZE;\r
+ mCertType = gEfiCertSha384Guid;\r
+ break;\r
+\r
+ case HASHALG_SHA512:\r
+ mImageDigestSize = SHA512_DIGEST_SIZE;\r
+ mCertType = gEfiCertSha512Guid;\r
+ break;\r
+\r
+ default:\r
+ return FALSE;\r
}\r
\r
mHashTypeStr = mHash[HashAlg].Name;\r
- CtxSize = mHash[HashAlg].GetContextSize();\r
+ CtxSize = mHash[HashAlg].GetContextSize ();\r
\r
HashCtx = AllocatePool (CtxSize);\r
if (HashCtx == NULL) {\r
// 1. Load the image header into memory.\r
\r
// 2. Initialize a SHA hash context.\r
- Status = mHash[HashAlg].HashInit(HashCtx);\r
+ Status = mHash[HashAlg].HashInit (HashCtx);\r
\r
if (!Status) {\r
goto Done;\r
//\r
// Use PE32 offset.\r
//\r
- HashSize = (UINTN) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - (UINTN) HashBase;\r
+ HashSize = (UINTN)(&mNtHeader.Pe32->OptionalHeader.CheckSum) - (UINTN)HashBase;\r
NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
} else if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
//\r
// Use PE32+ offset.\r
//\r
- HashSize = (UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - (UINTN) HashBase;\r
+ HashSize = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - (UINTN)HashBase;\r
NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
} else {\r
//\r
goto Done;\r
}\r
\r
- Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);\r
if (!Status) {\r
goto Done;\r
}\r
//\r
// Use PE32 offset.\r
//\r
- HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN) HashBase - (UINTN) mImageBase);\r
+ HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
+ HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase);\r
} else {\r
//\r
// Use PE32+ offset.\r
//\r
- HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN) HashBase - (UINTN) mImageBase);\r
+ HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
+ HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase);\r
}\r
\r
if (HashSize != 0) {\r
- Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);\r
if (!Status) {\r
goto Done;\r
}\r
//\r
// Use PE32 offset.\r
//\r
- HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = (UINTN) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase;\r
+ HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
+ HashSize = (UINTN)(&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase;\r
} else {\r
//\r
// Use PE32+ offset.\r
//\r
- HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = (UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase;\r
+ HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
+ HashSize = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase;\r
}\r
\r
if (HashSize != 0) {\r
- Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);\r
if (!Status) {\r
goto Done;\r
}\r
//\r
// Use PE32 offset\r
//\r
- HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
- HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN) HashBase - (UINTN) mImageBase);\r
+ HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
+ HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase);\r
} else {\r
//\r
// Use PE32+ offset.\r
//\r
- HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
- HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN) HashBase - (UINTN) mImageBase);\r
+ HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
+ HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase);\r
}\r
\r
if (HashSize != 0) {\r
- Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);\r
if (!Status) {\r
goto Done;\r
}\r
SumOfBytesHashed = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders;\r
}\r
\r
-\r
- Section = (EFI_IMAGE_SECTION_HEADER *) (\r
- mImageBase +\r
- mPeCoffHeaderOffset +\r
- sizeof (UINT32) +\r
- sizeof (EFI_IMAGE_FILE_HEADER) +\r
- mNtHeader.Pe32->FileHeader.SizeOfOptionalHeader\r
- );\r
+ Section = (EFI_IMAGE_SECTION_HEADER *)(\r
+ mImageBase +\r
+ mPeCoffHeaderOffset +\r
+ sizeof (UINT32) +\r
+ sizeof (EFI_IMAGE_FILE_HEADER) +\r
+ mNtHeader.Pe32->FileHeader.SizeOfOptionalHeader\r
+ );\r
\r
//\r
// 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER\r
// header indicates how big the table should be. Do not include any\r
// IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.\r
//\r
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * mNtHeader.Pe32->FileHeader.NumberOfSections);\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * mNtHeader.Pe32->FileHeader.NumberOfSections);\r
if (SectionHeader == NULL) {\r
Status = FALSE;\r
goto Done;\r
}\r
+\r
//\r
// 12. Using the 'PointerToRawData' in the referenced section headers as\r
// a key, arrange the elements in the table in ascending order. In other\r
CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER));\r
Pos--;\r
}\r
+\r
CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER));\r
Section += 1;\r
}\r
if (Section->SizeOfRawData == 0) {\r
continue;\r
}\r
- HashBase = mImageBase + Section->PointerToRawData;\r
- HashSize = (UINTN) Section->SizeOfRawData;\r
\r
- Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ HashBase = mImageBase + Section->PointerToRawData;\r
+ HashSize = (UINTN)Section->SizeOfRawData;\r
+\r
+ Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);\r
if (!Status) {\r
goto Done;\r
}\r
}\r
\r
if (mImageSize > CertSize + SumOfBytesHashed) {\r
- HashSize = (UINTN) (mImageSize - CertSize - SumOfBytesHashed);\r
+ HashSize = (UINTN)(mImageSize - CertSize - SumOfBytesHashed);\r
\r
- Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);\r
if (!Status) {\r
goto Done;\r
}\r
}\r
}\r
\r
- Status = mHash[HashAlg].HashFinal(HashCtx, mImageDigest);\r
+ Status = mHash[HashAlg].HashFinal (HashCtx, mImageDigest);\r
\r
Done:\r
if (HashCtx != NULL) {\r
FreePool (HashCtx);\r
}\r
+\r
if (SectionHeader != NULL) {\r
FreePool (SectionHeader);\r
}\r
+\r
return Status;\r
}\r
\r
**/\r
EFI_STATUS\r
HashPeImageByType (\r
- IN UINT8 *AuthData,\r
- IN UINTN AuthDataSize\r
+ IN UINT8 *AuthData,\r
+ IN UINTN AuthDataSize\r
)\r
{\r
- UINT8 Index;\r
+ UINT8 Index;\r
\r
for (Index = 0; Index < HASHALG_MAX; Index++) {\r
//\r
//\r
// HASH PE Image based on Hash algorithm in PE/COFF Authenticode.\r
//\r
- if (!HashPeImage(Index)) {\r
+ if (!HashPeImage (Index)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Returns the size of a given image execution info table in bytes.\r
\r
**/\r
UINTN\r
GetImageExeInfoTableSize (\r
- EFI_IMAGE_EXECUTION_INFO_TABLE *ImageExeInfoTable\r
+ EFI_IMAGE_EXECUTION_INFO_TABLE *ImageExeInfoTable\r
)\r
{\r
UINTN Index;\r
return 0;\r
}\r
\r
- ImageExeInfoItem = (EFI_IMAGE_EXECUTION_INFO *) ((UINT8 *) ImageExeInfoTable + sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE));\r
- TotalSize = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);\r
+ ImageExeInfoItem = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)ImageExeInfoTable + sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE));\r
+ TotalSize = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);\r
for (Index = 0; Index < ImageExeInfoTable->NumberOfImages; Index++) {\r
- TotalSize += ReadUnaligned32 ((UINT32 *) &ImageExeInfoItem->InfoSize);\r
- ImageExeInfoItem = (EFI_IMAGE_EXECUTION_INFO *) ((UINT8 *) ImageExeInfoItem + ReadUnaligned32 ((UINT32 *) &ImageExeInfoItem->InfoSize));\r
+ TotalSize += ReadUnaligned32 ((UINT32 *)&ImageExeInfoItem->InfoSize);\r
+ ImageExeInfoItem = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)ImageExeInfoItem + ReadUnaligned32 ((UINT32 *)&ImageExeInfoItem->InfoSize));\r
}\r
\r
return TotalSize;\r
@param[in] Name Input a null-terminated, user-friendly name.\r
@param[in] DevicePath Input device path pointer.\r
@param[in] Signature Input signature info in EFI_SIGNATURE_LIST data structure.\r
- @param[in] SignatureSize Size of signature.\r
+ @param[in] SignatureSize Size of signature. Must be zero if Signature is NULL.\r
\r
**/\r
VOID\r
AddImageExeInfo (\r
- IN EFI_IMAGE_EXECUTION_ACTION Action,\r
- IN CHAR16 *Name OPTIONAL,\r
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- IN EFI_SIGNATURE_LIST *Signature OPTIONAL,\r
- IN UINTN SignatureSize\r
+ IN EFI_IMAGE_EXECUTION_ACTION Action,\r
+ IN CHAR16 *Name OPTIONAL,\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN EFI_SIGNATURE_LIST *Signature OPTIONAL,\r
+ IN UINTN SignatureSize\r
)\r
{\r
EFI_IMAGE_EXECUTION_INFO_TABLE *ImageExeInfoTable;\r
UINTN DevicePathSize;\r
CHAR16 *NameStr;\r
\r
- ImageExeInfoTable = NULL;\r
- NewImageExeInfoTable = NULL;\r
- ImageExeInfoEntry = NULL;\r
- NameStringLen = 0;\r
- NameStr = NULL;\r
+ ImageExeInfoTable = NULL;\r
+ NewImageExeInfoTable = NULL;\r
+ ImageExeInfoEntry = NULL;\r
+ NameStringLen = 0;\r
+ NameStr = NULL;\r
\r
if (DevicePath == NULL) {\r
- return ;\r
+ return;\r
}\r
\r
if (Name != NULL) {\r
NameStringLen = sizeof (CHAR16);\r
}\r
\r
- EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID **) &ImageExeInfoTable);\r
+ EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID **)&ImageExeInfoTable);\r
if (ImageExeInfoTable != NULL) {\r
//\r
// The table has been found!\r
ImageExeInfoTableSize = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);\r
}\r
\r
- DevicePathSize = GetDevicePathSize (DevicePath);\r
+ DevicePathSize = GetDevicePathSize (DevicePath);\r
\r
//\r
// Signature size can be odd. Pad after signature to ensure next EXECUTION_INFO entry align\r
//\r
+ ASSERT (Signature != NULL || SignatureSize == 0);\r
NewImageExeInfoEntrySize = sizeof (EFI_IMAGE_EXECUTION_INFO) + NameStringLen + DevicePathSize + SignatureSize;\r
\r
- NewImageExeInfoTable = (EFI_IMAGE_EXECUTION_INFO_TABLE *) AllocateRuntimePool (ImageExeInfoTableSize + NewImageExeInfoEntrySize);\r
+ NewImageExeInfoTable = (EFI_IMAGE_EXECUTION_INFO_TABLE *)AllocateRuntimePool (ImageExeInfoTableSize + NewImageExeInfoEntrySize);\r
if (NewImageExeInfoTable == NULL) {\r
- return ;\r
+ return;\r
}\r
\r
if (ImageExeInfoTable != NULL) {\r
} else {\r
NewImageExeInfoTable->NumberOfImages = 0;\r
}\r
+\r
NewImageExeInfoTable->NumberOfImages++;\r
- ImageExeInfoEntry = (EFI_IMAGE_EXECUTION_INFO *) ((UINT8 *) NewImageExeInfoTable + ImageExeInfoTableSize);\r
+ ImageExeInfoEntry = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)NewImageExeInfoTable + ImageExeInfoTableSize);\r
//\r
// Update new item's information.\r
//\r
- WriteUnaligned32 ((UINT32 *) ImageExeInfoEntry, Action);\r
- WriteUnaligned32 ((UINT32 *) ((UINT8 *) ImageExeInfoEntry + sizeof (EFI_IMAGE_EXECUTION_ACTION)), (UINT32) NewImageExeInfoEntrySize);\r
+ WriteUnaligned32 ((UINT32 *)ImageExeInfoEntry, Action);\r
+ WriteUnaligned32 ((UINT32 *)((UINT8 *)ImageExeInfoEntry + sizeof (EFI_IMAGE_EXECUTION_ACTION)), (UINT32)NewImageExeInfoEntrySize);\r
\r
NameStr = (CHAR16 *)(ImageExeInfoEntry + 1);\r
if (Name != NULL) {\r
- CopyMem ((UINT8 *) NameStr, Name, NameStringLen);\r
+ CopyMem ((UINT8 *)NameStr, Name, NameStringLen);\r
} else {\r
- ZeroMem ((UINT8 *) NameStr, sizeof (CHAR16));\r
+ ZeroMem ((UINT8 *)NameStr, sizeof (CHAR16));\r
}\r
\r
CopyMem (\r
- (UINT8 *) NameStr + NameStringLen,\r
+ (UINT8 *)NameStr + NameStringLen,\r
DevicePath,\r
DevicePathSize\r
);\r
if (Signature != NULL) {\r
CopyMem (\r
- (UINT8 *) NameStr + NameStringLen + DevicePathSize,\r
+ (UINT8 *)NameStr + NameStringLen + DevicePathSize,\r
Signature,\r
SignatureSize\r
);\r
}\r
+\r
//\r
// Update/replace the image execution table.\r
//\r
- gBS->InstallConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID *) NewImageExeInfoTable);\r
+ gBS->InstallConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID *)NewImageExeInfoTable);\r
\r
//\r
// Free Old table data!\r
@param[in] SignatureList Pointer to the Signature List in forbidden database.\r
@param[in] SignatureListSize Size of Signature List.\r
@param[out] RevocationTime Return the time that the certificate was revoked.\r
+ @param[out] IsFound Search result. Only valid if EFI_SUCCESS returned.\r
\r
- @return TRUE The certificate hash is found in the forbidden database.\r
- @return FALSE The certificate hash is not found in the forbidden database.\r
+ @retval EFI_SUCCESS Finished the search without any error.\r
+ @retval Others Error occurred in the search of database.\r
\r
**/\r
-BOOLEAN\r
-IsCertHashFoundInDatabase (\r
+EFI_STATUS\r
+IsCertHashFoundInDbx (\r
IN UINT8 *Certificate,\r
IN UINTN CertSize,\r
IN EFI_SIGNATURE_LIST *SignatureList,\r
IN UINTN SignatureListSize,\r
- OUT EFI_TIME *RevocationTime\r
+ OUT EFI_TIME *RevocationTime,\r
+ OUT BOOLEAN *IsFound\r
)\r
{\r
- BOOLEAN IsFound;\r
- BOOLEAN Status;\r
+ EFI_STATUS Status;\r
EFI_SIGNATURE_LIST *DbxList;\r
UINTN DbxSize;\r
EFI_SIGNATURE_DATA *CertHash;\r
UINT8 *TBSCert;\r
UINTN TBSCertSize;\r
\r
- IsFound = FALSE;\r
+ Status = EFI_ABORTED;\r
+ *IsFound = FALSE;\r
DbxList = SignatureList;\r
DbxSize = SignatureListSize;\r
HashCtx = NULL;\r
HashAlg = HASHALG_MAX;\r
\r
if ((RevocationTime == NULL) || (DbxList == NULL)) {\r
- return FALSE;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
// Retrieve the TBSCertificate from the X.509 Certificate.\r
//\r
if (!X509GetTBSCert (Certificate, CertSize, &TBSCert, &TBSCertSize)) {\r
- return FALSE;\r
+ return Status;\r
}\r
\r
while ((DbxSize > 0) && (SignatureListSize >= DbxList->SignatureListSize)) {\r
HashAlg = HASHALG_SHA512;\r
} else {\r
DbxSize -= DbxList->SignatureListSize;\r
- DbxList = (EFI_SIGNATURE_LIST *) ((UINT8 *) DbxList + DbxList->SignatureListSize);\r
+ DbxList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxList + DbxList->SignatureListSize);\r
continue;\r
}\r
\r
if (mHash[HashAlg].GetContextSize == NULL) {\r
goto Done;\r
}\r
+\r
ZeroMem (CertDigest, MAX_DIGEST_SIZE);\r
HashCtx = AllocatePool (mHash[HashAlg].GetContextSize ());\r
if (HashCtx == NULL) {\r
goto Done;\r
}\r
- Status = mHash[HashAlg].HashInit (HashCtx);\r
- if (!Status) {\r
+\r
+ if (!mHash[HashAlg].HashInit (HashCtx)) {\r
goto Done;\r
}\r
- Status = mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize);\r
- if (!Status) {\r
+\r
+ if (!mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize)) {\r
goto Done;\r
}\r
- Status = mHash[HashAlg].HashFinal (HashCtx, CertDigest);\r
- if (!Status) {\r
+\r
+ if (!mHash[HashAlg].HashFinal (HashCtx, CertDigest)) {\r
goto Done;\r
}\r
\r
+ FreePool (HashCtx);\r
+ HashCtx = NULL;\r
+\r
SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbxList->SignatureHeaderSize;\r
- CertHash = (EFI_SIGNATURE_DATA *) ((UINT8 *) DbxList + SiglistHeaderSize);\r
+ CertHash = (EFI_SIGNATURE_DATA *)((UINT8 *)DbxList + SiglistHeaderSize);\r
CertHashCount = (DbxList->SignatureListSize - SiglistHeaderSize) / DbxList->SignatureSize;\r
for (Index = 0; Index < CertHashCount; Index++) {\r
//\r
//\r
// Hash of Certificate is found in forbidden database.\r
//\r
- IsFound = TRUE;\r
+ Status = EFI_SUCCESS;\r
+ *IsFound = TRUE;\r
\r
//\r
// Return the revocation time.\r
CopyMem (RevocationTime, (EFI_TIME *)(DbxCertHash + mHash[HashAlg].DigestLength), sizeof (EFI_TIME));\r
goto Done;\r
}\r
- CertHash = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertHash + DbxList->SignatureSize);\r
+\r
+ CertHash = (EFI_SIGNATURE_DATA *)((UINT8 *)CertHash + DbxList->SignatureSize);\r
}\r
\r
DbxSize -= DbxList->SignatureListSize;\r
- DbxList = (EFI_SIGNATURE_LIST *) ((UINT8 *) DbxList + DbxList->SignatureListSize);\r
+ DbxList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxList + DbxList->SignatureListSize);\r
}\r
\r
+ Status = EFI_SUCCESS;\r
+\r
Done:\r
if (HashCtx != NULL) {\r
FreePool (HashCtx);\r
}\r
\r
- return IsFound;\r
+ return Status;\r
}\r
\r
/**\r
@param[in] Signature Pointer to signature that is searched for.\r
@param[in] CertType Pointer to hash algorithm.\r
@param[in] SignatureSize Size of Signature.\r
+ @param[out] IsFound Search result. Only valid if EFI_SUCCESS returned\r
\r
- @return TRUE Found the signature in the variable database.\r
- @return FALSE Not found the signature in the variable database.\r
+ @retval EFI_SUCCESS Finished the search without any error.\r
+ @retval Others Error occurred in the search of database.\r
\r
**/\r
-BOOLEAN\r
+EFI_STATUS\r
IsSignatureFoundInDatabase (\r
- IN CHAR16 *VariableName,\r
- IN UINT8 *Signature,\r
- IN EFI_GUID *CertType,\r
- IN UINTN SignatureSize\r
+ IN CHAR16 *VariableName,\r
+ IN UINT8 *Signature,\r
+ IN EFI_GUID *CertType,\r
+ IN UINTN SignatureSize,\r
+ OUT BOOLEAN *IsFound\r
)\r
{\r
EFI_STATUS Status;\r
UINT8 *Data;\r
UINTN Index;\r
UINTN CertCount;\r
- BOOLEAN IsFound;\r
\r
//\r
// Read signature database variable.\r
//\r
- IsFound = FALSE;\r
- Data = NULL;\r
- DataSize = 0;\r
- Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
+ *IsFound = FALSE;\r
+ Data = NULL;\r
+ DataSize = 0;\r
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
if (Status != EFI_BUFFER_TOO_SMALL) {\r
- return FALSE;\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // No database, no need to search.\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ return Status;\r
}\r
\r
- Data = (UINT8 *) AllocateZeroPool (DataSize);\r
+ Data = (UINT8 *)AllocateZeroPool (DataSize);\r
if (Data == NULL) {\r
- return FALSE;\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
+\r
//\r
// Enumerate all signature data in SigDB to check if signature exists for executable.\r
//\r
- CertList = (EFI_SIGNATURE_LIST *) Data;\r
+ CertList = (EFI_SIGNATURE_LIST *)Data;\r
while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
- if ((CertList->SignatureSize == sizeof(EFI_SIGNATURE_DATA) - 1 + SignatureSize) && (CompareGuid(&CertList->SignatureType, CertType))) {\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+ if ((CertList->SignatureSize == sizeof (EFI_SIGNATURE_DATA) - 1 + SignatureSize) && (CompareGuid (&CertList->SignatureType, CertType))) {\r
for (Index = 0; Index < CertCount; Index++) {\r
if (CompareMem (Cert->SignatureData, Signature, SignatureSize) == 0) {\r
//\r
// Find the signature in database.\r
//\r
- IsFound = TRUE;\r
+ *IsFound = TRUE;\r
//\r
// Entries in UEFI_IMAGE_SECURITY_DATABASE that are used to validate image should be measured\r
//\r
- if (StrCmp(VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) {\r
+ if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) {\r
SecureBootHook (VariableName, &gEfiImageSecurityDatabaseGuid, CertList->SignatureSize, Cert);\r
}\r
+\r
break;\r
}\r
\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);\r
}\r
\r
- if (IsFound) {\r
+ if (*IsFound) {\r
break;\r
}\r
}\r
\r
DataSize -= CertList->SignatureListSize;\r
- CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
}\r
\r
Done:\r
FreePool (Data);\r
}\r
\r
- return IsFound;\r
+ return Status;\r
}\r
\r
/**\r
**/\r
BOOLEAN\r
IsValidSignatureByTimestamp (\r
- IN EFI_TIME *SigningTime,\r
- IN EFI_TIME *RevocationTime\r
+ IN EFI_TIME *SigningTime,\r
+ IN EFI_TIME *RevocationTime\r
)\r
{\r
if (SigningTime->Year != RevocationTime->Year) {\r
- return (BOOLEAN) (SigningTime->Year < RevocationTime->Year);\r
+ return (BOOLEAN)(SigningTime->Year < RevocationTime->Year);\r
} else if (SigningTime->Month != RevocationTime->Month) {\r
- return (BOOLEAN) (SigningTime->Month < RevocationTime->Month);\r
+ return (BOOLEAN)(SigningTime->Month < RevocationTime->Month);\r
} else if (SigningTime->Day != RevocationTime->Day) {\r
- return (BOOLEAN) (SigningTime->Day < RevocationTime->Day);\r
+ return (BOOLEAN)(SigningTime->Day < RevocationTime->Day);\r
} else if (SigningTime->Hour != RevocationTime->Hour) {\r
- return (BOOLEAN) (SigningTime->Hour < RevocationTime->Hour);\r
+ return (BOOLEAN)(SigningTime->Hour < RevocationTime->Hour);\r
} else if (SigningTime->Minute != RevocationTime->Minute) {\r
- return (BOOLEAN) (SigningTime->Minute < RevocationTime->Minute);\r
+ return (BOOLEAN)(SigningTime->Minute < RevocationTime->Minute);\r
}\r
\r
- return (BOOLEAN) (SigningTime->Second <= RevocationTime->Second);\r
+ return (BOOLEAN)(SigningTime->Second <= RevocationTime->Second);\r
}\r
\r
/**\r
**/\r
BOOLEAN\r
IsTimeZero (\r
- IN EFI_TIME *Time\r
+ IN EFI_TIME *Time\r
)\r
{\r
if ((Time->Year == 0) && (Time->Month == 0) && (Time->Day == 0) &&\r
- (Time->Hour == 0) && (Time->Minute == 0) && (Time->Second == 0)) {\r
+ (Time->Hour == 0) && (Time->Minute == 0) && (Time->Second == 0))\r
+ {\r
return TRUE;\r
}\r
\r
**/\r
BOOLEAN\r
PassTimestampCheck (\r
- IN UINT8 *AuthData,\r
- IN UINTN AuthDataSize,\r
- IN EFI_TIME *RevocationTime\r
+ IN UINT8 *AuthData,\r
+ IN UINTN AuthDataSize,\r
+ IN EFI_TIME *RevocationTime\r
)\r
{\r
- EFI_STATUS Status;\r
- BOOLEAN VerifyStatus;\r
- EFI_SIGNATURE_LIST *CertList;\r
- EFI_SIGNATURE_DATA *Cert;\r
- UINT8 *DbtData;\r
- UINTN DbtDataSize;\r
- UINT8 *RootCert;\r
- UINTN RootCertSize;\r
- UINTN Index;\r
- UINTN CertCount;\r
- EFI_TIME SigningTime;\r
+ EFI_STATUS Status;\r
+ BOOLEAN VerifyStatus;\r
+ EFI_SIGNATURE_LIST *CertList;\r
+ EFI_SIGNATURE_DATA *Cert;\r
+ UINT8 *DbtData;\r
+ UINTN DbtDataSize;\r
+ UINT8 *RootCert;\r
+ UINTN RootCertSize;\r
+ UINTN Index;\r
+ UINTN CertCount;\r
+ EFI_TIME SigningTime;\r
\r
//\r
// Variable Initialization\r
//\r
- VerifyStatus = FALSE;\r
- DbtData = NULL;\r
- CertList = NULL;\r
- Cert = NULL;\r
- RootCert = NULL;\r
- RootCertSize = 0;\r
+ VerifyStatus = FALSE;\r
+ DbtData = NULL;\r
+ CertList = NULL;\r
+ Cert = NULL;\r
+ RootCert = NULL;\r
+ RootCertSize = 0;\r
\r
//\r
// If RevocationTime is zero, the certificate shall be considered to always be revoked.\r
// Using the dbt to get the trusted TSA certificates.\r
//\r
DbtDataSize = 0;\r
- Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, NULL);\r
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, NULL);\r
if (Status != EFI_BUFFER_TOO_SMALL) {\r
goto Done;\r
}\r
- DbtData = (UINT8 *) AllocateZeroPool (DbtDataSize);\r
+\r
+ DbtData = (UINT8 *)AllocateZeroPool (DbtDataSize);\r
if (DbtData == NULL) {\r
goto Done;\r
}\r
- Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, (VOID *) DbtData);\r
+\r
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, (VOID *)DbtData);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- CertList = (EFI_SIGNATURE_LIST *) DbtData;\r
+ CertList = (EFI_SIGNATURE_LIST *)DbtData;\r
while ((DbtDataSize > 0) && (DbtDataSize >= CertList->SignatureListSize)) {\r
if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
for (Index = 0; Index < CertCount; Index++) {\r
//\r
goto Done;\r
}\r
}\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);\r
}\r
}\r
+\r
DbtDataSize -= CertList->SignatureListSize;\r
- CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
}\r
\r
Done:\r
**/\r
BOOLEAN\r
IsForbiddenByDbx (\r
- IN UINT8 *AuthData,\r
- IN UINTN AuthDataSize\r
+ IN UINT8 *AuthData,\r
+ IN UINTN AuthDataSize\r
)\r
{\r
- EFI_STATUS Status;\r
- BOOLEAN IsForbidden;\r
- UINT8 *Data;\r
- UINTN DataSize;\r
- EFI_SIGNATURE_LIST *CertList;\r
- UINTN CertListSize;\r
- EFI_SIGNATURE_DATA *CertData;\r
- UINT8 *RootCert;\r
- UINTN RootCertSize;\r
- UINTN CertCount;\r
- UINTN Index;\r
- UINT8 *CertBuffer;\r
- UINTN BufferLength;\r
- UINT8 *TrustedCert;\r
- UINTN TrustedCertLength;\r
- UINT8 CertNumber;\r
- UINT8 *CertPtr;\r
- UINT8 *Cert;\r
- UINTN CertSize;\r
- EFI_TIME RevocationTime;\r
+ EFI_STATUS Status;\r
+ BOOLEAN IsForbidden;\r
+ BOOLEAN IsFound;\r
+ UINT8 *Data;\r
+ UINTN DataSize;\r
+ EFI_SIGNATURE_LIST *CertList;\r
+ UINTN CertListSize;\r
+ EFI_SIGNATURE_DATA *CertData;\r
+ UINT8 *RootCert;\r
+ UINTN RootCertSize;\r
+ UINTN CertCount;\r
+ UINTN Index;\r
+ UINT8 *CertBuffer;\r
+ UINTN BufferLength;\r
+ UINT8 *TrustedCert;\r
+ UINTN TrustedCertLength;\r
+ UINT8 CertNumber;\r
+ UINT8 *CertPtr;\r
+ UINT8 *Cert;\r
+ UINTN CertSize;\r
+ EFI_TIME RevocationTime;\r
+\r
//\r
// Variable Initialization\r
//\r
- IsForbidden = FALSE;\r
+ IsForbidden = TRUE;\r
Data = NULL;\r
CertList = NULL;\r
CertData = NULL;\r
//\r
DataSize = 0;\r
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
+ ASSERT (EFI_ERROR (Status));\r
if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // Evidently not in dbx if the database doesn't exist.\r
+ //\r
+ IsForbidden = FALSE;\r
+ }\r
+\r
return IsForbidden;\r
}\r
- Data = (UINT8 *) AllocateZeroPool (DataSize);\r
+\r
+ Data = (UINT8 *)AllocateZeroPool (DataSize);\r
if (Data == NULL) {\r
return IsForbidden;\r
}\r
\r
- Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);\r
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *)Data);\r
if (EFI_ERROR (Status)) {\r
- return IsForbidden;\r
+ goto Done;\r
}\r
\r
//\r
// Verify image signature with RAW X509 certificates in DBX database.\r
// If passed, the image will be forbidden.\r
//\r
- CertList = (EFI_SIGNATURE_LIST *) Data;\r
+ CertList = (EFI_SIGNATURE_LIST *)Data;\r
CertListSize = DataSize;\r
while ((CertListSize > 0) && (CertListSize >= CertList->SignatureListSize)) {\r
if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
- CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+ CertData = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
\r
for (Index = 0; Index < CertCount; Index++) {\r
goto Done;\r
}\r
\r
- CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertData + CertList->SignatureSize);\r
+ CertData = (EFI_SIGNATURE_DATA *)((UINT8 *)CertData + CertList->SignatureSize);\r
}\r
}\r
\r
CertListSize -= CertList->SignatureListSize;\r
- CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
}\r
\r
//\r
// UINT8 Certn[];\r
//\r
Pkcs7GetSigners (AuthData, AuthDataSize, &CertBuffer, &BufferLength, &TrustedCert, &TrustedCertLength);\r
- if ((BufferLength == 0) || (CertBuffer == NULL)) {\r
+ if ((BufferLength == 0) || (CertBuffer == NULL) || ((*CertBuffer) == 0)) {\r
IsForbidden = TRUE;\r
goto Done;\r
}\r
//\r
// Check if any hash of certificates embedded in AuthData is in the forbidden database.\r
//\r
- CertNumber = (UINT8) (*CertBuffer);\r
+ CertNumber = (UINT8)(*CertBuffer);\r
CertPtr = CertBuffer + 1;\r
for (Index = 0; Index < CertNumber; Index++) {\r
- CertSize = (UINTN) ReadUnaligned32 ((UINT32 *)CertPtr);\r
+ CertSize = (UINTN)ReadUnaligned32 ((UINT32 *)CertPtr);\r
Cert = (UINT8 *)CertPtr + sizeof (UINT32);\r
//\r
// Advance CertPtr to the next cert in image signer's cert list\r
//\r
CertPtr = CertPtr + sizeof (UINT32) + CertSize;\r
\r
- if (IsCertHashFoundInDatabase (Cert, CertSize, (EFI_SIGNATURE_LIST *)Data, DataSize, &RevocationTime)) {\r
+ Status = IsCertHashFoundInDbx (Cert, CertSize, (EFI_SIGNATURE_LIST *)Data, DataSize, &RevocationTime, &IsFound);\r
+ if (EFI_ERROR (Status)) {\r
//\r
- // Check the timestamp signature and signing time to determine if the image can be trusted.\r
+ // Error in searching dbx. Consider it as 'found'. RevocationTime might\r
+ // not be valid in such situation.\r
//\r
IsForbidden = TRUE;\r
+ } else if (IsFound) {\r
+ //\r
+ // Found Cert in dbx successfully. Check the timestamp signature and\r
+ // signing time to determine if the image can be trusted.\r
+ //\r
if (PassTimestampCheck (AuthData, AuthDataSize, &RevocationTime)) {\r
IsForbidden = FALSE;\r
//\r
// Pass DBT check. Continue to check other certs in image signer's cert list against DBX, DBT\r
//\r
continue;\r
+ } else {\r
+ IsForbidden = TRUE;\r
+ DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature failed the timestamp check.\n"));\r
+ goto Done;\r
}\r
- DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature failed the timestamp check.\n"));\r
- goto Done;\r
}\r
-\r
}\r
\r
+ IsForbidden = FALSE;\r
+\r
Done:\r
if (Data != NULL) {\r
FreePool (Data);\r
return IsForbidden;\r
}\r
\r
-\r
/**\r
Check whether the image signature can be verified by the trusted certificates in DB database.\r
\r
**/\r
BOOLEAN\r
IsAllowedByDb (\r
- IN UINT8 *AuthData,\r
- IN UINTN AuthDataSize\r
+ IN UINT8 *AuthData,\r
+ IN UINTN AuthDataSize\r
)\r
{\r
- EFI_STATUS Status;\r
- BOOLEAN VerifyStatus;\r
- EFI_SIGNATURE_LIST *CertList;\r
- EFI_SIGNATURE_DATA *CertData;\r
- UINTN DataSize;\r
- UINT8 *Data;\r
- UINT8 *RootCert;\r
- UINTN RootCertSize;\r
- UINTN Index;\r
- UINTN CertCount;\r
- UINTN DbxDataSize;\r
- UINT8 *DbxData;\r
- EFI_TIME RevocationTime;\r
+ EFI_STATUS Status;\r
+ BOOLEAN VerifyStatus;\r
+ BOOLEAN IsFound;\r
+ EFI_SIGNATURE_LIST *CertList;\r
+ EFI_SIGNATURE_DATA *CertData;\r
+ UINTN DataSize;\r
+ UINT8 *Data;\r
+ UINT8 *RootCert;\r
+ UINTN RootCertSize;\r
+ UINTN Index;\r
+ UINTN CertCount;\r
+ UINTN DbxDataSize;\r
+ UINT8 *DbxData;\r
+ EFI_TIME RevocationTime;\r
\r
- Data = NULL;\r
- CertList = NULL;\r
- CertData = NULL;\r
- RootCert = NULL;\r
- DbxData = NULL;\r
- RootCertSize = 0;\r
- VerifyStatus = FALSE;\r
+ Data = NULL;\r
+ CertList = NULL;\r
+ CertData = NULL;\r
+ RootCert = NULL;\r
+ DbxData = NULL;\r
+ RootCertSize = 0;\r
+ VerifyStatus = FALSE;\r
\r
+ //\r
+ // Fetch 'db' content. If 'db' doesn't exist or encounters problem to get the\r
+ // data, return not-allowed-by-db (FALSE).\r
+ //\r
DataSize = 0;\r
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- Data = (UINT8 *) AllocateZeroPool (DataSize);\r
- if (Data == NULL) {\r
- return VerifyStatus;\r
- }\r
+ ASSERT (EFI_ERROR (Status));\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ return VerifyStatus;\r
+ }\r
\r
- Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);\r
- if (EFI_ERROR (Status)) {\r
+ Data = (UINT8 *)AllocateZeroPool (DataSize);\r
+ if (Data == NULL) {\r
+ return VerifyStatus;\r
+ }\r
+\r
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *)Data);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Fetch 'dbx' content. If 'dbx' doesn't exist, continue to check 'db'.\r
+ // If any other errors occurred, no need to check 'db' but just return\r
+ // not-allowed-by-db (FALSE) to avoid bypass.\r
+ //\r
+ DbxDataSize = 0;\r
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, NULL);\r
+ ASSERT (EFI_ERROR (Status));\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ if (Status != EFI_NOT_FOUND) {\r
goto Done;\r
}\r
\r
//\r
- // Find X509 certificate in Signature List to verify the signature in pkcs7 signed data.\r
+ // 'dbx' does not exist. Continue to check 'db'.\r
+ //\r
+ } else {\r
+ //\r
+ // 'dbx' exists. Get its content.\r
//\r
- CertList = (EFI_SIGNATURE_LIST *) Data;\r
- while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
- if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
- CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
- CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+ DbxData = (UINT8 *)AllocateZeroPool (DbxDataSize);\r
+ if (DbxData == NULL) {\r
+ goto Done;\r
+ }\r
\r
- for (Index = 0; Index < CertCount; Index++) {\r
- //\r
- // Iterate each Signature Data Node within this CertList for verify.\r
- //\r
- RootCert = CertData->SignatureData;\r
- RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);\r
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, (VOID *)DbxData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ }\r
\r
+ //\r
+ // Find X509 certificate in Signature List to verify the signature in pkcs7 signed data.\r
+ //\r
+ CertList = (EFI_SIGNATURE_LIST *)Data;\r
+ while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
+ CertData = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+\r
+ for (Index = 0; Index < CertCount; Index++) {\r
+ //\r
+ // Iterate each Signature Data Node within this CertList for verify.\r
+ //\r
+ RootCert = CertData->SignatureData;\r
+ RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);\r
+\r
+ //\r
+ // Call AuthenticodeVerify library to Verify Authenticode struct.\r
+ //\r
+ VerifyStatus = AuthenticodeVerify (\r
+ AuthData,\r
+ AuthDataSize,\r
+ RootCert,\r
+ RootCertSize,\r
+ mImageDigest,\r
+ mImageDigestSize\r
+ );\r
+ if (VerifyStatus) {\r
//\r
- // Call AuthenticodeVerify library to Verify Authenticode struct.\r
+ // The image is signed and its signature is found in 'db'.\r
//\r
- VerifyStatus = AuthenticodeVerify (\r
- AuthData,\r
- AuthDataSize,\r
- RootCert,\r
- RootCertSize,\r
- mImageDigest,\r
- mImageDigestSize\r
- );\r
- if (VerifyStatus) {\r
+ if (DbxData != NULL) {\r
//\r
// Here We still need to check if this RootCert's Hash is revoked\r
//\r
- Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, NULL);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- goto Done;\r
- }\r
- DbxData = (UINT8 *) AllocateZeroPool (DbxDataSize);\r
- if (DbxData == NULL) {\r
- goto Done;\r
- }\r
-\r
- Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, (VOID *) DbxData);\r
+ Status = IsCertHashFoundInDbx (RootCert, RootCertSize, (EFI_SIGNATURE_LIST *)DbxData, DbxDataSize, &RevocationTime, &IsFound);\r
if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (IsCertHashFoundInDatabase (RootCert, RootCertSize, (EFI_SIGNATURE_LIST *)DbxData, DbxDataSize, &RevocationTime)) {\r
+ //\r
+ // Error in searching dbx. Consider it as 'found'. RevocationTime might\r
+ // not be valid in such situation.\r
+ //\r
+ VerifyStatus = FALSE;\r
+ } else if (IsFound) {\r
//\r
// Check the timestamp signature and signing time to determine if the RootCert can be trusted.\r
//\r
DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed and signature is accepted by DB, but its root cert failed the timestamp check.\n"));\r
}\r
}\r
-\r
- goto Done;\r
}\r
\r
- CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertData + CertList->SignatureSize);\r
+ //\r
+ // There's no 'dbx' to check revocation time against (must-be pass),\r
+ // or, there's revocation time found in 'dbx' and checked againt 'dbt'\r
+ // (maybe pass or fail, depending on timestamp compare result). Either\r
+ // way the verification job has been completed at this point.\r
+ //\r
+ goto Done;\r
}\r
- }\r
\r
- DataSize -= CertList->SignatureListSize;\r
- CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+ CertData = (EFI_SIGNATURE_DATA *)((UINT8 *)CertData + CertList->SignatureSize);\r
+ }\r
}\r
+\r
+ DataSize -= CertList->SignatureListSize;\r
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
}\r
\r
Done:\r
if (Data != NULL) {\r
FreePool (Data);\r
}\r
+\r
if (DbxData != NULL) {\r
FreePool (DbxData);\r
}\r
execution table.\r
@retval EFI_ACCESS_DENIED The file specified by File and FileBuffer did not\r
authenticate, and the platform policy dictates that the DXE\r
- Foundation many not use File.\r
+ Foundation may not use File. The image has\r
+ been added to the file execution table.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
DxeImageVerificationHandler (\r
- IN UINT32 AuthenticationStatus,\r
- IN CONST EFI_DEVICE_PATH_PROTOCOL *File,\r
- IN VOID *FileBuffer,\r
- IN UINTN FileSize,\r
- IN BOOLEAN BootPolicy\r
+ IN UINT32 AuthenticationStatus,\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *File OPTIONAL,\r
+ IN VOID *FileBuffer,\r
+ IN UINTN FileSize,\r
+ IN BOOLEAN BootPolicy\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- BOOLEAN IsVerified;\r
- EFI_SIGNATURE_LIST *SignatureList;\r
- UINTN SignatureListSize;\r
- EFI_SIGNATURE_DATA *Signature;\r
- EFI_IMAGE_EXECUTION_ACTION Action;\r
- WIN_CERTIFICATE *WinCertificate;\r
- UINT32 Policy;\r
- UINT8 *SecureBoot;\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
- UINT32 NumberOfRvaAndSizes;\r
- WIN_CERTIFICATE_EFI_PKCS *PkcsCertData;\r
- WIN_CERTIFICATE_UEFI_GUID *WinCertUefiGuid;\r
- UINT8 *AuthData;\r
- UINTN AuthDataSize;\r
- EFI_IMAGE_DATA_DIRECTORY *SecDataDir;\r
- UINT32 OffSet;\r
- CHAR16 *NameStr;\r
- RETURN_STATUS PeCoffStatus;\r
- EFI_STATUS HashStatus;\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ BOOLEAN IsVerified;\r
+ EFI_SIGNATURE_LIST *SignatureList;\r
+ UINTN SignatureListSize;\r
+ EFI_SIGNATURE_DATA *Signature;\r
+ EFI_IMAGE_EXECUTION_ACTION Action;\r
+ WIN_CERTIFICATE *WinCertificate;\r
+ UINT32 Policy;\r
+ UINT8 *SecureBoot;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ UINT32 NumberOfRvaAndSizes;\r
+ WIN_CERTIFICATE_EFI_PKCS *PkcsCertData;\r
+ WIN_CERTIFICATE_UEFI_GUID *WinCertUefiGuid;\r
+ UINT8 *AuthData;\r
+ UINTN AuthDataSize;\r
+ EFI_IMAGE_DATA_DIRECTORY *SecDataDir;\r
+ UINT32 SecDataDirEnd;\r
+ UINT32 SecDataDirLeft;\r
+ UINT32 OffSet;\r
+ CHAR16 *NameStr;\r
+ RETURN_STATUS PeCoffStatus;\r
+ EFI_STATUS HashStatus;\r
+ EFI_STATUS DbStatus;\r
+ BOOLEAN IsFound;\r
\r
SignatureList = NULL;\r
SignatureListSize = 0;\r
SecDataDir = NULL;\r
PkcsCertData = NULL;\r
Action = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;\r
- Status = EFI_ACCESS_DENIED;\r
IsVerified = FALSE;\r
-\r
+ IsFound = FALSE;\r
\r
//\r
// Check the image type and get policy setting.\r
//\r
switch (GetImageType (File)) {\r
+ case IMAGE_FROM_FV:\r
+ Policy = ALWAYS_EXECUTE;\r
+ break;\r
\r
- case IMAGE_FROM_FV:\r
- Policy = ALWAYS_EXECUTE;\r
- break;\r
-\r
- case IMAGE_FROM_OPTION_ROM:\r
- Policy = PcdGet32 (PcdOptionRomImageVerificationPolicy);\r
- break;\r
+ case IMAGE_FROM_OPTION_ROM:\r
+ Policy = PcdGet32 (PcdOptionRomImageVerificationPolicy);\r
+ break;\r
\r
- case IMAGE_FROM_REMOVABLE_MEDIA:\r
- Policy = PcdGet32 (PcdRemovableMediaImageVerificationPolicy);\r
- break;\r
+ case IMAGE_FROM_REMOVABLE_MEDIA:\r
+ Policy = PcdGet32 (PcdRemovableMediaImageVerificationPolicy);\r
+ break;\r
\r
- case IMAGE_FROM_FIXED_MEDIA:\r
- Policy = PcdGet32 (PcdFixedMediaImageVerificationPolicy);\r
- break;\r
+ case IMAGE_FROM_FIXED_MEDIA:\r
+ Policy = PcdGet32 (PcdFixedMediaImageVerificationPolicy);\r
+ break;\r
\r
- default:\r
- Policy = DENY_EXECUTE_ON_SECURITY_VIOLATION;\r
- break;\r
+ default:\r
+ Policy = DENY_EXECUTE_ON_SECURITY_VIOLATION;\r
+ break;\r
}\r
+\r
//\r
// If policy is always/never execute, return directly.\r
//\r
if (Policy == ALWAYS_EXECUTE) {\r
return EFI_SUCCESS;\r
}\r
+\r
if (Policy == NEVER_EXECUTE) {\r
return EFI_ACCESS_DENIED;\r
}\r
// violates the UEFI spec and has been removed.\r
//\r
ASSERT (Policy != QUERY_USER_ON_SECURITY_VIOLATION && Policy != ALLOW_EXECUTE_ON_SECURITY_VIOLATION);\r
- if (Policy == QUERY_USER_ON_SECURITY_VIOLATION || Policy == ALLOW_EXECUTE_ON_SECURITY_VIOLATION) {\r
+ if ((Policy == QUERY_USER_ON_SECURITY_VIOLATION) || (Policy == ALLOW_EXECUTE_ON_SECURITY_VIOLATION)) {\r
CpuDeadLoop ();\r
}\r
\r
- GetEfiGlobalVariable2 (EFI_SECURE_BOOT_MODE_NAME, (VOID**)&SecureBoot, NULL);\r
+ GetEfiGlobalVariable2 (EFI_SECURE_BOOT_MODE_NAME, (VOID **)&SecureBoot, NULL);\r
//\r
// Skip verification if SecureBoot variable doesn't exist.\r
//\r
FreePool (SecureBoot);\r
return EFI_SUCCESS;\r
}\r
+\r
FreePool (SecureBoot);\r
\r
//\r
// Read the Dos header.\r
//\r
if (FileBuffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
+ return EFI_ACCESS_DENIED;\r
}\r
\r
- mImageBase = (UINT8 *) FileBuffer;\r
- mImageSize = FileSize;\r
+ mImageBase = (UINT8 *)FileBuffer;\r
+ mImageSize = FileSize;\r
\r
ZeroMem (&ImageContext, sizeof (ImageContext));\r
- ImageContext.Handle = (VOID *) FileBuffer;\r
- ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) DxeImageVerificationLibImageRead;\r
+ ImageContext.Handle = (VOID *)FileBuffer;\r
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)DxeImageVerificationLibImageRead;\r
\r
//\r
// Get information about the image being loaded\r
// The information can't be got from the invalid PeImage\r
//\r
DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: PeImage invalid. Cannot retrieve image information.\n"));\r
- goto Done;\r
+ goto Failed;\r
}\r
\r
- DosHdr = (EFI_IMAGE_DOS_HEADER *) mImageBase;\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)mImageBase;\r
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
//\r
// DOS image header is present,\r
} else {\r
mPeCoffHeaderOffset = 0;\r
}\r
+\r
//\r
// Check PE/COFF image.\r
//\r
- mNtHeader.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) (mImageBase + mPeCoffHeaderOffset);\r
+ mNtHeader.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(mImageBase + mPeCoffHeaderOffset);\r
if (mNtHeader.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
//\r
// It is not a valid Pe/Coff file.\r
//\r
DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Not a valid PE/COFF image.\n"));\r
- goto Done;\r
+ goto Failed;\r
}\r
\r
if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
- SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
+ SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *)&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
}\r
} else {\r
//\r
//\r
NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
- SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
+ SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *)&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
}\r
}\r
\r
//\r
// Start Image Validation.\r
//\r
- if (SecDataDir == NULL || SecDataDir->Size == 0) {\r
+ if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {\r
//\r
// This image is not signed. The SHA256 hash value of the image must match a record in the security database "db",\r
// and not be reflected in the security data base "dbx".\r
//\r
if (!HashPeImage (HASHALG_SHA256)) {\r
DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image using %s.\n", mHashTypeStr));\r
- goto Done;\r
+ goto Failed;\r
}\r
\r
- if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, mImageDigest, &mCertType, mImageDigestSize)) {\r
+ DbStatus = IsSignatureFoundInDatabase (\r
+ EFI_IMAGE_SECURITY_DATABASE1,\r
+ mImageDigest,\r
+ &mCertType,\r
+ mImageDigestSize,\r
+ &IsFound\r
+ );\r
+ if (EFI_ERROR (DbStatus) || IsFound) {\r
//\r
// Image Hash is in forbidden database (DBX).\r
//\r
DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is forbidden by DBX.\n", mHashTypeStr));\r
- goto Done;\r
+ goto Failed;\r
}\r
\r
- if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE, mImageDigest, &mCertType, mImageDigestSize)) {\r
+ DbStatus = IsSignatureFoundInDatabase (\r
+ EFI_IMAGE_SECURITY_DATABASE,\r
+ mImageDigest,\r
+ &mCertType,\r
+ mImageDigestSize,\r
+ &IsFound\r
+ );\r
+ if (!EFI_ERROR (DbStatus) && IsFound) {\r
//\r
// Image Hash is in allowed database (DB).\r
//\r
// Image Hash is not found in both forbidden and allowed database.\r
//\r
DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is not found in DB/DBX.\n", mHashTypeStr));\r
- goto Done;\r
+ goto Failed;\r
}\r
\r
//\r
// "Attribute Certificate Table".\r
// The first certificate starts at offset (SecDataDir->VirtualAddress) from the start of the file.\r
//\r
+ SecDataDirEnd = SecDataDir->VirtualAddress + SecDataDir->Size;\r
for (OffSet = SecDataDir->VirtualAddress;\r
- OffSet < (SecDataDir->VirtualAddress + SecDataDir->Size);\r
- OffSet += (WinCertificate->dwLength + ALIGN_SIZE (WinCertificate->dwLength))) {\r
- WinCertificate = (WIN_CERTIFICATE *) (mImageBase + OffSet);\r
- if ((SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) <= sizeof (WIN_CERTIFICATE) ||\r
- (SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) < WinCertificate->dwLength) {\r
+ OffSet < SecDataDirEnd;\r
+ OffSet += (WinCertificate->dwLength + ALIGN_SIZE (WinCertificate->dwLength)))\r
+ {\r
+ SecDataDirLeft = SecDataDirEnd - OffSet;\r
+ if (SecDataDirLeft <= sizeof (WIN_CERTIFICATE)) {\r
+ break;\r
+ }\r
+\r
+ WinCertificate = (WIN_CERTIFICATE *)(mImageBase + OffSet);\r
+ if ((SecDataDirLeft < WinCertificate->dwLength) ||\r
+ (SecDataDirLeft - WinCertificate->dwLength <\r
+ ALIGN_SIZE (WinCertificate->dwLength)))\r
+ {\r
break;\r
}\r
\r
// The certificate is formatted as WIN_CERTIFICATE_EFI_PKCS which is described in the\r
// Authenticode specification.\r
//\r
- PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *) WinCertificate;\r
+ PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *)WinCertificate;\r
if (PkcsCertData->Hdr.dwLength <= sizeof (PkcsCertData->Hdr)) {\r
break;\r
}\r
- AuthData = PkcsCertData->CertData;\r
- AuthDataSize = PkcsCertData->Hdr.dwLength - sizeof(PkcsCertData->Hdr);\r
+\r
+ AuthData = PkcsCertData->CertData;\r
+ AuthDataSize = PkcsCertData->Hdr.dwLength - sizeof (PkcsCertData->Hdr);\r
} else if (WinCertificate->wCertificateType == WIN_CERT_TYPE_EFI_GUID) {\r
//\r
// The certificate is formatted as WIN_CERTIFICATE_UEFI_GUID which is described in UEFI Spec.\r
//\r
- WinCertUefiGuid = (WIN_CERTIFICATE_UEFI_GUID *) WinCertificate;\r
- if (WinCertUefiGuid->Hdr.dwLength <= OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData)) {\r
+ WinCertUefiGuid = (WIN_CERTIFICATE_UEFI_GUID *)WinCertificate;\r
+ if (WinCertUefiGuid->Hdr.dwLength <= OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) {\r
break;\r
}\r
+\r
if (!CompareGuid (&WinCertUefiGuid->CertType, &gEfiCertPkcs7Guid)) {\r
continue;\r
}\r
- AuthData = WinCertUefiGuid->CertData;\r
- AuthDataSize = WinCertUefiGuid->Hdr.dwLength - OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData);\r
+\r
+ AuthData = WinCertUefiGuid->CertData;\r
+ AuthDataSize = WinCertUefiGuid->Hdr.dwLength - OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);\r
} else {\r
if (WinCertificate->dwLength < sizeof (WIN_CERTIFICATE)) {\r
break;\r
}\r
+\r
continue;\r
}\r
\r
// Check the digital signature against the revoked certificate in forbidden database (dbx).\r
//\r
if (IsForbiddenByDbx (AuthData, AuthDataSize)) {\r
- Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;\r
+ Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;\r
IsVerified = FALSE;\r
break;\r
}\r
//\r
// Check the image's hash value.\r
//\r
- if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, mImageDigest, &mCertType, mImageDigestSize)) {\r
+ DbStatus = IsSignatureFoundInDatabase (\r
+ EFI_IMAGE_SECURITY_DATABASE1,\r
+ mImageDigest,\r
+ &mCertType,\r
+ mImageDigestSize,\r
+ &IsFound\r
+ );\r
+ if (EFI_ERROR (DbStatus) || IsFound) {\r
Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;\r
DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but %s hash of image is found in DBX.\n", mHashTypeStr));\r
IsVerified = FALSE;\r
break;\r
}\r
+\r
if (!IsVerified) {\r
- if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE, mImageDigest, &mCertType, mImageDigestSize)) {\r
+ DbStatus = IsSignatureFoundInDatabase (\r
+ EFI_IMAGE_SECURITY_DATABASE,\r
+ mImageDigest,\r
+ &mCertType,\r
+ mImageDigestSize,\r
+ &IsFound\r
+ );\r
+ if (!EFI_ERROR (DbStatus) && IsFound) {\r
IsVerified = TRUE;\r
} else {\r
DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature is not allowed by DB and %s hash of image is not found in DB/DBX.\n", mHashTypeStr));\r
}\r
}\r
\r
- if (OffSet != (SecDataDir->VirtualAddress + SecDataDir->Size)) {\r
+ if (OffSet != SecDataDirEnd) {\r
//\r
// The Size in Certificate Table or the attribute certificate table is corrupted.\r
//\r
if (IsVerified) {\r
return EFI_SUCCESS;\r
}\r
- Status = EFI_ACCESS_DENIED;\r
- if (Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED || Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND) {\r
+\r
+ if ((Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED) || (Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND)) {\r
//\r
// Get image hash value as signature of executable.\r
//\r
SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;\r
- SignatureList = (EFI_SIGNATURE_LIST *) AllocateZeroPool (SignatureListSize);\r
+ SignatureList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (SignatureListSize);\r
if (SignatureList == NULL) {\r
- goto Done;\r
+ SignatureListSize = 0;\r
+ goto Failed;\r
}\r
- SignatureList->SignatureHeaderSize = 0;\r
- SignatureList->SignatureListSize = (UINT32) SignatureListSize;\r
- SignatureList->SignatureSize = (UINT32) (sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize);\r
+\r
+ SignatureList->SignatureHeaderSize = 0;\r
+ SignatureList->SignatureListSize = (UINT32)SignatureListSize;\r
+ SignatureList->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize);\r
CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID));\r
- Signature = (EFI_SIGNATURE_DATA *) ((UINT8 *) SignatureList + sizeof (EFI_SIGNATURE_LIST));\r
+ Signature = (EFI_SIGNATURE_DATA *)((UINT8 *)SignatureList + sizeof (EFI_SIGNATURE_LIST));\r
CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);\r
}\r
\r
-Done:\r
- if (Status != EFI_SUCCESS) {\r
- //\r
- // Policy decides to defer or reject the image; add its information in image executable information table.\r
- //\r
- NameStr = ConvertDevicePathToText (File, FALSE, TRUE);\r
- AddImageExeInfo (Action, NameStr, File, SignatureList, SignatureListSize);\r
- if (NameStr != NULL) {\r
- DEBUG((EFI_D_INFO, "The image doesn't pass verification: %s\n", NameStr));\r
- FreePool(NameStr);\r
- }\r
- Status = EFI_SECURITY_VIOLATION;\r
+Failed:\r
+ //\r
+ // Policy decides to defer or reject the image; add its information in image\r
+ // executable information table in either case.\r
+ //\r
+ NameStr = ConvertDevicePathToText (File, FALSE, TRUE);\r
+ AddImageExeInfo (Action, NameStr, File, SignatureList, SignatureListSize);\r
+ if (NameStr != NULL) {\r
+ DEBUG ((DEBUG_INFO, "The image doesn't pass verification: %s\n", NameStr));\r
+ FreePool (NameStr);\r
}\r
\r
if (SignatureList != NULL) {\r
FreePool (SignatureList);\r
}\r
\r
- return Status;\r
+ if (Policy == DEFER_EXECUTE_ON_SECURITY_VIOLATION) {\r
+ return EFI_SECURITY_VIOLATION;\r
+ }\r
+\r
+ return EFI_ACCESS_DENIED;\r
}\r
\r
/**\r
VOID\r
EFIAPI\r
OnReadyToBoot (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
)\r
{\r
EFI_IMAGE_EXECUTION_INFO_TABLE *ImageExeInfoTable;\r
UINTN ImageExeInfoTableSize;\r
\r
- EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID **) &ImageExeInfoTable);\r
+ EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID **)&ImageExeInfoTable);\r
if (ImageExeInfoTable != NULL) {\r
return;\r
}\r
\r
ImageExeInfoTableSize = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);\r
- ImageExeInfoTable = (EFI_IMAGE_EXECUTION_INFO_TABLE *) AllocateRuntimePool (ImageExeInfoTableSize);\r
+ ImageExeInfoTable = (EFI_IMAGE_EXECUTION_INFO_TABLE *)AllocateRuntimePool (ImageExeInfoTableSize);\r
if (ImageExeInfoTable == NULL) {\r
- return ;\r
+ return;\r
}\r
\r
ImageExeInfoTable->NumberOfImages = 0;\r
- gBS->InstallConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID *) ImageExeInfoTable);\r
-\r
+ gBS->InstallConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID *)ImageExeInfoTable);\r
}\r
\r
/**\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
- EFI_EVENT Event;\r
+ EFI_EVENT Event;\r
\r
//\r
// Register the event to publish the image execution table.\r
);\r
\r
return RegisterSecurity2Handler (\r
- DxeImageVerificationHandler,\r
- EFI_AUTH_OPERATION_VERIFY_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED\r
- );\r
+ DxeImageVerificationHandler,\r
+ EFI_AUTH_OPERATION_VERIFY_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED\r
+ );\r
}\r