mirror of
https://github.com/tianocore/edk2.git
synced 2025-09-16 16:43:03 +00:00
SecurityPkg: Added basic DxeImageVerificationLib tests
Add initial unit test for DxeImageVerificationHandler to validate signature verification bypass for selected image types. Signed-off-by: Alexander Gryanko <xpahos@gmail.com>
This commit is contained in:
parent
5125e2d6b1
commit
057a611ae6
@ -1704,6 +1704,13 @@ DxeImageVerificationHandler (
|
||||
IsFound = FALSE;
|
||||
IsFoundInDatabase = FALSE;
|
||||
|
||||
//
|
||||
// Sanity check
|
||||
//
|
||||
if (File == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check the image type and get policy setting.
|
||||
//
|
||||
|
@ -0,0 +1,137 @@
|
||||
/** @file
|
||||
Unit tests for the implementation of DxeImageVerificationLib.
|
||||
|
||||
Copyright (c) 2025, Yandex. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <Library/GoogleTestLib.h>
|
||||
#include <GoogleTest/Library/MockUefiLib.h>
|
||||
#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
|
||||
#include <GoogleTest/Library/MockUefiBootServicesTableLib.h>
|
||||
#include <GoogleTest/Library/MockDevicePathLib.h>
|
||||
|
||||
extern "C" {
|
||||
#include <Uefi.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#include "DxeImageVerificationLibGoogleTest.h"
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class CheckImageTypeResult : public ::testing::Test {
|
||||
public:
|
||||
EFI_DEVICE_PATH_PROTOCOL File;
|
||||
|
||||
protected:
|
||||
MockUefiRuntimeServicesTableLib RtServicesMock;
|
||||
MockUefiBootServicesTableLib BsMock;
|
||||
MockDevicePathLib DevicePathMock;
|
||||
|
||||
EFI_STATUS Status;
|
||||
|
||||
UINT32 AuthenticationStatus;
|
||||
VOID *FileBuffer;
|
||||
UINTN FileSize;
|
||||
BOOLEAN BootPolicy;
|
||||
|
||||
virtual void
|
||||
SetUp (
|
||||
)
|
||||
{
|
||||
AuthenticationStatus = 0;
|
||||
FileBuffer = NULL;
|
||||
FileSize = 0;
|
||||
BootPolicy = FALSE;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F (CheckImageTypeResult, ImageTypeVerifySanity) {
|
||||
// Sanity check
|
||||
Status = DxeImageVerificationHandler (AuthenticationStatus, NULL, FileBuffer, FileSize, BootPolicy);
|
||||
EXPECT_EQ (Status, EFI_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
TEST_F (CheckImageTypeResult, ImageTypeVerifyImageFromFv) {
|
||||
EXPECT_CALL (BsMock, gBS_LocateDevicePath)
|
||||
.WillRepeatedly (testing::Return (EFI_SUCCESS));
|
||||
EXPECT_CALL (BsMock, gBS_OpenProtocol)
|
||||
.WillRepeatedly (testing::Return (EFI_SUCCESS));
|
||||
|
||||
Status = DxeImageVerificationHandler (AuthenticationStatus, &File, FileBuffer, FileSize, BootPolicy);
|
||||
EXPECT_EQ (Status, EFI_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_F (CheckImageTypeResult, ImageTypeVerifyImageFromOptionRom) {
|
||||
auto TestFunc = [&](EFI_STATUS ExpectedStatus) {
|
||||
EXPECT_CALL (BsMock, gBS_LocateDevicePath)
|
||||
.Times (3)
|
||||
.WillRepeatedly (testing::Return (EFI_NOT_FOUND));
|
||||
EXPECT_CALL (BsMock, gBS_OpenProtocol)
|
||||
.WillRepeatedly (testing::Return (EFI_NOT_FOUND));
|
||||
EXPECT_CALL (DevicePathMock, IsDevicePathEndType)
|
||||
.WillOnce (testing::Return ((BOOLEAN)FALSE));
|
||||
EXPECT_CALL (DevicePathMock, DevicePathType)
|
||||
.WillOnce (testing::Return ((UINT8)MEDIA_DEVICE_PATH));
|
||||
EXPECT_CALL (DevicePathMock, DevicePathSubType)
|
||||
.WillOnce (testing::Return ((UINT8)MEDIA_RELATIVE_OFFSET_RANGE_DP));
|
||||
|
||||
Status = DxeImageVerificationHandler (AuthenticationStatus, &File, FileBuffer, FileSize, BootPolicy);
|
||||
EXPECT_EQ (Status, ExpectedStatus);
|
||||
};
|
||||
|
||||
PatchPcdSet32 (PcdOptionRomImageVerificationPolicy, ALWAYS_EXECUTE);
|
||||
TestFunc (EFI_SUCCESS);
|
||||
PatchPcdSet32 (PcdOptionRomImageVerificationPolicy, NEVER_EXECUTE);
|
||||
TestFunc (EFI_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
TEST_F (CheckImageTypeResult, ImageTypeVerifyImageFromRemovableMedia) {
|
||||
auto TestFunc = [&](EFI_STATUS ExpectedStatus) {
|
||||
EXPECT_CALL (BsMock, gBS_LocateDevicePath)
|
||||
.Times (3)
|
||||
.WillRepeatedly (testing::Return (EFI_NOT_FOUND));
|
||||
EXPECT_CALL (DevicePathMock, IsDevicePathEndType)
|
||||
.WillOnce (testing::Return ((BOOLEAN)FALSE));
|
||||
EXPECT_CALL (DevicePathMock, DevicePathType)
|
||||
.WillOnce (testing::Return ((UINT8)MESSAGING_DEVICE_PATH));
|
||||
EXPECT_CALL (DevicePathMock, DevicePathSubType)
|
||||
.WillOnce (testing::Return ((UINT8)MSG_MAC_ADDR_DP));
|
||||
|
||||
Status = DxeImageVerificationHandler (AuthenticationStatus, &File, FileBuffer, FileSize, BootPolicy);
|
||||
EXPECT_EQ (Status, ExpectedStatus);
|
||||
};
|
||||
|
||||
PatchPcdSet32 (PcdRemovableMediaImageVerificationPolicy, ALWAYS_EXECUTE);
|
||||
TestFunc (EFI_SUCCESS);
|
||||
PatchPcdSet32 (PcdRemovableMediaImageVerificationPolicy, NEVER_EXECUTE);
|
||||
TestFunc (EFI_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
TEST_F (CheckImageTypeResult, ImageTypeVerifyImageFromFixedMedia) {
|
||||
auto TestFunc = [&](EFI_STATUS ExpectedStatus) {
|
||||
EXPECT_CALL (BsMock, gBS_LocateDevicePath)
|
||||
.WillOnce (testing::Return (EFI_NOT_FOUND))
|
||||
.WillOnce (testing::Return (EFI_NOT_FOUND))
|
||||
.WillOnce (testing::Return (EFI_SUCCESS));
|
||||
|
||||
Status = DxeImageVerificationHandler (AuthenticationStatus, &File, FileBuffer, FileSize, BootPolicy);
|
||||
EXPECT_EQ (Status, ExpectedStatus);
|
||||
};
|
||||
|
||||
PatchPcdSet32 (PcdFixedMediaImageVerificationPolicy, ALWAYS_EXECUTE);
|
||||
TestFunc (EFI_SUCCESS);
|
||||
PatchPcdSet32 (PcdFixedMediaImageVerificationPolicy, NEVER_EXECUTE);
|
||||
TestFunc (EFI_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
int
|
||||
main (
|
||||
int argc,
|
||||
char *argv[]
|
||||
)
|
||||
{
|
||||
testing::InitGoogleTest (&argc, argv);
|
||||
return RUN_ALL_TESTS ();
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/** @file
|
||||
Unit tests for the implementation of DxeImageVerificationLib.
|
||||
|
||||
Copyright (c) 2025, Yandex. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#ifndef DXE_IMAGE_VERIFICATION_LIB_GOOGLE_TEST_H
|
||||
#define DXE_IMAGE_VERIFICATION_LIB_GOOGLE_TEST_H
|
||||
|
||||
/**
|
||||
Provide verification service for signed images, which include both signature validation
|
||||
and platform policy control. For signature types, both UEFI WIN_CERTIFICATE_UEFI_GUID and
|
||||
MSFT Authenticode type signatures are supported.
|
||||
|
||||
In this implementation, only verify external executables when in USER MODE.
|
||||
Executables from FV is bypass, so pass in AuthenticationStatus is ignored.
|
||||
|
||||
The image verification policy is:
|
||||
If the image is signed,
|
||||
At least one valid signature or at least one hash value of the image must match a record
|
||||
in the security database "db", and no valid signature nor any hash value of the image may
|
||||
be reflected in the security database "dbx".
|
||||
Otherwise, the image is not signed,
|
||||
The hash value of the image must match a record in the security database "db", and
|
||||
not be reflected in the security data base "dbx".
|
||||
|
||||
Caution: This function may receive untrusted input.
|
||||
PE/COFF image is external input, so this function will validate its data structure
|
||||
within this image buffer before use.
|
||||
|
||||
@param[in] AuthenticationStatus
|
||||
This is the authentication status returned from the security
|
||||
measurement services for the input file.
|
||||
@param[in] File This is a pointer to the device path of the file that is
|
||||
being dispatched. This will optionally be used for logging.
|
||||
@param[in] FileBuffer File buffer matches the input file device path.
|
||||
@param[in] FileSize Size of File buffer matches the input file device path.
|
||||
@param[in] BootPolicy A boot policy that was used to call LoadImage() UEFI service.
|
||||
|
||||
@retval EFI_SUCCESS The file specified by DevicePath and non-NULL
|
||||
FileBuffer did authenticate, and the platform policy dictates
|
||||
that the DXE Foundation may use the file.
|
||||
@retval EFI_SUCCESS The device path specified by NULL device path DevicePath
|
||||
and non-NULL FileBuffer did authenticate, and the platform
|
||||
policy dictates that the DXE Foundation may execute the image in
|
||||
FileBuffer.
|
||||
@retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and
|
||||
the platform policy dictates that File should be placed
|
||||
in the untrusted state. The image has been added to the file
|
||||
execution table.
|
||||
@retval EFI_ACCESS_DENIED The file specified by File and FileBuffer did not
|
||||
authenticate, and the platform policy dictates that the DXE
|
||||
Foundation may not use File. The image has
|
||||
been added to the file execution table.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DxeImageVerificationHandler (
|
||||
IN UINT32 AuthenticationStatus,
|
||||
IN CONST EFI_DEVICE_PATH_PROTOCOL *File OPTIONAL,
|
||||
IN VOID *FileBuffer,
|
||||
IN UINTN FileSize,
|
||||
IN BOOLEAN BootPolicy
|
||||
);
|
||||
|
||||
//
|
||||
// The DxeImageVerificationLib.h file has dependencies on Pi/PiFirmwareVolume.h and Pi/PiFirmwareFile.h.
|
||||
// These macros are copied from the header file to prevent PiPei.h from being included in HOST_APPLICATION.
|
||||
//
|
||||
|
||||
//
|
||||
// Authorization policy bit definition
|
||||
//
|
||||
#define ALWAYS_EXECUTE 0x00000000
|
||||
#define NEVER_EXECUTE 0x00000001
|
||||
|
||||
#endif // DXE_IMAGE_VERIFICATION_LIB_GOOGLE_TEST_H
|
@ -0,0 +1,79 @@
|
||||
## @file
|
||||
# Unit test suite for the DxeImageVerificationLib using Google Test
|
||||
#
|
||||
# Copyright (c) 2025, Yandex. All rights reserved.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DxeImageVerificationLibGoogleTest
|
||||
FILE_GUID = 18723239-55AA-4814-9B7A-874BAF719A65
|
||||
MODULE_TYPE = HOST_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
DxeImageVerificationLibGoogleTest.cpp
|
||||
../../../../MdePkg/Test/Mock/Library/GoogleTest/Protocol/MockRng.cpp
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DxeImageVerificationLib
|
||||
GoogleTestLib
|
||||
BaseCryptLib
|
||||
DebugLib
|
||||
|
||||
[Guids]
|
||||
## SOMETIMES_CONSUMES ## Variable:L"SecureBoot"
|
||||
gEfiGlobalVariableGuid
|
||||
|
||||
## SOMETIMES_CONSUMES ## Variable:L"DB"
|
||||
## SOMETIMES_CONSUMES ## Variable:L"DBX"
|
||||
## SOMETIMES_CONSUMES ## Variable:L"DBT"
|
||||
## PRODUCES ## SystemTable
|
||||
## CONSUMES ## SystemTable
|
||||
gEfiImageSecurityDatabaseGuid
|
||||
|
||||
## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||
## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature.
|
||||
gEfiCertSha1Guid
|
||||
|
||||
## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||
## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature.
|
||||
gEfiCertSha256Guid
|
||||
|
||||
## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||
## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature.
|
||||
gEfiCertSha384Guid
|
||||
|
||||
## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||
## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature.
|
||||
gEfiCertSha512Guid
|
||||
|
||||
gEfiCertX509Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||
gEfiCertX509Sha256Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||
gEfiCertX509Sha384Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||
gEfiCertX509Sha512Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||
gEfiCertPkcs7Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the certificate.
|
||||
|
||||
[Protocols]
|
||||
gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy ## SOMETIMES_CONSUMES
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy ## SOMETIMES_CONSUMES
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy ## SOMETIMES_CONSUMES
|
@ -46,3 +46,23 @@
|
||||
PlatformPKProtectionLib|SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
|
||||
UefiLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
|
||||
}
|
||||
SecurityPkg/Library/DxeImageVerificationLib/GoogleTest/DxeImageVerificationLibGoogleTest.inf {
|
||||
<LibraryClasses>
|
||||
UefiRuntimeServicesTableLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf
|
||||
UefiBootServicesTableLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiBootServicesTableLib/MockUefiBootServicesTableLib.inf
|
||||
DxeImageVerificationLib|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
|
||||
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
|
||||
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf
|
||||
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
|
||||
UefiLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
|
||||
DevicePathLib|MdePkg/Test/Mock/Library/GoogleTest/MockDevicePathLib/MockDevicePathLib.inf
|
||||
SecurityManagementLib|MdeModulePkg/Test/Mock/Library/GoogleTest/MockSecurityManagementLib/MockSecurityManagementLib.inf
|
||||
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
|
||||
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
|
||||
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
|
||||
}
|
||||
|
||||
[PcdsPatchableInModule]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
|
||||
|
Loading…
Reference in New Issue
Block a user