EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
UINTN Index;\r
UINTN Pos;\r
- UINTN SumOfSectionBytes;\r
- EFI_IMAGE_SECTION_HEADER *SectionCache;\r
+ UINT32 CertSize;\r
+ UINT32 NumberOfRvaAndSizes;\r
\r
HashCtx = NULL;\r
SectionHeader = NULL;\r
if (!Status) {\r
goto Done;\r
}\r
+\r
//\r
// Measuring PE/COFF Image Header;\r
// But CheckSum field and SECURITY data directory (certificate) are excluded\r
// Use PE32 offset.\r
//\r
HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - HashBase);\r
+ NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
} else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
//\r
// Use PE32+ offset.\r
//\r
HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - HashBase);\r
+ NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
} else {\r
//\r
// Invalid header magic number.\r
if (!Status) {\r
goto Done;\r
}\r
+\r
//\r
// 5. Skip over the image checksum (it occupies a single ULONG).\r
- // 6. Get the address of the beginning of the Cert Directory.\r
- // 7. Hash everything from the end of the checksum to the start of the Cert Directory.\r
//\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
//\r
- // Use PE32 offset.\r
+ // 6. Since there is no Cert Directory in optional header, hash everything\r
+ // from the end of the checksum to the end of image header.\r
//\r
- HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // Use PE32 offset.\r
+ //\r
+ HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
+ HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - 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 - mImageBase);\r
+ }\r
+\r
+ if (HashSize != 0) {\r
+ Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ if (!Status) {\r
+ goto Done;\r
+ }\r
+ }\r
} else {\r
//\r
- // Use PE32+ offset.\r
+ // 7. Hash everything from the end of the checksum to the start of the Cert Directory.\r
//\r
- HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
- }\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // Use PE32 offset.\r
+ //\r
+ HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
+ HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+ } else {\r
+ //\r
+ // Use PE32+ offset.\r
+ //\r
+ HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
+ HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+ }\r
+\r
+ if (HashSize != 0) {\r
+ Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ if (!Status) {\r
+ goto Done;\r
+ }\r
+ }\r
\r
- Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)\r
- // 9. Hash everything from the end of the Cert Directory to the end of image header.\r
- //\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\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) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);\r
- } else {\r
//\r
- // Use PE32+ offset.\r
+ // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)\r
+ // 9. Hash everything from the end of the Cert Directory to the end of image header.\r
//\r
- HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
- HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);\r
- }\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\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 - 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 - mImageBase);\r
+ }\r
\r
- Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
- if (!Status) {\r
- goto Done;\r
+ if (HashSize != 0) {\r
+ Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ if (!Status) {\r
+ goto Done;\r
+ }\r
+ } \r
}\r
+\r
//\r
// 10. Set the SUM_OF_BYTES_HASHED to the size of the header.\r
//\r
mNtHeader.Pe32->FileHeader.SizeOfOptionalHeader\r
);\r
\r
- SectionCache = Section;\r
- for (Index = 0, SumOfSectionBytes = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++, SectionCache++) {\r
- SumOfSectionBytes += SectionCache->SizeOfRawData;\r
- }\r
-\r
- //\r
- // Sanity check for file corruption. Sections raw data size should be smaller\r
- // than Image Size.\r
- //\r
- if (SumOfSectionBytes >= mImageSize) {\r
- Status = FALSE;\r
- goto Done;\r
- }\r
-\r
//\r
// 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER\r
// structures in the image. The 'NumberOfSections' field of the image\r
//\r
if (mImageSize > SumOfBytesHashed) {\r
HashBase = mImageBase + SumOfBytesHashed;\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- if (mImageSize - SumOfBytesHashed < mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {\r
- Status = FALSE;\r
- goto Done;\r
- }\r
- //\r
- // Use PE32 offset.\r
- //\r
- HashSize = (UINTN)(\r
- mImageSize -\r
- mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -\r
- SumOfBytesHashed);\r
+\r
+ if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
+ CertSize = 0;\r
} else {\r
- if (mImageSize - SumOfBytesHashed < mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {\r
- Status = FALSE;\r
- goto Done;\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // Use PE32 offset.\r
+ //\r
+ CertSize = mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;\r
+ } else {\r
+ //\r
+ // Use PE32+ offset.\r
+ //\r
+ CertSize = mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;\r
}\r
- //\r
- // Use PE32+ offset.\r
- //\r
- HashSize = (UINTN)(\r
- mImageSize -\r
- mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -\r
- SumOfBytesHashed);\r
}\r
\r
- Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
- if (!Status) {\r
+ if (mImageSize > CertSize + SumOfBytesHashed) {\r
+ HashSize = (UINTN) (mImageSize - CertSize - SumOfBytesHashed);\r
+\r
+ Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+ if (!Status) {\r
+ goto Done;\r
+ }\r
+ } else if (mImageSize < CertSize + SumOfBytesHashed) {\r
+ Status = FALSE;\r
goto Done;\r
}\r
}\r
+\r
Status = mHash[HashAlg].HashFinal(HashCtx, mImageDigest);\r
\r
Done:\r
\r
PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *) (mImageBase + mSecDataDir->VirtualAddress);\r
\r
+ if (PkcsCertData->Hdr.dwLength < sizeof (WIN_CERTIFICATE_EFI_PKCS) + 32) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
for (Index = 0; Index < HASHALG_MAX; Index++) {\r
//\r
// Check the Hash algorithm in PE/COFF Authenticode.\r
continue;\r
}\r
\r
+ if (PkcsCertData->Hdr.dwLength < sizeof (WIN_CERTIFICATE_EFI_PKCS) + 32 + mHash[Index].OidLength) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
if (CompareMem (PkcsCertData->CertData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) {\r
break;\r
}\r
//\r
VerifyStatus = AuthenticodeVerify (\r
PkcsCertData->CertData,\r
- mSecDataDir->Size - sizeof(PkcsCertData->Hdr),\r
+ PkcsCertData->Hdr.dwLength - sizeof(PkcsCertData->Hdr),\r
RootCert,\r
RootCertSize,\r
mImageDigest,\r
//\r
// Get KEK database variable.\r
//\r
- KekList = GetEfiGlobalVariable (EFI_KEY_EXCHANGE_KEY_NAME);\r
+ GetEfiGlobalVariable2 (EFI_KEY_EXCHANGE_KEY_NAME, (VOID**)&KekList, NULL);\r
if (KekList == NULL) {\r
return EFI_SECURITY_VIOLATION;\r
}\r
IN UINTN FileSize\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT16 Magic;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- EFI_STATUS VerifyStatus;\r
- UINT8 *SetupMode;\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 *SecureBootEnable;\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ EFI_STATUS Status;\r
+ UINT16 Magic;\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_STATUS VerifyStatus;\r
+ UINT8 *SetupMode;\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 *SecureBootEnable;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ UINT32 NumberOfRvaAndSizes;\r
+ UINT32 CertSize;\r
\r
if (File == NULL) {\r
return EFI_INVALID_PARAMETER;\r
return EFI_ACCESS_DENIED;\r
}\r
\r
- SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid);\r
+ GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL);\r
//\r
// Skip verification if SecureBootEnable variable doesn't exist.\r
//\r
return EFI_SUCCESS;\r
}\r
\r
- SetupMode = GetEfiGlobalVariable (EFI_SETUP_MODE_NAME);\r
+ FreePool (SecureBootEnable);\r
+\r
+ GetEfiGlobalVariable2 (EFI_SETUP_MODE_NAME, (VOID**)&SetupMode, NULL);\r
\r
//\r
// SetupMode doesn't exist means no AuthVar driver is dispatched,\r
FreePool (SetupMode);\r
return EFI_SUCCESS;\r
}\r
+\r
+ FreePool (SetupMode);\r
+\r
//\r
// Read the Dos header.\r
//\r
if (FileBuffer == NULL) {\r
- FreePool (SetupMode);\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
mImageBase = (UINT8 *) FileBuffer;\r
mImageSize = FileSize;\r
\r
goto Done;\r
}\r
\r
- DosHdr = (EFI_IMAGE_DOS_HEADER *) mImageBase;\r
+ Status = EFI_ACCESS_DENIED;\r
+\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *) mImageBase;\r
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
//\r
// DOS image header is present,\r
//\r
// It is not a valid Pe/Coff file.\r
//\r
- return EFI_ACCESS_DENIED;\r
+ goto Done;\r
}\r
\r
Magic = mNtHeader.Pe32->OptionalHeader.Magic;\r
//\r
// Use PE32 offset.\r
//\r
- mSecDataDir = (EFI_IMAGE_DATA_DIRECTORY *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
- } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
- //\r
- // Use PE32+ offset.\r
- //\r
- mSecDataDir = (EFI_IMAGE_DATA_DIRECTORY *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
+ NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
+ mSecDataDir = (EFI_IMAGE_DATA_DIRECTORY *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
+ } \r
} else {\r
//\r
- // Invalid header magic number.\r
- //\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- if (mSecDataDir->VirtualAddress >= mImageSize) {\r
- //\r
- // Sanity check to see if this file is corrupted.\r
+ // Use PE32+ offset.\r
//\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
+ mSecDataDir = (EFI_IMAGE_DATA_DIRECTORY *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
+ }\r
}\r
\r
- if (mSecDataDir->Size == 0) {\r
+ if ((mSecDataDir == NULL) || ((mSecDataDir != NULL) && (mSecDataDir->Size == 0))) {\r
//\r
// This image is not signed.\r
//\r
//\r
// Image Hash is in forbidden database (DBX).\r
//\r
- Action = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;\r
- Status = EFI_ACCESS_DENIED;\r
goto Done;\r
}\r
\r
//\r
// Image Hash is not found in both forbidden and allowed database.\r
//\r
- Action = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;\r
- Status = EFI_ACCESS_DENIED;\r
goto Done;\r
}\r
\r
//\r
WinCertificate = (WIN_CERTIFICATE *) (mImageBase + mSecDataDir->VirtualAddress);\r
\r
+ CertSize = sizeof (WIN_CERTIFICATE);\r
+\r
+ if ((mSecDataDir->Size <= CertSize) || (mSecDataDir->Size < WinCertificate->dwLength)) {\r
+ goto Done;\r
+ }\r
+\r
switch (WinCertificate->wCertificateType) {\r
\r
case WIN_CERT_TYPE_EFI_GUID:\r
+ CertSize = sizeof (WIN_CERTIFICATE_UEFI_GUID) + sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256) - sizeof (UINT8);\r
+ if (WinCertificate->dwLength < CertSize) {\r
+ goto Done;\r
+ }\r
+\r
//\r
// Verify UEFI GUID type.\r
//\r
//\r
// Verify Pkcs signed data type.\r
//\r
- Status = HashPeImageByType();\r
+ Status = HashPeImageByType();\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
break;\r
\r
default:\r
- Status = EFI_ACCESS_DENIED;\r
goto Done;\r
}\r
//\r
FreePool (SignatureList);\r
}\r
\r
- FreePool (SetupMode);\r
-\r
return Status;\r
}\r
\r
// If this library is built-in, it means firmware has capability to perform\r
// driver signing verification.\r
//\r
- SecureBootModePtr = GetEfiGlobalVariable (EFI_SECURE_BOOT_MODE_NAME);\r
+ GetEfiGlobalVariable2 (EFI_SECURE_BOOT_MODE_NAME, (VOID**)&SecureBootModePtr, NULL);\r
if (SecureBootModePtr == NULL) {\r
SecureBootMode = SECURE_BOOT_MODE_DISABLE;\r
//\r