/** @file\r
Implement image verification services for secure boot service in UEFI2.3.1.\r
\r
+ Caution: This file requires additional review when modified.\r
+ This library will have external input - PE/COFF image.\r
+ This external input must be validated carefully to avoid security issue like\r
+ buffer overflow, integer overflow.\r
+\r
+ DxeImageVerificationLibImageRead() function will make sure the PE/COFF image content\r
+ read is within the image buffer.\r
+\r
+ DxeImageVerificationHandler(), HashPeImageByType(), HashPeImage() function will accept\r
+ untrusted PE/COFF image and validate its data structure within this image buffer before use.\r
+\r
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
\r
#include "DxeImageVerificationLib.h"\r
\r
+//\r
+// 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
-UINTN mImageSize;\r
UINT32 mPeCoffHeaderOffset;\r
-UINT8 mImageDigest[MAX_DIGEST_SIZE];\r
-UINTN mImageDigestSize;\r
EFI_IMAGE_DATA_DIRECTORY *mSecDataDir = NULL;\r
-UINT8 *mImageBase = NULL;\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
+\r
//\r
// Notify string for authorization UI.\r
//\r
/**\r
Reads contents of a PE/COFF image in memory buffer.\r
\r
+ Caution: This function may receive untrusted input.\r
+ PE/COFF image is external input, so this function will make sure the PE/COFF image content\r
+ read is within the image buffer.\r
+\r
@param FileHandle Pointer to the file handle to read the PE/COFF image.\r
@param FileOffset Offset into the PE/COFF image to begin the read operation.\r
@param ReadSize On input, the size in bytes of the requested read operation. \r
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
\r
+ if (File == NULL) {\r
+ return IMAGE_UNKNOWN;\r
+ }\r
+\r
//\r
// First check to see if File is from a Firmware Volume\r
//\r
Caculate hash of Pe/Coff image based on the authenticode image hashing in\r
PE/COFF Specification 8.0 Appendix A\r
\r
+ Caution: This function may receive untrusted input.\r
+ PE/COFF image is external input, so this function will validate its data structure\r
+ within this image buffer before use.\r
+\r
@param[in] HashAlg Hash algorithm type.\r
\r
@retval TRUE Successfully hash image.\r
// Measuring PE/COFF Image Header;\r
// But CheckSum field and SECURITY data directory (certificate) are excluded\r
//\r
- Magic = mNtHeader.Pe32->OptionalHeader.Magic;\r
+ if (mNtHeader.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value \r
+ // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the \r
+ // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
+ // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
+ //\r
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
+ } else {\r
+ //\r
+ // Get the magic value from the PE/COFF Optional Header\r
+ //\r
+ Magic = mNtHeader.Pe32->OptionalHeader.Magic;\r
+ }\r
+ \r
//\r
// 3. Calculate the distance from the base of the image header to the image checksum address.\r
// 4. Hash the image header from its base to beginning of the image checksum.\r
Pe/Coff image based on the authenticode image hashing in PE/COFF Specification\r
8.0 Appendix A\r
\r
+ Caution: This function may receive untrusted input.\r
+ PE/COFF image is external input, so this function will validate its data structure\r
+ within this image buffer before use.\r
+\r
@retval EFI_UNSUPPORTED Hash algorithm is not supported.\r
@retval EFI_SUCCESS Hash successfully.\r
\r
}\r
}\r
\r
-/**\r
- Discover if the UEFI image is authorized by user's policy setting.\r
-\r
- @param[in] Policy Specify platform's policy setting.\r
-\r
- @retval EFI_ACCESS_DENIED Image is not allowed to run.\r
- @retval EFI_SECURITY_VIOLATION Image is deferred.\r
- @retval EFI_SUCCESS Image is authorized to run.\r
-\r
-**/\r
-EFI_STATUS\r
-ImageAuthorization (\r
- IN UINT32 Policy\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_INPUT_KEY Key;\r
-\r
- Status = EFI_ACCESS_DENIED;\r
-\r
- switch (Policy) {\r
-\r
- case QUERY_USER_ON_SECURITY_VIOLATION:\r
- do {\r
- CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, mNotifyString1, mNotifyString2, NULL);\r
- if (Key.UnicodeChar == L'Y' || Key.UnicodeChar == L'y') {\r
- Status = EFI_SUCCESS;\r
- break;\r
- } else if (Key.UnicodeChar == L'N' || Key.UnicodeChar == L'n') {\r
- Status = EFI_ACCESS_DENIED;\r
- break;\r
- } else if (Key.UnicodeChar == L'D' || Key.UnicodeChar == L'd') {\r
- Status = EFI_SECURITY_VIOLATION;\r
- break;\r
- }\r
- } while (TRUE);\r
- break;\r
-\r
- case ALLOW_EXECUTE_ON_SECURITY_VIOLATION:\r
- Status = EFI_SUCCESS;\r
- break;\r
-\r
- case DEFER_EXECUTE_ON_SECURITY_VIOLATION:\r
- Status = EFI_SECURITY_VIOLATION;\r
- break;\r
-\r
- case DENY_EXECUTE_ON_SECURITY_VIOLATION:\r
- Status = EFI_ACCESS_DENIED;\r
- break;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
/**\r
Check whether signature is in specified database.\r
\r
// Iterate each Signature Data Node within this CertList for verify.\r
//\r
RootCert = Cert->SignatureData;\r
- RootCertSize = CertList->SignatureSize;\r
+ RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);\r
\r
//\r
// Call AuthenticodeVerify library to Verify Authenticode struct.\r
}\r
\r
//\r
- // 2: Find certificate from KEK database and try to verify authenticode struct.\r
- //\r
- if (IsPkcsSignedDataVerifiedBySignatureList (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // 3: Find certificate from DB database and try to verify authenticode struct.\r
+ // 2: Find certificate from DB database and try to verify authenticode struct.\r
//\r
if (IsPkcsSignedDataVerifiedBySignatureList (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid)) {\r
return EFI_SUCCESS;\r
}\r
}\r
\r
-/**\r
- Verify certificate in WIN_CERTIFICATE_UEFI_GUID format.\r
-\r
- @retval EFI_SUCCESS Image pass verification.\r
- @retval EFI_SECURITY_VIOLATION Image fail verification.\r
- @retval other error value\r
-\r
-**/\r
-EFI_STATUS\r
-VerifyCertUefiGuid (\r
- VOID\r
- )\r
-{\r
- BOOLEAN Status;\r
- WIN_CERTIFICATE_UEFI_GUID *EfiCert;\r
- EFI_SIGNATURE_LIST *KekList;\r
- EFI_SIGNATURE_DATA *KekItem;\r
- EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;\r
- VOID *Rsa;\r
- UINTN KekCount;\r
- UINTN Index;\r
- UINTN KekDataSize;\r
- BOOLEAN IsFound;\r
- EFI_STATUS Result;\r
-\r
- EfiCert = NULL;\r
- KekList = NULL;\r
- KekItem = NULL;\r
- CertBlock = NULL;\r
- Rsa = NULL;\r
- Status = FALSE;\r
- IsFound = FALSE;\r
- KekDataSize = 0;\r
-\r
- EfiCert = (WIN_CERTIFICATE_UEFI_GUID *) (mImageBase + mSecDataDir->VirtualAddress);\r
- CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) EfiCert->CertData;\r
- if (!CompareGuid (&EfiCert->CertType, &gEfiCertTypeRsa2048Sha256Guid)) {\r
- //\r
- // Invalid Certificate Data Type.\r
- //\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- //\r
- // Get KEK database variable data size\r
- //\r
- Result = gRT->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, NULL, &KekDataSize, NULL);\r
- if (Result != EFI_BUFFER_TOO_SMALL) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- //\r
- // Get KEK database variable.\r
- //\r
- KekList = GetEfiGlobalVariable (EFI_KEY_EXCHANGE_KEY_NAME);\r
- if (KekList == NULL) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- //\r
- // Enumerate all Kek items in this list to verify the variable certificate data.\r
- // If anyone is authenticated successfully, it means the variable is correct!\r
- //\r
- while ((KekDataSize > 0) && (KekDataSize >= KekList->SignatureListSize)) {\r
- if (CompareGuid (&KekList->SignatureType, &gEfiCertRsa2048Guid)) {\r
- KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize);\r
- KekCount = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize;\r
- for (Index = 0; Index < KekCount; Index++) {\r
- if (CompareMem (KekItem->SignatureData, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize);\r
- }\r
- }\r
- KekDataSize -= KekList->SignatureListSize;\r
- KekList = (EFI_SIGNATURE_LIST *) ((UINT8 *) KekList + KekList->SignatureListSize);\r
- }\r
-\r
- if (!IsFound) {\r
- //\r
- // Signed key is not a trust one.\r
- //\r
- goto Done;\r
- }\r
-\r
- //\r
- // Now, we found the corresponding security policy.\r
- // Verify the data payload.\r
- //\r
- Rsa = RsaNew ();\r
- if (Rsa == NULL) {\r
- Status = FALSE;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Set RSA Key Components.\r
- // NOTE: Only N and E are needed to be set as RSA public key for signature verification.\r
- //\r
- Status = RsaSetKey (Rsa, RsaKeyN, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- Status = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // Verify the signature.\r
- //\r
- Status = RsaPkcs1Verify (\r
- Rsa,\r
- mImageDigest,\r
- mImageDigestSize,\r
- CertBlock->Signature,\r
- EFI_CERT_TYPE_RSA2048_SHA256_SIZE\r
- );\r
-\r
-Done:\r
- if (KekList != NULL) {\r
- FreePool (KekList);\r
- }\r
- if (Rsa != NULL ) {\r
- RsaFree (Rsa);\r
- }\r
- if (Status) {\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-}\r
-\r
/**\r
Provide verification service for signed images, which include both signature validation\r
and platform policy control. For signature types, both UEFI WIN_CERTIFICATE_UEFI_GUID and\r
Executables from FV is bypass, so pass in AuthenticationStatus is ignored.\r
\r
The image verification process is:\r
- Is the Image signed?\r
- If yes,\r
- Does the image verify against a certificate (root or intermediate) in the allowed db?\r
- Run it\r
- Image verification fail\r
- Is the Image's Hash not in forbidden database and the Image's Hash in allowed db?\r
- Run it\r
- If no,\r
- Is the Image's Hash in the forbidden database (DBX)?\r
- if yes,\r
- Error out\r
- Is the Image's Hash in the allowed database (DB)?\r
- If yes,\r
- Run it\r
- If no,\r
- Error out\r
+ If the image is signed,\r
+ If the image's certificate verifies against a certificate (root or intermediate) in the allowed \r
+ database (DB) and not in the forbidden database (DBX), the certificate verification is passed.\r
+ If the image's hash digest is in DBX,\r
+ deny execution.\r
+ If not,\r
+ run it.\r
+ If the Image's certificate verification failed.\r
+ If the Image's Hash is in DB and not in DBX,\r
+ run it.\r
+ Otherwise,\r
+ deny execution.\r
+ Otherwise, the image is not signed,\r
+ Is the Image's Hash in DBX?\r
+ If yes, deny execution.\r
+ If not, is the Image's Hash in DB?\r
+ If yes, run it.\r
+ If not, deny execution.\r
+\r
+ Caution: This function may receive untrusted input.\r
+ PE/COFF image is external input, so this function will validate its data structure\r
+ within this image buffer before use.\r
\r
@param[in] AuthenticationStatus\r
This is the authentication status returned from the security\r
being dispatched. This will optionally be used for logging.\r
@param[in] FileBuffer File buffer matches the input file device path.\r
@param[in] FileSize Size of File buffer matches the input file device path.\r
-\r
- @retval EFI_SUCCESS The file specified by File did authenticate, and the\r
- platform policy dictates that the DXE Core may use File.\r
- @retval EFI_INVALID_PARAMETER Input argument is incorrect.\r
+ @param[in] BootPolicy A boot policy that was used to call LoadImage() UEFI service.\r
+\r
+ @retval EFI_SUCCESS The file specified by DevicePath and non-NULL\r
+ FileBuffer did authenticate, and the platform policy dictates\r
+ that the DXE Foundation may use the file.\r
+ @retval EFI_SUCCESS The device path specified by NULL device path DevicePath\r
+ and non-NULL FileBuffer did authenticate, and the platform\r
+ policy dictates that the DXE Foundation may execute the image in\r
+ FileBuffer.\r
@retval EFI_OUT_RESOURCE Fail to allocate memory.\r
@retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and\r
the platform policy dictates that File should be placed\r
- in the untrusted state. A file may be promoted from\r
- the untrusted to the trusted state at a future time\r
- with a call to the Trust() DXE Service.\r
- @retval EFI_ACCESS_DENIED The file specified by File did not authenticate, and\r
- the platform policy dictates that File should not be\r
- used for any purpose.\r
+ in the untrusted state. The image has been added to the file\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
\r
**/\r
EFI_STATUS\r
IN UINT32 AuthenticationStatus,\r
IN CONST EFI_DEVICE_PATH_PROTOCOL *File,\r
IN VOID *FileBuffer,\r
- IN UINTN FileSize\r
+ IN UINTN FileSize,\r
+ IN BOOLEAN BootPolicy\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
+ UINT8 *SecureBoot;\r
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
UINT32 NumberOfRvaAndSizes;\r
UINT32 CertSize;\r
\r
- if (File == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
SignatureList = NULL;\r
SignatureListSize = 0;\r
WinCertificate = NULL;\r
return EFI_ACCESS_DENIED;\r
}\r
\r
- SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid);\r
+ GetEfiGlobalVariable2 (EFI_SECURE_BOOT_MODE_NAME, (VOID**)&SecureBoot, NULL);\r
//\r
- // Skip verification if SecureBootEnable variable doesn't exist.\r
+ // Skip verification if SecureBoot variable doesn't exist.\r
//\r
- if (SecureBootEnable == NULL) {\r
+ if (SecureBoot == NULL) {\r
return EFI_SUCCESS;\r
}\r
\r
//\r
- // Skip verification if SecureBootEnable is disabled.\r
+ // Skip verification if SecureBoot is disabled.\r
//\r
- if (*SecureBootEnable == SECURE_BOOT_DISABLE) {\r
- FreePool (SecureBootEnable);\r
+ if (*SecureBoot == SECURE_BOOT_MODE_DISABLE) {\r
+ FreePool (SecureBoot);\r
return EFI_SUCCESS;\r
}\r
-\r
- FreePool (SecureBootEnable);\r
-\r
- SetupMode = GetEfiGlobalVariable (EFI_SETUP_MODE_NAME);\r
-\r
- //\r
- // SetupMode doesn't exist means no AuthVar driver is dispatched,\r
- // skip verification.\r
- //\r
- if (SetupMode == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // If platform is in SETUP MODE, skip verification.\r
- //\r
- if (*SetupMode == SETUP_MODE) {\r
- FreePool (SetupMode);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- FreePool (SetupMode);\r
+ FreePool (SecureBoot);\r
\r
//\r
// Read the Dos header.\r
goto Done;\r
}\r
\r
- Magic = mNtHeader.Pe32->OptionalHeader.Magic;\r
+ if (mNtHeader.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value \r
+ // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the \r
+ // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
+ // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
+ //\r
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
+ } else {\r
+ //\r
+ // Get the magic value from the PE/COFF Optional Header\r
+ //\r
+ Magic = mNtHeader.Pe32->OptionalHeader.Magic;\r
+ }\r
+ \r
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset.\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
- if (!HashPeImage (HASHALG_SHA256)) {\r
- goto Done;\r
- }\r
-\r
- VerifyStatus = VerifyCertUefiGuid ();\r
- break;\r
-\r
- case WIN_CERT_TYPE_PKCS_SIGNED_DATA:\r
+ if (WinCertificate->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {\r
//\r
// Verify Pkcs signed data type.\r
//\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
-\r
+ \r
VerifyStatus = VerifyCertPkcsSignedData ();\r
+ } else {\r
+ goto Done;\r
+ }\r
\r
+ if (!EFI_ERROR (VerifyStatus)) {\r
//\r
- // For image verification against enrolled certificate(root or intermediate),\r
- // no need to check image's hash in the allowed database.\r
+ // Verification is passed.\r
+ // Continue to check the image digest in signature database.\r
//\r
- if (!EFI_ERROR (VerifyStatus)) {\r
- if (!IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, mImageDigest, &mCertType, mImageDigestSize)) {\r
- return EFI_SUCCESS;\r
- }\r
+ if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, mImageDigest, &mCertType, mImageDigestSize)) {\r
+ //\r
+ // Executable signature verification passes, but is found in forbidden signature database.\r
+ //\r
+ Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;\r
+ Status = EFI_ACCESS_DENIED;\r
+ } else {\r
+ //\r
+ // For image verification against enrolled X.509 certificate(root or intermediate),\r
+ // no need to check image's hash in the allowed database.\r
+ //\r
+ return EFI_SUCCESS;\r
}\r
- break;\r
-\r
- default:\r
- goto Done;\r
- }\r
- //\r
- // Get image hash value as executable's signature.\r
- //\r
- SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;\r
- SignatureList = (EFI_SIGNATURE_LIST *) AllocateZeroPool (SignatureListSize);\r
- if (SignatureList == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- SignatureList->SignatureHeaderSize = 0;\r
- SignatureList->SignatureListSize = (UINT32) SignatureListSize;\r
- SignatureList->SignatureSize = (UINT32) mImageDigestSize;\r
- CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID));\r
- Signature = (EFI_SIGNATURE_DATA *) ((UINT8 *) SignatureList + sizeof (EFI_SIGNATURE_LIST));\r
- CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);\r
- //\r
- // Signature database check after verification.\r
- //\r
- if (EFI_ERROR (VerifyStatus)) {\r
+ } else {\r
//\r
// Verification failure.\r
//\r
Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;\r
Status = EFI_ACCESS_DENIED;\r
}\r
- } else if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, Signature->SignatureData, &mCertType, mImageDigestSize)) {\r
- //\r
- // Executable signature verification passes, but is found in forbidden signature database.\r
- //\r
- Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;\r
- Status = EFI_ACCESS_DENIED;\r
- } else if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE, Signature->SignatureData, &mCertType, mImageDigestSize)) {\r
- //\r
- // Executable signature is found in authorized signature database.\r
- //\r
- Status = EFI_SUCCESS;\r
- } else {\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
//\r
- // Executable signature verification passes, but cannot be found in authorized signature database.\r
- // Get platform policy to determine the action.\r
+ // Get image hash value as executable's signature.\r
//\r
- Action = EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED;\r
- Status = ImageAuthorization (Policy);\r
+ SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;\r
+ SignatureList = (EFI_SIGNATURE_LIST *) AllocateZeroPool (SignatureListSize);\r
+ if (SignatureList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ SignatureList->SignatureHeaderSize = 0;\r
+ SignatureList->SignatureListSize = (UINT32) SignatureListSize;\r
+ SignatureList->SignatureSize = (UINT32) mImageDigestSize;\r
+ CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID));\r
+ Signature = (EFI_SIGNATURE_DATA *) ((UINT8 *) SignatureList + sizeof (EFI_SIGNATURE_LIST));\r
+ CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);\r
}\r
\r
Done:\r
// Policy decides to defer or reject the image; add its information in image executable information table.\r
//\r
AddImageExeInfo (Action, NULL, File, SignatureList, SignatureListSize);\r
+ Status = EFI_SECURITY_VIOLATION;\r
}\r
\r
if (SignatureList != NULL) {\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
&Registration\r
);\r
\r
- return RegisterSecurityHandler (\r
+ return RegisterSecurity2Handler (\r
DxeImageVerificationHandler,\r
EFI_AUTH_OPERATION_VERIFY_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED\r
);\r