* [PATCH v7 13/14] MdeModulePkg: Drop VarLock from RuntimeDxe variable driver @ 2020-09-08 22:17 Bret Barkelew 2020-09-08 22:17 ` [PATCH v7 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy Bret Barkelew 0 siblings, 1 reply; 3+ messages in thread From: Bret Barkelew @ 2020-09-08 22:17 UTC (permalink / raw) To: devel; +Cc: Jian J Wang, Hao A Wu, Liming Gao https://bugzilla.tianocore.org/show_bug.cgi?id=2522 Now that everything should be moved to VariablePolicy, drop support for the deprecated VarLock SMI interface and associated functions from variable RuntimeDxe. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Bret Barkelew <brbarkel@microsoft.com> Signed-off-by: Bret Barkelew <brbarkel@microsoft.com> --- MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c | 49 +------------- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock.c | 71 ++++++++++++++++++++ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf | 1 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf | 1 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf | 1 + 5 files changed, 75 insertions(+), 48 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c index f15219df5eb8..486d85b022e1 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c @@ -3,60 +3,13 @@ and variable lock protocol based on VarCheckLib. Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> +Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "Variable.h" -/** - Mark a variable that will become read-only after leaving the DXE phase of execution. - Write request coming from SMM environment through EFI_SMM_VARIABLE_PROTOCOL is allowed. - - @param[in] This The VARIABLE_LOCK_PROTOCOL instance. - @param[in] VariableName A pointer to the variable name that will be made read-only subsequently. - @param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently. - - @retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked - as pending to be read-only. - @retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL. - Or VariableName is an empty string. - @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has - already been signaled. - @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request. -**/ -EFI_STATUS -EFIAPI -VariableLockRequestToLock ( - IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid - ) -{ - EFI_STATUS Status; - VAR_CHECK_VARIABLE_PROPERTY Property; - - AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); - - Status = VarCheckLibVariablePropertyGet (VariableName, VendorGuid, &Property); - if (!EFI_ERROR (Status)) { - Property.Property |= VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY; - } else { - Property.Revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION; - Property.Property = VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY; - Property.Attributes = 0; - Property.MinSize = 1; - Property.MaxSize = MAX_UINTN; - } - Status = VarCheckLibVariablePropertySet (VariableName, VendorGuid, &Property); - - DEBUG ((EFI_D_INFO, "[Variable] Lock: %g:%s %r\n", VendorGuid, VariableName, Status)); - - ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); - - return Status; -} - /** Register SetVariable check handler. diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock.c new file mode 100644 index 000000000000..1f7f0b7ef06c --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock.c @@ -0,0 +1,71 @@ +/** @file -- VariableLockRequstToLock.c +Temporary location of the RequestToLock shim code while +projects are moved to VariablePolicy. Should be removed when deprecated. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Uefi.h> + +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> + +#include <Protocol/VariableLock.h> + +#include <Protocol/VariablePolicy.h> +#include <Library/VariablePolicyLib.h> +#include <Library/VariablePolicyHelperLib.h> + + +/** + DEPRECATED. THIS IS ONLY HERE AS A CONVENIENCE WHILE PORTING. + Mark a variable that will become read-only after leaving the DXE phase of execution. + Write request coming from SMM environment through EFI_SMM_VARIABLE_PROTOCOL is allowed. + + @param[in] This The VARIABLE_LOCK_PROTOCOL instance. + @param[in] VariableName A pointer to the variable name that will be made read-only subsequently. + @param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently. + + @retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked + as pending to be read-only. + @retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL. + Or VariableName is an empty string. + @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has + already been signaled. + @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request. +**/ +EFI_STATUS +EFIAPI +VariableLockRequestToLock ( + IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewPolicy; + + NewPolicy = NULL; + Status = CreateBasicVariablePolicy( VendorGuid, + VariableName, + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW, + &NewPolicy ); + if (!EFI_ERROR( Status )) { + Status = RegisterVariablePolicy( NewPolicy ); + } + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Failed to lock variable %s! %r\n", __FUNCTION__, VariableName, Status )); + ASSERT_EFI_ERROR( Status ); + } + if (NewPolicy != NULL) { + FreePool( NewPolicy ); + } + + return Status; +} diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index 8debc560e6dc..3005e9617423 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -49,6 +49,7 @@ [Sources] VarCheck.c VariableExLib.c SpeculationBarrierDxe.c + VariableLockRequstToLock.c [Packages] MdePkg/MdePkg.dec diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf index bbc8d2080193..26fbad97339f 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf @@ -58,6 +58,7 @@ [Sources] VariableExLib.c TcgMorLockSmm.c SpeculationBarrierSmm.c + VariableLockRequstToLock.c [Packages] MdePkg/MdePkg.dec diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf index 62f2f9252f43..7c6fdf4d65fd 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf @@ -58,6 +58,7 @@ [Sources] VariableExLib.c TcgMorLockSmm.c SpeculationBarrierSmm.c + VariableLockRequstToLock.c [Packages] MdePkg/MdePkg.dec -- 2.28.0.windows.1 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v7 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy 2020-09-08 22:17 [PATCH v7 13/14] MdeModulePkg: Drop VarLock from RuntimeDxe variable driver Bret Barkelew @ 2020-09-08 22:17 ` Bret Barkelew 0 siblings, 0 replies; 3+ messages in thread From: Bret Barkelew @ 2020-09-08 22:17 UTC (permalink / raw) To: devel; +Cc: Jian J Wang, Hao A Wu, Liming Gao https://bugzilla.tianocore.org/show_bug.cgi?id=2522 To verify that VariablePolicy is correctly integrated on platforms, add a Shell-based functional test to confirm expected behavior. NOTE: This test assumes that VariablePolicy is built with PcdAllowVariablePolicyEnforcementDisable set to TRUE. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Bret Barkelew <brbarkel@microsoft.com> Signed-off-by: Bret Barkelew <brbarkel@microsoft.com> --- MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c | 2226 ++++++++++++++++++++ MdeModulePkg/MdeModulePkg.ci.yaml | 4 +- MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md | 55 + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf | 47 + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h | 128 ++ 5 files changed, 2459 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c new file mode 100644 index 000000000000..c2b28e4b642b --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c @@ -0,0 +1,2226 @@ +/** @file +UEFI Shell based application for unit testing the Variable Policy Protocol. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <Library/UefiLib.h> +#include <Library/PrintLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/UnitTestLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Protocol/VariablePolicy.h> +#include <Library/VariablePolicyHelperLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> + +#include "VariablePolicyTestAuthVar.h" + +// TODO: Need to add to the UnitTestFrameworkPkg +// #include <Library/UnitTestBootLib.h> + +#define UNIT_TEST_APP_NAME "Variable Policy Unit Test Application" +#define UNIT_TEST_APP_VERSION "0.1" + +// TODO: Need to add to the UnitTestFrameworkPkg +UNIT_TEST_FRAMEWORK_HANDLE +GetActiveFrameworkHandle ( + VOID + ); + +EDKII_VARIABLE_POLICY_PROTOCOL *mVarPol = NULL; + + +EFI_GUID mTestNamespaceGuid1 = { 0x3b389299, 0xabaf, 0x433b, { 0xa4, 0xa9, 0x23, 0xc8, 0x44, 0x02, 0xfc, 0xad } }; +EFI_GUID mTestNamespaceGuid2 = { 0x4c49a3aa, 0xbcb0, 0x544c, { 0xb5, 0xba, 0x34, 0xd9, 0x55, 0x13, 0x0d, 0xbe } }; +EFI_GUID mTestNamespaceGuid3 = { 0x5d5ab4bb, 0xcdc1, 0x655d, { 0xc6, 0xcb, 0x45, 0xea, 0x66, 0x24, 0x1e, 0xcf } }; + +#define TEST_AUTH_VAR_NAME L"DummyAuthVar" +EFI_GUID mTestAuthNamespaceGuid = { 0xb6c5a2c6, 0x3ece, 0x4b9b, { 0x8c, 0xc8, 0x96, 0xd8, 0xd9, 0xca, 0xd3, 0x4e } }; + +/** + Prerequisite for most test cases. +**/ +UNIT_TEST_STATUS +EFIAPI +LocateVarPolicyPreReq ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + if (mVarPol == NULL) { + Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, + NULL, + (VOID **) &mVarPol); + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_NOT_NULL (mVarPol); + } + + return UNIT_TEST_PASSED; +} // LocateVarPolicyPreReq + +UNIT_TEST_STATUS +EFIAPI +VarPolicyEnabledPreReq ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + + UT_ASSERT_EQUAL(LocateVarPolicyPreReq(Context), UNIT_TEST_PASSED); + Status = mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR(Status); + UT_ASSERT_TRUE(State); + + return UNIT_TEST_PASSED; +} + +UNIT_TEST_STATUS +EFIAPI +VarPolicyDisabledPreReq ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + + UT_ASSERT_EQUAL(LocateVarPolicyPreReq(Context), UNIT_TEST_PASSED); + Status = mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR(Status); + UT_ASSERT_FALSE(State); + + return UNIT_TEST_PASSED; +} + +/** + Getting Started tests. +**/ +UNIT_TEST_STATUS +EFIAPI +CheckVpEnabled ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + + Status = mVarPol->IsVariablePolicyEnabled (&State); + + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_EQUAL (State, TRUE); + + return UNIT_TEST_PASSED; +} // CheckVpEnabled + +UNIT_TEST_STATUS +EFIAPI +CheckVpRevision ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UT_ASSERT_NOT_EQUAL (mVarPol->Revision, 0); + UT_LOG_INFO ("VP Revision: 0x%x\n", mVarPol->Revision); + + return UNIT_TEST_PASSED; +} // CheckVpRevision + +/** + NOTE: Copied from SecureBootConfigImpl.c, then modified. + + Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2 + descriptor with the input data. NO authentication is required in this function. + + @param[in, out] DataSize On input, the size of Data buffer in bytes. + On output, the size of data returned in Data + buffer in bytes. + @param[in, out] Data On input, Pointer to data buffer to be wrapped or + pointer to NULL to wrap an empty payload. + On output, Pointer to the new payload date buffer allocated from pool, + it's caller's responsibility to free the memory when finish using it. + @param[in] Time [Optional] If provided, will be used as the timestamp for the payload. + If NULL, a new timestamp will be generated using GetTime(). + + @retval EFI_SUCCESS Create time based payload successfully. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources to create time based payload. + @retval EFI_INVALID_PARAMETER The parameter is invalid. + @retval Others Unexpected error happens. + +**/ +STATIC +EFI_STATUS +CreateEmptyTimeBasedPayload ( + IN OUT UINTN *DataSize, + IN OUT UINT8 **Data, + IN EFI_TIME *Time OPTIONAL + ) +{ + UINT8 *NewData; + UINT8 *Payload; + UINTN PayloadSize; + EFI_VARIABLE_AUTHENTICATION_2 *DescriptorData; + UINTN DescriptorSize; + EFI_TIME NewTime; + + if (Data == NULL || DataSize == NULL) { + DEBUG((DEBUG_ERROR, "CreateEmptyTimeBasedPayload(), invalid arg\n")); + return EFI_INVALID_PARAMETER; + } + + // + // In Setup mode or Custom mode, the variable does not need to be signed but the + // parameters to the SetVariable() call still need to be prepared as authenticated + // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate + // data in it. + // + Payload = *Data; + PayloadSize = *DataSize; + + DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); + NewData = (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize); + if (NewData == NULL) { + DEBUG((DEBUG_ERROR, "CreateEmptyTimeBasedPayload() Out of resources.\n")); + return EFI_OUT_OF_RESOURCES; + } + + if ((Payload != NULL) && (PayloadSize != 0)) { + CopyMem (NewData + DescriptorSize, Payload, PayloadSize); + } + + DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData); + + // + // Use or create the timestamp. + // + // If Time is NULL, create a new timestamp. + if (Time == NULL) + { + NewTime.Year = 9999; + NewTime.Month = 12; + NewTime.Day = 31; + NewTime.Hour = 23; + NewTime.Minute = 59; + NewTime.Second = 59; + NewTime.Pad1 = 0; + NewTime.Nanosecond = 0; + NewTime.TimeZone = 0; + NewTime.Daylight = 0; + NewTime.Pad2 = 0; + Time = &NewTime; // Use the new timestamp. + } + CopyMem (&DescriptorData->TimeStamp, Time, sizeof (EFI_TIME)); + + DescriptorData->AuthInfo.Hdr.dwLength = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); + DescriptorData->AuthInfo.Hdr.wRevision = 0x0200; + DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; + CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid); + + if (Payload != NULL) { + FreePool(Payload); + } + + *DataSize = DescriptorSize + PayloadSize; + *Data = NewData; + return EFI_SUCCESS; +} + +/** + NoLock Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestMinSizeNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINT8 *Buffer; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MinSizeNoLockVar", + 4, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that is smaller than minsize + // + Value1 = 0x12; + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value1), + &Value1); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Try to write a var of size that matches minsize + // + Value2 = 0xa1b2c3d4; + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size larger than minsize + // + Buffer = AllocateZeroPool (40); + UT_ASSERT_NOT_NULL (Buffer); + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + 40, + Buffer); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Delete the variable + // + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + FreePool (Buffer); + + return UNIT_TEST_PASSED; +} // TestMinSizeNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMaxSizeNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINT8 *Buffer; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MaxSizeNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 4, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that is smaller than maxsize + // + Value1 = 0x34; + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value1), + &Value1); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size that matches maxsize + // + Value2 = 0xa1b2c3d4; + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size larger than maxsize + // + Buffer = AllocateZeroPool (40); + UT_ASSERT_NOT_NULL (Buffer); + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + 40, + Buffer); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + FreePool (Buffer); + + return UNIT_TEST_PASSED; +} // TestMaxSizeNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMustHaveAttrNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MustHaveAttrNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that doesn't have the must-have attributes + // + Value = 0x56; + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Try to write a var that has exactly the required attributes + // + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting + // + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that has the required attributes and one extra attribute + // + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting + // + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + return UNIT_TEST_PASSED; +} // TestMustHaveAttrNoLock + +UNIT_TEST_STATUS +EFIAPI +TestCantHaveAttrNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"CantHaveAttrNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_NON_VOLATILE, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that has a can't have attr + // + Value = 0x78; + Status = gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Try to write a var that satisfies the can't have requirement + // + Status = gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestCantHaveAttrNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMaxSizeNamespaceNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINT8 *Buffer; + + // + // Register a namespace-wide policy limiting max size to 4 bytes + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid2, + NULL, + VARIABLE_POLICY_NO_MIN_SIZE, + 4, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that is smaller than maxsize + // + Value1 = 0x34; + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value1), + &Value1); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size that matches maxsize + // + Value2 = 0xa1b2c3d4; + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size larger than maxsize + // + Buffer = AllocateZeroPool (40); + UT_ASSERT_NOT_NULL (Buffer); + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + 40, + Buffer); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + FreePool (Buffer); + + return UNIT_TEST_PASSED; +} // TestMaxSizeNamespaceNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMustHaveAttrWildcardNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MustHaveAttrWildcardNoLockVar####", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that doesn't have the must-have attributes + // + Value = 0x56; + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1573", + &mTestNamespaceGuid1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Try to write a var that has exactly the required attributes + // + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1234", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting + // + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1234", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that has the required attributes and one extra attribute + // + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar5612", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting + // + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar5612", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestMustHaveAttrWildcardNoLock + +UNIT_TEST_STATUS +EFIAPI +TestPolicyprioritizationNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value8; + UINT16 Value16; + UINT32 Value32; + UINT64 Value64; + + // + // Register a policy targeting the specific var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid3, + L"PolicyPriorityTestVar123", + 8, // min size of UINT64 + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a policy with wildcards in the name + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid3, + L"PolicyPriorityTestVar###", + 4, // min size of UINT32 + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a policy with wildcards in the name + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid3, + NULL, + 2, // min size of UINT16 + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // The idea is that the most specific policy is applied: + // For varname "TestVar", the namespace-wide one should apply: UINT16 minimum + // For varname "PolicyPriorityTestVar567" the wildcard policy should apply: UINT32 minimum + // For varname "PolicyPriorityTestVar123" the var-specific policy should apply: UINT64 minimum + // + + // + // Let's confirm the namespace-wide policy enforcement + // + Value8 = 0x78; + Status = gRT->SetVariable (L"TestVar", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value8), + &Value8); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + Value16 = 0x6543; + Status = gRT->SetVariable (L"TestVar", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value16), + &Value16); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's confirm the wildcard policy enforcement + // + Value16 = 0xabba; + Status = gRT->SetVariable (L"PolicyPriorityTestVar567", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value16), + &Value16); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + Value32 = 0xfedcba98; + Status = gRT->SetVariable (L"PolicyPriorityTestVar567", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value32), + &Value32); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's confirm the var-specific policy enforcement + // + Value32 = 0x8d3f627c; + Status = gRT->SetVariable (L"PolicyPriorityTestVar123", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value32), + &Value32); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + Value64 = 0xbebecdcdafaf6767; + Status = gRT->SetVariable (L"PolicyPriorityTestVar123", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value64), + &Value64); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestPolicyprioritizationNoLock + +/** + LockNow Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestExistingVarLockNow ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // Write a var that we'll protect next + // + Value = 0x78; + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a LockNow policy targeting the var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ExistingLockNowVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to modify the locked var + // + Value = 0xA5; + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Attempt to delete the locked var + // + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // This variable is deleted in final cleanup. + // + + return UNIT_TEST_PASSED; +} // TestExistingVarLockNow + +UNIT_TEST_STATUS +EFIAPI +TestNonexistentVarLockNow ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + UINTN Size; + + // + // Make sure the variable we're about to create the policy for doesn't exist + // + Size = 0; + Status = gRT->GetVariable (L"NonexistentLockNowVar", + &mTestNamespaceGuid1, + NULL, + &Size, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); + + // + // Register a LockNow policy targeting the var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"NonexistentLockNowVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to create the locked var + // + Value = 0xA5; + Status = gRT->SetVariable (L"NonexistentLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + return UNIT_TEST_PASSED; +} // TestNonexistentVarLockNow + +/** + LockOnCreate Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestExistingVarLockOnCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // Write a var that we'll protect later + // + Value = 0x78; + Status = gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a LockNow policy targeting the var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ExistingLockOnCreateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_ON_CREATE); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to modify the locked var + // + Value = 0xA5; + Status = gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Attempt to delete the locked var + // + Status = gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // This variable is deleted in final cleanup. + // + + return UNIT_TEST_PASSED; +} // TestExistingVarLockOnCreate + +UNIT_TEST_STATUS +EFIAPI +TestNonexistentVarLockOnCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINTN Size; + + // + // Make sure the variable we're about to create the policy for doesn't exist + // + Size = 0; + Status = gRT->GetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + NULL, + &Size, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); + + // + // Register a LockOnCreate policy targeting the var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"NonexistentLockOnCreateVar", + 2, // min size of 2 bytes, UINT16+ + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_RUNTIME_ACCESS, // must have RT attr + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_ON_CREATE); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to create the var, but smaller than min size + // + Value1 = 0xA5; + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value1), + &Value1); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Now let's make sure attribute req is enforced + // + Value2 = 0x43218765; + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value2), + &Value2); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Now let's create a valid variable + // + Value2 = 0x43218765; + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's make sure we can't modify it + // + Value2 = 0xa5a5b6b6; + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value2), + &Value2); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Finally, let's make sure we can't delete it + // + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // This variable is deleted in final cleanup. + // + + return UNIT_TEST_PASSED; +} // TestNonexistentVarLockOnCreate + +/** + LockOnVarState Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateBeforeCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINTN Size; + UINT8 Value; + + // + // First of all, let's make sure the var we're trying to protect doesn't exist + // + Size = 0; + Status = gRT->GetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + NULL, + &Size, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); + + // + // Good, now let's create a policy + // + Status = RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"NonexistentLockOnVarStateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger1", + 0x7E); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now we write the trigger var + // + Value = 0x7E; + Status = gRT->SetVariable (L"Trigger1", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Ok, now we attempt to write a var protected by the trigger + // + Value = 0xFA; + Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Let's modify the trigger var and "untrigger" the policy + // + Value = 0x38; + Status = gRT->SetVariable (L"Trigger1", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now we should be able to create the var targeted by the policy + // + Value = 0x23; + Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Cleanup: delete the trigger and the protected var + // + Status = gRT->SetVariable (L"Trigger1", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateBeforeCreate + +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateAfterCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // Let's create a policy + // + Status = RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ExistingLockOnVarStateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger2", + 0x5C); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to write targeted var since the policy isn't active yet. + // + Value = 0x17; + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's modify the var to make sure the policy isn't acting like a lock-on-create one + // + Value = 0x30; + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now we trigger the policy + // + Value = 0x5C; + Status = gRT->SetVariable (L"Trigger2", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's now verify the variable is protected + // + Value = 0xB9; + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Ok, to clean up, we need to remove the trigger var, so delete it, and then delete the target var + // + Status = gRT->SetVariable (L"Trigger2", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateAfterCreate + +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateInvalidLargeTrigger ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT16 Value; + + // + // First let's create a variable policy + // + Status = RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidLargeTriggerLockOnVarStateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger3", + 0x5C); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now attempt to trigger the lock but with a variable larger than one byte + // + Value = 0x8085; + Status = gRT->SetVariable (L"Trigger3", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should still be able to create the targeted var + // + Value = 0x1234; + Status = gRT->SetVariable (L"InvalidLargeTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's clean up by deleting the invalid trigger and the targeted var + // + Status = gRT->SetVariable (L"Trigger3", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status = gRT->SetVariable (L"InvalidLargeTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateInvalidLargeTrigger + +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateWrongValueTrigger ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // First let's create a variable policy + // + Status = RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"WrongValueTriggerLockOnVarStateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger4", + 0xCA); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now attempt to trigger the lock but with a wrong value + // + Value = 0x80; + Status = gRT->SetVariable (L"Trigger4", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should still be able to create the targeted var + // + Value = 0x14; + Status = gRT->SetVariable (L"WrongValueTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's clean up by deleting the invalid trigger and the targeted var + // + Status = gRT->SetVariable (L"Trigger4", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status = gRT->SetVariable (L"WrongValueTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateWrongValueTrigger + +/** + Invalid policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestInvalidAttributesPolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // The only must/can't have attributes supported by VPE are NV, BS, and RT. They are 1, 2, and 4, respectively. + // Let's try some bits higher than that? + // + + // + // Trying must have attribute 0x8 which is EFI_VARIABLE_HARDWARE_ERROR_RECORD + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyVar1", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_HARDWARE_ERROR_RECORD, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_HARDWARE_ERROR_RECORD returned %r\n", Status); + + // + // Let's try 0x10 - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, a deprecated attribute + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyVar2", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status); + + // + // Let's try 0x20 - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyVar3", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status); + + // + // Let's try something wild, like 0x4000 + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyVar4", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + 0x4000, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to 0x4000 returned %r\n", Status); + + // + // Now repeat the same tests, but for the can't-have param + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyVar1", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_HARDWARE_ERROR_RECORD, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_HARDWARE_ERROR_RECORD returned %r\n", Status); + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyVar2", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status); + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyVar3", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status); + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyVar4", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + 0x4000, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to 0x4000 returned %r\n", Status); + + return UNIT_TEST_PASSED; +} // TestInvalidAttributesPolicy + +UNIT_TEST_STATUS +EFIAPI +TestLargeMinSizePolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Let's set the min size to 2GB and see what happens + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"LargeMinSizeInvalidPolicyVar", + 0x80000000, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + + UT_LOG_INFO ("Setting min size to 0x80000000 returned %r\n", Status); + + return UNIT_TEST_PASSED; +} // TestLargeMinSizePolicy + +UNIT_TEST_STATUS +EFIAPI +TestZeroMaxSizePolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Let's set the max size to 0 and see what happens + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ZeroMinSizeInvalidPolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 0, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + //UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); // this fails on QC. Real bug? Do we care? + UT_LOG_INFO ("Setting max size to 0 returned %r\n", Status); + + return UNIT_TEST_PASSED; +} // TestZeroMaxSizePolicy + +UNIT_TEST_STATUS +EFIAPI +TestInvalidPolicyTypePolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Let's set policy type to an invalid value and see what happens + // Valid ones are: + // VARIABLE_POLICY_TYPE_NO_LOCK 0 + // VARIABLE_POLICY_TYPE_LOCK_NOW 1 + // VARIABLE_POLICY_TYPE_LOCK_ON_CREATE 2 + // VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE 3 + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidPolicyTypePolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + 4); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidPolicyTypePolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + 147); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + return UNIT_TEST_PASSED; +} // TestInvalidPolicyTypePolicy + +/** + Test dumping policy. +**/ +UNIT_TEST_STATUS +EFIAPI +TestDumpPolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8* Buffer; + UINT32 Size; + + // + // First let's call DumpVariablePolicy with null buffer to get size + // + Size = 0; + Status = mVarPol->DumpVariablePolicy (NULL, &Size); + UT_ASSERT_STATUS_EQUAL (Status, EFI_BUFFER_TOO_SMALL); + + // + // Now we allocate the buffer for the dump + // + Buffer = NULL; + Buffer = AllocatePool (Size); + UT_ASSERT_NOT_NULL (Buffer); + + // + // Now we get the dump. In this test we will not analyze the dump. + // + Status = mVarPol->DumpVariablePolicy (Buffer, &Size); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestDumpPolicy + +/** + Test policy version. +**/ +UNIT_TEST_STATUS +EFIAPI +TestPolicyVersion ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewEntry; + + // + // Create the new entry using a helper lib + // + NewEntry = NULL; + Status = CreateBasicVariablePolicy (&mTestNamespaceGuid1, + L"PolicyVersionTestNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 4, // max size of 4 bytes + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK, + &NewEntry); + UT_ASSERT_NOT_EFI_ERROR (Status); + + NewEntry->Version = 0x1234; + Status = mVarPol->RegisterVariablePolicy (NewEntry); + UT_LOG_INFO ("Registering policy entry with an unknown version status: %r\n", Status); + + FreePool (NewEntry); + + return UNIT_TEST_PASSED; +} // TestPolicyVersion + +/** + Lock Policy Tests. +**/ +UNIT_TEST_STATUS +EFIAPI +LockPolicyEngineTests ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT16 Value; + UINT64 Value64; + BOOLEAN State; + + // + // First let's register a policy that we'll test after VPE lock + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"BeforeVpeLockNoLockPolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 4, // max size of 4 bytes + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_ON_CREATE); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now, lock VPE! + // + Status = mVarPol->LockVariablePolicy (); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // See if we can lock it again? + // + Status = mVarPol->LockVariablePolicy (); + UT_LOG_INFO ("Locking VPE for second time returned %r\n", Status); + + // + // Let's confirm one of the policies from prior test suites is still enforced + // Attempt to delete a locked var + // + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // We'll make sure the policy from earlier in this test case is actively filtering out by size + // + Value64 = 0x3829fed212345678; + Status = gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value64), + &Value64); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Let's create the variable from the policy now + // + Value = 0x323f; + Status = gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now confirm that the var is locked after creation + // + Value = 0x1212; + Status = gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Let's attempt to register a new policy, it should fail + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"AfterVpeLockNowPolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + // + // Make sure VPE is enabled + // + Status = mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_EQUAL (State, TRUE); + + // + // Finally, make sure we can't disable VPE + // + Status = mVarPol->DisableVariablePolicy (); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + return UNIT_TEST_PASSED; +} // LockPolicyEngineTests + +/** + Save context and reboot after the lock policy test suite. +**/ +STATIC +VOID +EFIAPI +SaveStateAndReboot ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Now, save all the data associated with this framework. + // TODO: Need to add to the UnitTestFrameworkPkg + Status = SaveFrameworkState( NULL, 0 ); + + // + // If we're all good, let's book... + if (!EFI_ERROR( Status )) + { + // + // Next, we want to update the BootNext variable to USB + // so that we have a fighting chance of coming back here. + // + // TODO: Need to add to the UnitTestFrameworkPkg + // SetBootNextDevice(); + + // + // Reset + DEBUG(( DEBUG_INFO, "%a - Rebooting! Launch this test again once booted.\n", __FUNCTION__ )); + gRT->ResetSystem( EfiResetCold, EFI_SUCCESS, 0, NULL ); + DEBUG(( DEBUG_ERROR, "%a - Unit test failed to quit! Framework can no longer be used!\n", __FUNCTION__ )); + + // + // We REALLY shouldn't be here. + Status = EFI_ABORTED; + } + + return; +} // SaveContextAndReboot + +STATIC +VOID +IgnoreContextAndReboot ( + IN UNIT_TEST_CONTEXT Context + ) +{ + // Just a wrapper for prototype reuse. + SaveStateAndReboot(); +} + +/** + Disable policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +DisablePolicyEngineTests ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + UINT8 Value; + + // + // First, we disable the variable policy + // + Status = mVarPol->DisableVariablePolicy (); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Confirm it's disabled + // + Status = mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_EQUAL (State, FALSE); + + // + // Try locking it? + // + Status = mVarPol->LockVariablePolicy (); + UT_LOG_INFO ("Locking VP after disabling it status: %r\n", Status); + + // + // Try modifying the var from TestExistingVarLockNow + // + Value = 0xB5; + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // DisablePolicyEngineTests + +// +// Pre-Disable Setup and Test for Authenticated Variables +// +UNIT_TEST_STATUS +TestAuthVarPart1 ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT32 Data; + UINTN DataSize; + UINT8 *DeleteData; + + // First, we need to create our dummy Authenticated Variable. + Status = gRT->SetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS), + mTestAuthVarPayloadSize, + &mTestAuthVarPayload[0]); + UT_ASSERT_NOT_EFI_ERROR(Status); + + // Prove that we created it. + DataSize = sizeof(Data); + Status = gRT->GetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + NULL, + &DataSize, + &Data); + UT_ASSERT_NOT_EFI_ERROR(Status); + UT_ASSERT_EQUAL(Data, 0xDEADBEEF); + + // Prove that we cannot delete it. + DeleteData = NULL; + DataSize = 0; + Status = CreateEmptyTimeBasedPayload(&DataSize, &DeleteData, NULL); + UT_ASSERT_NOT_EFI_ERROR(Status); + Status = gRT->SetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS), + DataSize, + (VOID*)DeleteData); + UT_ASSERT_STATUS_EQUAL(Status, EFI_SECURITY_VIOLATION); + FreePool(DeleteData); + + return UNIT_TEST_PASSED; +} + +// +// Post-Disable Test for Authenticated Variables +// +UNIT_TEST_STATUS +TestAuthVarPart2 ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT32 Data; + UINTN DataSize; + UINT8 *DeleteData; + + // Prove that it exists. + DataSize = sizeof(Data); + Status = gRT->GetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + NULL, + &DataSize, + &Data); + UT_ASSERT_NOT_EFI_ERROR(Status); + UT_ASSERT_EQUAL(Data, 0xDEADBEEF); + + // Prove that we can delete it. + DeleteData = NULL; + DataSize = 0; + Status = CreateEmptyTimeBasedPayload(&DataSize, &DeleteData, NULL); + UT_ASSERT_NOT_EFI_ERROR(Status); + Status = gRT->SetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS), + DataSize, + (VOID*)DeleteData); + UT_ASSERT_NOT_EFI_ERROR(Status); + FreePool(DeleteData); + + // Prove that we deleted it. + DataSize = sizeof(Data); + Status = gRT->GetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + NULL, + &DataSize, + &Data); + UT_ASSERT_STATUS_EQUAL(Status, EFI_NOT_FOUND); + + return UNIT_TEST_PASSED; +} + +/** + Final Cleanup: delete some variables earlier test cases created. +**/ +STATIC +VOID +EFIAPI +FinalCleanup ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete ExistingLockNowVar status: %r\n", Status); + + Status = gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete ExistingLockOnCreateVar status: %r\n", Status); + + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete NonexistentLockOnCreateVar status: %r\n", Status); + + Status = gRT->SetVariable (L"NonexistentLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete NonexistentLockNowVar status: %r\n", Status); + + Status = gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete CantHaveAttrNoLockVar status: %r\n", Status); + + Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete NonexistentLockOnVarStateVar status: %r\n", Status); + + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete ExistingLockOnVarStateVar status: %r\n", Status); +} // FinalCleanup + +/** + + Main fuction sets up the unit test environment. + +**/ +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE* SystemTable) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE GettingStartedTestSuite; + UNIT_TEST_SUITE_HANDLE NoLockPoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE LockNowPoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE LockOnCreatePoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE LockOnVarStatePoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE InvalidPoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE DumpPolicyTestSuite; + UNIT_TEST_SUITE_HANDLE PolicyVersionTestSuite; + UNIT_TEST_SUITE_HANDLE LockPolicyTestSuite; + UNIT_TEST_SUITE_HANDLE DisablePolicyTestSuite; + + Framework = NULL; + GettingStartedTestSuite = NULL; + NoLockPoliciesTestSuite = NULL; + LockNowPoliciesTestSuite = NULL; + LockOnCreatePoliciesTestSuite = NULL; + LockOnVarStatePoliciesTestSuite = NULL; + InvalidPoliciesTestSuite = NULL; + DumpPolicyTestSuite = NULL; + PolicyVersionTestSuite = NULL; + LockPolicyTestSuite = NULL; + DisablePolicyTestSuite = NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION)); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Test suite 1: Getting Started. Get VP protocol, check state, log revision + // + Status = CreateUnitTestSuite (&GettingStartedTestSuite, Framework, "Getting Started", "Common.VP.GettingStarted", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Getting Started Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (GettingStartedTestSuite, "Confirm VP is enabled", "Common.VP.GettingStarted.CheckVpEnabled", CheckVpEnabled, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (GettingStartedTestSuite, "Check VP revision", "Common.VP.GettingStarted.CheckVpRevision", CheckVpRevision, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 2: Test NoLock Policies + // + Status = CreateUnitTestSuite (&NoLockPoliciesTestSuite, Framework, "Exercise NoLock Policies", "Common.VP.NoLockPolicies", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the NoLock Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (NoLockPoliciesTestSuite, "Test Min Size enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestMinSizeNoLock", TestMinSizeNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestMaxSizeNoLock", TestMaxSizeNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attribute enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestMustHaveAttrNoLock", TestMustHaveAttrNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Can't Have Attribute enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestCantHaveAttrNoLock", TestCantHaveAttrNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enforcement in NoLock policy for entire namespace", "Common.VP.NoLockPolicies.TestMaxSizeNamespaceNoLock", TestMaxSizeNamespaceNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attribute enforcement in NoLock policy with wildcards", "Common.VP.NoLockPolicies.TestMustHaveAttrWildcardNoLock", TestMustHaveAttrWildcardNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test policy prioritization between namespace-wide, wildcard, and var-specific policies", "Common.VP.NoLockPolicies.TestPolicyprioritizationNoLock", TestPolicyprioritizationNoLock, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 3: Test LockNow policies + // + Status = CreateUnitTestSuite (&LockNowPoliciesTestSuite, Framework, "Exercise LockNow Policies", "Common.VP.LockNowPolicies", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockNow Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockNowPoliciesTestSuite, "Test LockNow policy for a pre-existing variable", "Common.VP.LockNowPolicies.TestExistingVarLockNow", TestExistingVarLockNow, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockNowPoliciesTestSuite, "Test LockNow policy for a nonexistent variable", "Common.VP.LockNowPolicies.TestNonexistentVarLockNow", TestNonexistentVarLockNow, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 4: Test LockOnCreate policies + // + Status = CreateUnitTestSuite (&LockOnCreatePoliciesTestSuite, Framework, "Exercise LockOnCreate Policies", "Common.VP.LockOnCreate", NULL, NULL); + if (EFI_ERROR (Status)) + { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockOnCreate Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCreate policy for a pre-existing variable", "Common.VP.LockOnCreate.TestExistingVarLockOnCreate", TestExistingVarLockOnCreate, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCreate policy for a nonexistent variable", "Common.VP.LockOnCreate.TestNonexistentVarLockOnCreate", TestNonexistentVarLockOnCreate, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 5: Test LockOnVarState policies + // + Status = CreateUnitTestSuite (&LockOnVarStatePoliciesTestSuite, Framework, "Exercise LockOnVarState Policies", "Common.VP.LockOnVarState", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockOnVarState Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy for a nonexistent variable", "Common.VP.LockOnVarState.TestLockOnVarStateBeforeCreate", TestLockOnVarStateBeforeCreate, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy for a pre-existing variable", "Common.VP.LockOnVarState.TestLockOnVarStateAfterCreate", TestLockOnVarStateAfterCreate, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy triggered by invalid-size variable", "Common.VP.LockOnVarState.TestLockOnVarStateInvalidLargeTrigger", TestLockOnVarStateInvalidLargeTrigger, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy triggered by invalid-value variable", "Common.VP.LockOnVarState.TestLockOnVarStateWrongValueTrigger", TestLockOnVarStateWrongValueTrigger, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 6: Test registering invalid policies + // + Status = CreateUnitTestSuite (&InvalidPoliciesTestSuite, Framework, "Attempt registering invalid policies", "Common.VP.InvalidPolicies", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Invalid Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid must-have attributes", "Common.VP.InvalidPolicies.TestInvalidAttributesPolicy", TestInvalidAttributesPolicy, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid attributes", "Common.VP.InvalidPolicies.TestLargeMinSizePolicy", TestLargeMinSizePolicy, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid attributes", "Common.VP.InvalidPolicies.TestZeroMaxSizePolicy", TestZeroMaxSizePolicy, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid type", "Common.VP.InvalidPolicies.TestInvalidPolicyTypePolicy", TestInvalidPolicyTypePolicy, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 7: Test dumping the policy + // + Status = CreateUnitTestSuite (&DumpPolicyTestSuite, Framework, "Attempt dumping policy", "Common.VP.DumpPolicy", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Dump Policy Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (DumpPolicyTestSuite, "Test dumping policy", "Common.VP.DumpPolicy.TestDumpPolicy", TestDumpPolicy, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 8: Test policy version + // + Status = CreateUnitTestSuite (&PolicyVersionTestSuite, Framework, "Use non-zero policy version", "Common.VP.PolicyVersion", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Policy Version Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (PolicyVersionTestSuite, "Test policy version", "Common.VP.DumpPolicy.TestPolicyVersion", TestPolicyVersion, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 9: Lock VPE and test implications + // + Status = CreateUnitTestSuite (&LockPolicyTestSuite, Framework, "Lock policy, test it", "Common.VP.LockPolicyTests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Lock Policy Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockPolicyTestSuite, "Test locking policy", "Common.VP.LockPolicyTests.LockPolicyEngineTests", LockPolicyEngineTests, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockPolicyTestSuite, "Test locking policy", "Common.VP.LockPolicyTests.LockPolicyEngineTests", LockPolicyEngineTests, LocateVarPolicyPreReq, IgnoreContextAndReboot, NULL); + + // + // Test suite 10: Disable var policy and confirm expected behavior + // + Status = CreateUnitTestSuite (&DisablePolicyTestSuite, Framework, "Disable policy, test it", "Common.VP.DisablePolicyTests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Disable Policy Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (DisablePolicyTestSuite, "Confirm VP is enabled", "Common.VP.DisablePolicyTests.CheckVpEnabled", CheckVpEnabled, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test LockNow policy for a pre-existing variable", "Common.VP.DisablePolicyTests.TestExistingVarLockNow", TestExistingVarLockNow, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test AuthVar protection while VariablePolicy is enabled", "Common.VP.DisablePolicyTests.TestAuthVar1", TestAuthVarPart1, VarPolicyEnabledPreReq, NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test disabling policy", "Common.VP.DisablePolicyTests.DisablePolicyEngineTests", DisablePolicyEngineTests, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test AuthVar protection while VariablePolicy is disabled", "Common.VP.DisablePolicyTests.TestAuthVar2", TestAuthVarPart2, VarPolicyDisabledPreReq, FinalCleanup, NULL); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework != NULL) { + FreeUnitTestFramework (Framework); + } + + return Status; +} // UefiMain diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.ci.yaml index 20d53fc5a5fa..a1beee9f4aab 100644 --- a/MdeModulePkg/MdeModulePkg.ci.yaml +++ b/MdeModulePkg/MdeModulePkg.ci.yaml @@ -53,7 +53,9 @@ "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec" ], # For UEFI shell based apps - "AcceptableDependencies-UEFI_APPLICATION":[], + "AcceptableDependencies-UEFI_APPLICATION":[ + "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec" + ], "IgnoreInf": [] }, diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md new file mode 100644 index 000000000000..804ad4173a5f --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md @@ -0,0 +1,55 @@ +# variable Policy Unit Tests + +## 🔹 Copyright +Copyright (C) Microsoft Corporation. All rights reserved. +SPDX-License-Identifier: BSD-2-Clause-Patent + +## About This Test +This test verifies functionality of the Variable Policy Protocol by registering various variable policies and exercising them, as well as tests locking the policy, disabling it, and dumping the policy entries. + +Only policies that are created as a part of this test will be tested. +1. Try getting test context, if empty then get VP protocol, confirm that VP is not disabled by calling IsVariablePolicyEnabled. Log VP revision. +2. "No lock" policies: + * check minsize enforcement + * check maxsize enforcement + * check musthave attr enforcement + * check canthave attr enforcement + * check one of the above with empty string policy i.e. name wildcard + * check another one of the above with a "#" containing policy string + * check policy prioritization by having a namespace-wide policy, a policy with a # wildcard, and a one-var specific policy and testing which one is enforced +3. "Lock now" policies (means if the var doesn't exist, it won't be created; if one exists, it can't be updated): + * test a policy for an already existing variable, verify we can't write into that variable + * create a policy for a non-existing variable and attempt to register such var +4. "Lock on create" policies (means the var can still be created, but no updates later, existing vars can't be updated): + * create a var, lock it with LockOnCreate, attempt to update its contents + * create LockOnCreate VP, attempt to create var with invalid size, then invalid attr, then create valid var, attempt to update its contents +5. "Lock on var state" policies (means the var protected by this policy can't be created or updated once the trigger is set) + * create VP, trigger lock with a valid var, attempt to create a locked var, then modify the trigger var, create locked var + * create VP, create targeted var, modify it, trigger lock, attempt to modify var + * create VP, trigger lock with invalid (larger than one byte) var, see if VPE allows creation of the locked var (it should allow) + * create VP, set locking var with wrong value, see if VPE allows creation of the locked var (should allow) +6. Attempt registering invalid policy entries + * invalid required and banned attributes + * large min size - let's say 2GB + * max size equal to 0 + * invalid policy type +7. Exercise dumping policy. No need to check the validity of the dump blob. +8. Test registering a policy with a random version. +9. Lock VPE, make sure old policies are enforced, new ones can't be registered. + * Register a LockOnCreate policy + * Lock VPE + * Test locking it again. + * Verify one of the prior policies is enforced + * Make sure we can create variables even if those are protected by LockOnCreate policy, after locking the VPE + * Attempt to register new policies + * Make sure can't disable VPE + * Cleanup: save context and reboot +10. Disable variable policy and try some things + * Locate Variable Policy Protocol + * Make sure VP is enabled + * Register a policy + * Disable VPE + * Call IsVariablePolicyEnabled to confirm it's disabled. + * Make sure can't lock policy + * Make sure the policy from a is no longer enforced + * Final cleanup: delete vars that were created in some earlier test suites diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf new file mode 100644 index 000000000000..bfbac406b504 --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf @@ -0,0 +1,47 @@ +## @file +# Uefi Shell based Application that unit tests the Variable Policy Protocol +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VariablePolicyFuncTestApp + FILE_GUID = B653C4C3-3FCC-4B6C-8051-5F692AEAECBA + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = UefiMain + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = X64 AARCH64 +# + +[Sources] + VariablePolicyFuncTestApp.c + VariablePolicyTestAuthVar.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + BaseLib + BaseMemoryLib + UnitTestLib + UnitTestBootLib + PrintLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + MemoryAllocationLib + VariablePolicyHelperLib + +[Guids] + gEfiCertPkcs7Guid + +[Protocols] + gEdkiiVariablePolicyProtocolGuid diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h new file mode 100644 index 000000000000..c90310226827 --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h @@ -0,0 +1,128 @@ +/** @file -- VarPolicyTestAuthVar.h +Payload to be used to create an Authenticated Variable for testing. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VAR_POLICY_TEST_AUTH_VAR_H_ +#define _VAR_POLICY_TEST_AUTH_VAR_H_ + +UINT8 mTestAuthVarPayload[] = { + // EFI_VARIABLE_AUTHENTICATION_2 + // Timestamp + 0xE4, 0x07, 0x08, 0x15, 0x0D, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // AuthInfo (WIN_CERTIFICATE_UEFI_GUID) + // Hdr (WIN_CERTIFICATE) + // dwLength + 0x45, 0x05, 0x00, 0x00, + // wRevision + 0x00, 0x02, + // wCertificateType + // (WIN_CERT_TYPE_EFI_GUID) + 0xF1, 0x0E, + // CertType + // (gEfiCertPkcs7Guid) + 0x9D, 0xD2, 0xAF, 0x4A, 0xDF, 0x68, 0xEE, 0x49, 0x8A, 0xA9, 0x34, 0x7D, 0x37, 0x56, 0x65, 0xA7, + // CertData (Packed SignedData Signature) + // Digest Buffer Was... + // Name (DummyAuthVar) + // 44 00 75 00 6D 00 6D 00 79 00 41 00 75 00 74 00 68 00 56 00 61 00 72 00 + // Vendor Guid (mTestAuthNamespaceGuid) + // C6 A2 C5 B6 CE 3E 9B 4B 8C C8 96 D8 D9 CA D3 4E + // Attributes (NV + BS + RT, TimeAuth) + // 27 00 00 00 + // Timestamp + // E4 07 08 15 0D 1E 00 00 00 00 00 00 00 00 00 00 + // Data (0xDEADBEEF) + // EF BE AD DE + 0x30, 0x82, 0x05, 0x29, 0x02, 0x01, 0x01, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x03, 0x82, 0x30, 0x82, 0x03, 0x7E, 0x30, 0x82, 0x02, + 0x66, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x5A, 0xAE, 0x85, 0xA8, 0x61, 0x6E, 0x80, 0xA3, + 0x4D, 0x11, 0x69, 0x06, 0xC3, 0xFE, 0x2D, 0x89, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x3F, 0x31, 0x3D, 0x30, 0x3B, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x1E, 0x34, 0x00, 0x50, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x44, + 0x00, 0x52, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x45, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x65, 0x00, 0x6C, + 0x00, 0x66, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x69, + 0x00, 0x67, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x72, 0x30, 0x20, 0x17, 0x0D, 0x30, 0x30, 0x30, 0x31, + 0x30, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x18, 0x0F, 0x32, 0x39, 0x39, 0x39, 0x31, + 0x32, 0x33, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x3F, 0x31, 0x3D, 0x30, 0x3B, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x1E, 0x34, 0x00, 0x50, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x49, 0x00, + 0x4E, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x45, 0x00, 0x5F, 0x00, 0x53, 0x00, + 0x65, 0x00, 0x6C, 0x00, 0x66, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5F, 0x00, + 0x53, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x72, 0x30, 0x82, 0x01, 0x22, 0x30, + 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xC9, 0xA2, 0x80, 0xE7, + 0x3A, 0x0B, 0x3E, 0xCF, 0xEE, 0x0E, 0x22, 0x65, 0xF5, 0x03, 0xD2, 0x6A, 0x99, 0xBF, 0x5F, 0x48, + 0xF4, 0xC0, 0xD3, 0x19, 0xE7, 0x6B, 0x09, 0xFC, 0x0C, 0xB0, 0x3B, 0x69, 0x3A, 0x07, 0x6F, 0x36, + 0x57, 0xF6, 0x63, 0xAF, 0x6B, 0x7B, 0x30, 0x55, 0xD5, 0xE9, 0xF4, 0xDE, 0x89, 0xE3, 0x5F, 0xA1, + 0x71, 0x13, 0x3E, 0x84, 0x5D, 0x46, 0x9F, 0x78, 0xA9, 0x5B, 0xA5, 0x46, 0x3B, 0x38, 0x4F, 0x00, + 0x06, 0x63, 0x0E, 0x7A, 0x0A, 0x93, 0xE7, 0x36, 0x87, 0xCC, 0x47, 0xBD, 0xFB, 0x0A, 0x5D, 0x45, + 0x9C, 0xC4, 0x1B, 0xE6, 0x9E, 0xCB, 0xAB, 0xF9, 0x20, 0x11, 0xEF, 0x03, 0xCA, 0x9F, 0xE9, 0x29, + 0x1A, 0x05, 0xF8, 0xB3, 0x46, 0xB0, 0x3D, 0xFD, 0x88, 0x7C, 0x82, 0x0E, 0x3C, 0x6F, 0xEA, 0x5B, + 0xFF, 0xA8, 0xA4, 0xE0, 0x40, 0x2B, 0x25, 0xE8, 0x59, 0x46, 0xEE, 0xDB, 0x4B, 0x5F, 0x02, 0xB3, + 0x21, 0x33, 0x47, 0x2E, 0xD5, 0x66, 0x79, 0xF3, 0x79, 0x93, 0x18, 0x75, 0x94, 0x4A, 0x01, 0xCF, + 0x59, 0x86, 0xF4, 0x8B, 0x35, 0xBD, 0xA4, 0x58, 0xA4, 0x76, 0x89, 0x77, 0x55, 0x55, 0xB1, 0xE4, + 0x00, 0x09, 0x78, 0xF3, 0x29, 0x5B, 0xC0, 0xED, 0xD6, 0x68, 0x7E, 0xDB, 0xAA, 0x9F, 0x4E, 0xFE, + 0x67, 0x41, 0x4E, 0x6C, 0xC8, 0xDD, 0x52, 0xD6, 0xA5, 0x8A, 0x8A, 0x56, 0x50, 0x51, 0x27, 0x29, + 0x2B, 0xD3, 0x1B, 0x4D, 0xCE, 0x93, 0x76, 0x8E, 0x55, 0x53, 0x55, 0x30, 0x10, 0xF5, 0xF9, 0x6C, + 0xAE, 0xDA, 0xBA, 0xAC, 0x36, 0x79, 0x11, 0x02, 0xD0, 0x24, 0x07, 0xA6, 0xD1, 0x56, 0xCB, 0xEC, + 0x81, 0x29, 0xA8, 0xC1, 0x2E, 0x9D, 0x9B, 0xF9, 0xE9, 0xF4, 0x55, 0x74, 0xA0, 0x52, 0x87, 0x49, + 0x4F, 0xAC, 0x71, 0xFF, 0x30, 0x12, 0x24, 0xDD, 0x6D, 0x50, 0x5C, 0x7D, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xA3, 0x74, 0x30, 0x72, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1D, 0x01, 0x04, 0x69, 0x30, 0x67, + 0x80, 0x10, 0x0E, 0xB2, 0xFB, 0xDC, 0xD5, 0xAB, 0xCC, 0xB4, 0x3B, 0x46, 0x1B, 0x60, 0x18, 0xFD, + 0xDE, 0x74, 0xA1, 0x41, 0x30, 0x3F, 0x31, 0x3D, 0x30, 0x3B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x1E, + 0x34, 0x00, 0x50, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x44, 0x00, 0x52, 0x00, + 0x4F, 0x00, 0x4D, 0x00, 0x45, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x66, 0x00, + 0x68, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x69, 0x00, 0x67, 0x00, + 0x6E, 0x00, 0x65, 0x00, 0x72, 0x82, 0x10, 0x5A, 0xAE, 0x85, 0xA8, 0x61, 0x6E, 0x80, 0xA3, 0x4D, + 0x11, 0x69, 0x06, 0xC3, 0xFE, 0x2D, 0x89, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xB5, 0xA2, 0xD0, 0x1B, 0x70, + 0x24, 0xC2, 0xE8, 0x64, 0xCD, 0xF1, 0xE9, 0x97, 0x9E, 0xA7, 0xC1, 0x86, 0x92, 0x06, 0x2F, 0x8F, + 0x33, 0x64, 0x0A, 0xB9, 0x2B, 0x77, 0xE2, 0x70, 0x82, 0xDE, 0x06, 0xD3, 0x69, 0x8E, 0xB4, 0x69, + 0xF1, 0x6B, 0x59, 0x5E, 0x68, 0x5F, 0xB4, 0xFA, 0x30, 0xC3, 0xB6, 0xA1, 0x72, 0x1A, 0xD4, 0x01, + 0xED, 0x69, 0x4A, 0x96, 0x0F, 0x1C, 0xC3, 0x6F, 0x80, 0x0B, 0xE5, 0xD4, 0x46, 0xBE, 0x27, 0x9D, + 0xDE, 0x68, 0xB3, 0xA1, 0x93, 0xC3, 0x1A, 0x47, 0x20, 0x7A, 0x87, 0x80, 0x13, 0x85, 0x1E, 0x46, + 0x01, 0x42, 0x6A, 0x68, 0x46, 0xE2, 0x77, 0x3D, 0x2E, 0x50, 0xA1, 0x96, 0x23, 0x83, 0x03, 0xD1, + 0x57, 0xDD, 0xC6, 0x63, 0x59, 0xB7, 0x1A, 0x49, 0xA2, 0xC9, 0x44, 0x8D, 0xC7, 0x81, 0x18, 0xE8, + 0x52, 0x3A, 0x74, 0x32, 0xD3, 0xE6, 0x6D, 0x54, 0x9F, 0xC9, 0x87, 0x1C, 0xBC, 0x81, 0xEB, 0x6D, + 0x5D, 0x58, 0xF7, 0x91, 0x81, 0x5B, 0xB0, 0x86, 0xB4, 0x06, 0xE7, 0x19, 0x44, 0xE9, 0x24, 0x28, + 0xF5, 0x42, 0x7A, 0x7A, 0x28, 0x94, 0x3E, 0x70, 0x61, 0x1B, 0x68, 0x8D, 0xA9, 0x48, 0x3A, 0xFE, + 0x7D, 0xB5, 0x29, 0x10, 0xCE, 0xD6, 0xC1, 0xFF, 0x16, 0xDF, 0x90, 0x94, 0x16, 0xC8, 0xFA, 0x9E, + 0x52, 0x49, 0xE5, 0xC3, 0xF5, 0x8C, 0x87, 0xC2, 0x93, 0x3D, 0x3D, 0x27, 0x23, 0x37, 0xC3, 0xDA, + 0x55, 0x92, 0x12, 0xE9, 0x1F, 0xEB, 0x32, 0xB5, 0xD8, 0x30, 0xD6, 0xC0, 0x23, 0x45, 0xBB, 0x06, + 0xBC, 0x11, 0xA6, 0xA3, 0x47, 0x82, 0x04, 0xCB, 0xAA, 0x98, 0xCA, 0xF9, 0x00, 0x0E, 0xD3, 0xC3, + 0x09, 0xF6, 0x21, 0x4C, 0x90, 0xE0, 0x78, 0x08, 0xAE, 0x8F, 0xB1, 0x7D, 0x62, 0x3F, 0x6A, 0x1E, + 0xD6, 0xF1, 0x8E, 0xEE, 0xFD, 0x49, 0x04, 0xDE, 0x14, 0x9C, 0x7B, 0x31, 0x82, 0x01, 0x7E, 0x30, + 0x82, 0x01, 0x7A, 0x02, 0x01, 0x01, 0x30, 0x53, 0x30, 0x3F, 0x31, 0x3D, 0x30, 0x3B, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x1E, 0x34, 0x00, 0x50, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x49, 0x00, 0x4E, 0x00, + 0x44, 0x00, 0x52, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x45, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x65, 0x00, + 0x6C, 0x00, 0x66, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5F, 0x00, 0x53, 0x00, + 0x69, 0x00, 0x67, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x72, 0x02, 0x10, 0x5A, 0xAE, 0x85, 0xA8, 0x61, + 0x6E, 0x80, 0xA3, 0x4D, 0x11, 0x69, 0x06, 0xC3, 0xFE, 0x2D, 0x89, 0x30, 0x0D, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xA6, 0x06, 0xE7, + 0x46, 0x7E, 0xFB, 0x4A, 0xA7, 0x25, 0x2F, 0x52, 0x1D, 0xBC, 0x5C, 0x41, 0x3B, 0xD3, 0x13, 0x50, + 0xCE, 0x5F, 0xE2, 0x4B, 0x31, 0xED, 0x28, 0x5E, 0xF5, 0x36, 0xBD, 0x1C, 0x38, 0xA1, 0xB6, 0x45, + 0x7C, 0xFD, 0xAB, 0x7B, 0x0C, 0xBF, 0x06, 0x06, 0xBB, 0x95, 0x5E, 0x47, 0x10, 0x7C, 0xD8, 0x10, + 0x76, 0x74, 0x81, 0x2D, 0x40, 0x3A, 0xD0, 0xF4, 0x15, 0x9D, 0xDF, 0x44, 0x2B, 0xA4, 0xCD, 0xF7, + 0x44, 0x77, 0x9F, 0x35, 0x46, 0xD3, 0x30, 0x67, 0x44, 0x33, 0xF4, 0x7B, 0xB6, 0xC0, 0xE4, 0xA2, + 0xAD, 0xDF, 0xAF, 0x56, 0x41, 0xA3, 0x0D, 0x76, 0x36, 0xB9, 0x7E, 0x29, 0x49, 0x17, 0x43, 0xAF, + 0xB0, 0xA0, 0xC0, 0xF1, 0xE1, 0xE6, 0xCA, 0x62, 0x9F, 0x3E, 0x9D, 0x6C, 0x63, 0x03, 0xF6, 0xDF, + 0x84, 0x32, 0xB1, 0x01, 0x0C, 0x12, 0x83, 0x52, 0x13, 0x2F, 0xAE, 0xBC, 0x79, 0xB7, 0x75, 0xF6, + 0x10, 0x20, 0xFC, 0x7A, 0x13, 0x92, 0xF7, 0x87, 0x50, 0xF5, 0x9C, 0xD9, 0xE4, 0xEA, 0x4C, 0x3D, + 0x31, 0xED, 0x7F, 0xA6, 0x6C, 0x58, 0xAD, 0x6C, 0x31, 0xAF, 0xC4, 0x64, 0xAE, 0x11, 0xBF, 0x72, + 0xF5, 0xAA, 0x69, 0xB4, 0x76, 0xDB, 0x73, 0x8F, 0x8C, 0x3E, 0x23, 0x4A, 0x2D, 0xB7, 0x65, 0x65, + 0x10, 0xA8, 0xC6, 0x52, 0x14, 0xE2, 0xC6, 0x2B, 0x07, 0xCE, 0x45, 0x58, 0x6F, 0x92, 0x78, 0xAA, + 0xB5, 0xE9, 0x76, 0x39, 0x8A, 0x17, 0xE3, 0x0B, 0xA5, 0x12, 0x0F, 0x2A, 0xC1, 0xCE, 0xC5, 0x4F, + 0xD8, 0xA7, 0xD1, 0x7C, 0x3F, 0xE3, 0x23, 0x9B, 0x53, 0x56, 0x18, 0x28, 0x66, 0xC7, 0xB3, 0x04, + 0x38, 0xE3, 0x40, 0xCC, 0xB2, 0x18, 0xA8, 0xC7, 0x11, 0xE1, 0x67, 0xD8, 0xBF, 0xBE, 0x8D, 0x2A, + 0x75, 0x00, 0x96, 0x8F, 0x7F, 0x80, 0xCF, 0xDB, 0xF0, 0x0D, 0xB5, 0x8D, 0x73, + // Data + 0xEF, 0xBE, 0xAD, 0xDE +}; +UINTN mTestAuthVarPayloadSize = sizeof(mTestAuthVarPayload); + +#endif // _VAR_POLICY_TEST_AUTH_VAR_H_ -- 2.28.0.windows.1 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v7 00/14] Add the VariablePolicy feature @ 2020-08-28 5:51 Bret Barkelew 2020-08-28 5:51 ` [PATCH v7 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy Bret Barkelew 0 siblings, 1 reply; 3+ messages in thread From: Bret Barkelew @ 2020-08-28 5:51 UTC (permalink / raw) To: devel Cc: Jiewen Yao, Chao Zhang, Jian J Wang, Hao A Wu, Liming Gao, Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Andrew Fish, Ray Ni The 14 patches in this series add the VariablePolicy feature to the core, deprecate Edk2VarLock (while adding a compatibility layer to reduce code churn), and integrate the VariablePolicy libraries and protocols into Variable Services. Since the integration requires multiple changes, including adding libraries, a protocol, an SMI communication handler, and VariableServices integration, the patches are broken up by individual library additions and then a final integration. Security-sensitive changes like bypassing Authenticated Variable enforcement are also broken out into individual patches so that attention can be called directly to them. Platform porting instructions are described in this wiki entry: https://github.com/tianocore/tianocore.github.io/wiki/VariablePolicy-Protocol---Enhanced-Method-for-Managing-Variables#platform-porting Discussion of the feature can be found in multiple places throughout the last year on the RFC channel, staging branches, and in devel. Most recently, this subject was discussed in this thread: https://edk2.groups.io/g/devel/message/53712 (the code branches shared in that discussion are now out of date, but the whitepapers and discussion are relevant). Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Chao Zhang <chao.b.zhang@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com> Cc: Andrew Fish <afish@apple.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Bret Barkelew <brbarkel@microsoft.com> Signed-off-by: Bret Barkelew <brbarkel@microsoft.com> v7 changes: * Address comments from Dandan about security of the MM handler * Add readme * Fix bug around hex characters in BOOT####, etc * Add additional testing for hex characters * Add additional testing for authenticated variables v6 changes: * Fix an issue with uninitialized Status in InitVariablePolicyLib() and DeinitVariablePolicyLib() * Fix GCC building in shell-based functional test * Rebase on latest origin/master v5 changes: * Fix the CONST mismatch in VariablePolicy.h and VariablePolicySmmDxe.c * Fix EFIAPI mismatches in the functional unittest * Rebase on latest origin/master v4 changes: * Remove Optional PcdAllowVariablePolicyEnforcementDisable PCD from platforms * Rebase on master * Migrate to new MmCommunicate2 protocol * Fix an oversight in the default return value for InitMmCommonCommBuffer * Fix in VariablePolicyLib to allow ExtraInitRuntimeDxe to consume variables V3 changes: * Address all non-unittest issues with ECC * Make additional style changes * Include section name in hunk headers in "ini-style" files * Remove requirement for the EdkiiPiSmmCommunicationsRegionTable driver (now allocates its own buffer) * Change names from VARIABLE_POLICY_PROTOCOL and gVariablePolicyProtocolGuid to EDKII_VARIABLE_POLICY_PROTOCOL and gEdkiiVariablePolicyProtocolGuid * Fix GCC warning about initializing externs * Add UNI strings for new PCD * Add patches for ArmVirtPkg, OvmfXen, and UefiPayloadPkg * Reorder patches according to Liming's feedback about adding to platforms before changing variable driver V2 changes: * Fixed implementation for RuntimeDxe * Add PCD to block DisableVariablePolicy * Fix the DumpVariablePolicy pagination in SMM Bret Barkelew (14): MdeModulePkg: Define the VariablePolicy protocol interface MdeModulePkg: Define the VariablePolicyLib MdeModulePkg: Define the VariablePolicyHelperLib MdeModulePkg: Define the VarCheckPolicyLib and SMM interface OvmfPkg: Add VariablePolicy engine to OvmfPkg platform EmulatorPkg: Add VariablePolicy engine to EmulatorPkg platform ArmVirtPkg: Add VariablePolicy engine to ArmVirtPkg platform UefiPayloadPkg: Add VariablePolicy engine to UefiPayloadPkg platform MdeModulePkg: Connect VariablePolicy business logic to VariableServices MdeModulePkg: Allow VariablePolicy state to delete protected variables SecurityPkg: Allow VariablePolicy state to delete authenticated variables MdeModulePkg: Change TCG MOR variables to use VariablePolicy MdeModulePkg: Drop VarLock from RuntimeDxe variable driver MdeModulePkg: Add a shell-based functional test for VariablePolicy MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c | 345 +++ MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c | 396 ++++ MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c | 46 + MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c | 85 + MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c | 830 +++++++ MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.c | 2452 ++++++++++++++++++++ MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c | 2226 ++++++++++++++++++ MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c | 52 +- MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c | 60 +- MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c | 49 +- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c | 53 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock.c | 71 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c | 642 +++++ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c | 14 + SecurityPkg/Library/AuthVariableLib/AuthService.c | 22 +- ArmVirtPkg/ArmVirt.dsc.inc | 4 + EmulatorPkg/EmulatorPkg.dsc | 3 + MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h | 54 + MdeModulePkg/Include/Library/VariablePolicyHelperLib.h | 164 ++ MdeModulePkg/Include/Library/VariablePolicyLib.h | 207 ++ MdeModulePkg/Include/Protocol/VariablePolicy.h | 157 ++ MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf | 42 + MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni | 12 + MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf | 35 + MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.uni | 12 + MdeModulePkg/Library/VariablePolicyLib/ReadMe.md | 410 ++++ MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf | 49 + MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni | 12 + MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf | 51 + MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.inf | 45 + MdeModulePkg/MdeModulePkg.ci.yaml | 8 +- MdeModulePkg/MdeModulePkg.dec | 26 +- MdeModulePkg/MdeModulePkg.dsc | 9 + MdeModulePkg/MdeModulePkg.uni | 7 + MdeModulePkg/Test/MdeModulePkgHostTest.dsc | 11 + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md | 55 + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf | 47 + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h | 128 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf | 5 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf | 4 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf | 11 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf | 4 + OvmfPkg/OvmfPkgIa32.dsc | 5 + OvmfPkg/OvmfPkgIa32X64.dsc | 5 + OvmfPkg/OvmfPkgX64.dsc | 5 + OvmfPkg/OvmfXen.dsc | 4 + SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf | 2 + UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 4 + UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 4 + 49 files changed, 8865 insertions(+), 79 deletions(-) create mode 100644 MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c create mode 100644 MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c create mode 100644 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c create mode 100644 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c create mode 100644 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c create mode 100644 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.c create mode 100644 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock.c create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c create mode 100644 MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h create mode 100644 MdeModulePkg/Include/Library/VariablePolicyHelperLib.h create mode 100644 MdeModulePkg/Include/Library/VariablePolicyLib.h create mode 100644 MdeModulePkg/Include/Protocol/VariablePolicy.h create mode 100644 MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf create mode 100644 MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni create mode 100644 MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf create mode 100644 MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.uni create mode 100644 MdeModulePkg/Library/VariablePolicyLib/ReadMe.md create mode 100644 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf create mode 100644 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni create mode 100644 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf create mode 100644 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.inf create mode 100644 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md create mode 100644 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf create mode 100644 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h -- 2.28.0.windows.1 ^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v7 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy 2020-08-28 5:51 [PATCH v7 00/14] Add the VariablePolicy feature Bret Barkelew @ 2020-08-28 5:51 ` Bret Barkelew 0 siblings, 0 replies; 3+ messages in thread From: Bret Barkelew @ 2020-08-28 5:51 UTC (permalink / raw) To: devel; +Cc: Jian J Wang, Hao A Wu, Liming Gao https://bugzilla.tianocore.org/show_bug.cgi?id=2522 To verify that VariablePolicy is correctly integrated on platforms, add a Shell-based functional test to confirm expected behavior. NOTE: This test assumes that VariablePolicy is built with PcdAllowVariablePolicyEnforcementDisable set to TRUE. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Bret Barkelew <brbarkel@microsoft.com> Signed-off-by: Bret Barkelew <brbarkel@microsoft.com> --- MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c | 2226 ++++++++++++++++++++ MdeModulePkg/MdeModulePkg.ci.yaml | 4 +- MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md | 55 + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf | 47 + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h | 128 ++ 5 files changed, 2459 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c new file mode 100644 index 000000000000..c2b28e4b642b --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c @@ -0,0 +1,2226 @@ +/** @file +UEFI Shell based application for unit testing the Variable Policy Protocol. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <Library/UefiLib.h> +#include <Library/PrintLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/UnitTestLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Protocol/VariablePolicy.h> +#include <Library/VariablePolicyHelperLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> + +#include "VariablePolicyTestAuthVar.h" + +// TODO: Need to add to the UnitTestFrameworkPkg +// #include <Library/UnitTestBootLib.h> + +#define UNIT_TEST_APP_NAME "Variable Policy Unit Test Application" +#define UNIT_TEST_APP_VERSION "0.1" + +// TODO: Need to add to the UnitTestFrameworkPkg +UNIT_TEST_FRAMEWORK_HANDLE +GetActiveFrameworkHandle ( + VOID + ); + +EDKII_VARIABLE_POLICY_PROTOCOL *mVarPol = NULL; + + +EFI_GUID mTestNamespaceGuid1 = { 0x3b389299, 0xabaf, 0x433b, { 0xa4, 0xa9, 0x23, 0xc8, 0x44, 0x02, 0xfc, 0xad } }; +EFI_GUID mTestNamespaceGuid2 = { 0x4c49a3aa, 0xbcb0, 0x544c, { 0xb5, 0xba, 0x34, 0xd9, 0x55, 0x13, 0x0d, 0xbe } }; +EFI_GUID mTestNamespaceGuid3 = { 0x5d5ab4bb, 0xcdc1, 0x655d, { 0xc6, 0xcb, 0x45, 0xea, 0x66, 0x24, 0x1e, 0xcf } }; + +#define TEST_AUTH_VAR_NAME L"DummyAuthVar" +EFI_GUID mTestAuthNamespaceGuid = { 0xb6c5a2c6, 0x3ece, 0x4b9b, { 0x8c, 0xc8, 0x96, 0xd8, 0xd9, 0xca, 0xd3, 0x4e } }; + +/** + Prerequisite for most test cases. +**/ +UNIT_TEST_STATUS +EFIAPI +LocateVarPolicyPreReq ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + if (mVarPol == NULL) { + Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, + NULL, + (VOID **) &mVarPol); + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_NOT_NULL (mVarPol); + } + + return UNIT_TEST_PASSED; +} // LocateVarPolicyPreReq + +UNIT_TEST_STATUS +EFIAPI +VarPolicyEnabledPreReq ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + + UT_ASSERT_EQUAL(LocateVarPolicyPreReq(Context), UNIT_TEST_PASSED); + Status = mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR(Status); + UT_ASSERT_TRUE(State); + + return UNIT_TEST_PASSED; +} + +UNIT_TEST_STATUS +EFIAPI +VarPolicyDisabledPreReq ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + + UT_ASSERT_EQUAL(LocateVarPolicyPreReq(Context), UNIT_TEST_PASSED); + Status = mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR(Status); + UT_ASSERT_FALSE(State); + + return UNIT_TEST_PASSED; +} + +/** + Getting Started tests. +**/ +UNIT_TEST_STATUS +EFIAPI +CheckVpEnabled ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + + Status = mVarPol->IsVariablePolicyEnabled (&State); + + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_EQUAL (State, TRUE); + + return UNIT_TEST_PASSED; +} // CheckVpEnabled + +UNIT_TEST_STATUS +EFIAPI +CheckVpRevision ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UT_ASSERT_NOT_EQUAL (mVarPol->Revision, 0); + UT_LOG_INFO ("VP Revision: 0x%x\n", mVarPol->Revision); + + return UNIT_TEST_PASSED; +} // CheckVpRevision + +/** + NOTE: Copied from SecureBootConfigImpl.c, then modified. + + Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2 + descriptor with the input data. NO authentication is required in this function. + + @param[in, out] DataSize On input, the size of Data buffer in bytes. + On output, the size of data returned in Data + buffer in bytes. + @param[in, out] Data On input, Pointer to data buffer to be wrapped or + pointer to NULL to wrap an empty payload. + On output, Pointer to the new payload date buffer allocated from pool, + it's caller's responsibility to free the memory when finish using it. + @param[in] Time [Optional] If provided, will be used as the timestamp for the payload. + If NULL, a new timestamp will be generated using GetTime(). + + @retval EFI_SUCCESS Create time based payload successfully. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources to create time based payload. + @retval EFI_INVALID_PARAMETER The parameter is invalid. + @retval Others Unexpected error happens. + +**/ +STATIC +EFI_STATUS +CreateEmptyTimeBasedPayload ( + IN OUT UINTN *DataSize, + IN OUT UINT8 **Data, + IN EFI_TIME *Time OPTIONAL + ) +{ + UINT8 *NewData; + UINT8 *Payload; + UINTN PayloadSize; + EFI_VARIABLE_AUTHENTICATION_2 *DescriptorData; + UINTN DescriptorSize; + EFI_TIME NewTime; + + if (Data == NULL || DataSize == NULL) { + DEBUG((DEBUG_ERROR, "CreateEmptyTimeBasedPayload(), invalid arg\n")); + return EFI_INVALID_PARAMETER; + } + + // + // In Setup mode or Custom mode, the variable does not need to be signed but the + // parameters to the SetVariable() call still need to be prepared as authenticated + // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate + // data in it. + // + Payload = *Data; + PayloadSize = *DataSize; + + DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); + NewData = (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize); + if (NewData == NULL) { + DEBUG((DEBUG_ERROR, "CreateEmptyTimeBasedPayload() Out of resources.\n")); + return EFI_OUT_OF_RESOURCES; + } + + if ((Payload != NULL) && (PayloadSize != 0)) { + CopyMem (NewData + DescriptorSize, Payload, PayloadSize); + } + + DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData); + + // + // Use or create the timestamp. + // + // If Time is NULL, create a new timestamp. + if (Time == NULL) + { + NewTime.Year = 9999; + NewTime.Month = 12; + NewTime.Day = 31; + NewTime.Hour = 23; + NewTime.Minute = 59; + NewTime.Second = 59; + NewTime.Pad1 = 0; + NewTime.Nanosecond = 0; + NewTime.TimeZone = 0; + NewTime.Daylight = 0; + NewTime.Pad2 = 0; + Time = &NewTime; // Use the new timestamp. + } + CopyMem (&DescriptorData->TimeStamp, Time, sizeof (EFI_TIME)); + + DescriptorData->AuthInfo.Hdr.dwLength = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); + DescriptorData->AuthInfo.Hdr.wRevision = 0x0200; + DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; + CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid); + + if (Payload != NULL) { + FreePool(Payload); + } + + *DataSize = DescriptorSize + PayloadSize; + *Data = NewData; + return EFI_SUCCESS; +} + +/** + NoLock Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestMinSizeNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINT8 *Buffer; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MinSizeNoLockVar", + 4, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that is smaller than minsize + // + Value1 = 0x12; + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value1), + &Value1); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Try to write a var of size that matches minsize + // + Value2 = 0xa1b2c3d4; + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size larger than minsize + // + Buffer = AllocateZeroPool (40); + UT_ASSERT_NOT_NULL (Buffer); + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + 40, + Buffer); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Delete the variable + // + Status = gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + FreePool (Buffer); + + return UNIT_TEST_PASSED; +} // TestMinSizeNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMaxSizeNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINT8 *Buffer; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MaxSizeNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 4, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that is smaller than maxsize + // + Value1 = 0x34; + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value1), + &Value1); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size that matches maxsize + // + Value2 = 0xa1b2c3d4; + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size larger than maxsize + // + Buffer = AllocateZeroPool (40); + UT_ASSERT_NOT_NULL (Buffer); + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + 40, + Buffer); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + FreePool (Buffer); + + return UNIT_TEST_PASSED; +} // TestMaxSizeNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMustHaveAttrNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MustHaveAttrNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that doesn't have the must-have attributes + // + Value = 0x56; + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Try to write a var that has exactly the required attributes + // + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting + // + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that has the required attributes and one extra attribute + // + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting + // + Status = gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + return UNIT_TEST_PASSED; +} // TestMustHaveAttrNoLock + +UNIT_TEST_STATUS +EFIAPI +TestCantHaveAttrNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"CantHaveAttrNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_NON_VOLATILE, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that has a can't have attr + // + Value = 0x78; + Status = gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Try to write a var that satisfies the can't have requirement + // + Status = gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestCantHaveAttrNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMaxSizeNamespaceNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINT8 *Buffer; + + // + // Register a namespace-wide policy limiting max size to 4 bytes + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid2, + NULL, + VARIABLE_POLICY_NO_MIN_SIZE, + 4, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that is smaller than maxsize + // + Value1 = 0x34; + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value1), + &Value1); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size that matches maxsize + // + Value2 = 0xa1b2c3d4; + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size larger than maxsize + // + Buffer = AllocateZeroPool (40); + UT_ASSERT_NOT_NULL (Buffer); + Status = gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + 40, + Buffer); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + FreePool (Buffer); + + return UNIT_TEST_PASSED; +} // TestMaxSizeNamespaceNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMustHaveAttrWildcardNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MustHaveAttrWildcardNoLockVar####", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that doesn't have the must-have attributes + // + Value = 0x56; + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1573", + &mTestNamespaceGuid1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Try to write a var that has exactly the required attributes + // + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1234", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting + // + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1234", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that has the required attributes and one extra attribute + // + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar5612", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting + // + Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar5612", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestMustHaveAttrWildcardNoLock + +UNIT_TEST_STATUS +EFIAPI +TestPolicyprioritizationNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value8; + UINT16 Value16; + UINT32 Value32; + UINT64 Value64; + + // + // Register a policy targeting the specific var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid3, + L"PolicyPriorityTestVar123", + 8, // min size of UINT64 + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a policy with wildcards in the name + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid3, + L"PolicyPriorityTestVar###", + 4, // min size of UINT32 + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a policy with wildcards in the name + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid3, + NULL, + 2, // min size of UINT16 + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // The idea is that the most specific policy is applied: + // For varname "TestVar", the namespace-wide one should apply: UINT16 minimum + // For varname "PolicyPriorityTestVar567" the wildcard policy should apply: UINT32 minimum + // For varname "PolicyPriorityTestVar123" the var-specific policy should apply: UINT64 minimum + // + + // + // Let's confirm the namespace-wide policy enforcement + // + Value8 = 0x78; + Status = gRT->SetVariable (L"TestVar", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value8), + &Value8); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + Value16 = 0x6543; + Status = gRT->SetVariable (L"TestVar", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value16), + &Value16); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's confirm the wildcard policy enforcement + // + Value16 = 0xabba; + Status = gRT->SetVariable (L"PolicyPriorityTestVar567", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value16), + &Value16); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + Value32 = 0xfedcba98; + Status = gRT->SetVariable (L"PolicyPriorityTestVar567", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value32), + &Value32); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's confirm the var-specific policy enforcement + // + Value32 = 0x8d3f627c; + Status = gRT->SetVariable (L"PolicyPriorityTestVar123", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value32), + &Value32); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + Value64 = 0xbebecdcdafaf6767; + Status = gRT->SetVariable (L"PolicyPriorityTestVar123", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value64), + &Value64); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestPolicyprioritizationNoLock + +/** + LockNow Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestExistingVarLockNow ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // Write a var that we'll protect next + // + Value = 0x78; + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a LockNow policy targeting the var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ExistingLockNowVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to modify the locked var + // + Value = 0xA5; + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Attempt to delete the locked var + // + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // This variable is deleted in final cleanup. + // + + return UNIT_TEST_PASSED; +} // TestExistingVarLockNow + +UNIT_TEST_STATUS +EFIAPI +TestNonexistentVarLockNow ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + UINTN Size; + + // + // Make sure the variable we're about to create the policy for doesn't exist + // + Size = 0; + Status = gRT->GetVariable (L"NonexistentLockNowVar", + &mTestNamespaceGuid1, + NULL, + &Size, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); + + // + // Register a LockNow policy targeting the var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"NonexistentLockNowVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to create the locked var + // + Value = 0xA5; + Status = gRT->SetVariable (L"NonexistentLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + return UNIT_TEST_PASSED; +} // TestNonexistentVarLockNow + +/** + LockOnCreate Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestExistingVarLockOnCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // Write a var that we'll protect later + // + Value = 0x78; + Status = gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a LockNow policy targeting the var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ExistingLockOnCreateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_ON_CREATE); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to modify the locked var + // + Value = 0xA5; + Status = gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Attempt to delete the locked var + // + Status = gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // This variable is deleted in final cleanup. + // + + return UNIT_TEST_PASSED; +} // TestExistingVarLockOnCreate + +UNIT_TEST_STATUS +EFIAPI +TestNonexistentVarLockOnCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINTN Size; + + // + // Make sure the variable we're about to create the policy for doesn't exist + // + Size = 0; + Status = gRT->GetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + NULL, + &Size, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); + + // + // Register a LockOnCreate policy targeting the var + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"NonexistentLockOnCreateVar", + 2, // min size of 2 bytes, UINT16+ + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_RUNTIME_ACCESS, // must have RT attr + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_ON_CREATE); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to create the var, but smaller than min size + // + Value1 = 0xA5; + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value1), + &Value1); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Now let's make sure attribute req is enforced + // + Value2 = 0x43218765; + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value2), + &Value2); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Now let's create a valid variable + // + Value2 = 0x43218765; + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's make sure we can't modify it + // + Value2 = 0xa5a5b6b6; + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value2), + &Value2); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Finally, let's make sure we can't delete it + // + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // This variable is deleted in final cleanup. + // + + return UNIT_TEST_PASSED; +} // TestNonexistentVarLockOnCreate + +/** + LockOnVarState Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateBeforeCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINTN Size; + UINT8 Value; + + // + // First of all, let's make sure the var we're trying to protect doesn't exist + // + Size = 0; + Status = gRT->GetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + NULL, + &Size, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); + + // + // Good, now let's create a policy + // + Status = RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"NonexistentLockOnVarStateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger1", + 0x7E); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now we write the trigger var + // + Value = 0x7E; + Status = gRT->SetVariable (L"Trigger1", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Ok, now we attempt to write a var protected by the trigger + // + Value = 0xFA; + Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Let's modify the trigger var and "untrigger" the policy + // + Value = 0x38; + Status = gRT->SetVariable (L"Trigger1", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now we should be able to create the var targeted by the policy + // + Value = 0x23; + Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Cleanup: delete the trigger and the protected var + // + Status = gRT->SetVariable (L"Trigger1", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateBeforeCreate + +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateAfterCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // Let's create a policy + // + Status = RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ExistingLockOnVarStateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger2", + 0x5C); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to write targeted var since the policy isn't active yet. + // + Value = 0x17; + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's modify the var to make sure the policy isn't acting like a lock-on-create one + // + Value = 0x30; + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now we trigger the policy + // + Value = 0x5C; + Status = gRT->SetVariable (L"Trigger2", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's now verify the variable is protected + // + Value = 0xB9; + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Ok, to clean up, we need to remove the trigger var, so delete it, and then delete the target var + // + Status = gRT->SetVariable (L"Trigger2", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateAfterCreate + +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateInvalidLargeTrigger ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT16 Value; + + // + // First let's create a variable policy + // + Status = RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidLargeTriggerLockOnVarStateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger3", + 0x5C); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now attempt to trigger the lock but with a variable larger than one byte + // + Value = 0x8085; + Status = gRT->SetVariable (L"Trigger3", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should still be able to create the targeted var + // + Value = 0x1234; + Status = gRT->SetVariable (L"InvalidLargeTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's clean up by deleting the invalid trigger and the targeted var + // + Status = gRT->SetVariable (L"Trigger3", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status = gRT->SetVariable (L"InvalidLargeTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateInvalidLargeTrigger + +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateWrongValueTrigger ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // First let's create a variable policy + // + Status = RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"WrongValueTriggerLockOnVarStateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger4", + 0xCA); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now attempt to trigger the lock but with a wrong value + // + Value = 0x80; + Status = gRT->SetVariable (L"Trigger4", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should still be able to create the targeted var + // + Value = 0x14; + Status = gRT->SetVariable (L"WrongValueTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's clean up by deleting the invalid trigger and the targeted var + // + Status = gRT->SetVariable (L"Trigger4", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status = gRT->SetVariable (L"WrongValueTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateWrongValueTrigger + +/** + Invalid policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestInvalidAttributesPolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // The only must/can't have attributes supported by VPE are NV, BS, and RT. They are 1, 2, and 4, respectively. + // Let's try some bits higher than that? + // + + // + // Trying must have attribute 0x8 which is EFI_VARIABLE_HARDWARE_ERROR_RECORD + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyVar1", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_HARDWARE_ERROR_RECORD, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_HARDWARE_ERROR_RECORD returned %r\n", Status); + + // + // Let's try 0x10 - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, a deprecated attribute + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyVar2", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status); + + // + // Let's try 0x20 - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyVar3", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status); + + // + // Let's try something wild, like 0x4000 + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyVar4", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + 0x4000, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to 0x4000 returned %r\n", Status); + + // + // Now repeat the same tests, but for the can't-have param + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyVar1", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_HARDWARE_ERROR_RECORD, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_HARDWARE_ERROR_RECORD returned %r\n", Status); + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyVar2", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status); + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyVar3", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status); + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyVar4", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + 0x4000, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to 0x4000 returned %r\n", Status); + + return UNIT_TEST_PASSED; +} // TestInvalidAttributesPolicy + +UNIT_TEST_STATUS +EFIAPI +TestLargeMinSizePolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Let's set the min size to 2GB and see what happens + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"LargeMinSizeInvalidPolicyVar", + 0x80000000, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + + UT_LOG_INFO ("Setting min size to 0x80000000 returned %r\n", Status); + + return UNIT_TEST_PASSED; +} // TestLargeMinSizePolicy + +UNIT_TEST_STATUS +EFIAPI +TestZeroMaxSizePolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Let's set the max size to 0 and see what happens + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ZeroMinSizeInvalidPolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 0, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + //UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); // this fails on QC. Real bug? Do we care? + UT_LOG_INFO ("Setting max size to 0 returned %r\n", Status); + + return UNIT_TEST_PASSED; +} // TestZeroMaxSizePolicy + +UNIT_TEST_STATUS +EFIAPI +TestInvalidPolicyTypePolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Let's set policy type to an invalid value and see what happens + // Valid ones are: + // VARIABLE_POLICY_TYPE_NO_LOCK 0 + // VARIABLE_POLICY_TYPE_LOCK_NOW 1 + // VARIABLE_POLICY_TYPE_LOCK_ON_CREATE 2 + // VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE 3 + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidPolicyTypePolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + 4); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidPolicyTypePolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + 147); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + return UNIT_TEST_PASSED; +} // TestInvalidPolicyTypePolicy + +/** + Test dumping policy. +**/ +UNIT_TEST_STATUS +EFIAPI +TestDumpPolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8* Buffer; + UINT32 Size; + + // + // First let's call DumpVariablePolicy with null buffer to get size + // + Size = 0; + Status = mVarPol->DumpVariablePolicy (NULL, &Size); + UT_ASSERT_STATUS_EQUAL (Status, EFI_BUFFER_TOO_SMALL); + + // + // Now we allocate the buffer for the dump + // + Buffer = NULL; + Buffer = AllocatePool (Size); + UT_ASSERT_NOT_NULL (Buffer); + + // + // Now we get the dump. In this test we will not analyze the dump. + // + Status = mVarPol->DumpVariablePolicy (Buffer, &Size); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestDumpPolicy + +/** + Test policy version. +**/ +UNIT_TEST_STATUS +EFIAPI +TestPolicyVersion ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewEntry; + + // + // Create the new entry using a helper lib + // + NewEntry = NULL; + Status = CreateBasicVariablePolicy (&mTestNamespaceGuid1, + L"PolicyVersionTestNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 4, // max size of 4 bytes + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK, + &NewEntry); + UT_ASSERT_NOT_EFI_ERROR (Status); + + NewEntry->Version = 0x1234; + Status = mVarPol->RegisterVariablePolicy (NewEntry); + UT_LOG_INFO ("Registering policy entry with an unknown version status: %r\n", Status); + + FreePool (NewEntry); + + return UNIT_TEST_PASSED; +} // TestPolicyVersion + +/** + Lock Policy Tests. +**/ +UNIT_TEST_STATUS +EFIAPI +LockPolicyEngineTests ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT16 Value; + UINT64 Value64; + BOOLEAN State; + + // + // First let's register a policy that we'll test after VPE lock + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"BeforeVpeLockNoLockPolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 4, // max size of 4 bytes + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_ON_CREATE); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now, lock VPE! + // + Status = mVarPol->LockVariablePolicy (); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // See if we can lock it again? + // + Status = mVarPol->LockVariablePolicy (); + UT_LOG_INFO ("Locking VPE for second time returned %r\n", Status); + + // + // Let's confirm one of the policies from prior test suites is still enforced + // Attempt to delete a locked var + // + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // We'll make sure the policy from earlier in this test case is actively filtering out by size + // + Value64 = 0x3829fed212345678; + Status = gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value64), + &Value64); + UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER)); + + // + // Let's create the variable from the policy now + // + Value = 0x323f; + Status = gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now confirm that the var is locked after creation + // + Value = 0x1212; + Status = gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Let's attempt to register a new policy, it should fail + // + Status = RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"AfterVpeLockNowPolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + // + // Make sure VPE is enabled + // + Status = mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_EQUAL (State, TRUE); + + // + // Finally, make sure we can't disable VPE + // + Status = mVarPol->DisableVariablePolicy (); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + return UNIT_TEST_PASSED; +} // LockPolicyEngineTests + +/** + Save context and reboot after the lock policy test suite. +**/ +STATIC +VOID +EFIAPI +SaveStateAndReboot ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Now, save all the data associated with this framework. + // TODO: Need to add to the UnitTestFrameworkPkg + Status = SaveFrameworkState( NULL, 0 ); + + // + // If we're all good, let's book... + if (!EFI_ERROR( Status )) + { + // + // Next, we want to update the BootNext variable to USB + // so that we have a fighting chance of coming back here. + // + // TODO: Need to add to the UnitTestFrameworkPkg + // SetBootNextDevice(); + + // + // Reset + DEBUG(( DEBUG_INFO, "%a - Rebooting! Launch this test again once booted.\n", __FUNCTION__ )); + gRT->ResetSystem( EfiResetCold, EFI_SUCCESS, 0, NULL ); + DEBUG(( DEBUG_ERROR, "%a - Unit test failed to quit! Framework can no longer be used!\n", __FUNCTION__ )); + + // + // We REALLY shouldn't be here. + Status = EFI_ABORTED; + } + + return; +} // SaveContextAndReboot + +STATIC +VOID +IgnoreContextAndReboot ( + IN UNIT_TEST_CONTEXT Context + ) +{ + // Just a wrapper for prototype reuse. + SaveStateAndReboot(); +} + +/** + Disable policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +DisablePolicyEngineTests ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + UINT8 Value; + + // + // First, we disable the variable policy + // + Status = mVarPol->DisableVariablePolicy (); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Confirm it's disabled + // + Status = mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_EQUAL (State, FALSE); + + // + // Try locking it? + // + Status = mVarPol->LockVariablePolicy (); + UT_LOG_INFO ("Locking VP after disabling it status: %r\n", Status); + + // + // Try modifying the var from TestExistingVarLockNow + // + Value = 0xB5; + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // DisablePolicyEngineTests + +// +// Pre-Disable Setup and Test for Authenticated Variables +// +UNIT_TEST_STATUS +TestAuthVarPart1 ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT32 Data; + UINTN DataSize; + UINT8 *DeleteData; + + // First, we need to create our dummy Authenticated Variable. + Status = gRT->SetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS), + mTestAuthVarPayloadSize, + &mTestAuthVarPayload[0]); + UT_ASSERT_NOT_EFI_ERROR(Status); + + // Prove that we created it. + DataSize = sizeof(Data); + Status = gRT->GetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + NULL, + &DataSize, + &Data); + UT_ASSERT_NOT_EFI_ERROR(Status); + UT_ASSERT_EQUAL(Data, 0xDEADBEEF); + + // Prove that we cannot delete it. + DeleteData = NULL; + DataSize = 0; + Status = CreateEmptyTimeBasedPayload(&DataSize, &DeleteData, NULL); + UT_ASSERT_NOT_EFI_ERROR(Status); + Status = gRT->SetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS), + DataSize, + (VOID*)DeleteData); + UT_ASSERT_STATUS_EQUAL(Status, EFI_SECURITY_VIOLATION); + FreePool(DeleteData); + + return UNIT_TEST_PASSED; +} + +// +// Post-Disable Test for Authenticated Variables +// +UNIT_TEST_STATUS +TestAuthVarPart2 ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT32 Data; + UINTN DataSize; + UINT8 *DeleteData; + + // Prove that it exists. + DataSize = sizeof(Data); + Status = gRT->GetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + NULL, + &DataSize, + &Data); + UT_ASSERT_NOT_EFI_ERROR(Status); + UT_ASSERT_EQUAL(Data, 0xDEADBEEF); + + // Prove that we can delete it. + DeleteData = NULL; + DataSize = 0; + Status = CreateEmptyTimeBasedPayload(&DataSize, &DeleteData, NULL); + UT_ASSERT_NOT_EFI_ERROR(Status); + Status = gRT->SetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS), + DataSize, + (VOID*)DeleteData); + UT_ASSERT_NOT_EFI_ERROR(Status); + FreePool(DeleteData); + + // Prove that we deleted it. + DataSize = sizeof(Data); + Status = gRT->GetVariable(TEST_AUTH_VAR_NAME, + &mTestAuthNamespaceGuid, + NULL, + &DataSize, + &Data); + UT_ASSERT_STATUS_EQUAL(Status, EFI_NOT_FOUND); + + return UNIT_TEST_PASSED; +} + +/** + Final Cleanup: delete some variables earlier test cases created. +**/ +STATIC +VOID +EFIAPI +FinalCleanup ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + Status = gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete ExistingLockNowVar status: %r\n", Status); + + Status = gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete ExistingLockOnCreateVar status: %r\n", Status); + + Status = gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete NonexistentLockOnCreateVar status: %r\n", Status); + + Status = gRT->SetVariable (L"NonexistentLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete NonexistentLockNowVar status: %r\n", Status); + + Status = gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete CantHaveAttrNoLockVar status: %r\n", Status); + + Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete NonexistentLockOnVarStateVar status: %r\n", Status); + + Status = gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete ExistingLockOnVarStateVar status: %r\n", Status); +} // FinalCleanup + +/** + + Main fuction sets up the unit test environment. + +**/ +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE* SystemTable) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE GettingStartedTestSuite; + UNIT_TEST_SUITE_HANDLE NoLockPoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE LockNowPoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE LockOnCreatePoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE LockOnVarStatePoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE InvalidPoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE DumpPolicyTestSuite; + UNIT_TEST_SUITE_HANDLE PolicyVersionTestSuite; + UNIT_TEST_SUITE_HANDLE LockPolicyTestSuite; + UNIT_TEST_SUITE_HANDLE DisablePolicyTestSuite; + + Framework = NULL; + GettingStartedTestSuite = NULL; + NoLockPoliciesTestSuite = NULL; + LockNowPoliciesTestSuite = NULL; + LockOnCreatePoliciesTestSuite = NULL; + LockOnVarStatePoliciesTestSuite = NULL; + InvalidPoliciesTestSuite = NULL; + DumpPolicyTestSuite = NULL; + PolicyVersionTestSuite = NULL; + LockPolicyTestSuite = NULL; + DisablePolicyTestSuite = NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION)); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Test suite 1: Getting Started. Get VP protocol, check state, log revision + // + Status = CreateUnitTestSuite (&GettingStartedTestSuite, Framework, "Getting Started", "Common.VP.GettingStarted", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Getting Started Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (GettingStartedTestSuite, "Confirm VP is enabled", "Common.VP.GettingStarted.CheckVpEnabled", CheckVpEnabled, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (GettingStartedTestSuite, "Check VP revision", "Common.VP.GettingStarted.CheckVpRevision", CheckVpRevision, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 2: Test NoLock Policies + // + Status = CreateUnitTestSuite (&NoLockPoliciesTestSuite, Framework, "Exercise NoLock Policies", "Common.VP.NoLockPolicies", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the NoLock Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (NoLockPoliciesTestSuite, "Test Min Size enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestMinSizeNoLock", TestMinSizeNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestMaxSizeNoLock", TestMaxSizeNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attribute enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestMustHaveAttrNoLock", TestMustHaveAttrNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Can't Have Attribute enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestCantHaveAttrNoLock", TestCantHaveAttrNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enforcement in NoLock policy for entire namespace", "Common.VP.NoLockPolicies.TestMaxSizeNamespaceNoLock", TestMaxSizeNamespaceNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attribute enforcement in NoLock policy with wildcards", "Common.VP.NoLockPolicies.TestMustHaveAttrWildcardNoLock", TestMustHaveAttrWildcardNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test policy prioritization between namespace-wide, wildcard, and var-specific policies", "Common.VP.NoLockPolicies.TestPolicyprioritizationNoLock", TestPolicyprioritizationNoLock, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 3: Test LockNow policies + // + Status = CreateUnitTestSuite (&LockNowPoliciesTestSuite, Framework, "Exercise LockNow Policies", "Common.VP.LockNowPolicies", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockNow Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockNowPoliciesTestSuite, "Test LockNow policy for a pre-existing variable", "Common.VP.LockNowPolicies.TestExistingVarLockNow", TestExistingVarLockNow, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockNowPoliciesTestSuite, "Test LockNow policy for a nonexistent variable", "Common.VP.LockNowPolicies.TestNonexistentVarLockNow", TestNonexistentVarLockNow, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 4: Test LockOnCreate policies + // + Status = CreateUnitTestSuite (&LockOnCreatePoliciesTestSuite, Framework, "Exercise LockOnCreate Policies", "Common.VP.LockOnCreate", NULL, NULL); + if (EFI_ERROR (Status)) + { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockOnCreate Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCreate policy for a pre-existing variable", "Common.VP.LockOnCreate.TestExistingVarLockOnCreate", TestExistingVarLockOnCreate, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCreate policy for a nonexistent variable", "Common.VP.LockOnCreate.TestNonexistentVarLockOnCreate", TestNonexistentVarLockOnCreate, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 5: Test LockOnVarState policies + // + Status = CreateUnitTestSuite (&LockOnVarStatePoliciesTestSuite, Framework, "Exercise LockOnVarState Policies", "Common.VP.LockOnVarState", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockOnVarState Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy for a nonexistent variable", "Common.VP.LockOnVarState.TestLockOnVarStateBeforeCreate", TestLockOnVarStateBeforeCreate, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy for a pre-existing variable", "Common.VP.LockOnVarState.TestLockOnVarStateAfterCreate", TestLockOnVarStateAfterCreate, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy triggered by invalid-size variable", "Common.VP.LockOnVarState.TestLockOnVarStateInvalidLargeTrigger", TestLockOnVarStateInvalidLargeTrigger, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy triggered by invalid-value variable", "Common.VP.LockOnVarState.TestLockOnVarStateWrongValueTrigger", TestLockOnVarStateWrongValueTrigger, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 6: Test registering invalid policies + // + Status = CreateUnitTestSuite (&InvalidPoliciesTestSuite, Framework, "Attempt registering invalid policies", "Common.VP.InvalidPolicies", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Invalid Policies Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid must-have attributes", "Common.VP.InvalidPolicies.TestInvalidAttributesPolicy", TestInvalidAttributesPolicy, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid attributes", "Common.VP.InvalidPolicies.TestLargeMinSizePolicy", TestLargeMinSizePolicy, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid attributes", "Common.VP.InvalidPolicies.TestZeroMaxSizePolicy", TestZeroMaxSizePolicy, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid type", "Common.VP.InvalidPolicies.TestInvalidPolicyTypePolicy", TestInvalidPolicyTypePolicy, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 7: Test dumping the policy + // + Status = CreateUnitTestSuite (&DumpPolicyTestSuite, Framework, "Attempt dumping policy", "Common.VP.DumpPolicy", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Dump Policy Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (DumpPolicyTestSuite, "Test dumping policy", "Common.VP.DumpPolicy.TestDumpPolicy", TestDumpPolicy, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 8: Test policy version + // + Status = CreateUnitTestSuite (&PolicyVersionTestSuite, Framework, "Use non-zero policy version", "Common.VP.PolicyVersion", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Policy Version Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (PolicyVersionTestSuite, "Test policy version", "Common.VP.DumpPolicy.TestPolicyVersion", TestPolicyVersion, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 9: Lock VPE and test implications + // + Status = CreateUnitTestSuite (&LockPolicyTestSuite, Framework, "Lock policy, test it", "Common.VP.LockPolicyTests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Lock Policy Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockPolicyTestSuite, "Test locking policy", "Common.VP.LockPolicyTests.LockPolicyEngineTests", LockPolicyEngineTests, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockPolicyTestSuite, "Test locking policy", "Common.VP.LockPolicyTests.LockPolicyEngineTests", LockPolicyEngineTests, LocateVarPolicyPreReq, IgnoreContextAndReboot, NULL); + + // + // Test suite 10: Disable var policy and confirm expected behavior + // + Status = CreateUnitTestSuite (&DisablePolicyTestSuite, Framework, "Disable policy, test it", "Common.VP.DisablePolicyTests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Disable Policy Test Suite\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (DisablePolicyTestSuite, "Confirm VP is enabled", "Common.VP.DisablePolicyTests.CheckVpEnabled", CheckVpEnabled, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test LockNow policy for a pre-existing variable", "Common.VP.DisablePolicyTests.TestExistingVarLockNow", TestExistingVarLockNow, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test AuthVar protection while VariablePolicy is enabled", "Common.VP.DisablePolicyTests.TestAuthVar1", TestAuthVarPart1, VarPolicyEnabledPreReq, NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test disabling policy", "Common.VP.DisablePolicyTests.DisablePolicyEngineTests", DisablePolicyEngineTests, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test AuthVar protection while VariablePolicy is disabled", "Common.VP.DisablePolicyTests.TestAuthVar2", TestAuthVarPart2, VarPolicyDisabledPreReq, FinalCleanup, NULL); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework != NULL) { + FreeUnitTestFramework (Framework); + } + + return Status; +} // UefiMain diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.ci.yaml index 20d53fc5a5fa..a1beee9f4aab 100644 --- a/MdeModulePkg/MdeModulePkg.ci.yaml +++ b/MdeModulePkg/MdeModulePkg.ci.yaml @@ -53,7 +53,9 @@ "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec" ], # For UEFI shell based apps - "AcceptableDependencies-UEFI_APPLICATION":[], + "AcceptableDependencies-UEFI_APPLICATION":[ + "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec" + ], "IgnoreInf": [] }, diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md new file mode 100644 index 000000000000..804ad4173a5f --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md @@ -0,0 +1,55 @@ +# variable Policy Unit Tests + +## 🔹 Copyright +Copyright (C) Microsoft Corporation. All rights reserved. +SPDX-License-Identifier: BSD-2-Clause-Patent + +## About This Test +This test verifies functionality of the Variable Policy Protocol by registering various variable policies and exercising them, as well as tests locking the policy, disabling it, and dumping the policy entries. + +Only policies that are created as a part of this test will be tested. +1. Try getting test context, if empty then get VP protocol, confirm that VP is not disabled by calling IsVariablePolicyEnabled. Log VP revision. +2. "No lock" policies: + * check minsize enforcement + * check maxsize enforcement + * check musthave attr enforcement + * check canthave attr enforcement + * check one of the above with empty string policy i.e. name wildcard + * check another one of the above with a "#" containing policy string + * check policy prioritization by having a namespace-wide policy, a policy with a # wildcard, and a one-var specific policy and testing which one is enforced +3. "Lock now" policies (means if the var doesn't exist, it won't be created; if one exists, it can't be updated): + * test a policy for an already existing variable, verify we can't write into that variable + * create a policy for a non-existing variable and attempt to register such var +4. "Lock on create" policies (means the var can still be created, but no updates later, existing vars can't be updated): + * create a var, lock it with LockOnCreate, attempt to update its contents + * create LockOnCreate VP, attempt to create var with invalid size, then invalid attr, then create valid var, attempt to update its contents +5. "Lock on var state" policies (means the var protected by this policy can't be created or updated once the trigger is set) + * create VP, trigger lock with a valid var, attempt to create a locked var, then modify the trigger var, create locked var + * create VP, create targeted var, modify it, trigger lock, attempt to modify var + * create VP, trigger lock with invalid (larger than one byte) var, see if VPE allows creation of the locked var (it should allow) + * create VP, set locking var with wrong value, see if VPE allows creation of the locked var (should allow) +6. Attempt registering invalid policy entries + * invalid required and banned attributes + * large min size - let's say 2GB + * max size equal to 0 + * invalid policy type +7. Exercise dumping policy. No need to check the validity of the dump blob. +8. Test registering a policy with a random version. +9. Lock VPE, make sure old policies are enforced, new ones can't be registered. + * Register a LockOnCreate policy + * Lock VPE + * Test locking it again. + * Verify one of the prior policies is enforced + * Make sure we can create variables even if those are protected by LockOnCreate policy, after locking the VPE + * Attempt to register new policies + * Make sure can't disable VPE + * Cleanup: save context and reboot +10. Disable variable policy and try some things + * Locate Variable Policy Protocol + * Make sure VP is enabled + * Register a policy + * Disable VPE + * Call IsVariablePolicyEnabled to confirm it's disabled. + * Make sure can't lock policy + * Make sure the policy from a is no longer enforced + * Final cleanup: delete vars that were created in some earlier test suites diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf new file mode 100644 index 000000000000..bfbac406b504 --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf @@ -0,0 +1,47 @@ +## @file +# Uefi Shell based Application that unit tests the Variable Policy Protocol +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VariablePolicyFuncTestApp + FILE_GUID = B653C4C3-3FCC-4B6C-8051-5F692AEAECBA + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = UefiMain + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = X64 AARCH64 +# + +[Sources] + VariablePolicyFuncTestApp.c + VariablePolicyTestAuthVar.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + BaseLib + BaseMemoryLib + UnitTestLib + UnitTestBootLib + PrintLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + MemoryAllocationLib + VariablePolicyHelperLib + +[Guids] + gEfiCertPkcs7Guid + +[Protocols] + gEdkiiVariablePolicyProtocolGuid diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h new file mode 100644 index 000000000000..c90310226827 --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTestAuthVar.h @@ -0,0 +1,128 @@ +/** @file -- VarPolicyTestAuthVar.h +Payload to be used to create an Authenticated Variable for testing. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VAR_POLICY_TEST_AUTH_VAR_H_ +#define _VAR_POLICY_TEST_AUTH_VAR_H_ + +UINT8 mTestAuthVarPayload[] = { + // EFI_VARIABLE_AUTHENTICATION_2 + // Timestamp + 0xE4, 0x07, 0x08, 0x15, 0x0D, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // AuthInfo (WIN_CERTIFICATE_UEFI_GUID) + // Hdr (WIN_CERTIFICATE) + // dwLength + 0x45, 0x05, 0x00, 0x00, + // wRevision + 0x00, 0x02, + // wCertificateType + // (WIN_CERT_TYPE_EFI_GUID) + 0xF1, 0x0E, + // CertType + // (gEfiCertPkcs7Guid) + 0x9D, 0xD2, 0xAF, 0x4A, 0xDF, 0x68, 0xEE, 0x49, 0x8A, 0xA9, 0x34, 0x7D, 0x37, 0x56, 0x65, 0xA7, + // CertData (Packed SignedData Signature) + // Digest Buffer Was... + // Name (DummyAuthVar) + // 44 00 75 00 6D 00 6D 00 79 00 41 00 75 00 74 00 68 00 56 00 61 00 72 00 + // Vendor Guid (mTestAuthNamespaceGuid) + // C6 A2 C5 B6 CE 3E 9B 4B 8C C8 96 D8 D9 CA D3 4E + // Attributes (NV + BS + RT, TimeAuth) + // 27 00 00 00 + // Timestamp + // E4 07 08 15 0D 1E 00 00 00 00 00 00 00 00 00 00 + // Data (0xDEADBEEF) + // EF BE AD DE + 0x30, 0x82, 0x05, 0x29, 0x02, 0x01, 0x01, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x03, 0x82, 0x30, 0x82, 0x03, 0x7E, 0x30, 0x82, 0x02, + 0x66, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x5A, 0xAE, 0x85, 0xA8, 0x61, 0x6E, 0x80, 0xA3, + 0x4D, 0x11, 0x69, 0x06, 0xC3, 0xFE, 0x2D, 0x89, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x3F, 0x31, 0x3D, 0x30, 0x3B, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x1E, 0x34, 0x00, 0x50, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x44, + 0x00, 0x52, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x45, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x65, 0x00, 0x6C, + 0x00, 0x66, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x69, + 0x00, 0x67, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x72, 0x30, 0x20, 0x17, 0x0D, 0x30, 0x30, 0x30, 0x31, + 0x30, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x18, 0x0F, 0x32, 0x39, 0x39, 0x39, 0x31, + 0x32, 0x33, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x3F, 0x31, 0x3D, 0x30, 0x3B, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x1E, 0x34, 0x00, 0x50, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x49, 0x00, + 0x4E, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x45, 0x00, 0x5F, 0x00, 0x53, 0x00, + 0x65, 0x00, 0x6C, 0x00, 0x66, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5F, 0x00, + 0x53, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x72, 0x30, 0x82, 0x01, 0x22, 0x30, + 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xC9, 0xA2, 0x80, 0xE7, + 0x3A, 0x0B, 0x3E, 0xCF, 0xEE, 0x0E, 0x22, 0x65, 0xF5, 0x03, 0xD2, 0x6A, 0x99, 0xBF, 0x5F, 0x48, + 0xF4, 0xC0, 0xD3, 0x19, 0xE7, 0x6B, 0x09, 0xFC, 0x0C, 0xB0, 0x3B, 0x69, 0x3A, 0x07, 0x6F, 0x36, + 0x57, 0xF6, 0x63, 0xAF, 0x6B, 0x7B, 0x30, 0x55, 0xD5, 0xE9, 0xF4, 0xDE, 0x89, 0xE3, 0x5F, 0xA1, + 0x71, 0x13, 0x3E, 0x84, 0x5D, 0x46, 0x9F, 0x78, 0xA9, 0x5B, 0xA5, 0x46, 0x3B, 0x38, 0x4F, 0x00, + 0x06, 0x63, 0x0E, 0x7A, 0x0A, 0x93, 0xE7, 0x36, 0x87, 0xCC, 0x47, 0xBD, 0xFB, 0x0A, 0x5D, 0x45, + 0x9C, 0xC4, 0x1B, 0xE6, 0x9E, 0xCB, 0xAB, 0xF9, 0x20, 0x11, 0xEF, 0x03, 0xCA, 0x9F, 0xE9, 0x29, + 0x1A, 0x05, 0xF8, 0xB3, 0x46, 0xB0, 0x3D, 0xFD, 0x88, 0x7C, 0x82, 0x0E, 0x3C, 0x6F, 0xEA, 0x5B, + 0xFF, 0xA8, 0xA4, 0xE0, 0x40, 0x2B, 0x25, 0xE8, 0x59, 0x46, 0xEE, 0xDB, 0x4B, 0x5F, 0x02, 0xB3, + 0x21, 0x33, 0x47, 0x2E, 0xD5, 0x66, 0x79, 0xF3, 0x79, 0x93, 0x18, 0x75, 0x94, 0x4A, 0x01, 0xCF, + 0x59, 0x86, 0xF4, 0x8B, 0x35, 0xBD, 0xA4, 0x58, 0xA4, 0x76, 0x89, 0x77, 0x55, 0x55, 0xB1, 0xE4, + 0x00, 0x09, 0x78, 0xF3, 0x29, 0x5B, 0xC0, 0xED, 0xD6, 0x68, 0x7E, 0xDB, 0xAA, 0x9F, 0x4E, 0xFE, + 0x67, 0x41, 0x4E, 0x6C, 0xC8, 0xDD, 0x52, 0xD6, 0xA5, 0x8A, 0x8A, 0x56, 0x50, 0x51, 0x27, 0x29, + 0x2B, 0xD3, 0x1B, 0x4D, 0xCE, 0x93, 0x76, 0x8E, 0x55, 0x53, 0x55, 0x30, 0x10, 0xF5, 0xF9, 0x6C, + 0xAE, 0xDA, 0xBA, 0xAC, 0x36, 0x79, 0x11, 0x02, 0xD0, 0x24, 0x07, 0xA6, 0xD1, 0x56, 0xCB, 0xEC, + 0x81, 0x29, 0xA8, 0xC1, 0x2E, 0x9D, 0x9B, 0xF9, 0xE9, 0xF4, 0x55, 0x74, 0xA0, 0x52, 0x87, 0x49, + 0x4F, 0xAC, 0x71, 0xFF, 0x30, 0x12, 0x24, 0xDD, 0x6D, 0x50, 0x5C, 0x7D, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xA3, 0x74, 0x30, 0x72, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1D, 0x01, 0x04, 0x69, 0x30, 0x67, + 0x80, 0x10, 0x0E, 0xB2, 0xFB, 0xDC, 0xD5, 0xAB, 0xCC, 0xB4, 0x3B, 0x46, 0x1B, 0x60, 0x18, 0xFD, + 0xDE, 0x74, 0xA1, 0x41, 0x30, 0x3F, 0x31, 0x3D, 0x30, 0x3B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x1E, + 0x34, 0x00, 0x50, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x44, 0x00, 0x52, 0x00, + 0x4F, 0x00, 0x4D, 0x00, 0x45, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x66, 0x00, + 0x68, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x69, 0x00, 0x67, 0x00, + 0x6E, 0x00, 0x65, 0x00, 0x72, 0x82, 0x10, 0x5A, 0xAE, 0x85, 0xA8, 0x61, 0x6E, 0x80, 0xA3, 0x4D, + 0x11, 0x69, 0x06, 0xC3, 0xFE, 0x2D, 0x89, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xB5, 0xA2, 0xD0, 0x1B, 0x70, + 0x24, 0xC2, 0xE8, 0x64, 0xCD, 0xF1, 0xE9, 0x97, 0x9E, 0xA7, 0xC1, 0x86, 0x92, 0x06, 0x2F, 0x8F, + 0x33, 0x64, 0x0A, 0xB9, 0x2B, 0x77, 0xE2, 0x70, 0x82, 0xDE, 0x06, 0xD3, 0x69, 0x8E, 0xB4, 0x69, + 0xF1, 0x6B, 0x59, 0x5E, 0x68, 0x5F, 0xB4, 0xFA, 0x30, 0xC3, 0xB6, 0xA1, 0x72, 0x1A, 0xD4, 0x01, + 0xED, 0x69, 0x4A, 0x96, 0x0F, 0x1C, 0xC3, 0x6F, 0x80, 0x0B, 0xE5, 0xD4, 0x46, 0xBE, 0x27, 0x9D, + 0xDE, 0x68, 0xB3, 0xA1, 0x93, 0xC3, 0x1A, 0x47, 0x20, 0x7A, 0x87, 0x80, 0x13, 0x85, 0x1E, 0x46, + 0x01, 0x42, 0x6A, 0x68, 0x46, 0xE2, 0x77, 0x3D, 0x2E, 0x50, 0xA1, 0x96, 0x23, 0x83, 0x03, 0xD1, + 0x57, 0xDD, 0xC6, 0x63, 0x59, 0xB7, 0x1A, 0x49, 0xA2, 0xC9, 0x44, 0x8D, 0xC7, 0x81, 0x18, 0xE8, + 0x52, 0x3A, 0x74, 0x32, 0xD3, 0xE6, 0x6D, 0x54, 0x9F, 0xC9, 0x87, 0x1C, 0xBC, 0x81, 0xEB, 0x6D, + 0x5D, 0x58, 0xF7, 0x91, 0x81, 0x5B, 0xB0, 0x86, 0xB4, 0x06, 0xE7, 0x19, 0x44, 0xE9, 0x24, 0x28, + 0xF5, 0x42, 0x7A, 0x7A, 0x28, 0x94, 0x3E, 0x70, 0x61, 0x1B, 0x68, 0x8D, 0xA9, 0x48, 0x3A, 0xFE, + 0x7D, 0xB5, 0x29, 0x10, 0xCE, 0xD6, 0xC1, 0xFF, 0x16, 0xDF, 0x90, 0x94, 0x16, 0xC8, 0xFA, 0x9E, + 0x52, 0x49, 0xE5, 0xC3, 0xF5, 0x8C, 0x87, 0xC2, 0x93, 0x3D, 0x3D, 0x27, 0x23, 0x37, 0xC3, 0xDA, + 0x55, 0x92, 0x12, 0xE9, 0x1F, 0xEB, 0x32, 0xB5, 0xD8, 0x30, 0xD6, 0xC0, 0x23, 0x45, 0xBB, 0x06, + 0xBC, 0x11, 0xA6, 0xA3, 0x47, 0x82, 0x04, 0xCB, 0xAA, 0x98, 0xCA, 0xF9, 0x00, 0x0E, 0xD3, 0xC3, + 0x09, 0xF6, 0x21, 0x4C, 0x90, 0xE0, 0x78, 0x08, 0xAE, 0x8F, 0xB1, 0x7D, 0x62, 0x3F, 0x6A, 0x1E, + 0xD6, 0xF1, 0x8E, 0xEE, 0xFD, 0x49, 0x04, 0xDE, 0x14, 0x9C, 0x7B, 0x31, 0x82, 0x01, 0x7E, 0x30, + 0x82, 0x01, 0x7A, 0x02, 0x01, 0x01, 0x30, 0x53, 0x30, 0x3F, 0x31, 0x3D, 0x30, 0x3B, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x1E, 0x34, 0x00, 0x50, 0x00, 0x41, 0x00, 0x4C, 0x00, 0x49, 0x00, 0x4E, 0x00, + 0x44, 0x00, 0x52, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x45, 0x00, 0x5F, 0x00, 0x53, 0x00, 0x65, 0x00, + 0x6C, 0x00, 0x66, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x74, 0x00, 0x5F, 0x00, 0x53, 0x00, + 0x69, 0x00, 0x67, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x72, 0x02, 0x10, 0x5A, 0xAE, 0x85, 0xA8, 0x61, + 0x6E, 0x80, 0xA3, 0x4D, 0x11, 0x69, 0x06, 0xC3, 0xFE, 0x2D, 0x89, 0x30, 0x0D, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xA6, 0x06, 0xE7, + 0x46, 0x7E, 0xFB, 0x4A, 0xA7, 0x25, 0x2F, 0x52, 0x1D, 0xBC, 0x5C, 0x41, 0x3B, 0xD3, 0x13, 0x50, + 0xCE, 0x5F, 0xE2, 0x4B, 0x31, 0xED, 0x28, 0x5E, 0xF5, 0x36, 0xBD, 0x1C, 0x38, 0xA1, 0xB6, 0x45, + 0x7C, 0xFD, 0xAB, 0x7B, 0x0C, 0xBF, 0x06, 0x06, 0xBB, 0x95, 0x5E, 0x47, 0x10, 0x7C, 0xD8, 0x10, + 0x76, 0x74, 0x81, 0x2D, 0x40, 0x3A, 0xD0, 0xF4, 0x15, 0x9D, 0xDF, 0x44, 0x2B, 0xA4, 0xCD, 0xF7, + 0x44, 0x77, 0x9F, 0x35, 0x46, 0xD3, 0x30, 0x67, 0x44, 0x33, 0xF4, 0x7B, 0xB6, 0xC0, 0xE4, 0xA2, + 0xAD, 0xDF, 0xAF, 0x56, 0x41, 0xA3, 0x0D, 0x76, 0x36, 0xB9, 0x7E, 0x29, 0x49, 0x17, 0x43, 0xAF, + 0xB0, 0xA0, 0xC0, 0xF1, 0xE1, 0xE6, 0xCA, 0x62, 0x9F, 0x3E, 0x9D, 0x6C, 0x63, 0x03, 0xF6, 0xDF, + 0x84, 0x32, 0xB1, 0x01, 0x0C, 0x12, 0x83, 0x52, 0x13, 0x2F, 0xAE, 0xBC, 0x79, 0xB7, 0x75, 0xF6, + 0x10, 0x20, 0xFC, 0x7A, 0x13, 0x92, 0xF7, 0x87, 0x50, 0xF5, 0x9C, 0xD9, 0xE4, 0xEA, 0x4C, 0x3D, + 0x31, 0xED, 0x7F, 0xA6, 0x6C, 0x58, 0xAD, 0x6C, 0x31, 0xAF, 0xC4, 0x64, 0xAE, 0x11, 0xBF, 0x72, + 0xF5, 0xAA, 0x69, 0xB4, 0x76, 0xDB, 0x73, 0x8F, 0x8C, 0x3E, 0x23, 0x4A, 0x2D, 0xB7, 0x65, 0x65, + 0x10, 0xA8, 0xC6, 0x52, 0x14, 0xE2, 0xC6, 0x2B, 0x07, 0xCE, 0x45, 0x58, 0x6F, 0x92, 0x78, 0xAA, + 0xB5, 0xE9, 0x76, 0x39, 0x8A, 0x17, 0xE3, 0x0B, 0xA5, 0x12, 0x0F, 0x2A, 0xC1, 0xCE, 0xC5, 0x4F, + 0xD8, 0xA7, 0xD1, 0x7C, 0x3F, 0xE3, 0x23, 0x9B, 0x53, 0x56, 0x18, 0x28, 0x66, 0xC7, 0xB3, 0x04, + 0x38, 0xE3, 0x40, 0xCC, 0xB2, 0x18, 0xA8, 0xC7, 0x11, 0xE1, 0x67, 0xD8, 0xBF, 0xBE, 0x8D, 0x2A, + 0x75, 0x00, 0x96, 0x8F, 0x7F, 0x80, 0xCF, 0xDB, 0xF0, 0x0D, 0xB5, 0x8D, 0x73, + // Data + 0xEF, 0xBE, 0xAD, 0xDE +}; +UINTN mTestAuthVarPayloadSize = sizeof(mTestAuthVarPayload); + +#endif // _VAR_POLICY_TEST_AUTH_VAR_H_ -- 2.28.0.windows.1 ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-09-08 22:17 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-09-08 22:17 [PATCH v7 13/14] MdeModulePkg: Drop VarLock from RuntimeDxe variable driver Bret Barkelew 2020-09-08 22:17 ` [PATCH v7 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy Bret Barkelew -- strict thread matches above, loose matches on Subject: below -- 2020-08-28 5:51 [PATCH v7 00/14] Add the VariablePolicy feature Bret Barkelew 2020-08-28 5:51 ` [PATCH v7 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy Bret Barkelew
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox