4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implement authentication services for the authenticated variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync service in UEFI2.2.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchttp://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Variable.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "AuthService.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync///
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/// Global database array for scratch
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync///
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32 mPubKeyNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32 mPlatformMode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_GUID mSignatureSupport[SIGSUPPORT_NUM] = {EFI_CERT_RSA2048_SHA256_GUID, EFI_CERT_RSA2048_SHA1_GUID};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Public Exponent of RSA Key.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initializes for authenticated varibale service.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function successfully executed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate enough memory resources.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAutenticatedVariableServiceInitialize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_POINTER_TRACK Variable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 VarValue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 VarAttr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN DataSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN CtxSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_HEADER VariableHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Valid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->AuthenticatedVariableGuid[Physical] = &gEfiAuthenticatedVariableGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->CertRsa2048Sha256Guid[Physical] = &gEfiCertRsa2048Sha256Guid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->ImageSecurityDatabaseGuid[Physical] = &gEfiImageSecurityDatabaseGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize hash context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CtxSize = Sha256GetContextSize ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->HashContext[Physical] = AllocateRuntimePool (CtxSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (mVariableModuleGlobal->HashContext[Physical] != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check "AuthVarKeyDatabase" variable's existence.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If it doesn't exist, create a new one with initial value of 0 and EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->VariableName[Physical][VAR_AUTH_KEY_DB],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiAuthenticatedVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mVariableModuleGlobal->VariableGlobal[Physical],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->FvbInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable.CurrPtr == 0x0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarValue = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mPubKeyNumber = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UpdateVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->VariableName[Physical][VAR_AUTH_KEY_DB],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiAuthenticatedVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &VarValue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof(UINT8),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarAttr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Load database in global variable for cache.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Valid = IsValidVariableHeader (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.CurrPtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.Volatile,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mVariableModuleGlobal->VariableGlobal[Physical],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->FvbInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &VariableHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Valid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataSize = DataSizeOfVariable (&VariableHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (DataSize <= MAX_KEYDB_SIZE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GetVariableDataPtr (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.CurrPtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.Volatile,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mVariableModuleGlobal->VariableGlobal[Physical],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->FvbInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (CHAR16 *) mVariableModuleGlobal->PubKeyStore
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mPubKeyNumber = (UINT32) (DataSize / EFI_CERT_TYPE_RSA2048_SIZE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check "SetupMode" variable's existence.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If it doesn't exist, check PK database's existence to determine the value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->VariableName[Physical][VAR_SETUP_MODE],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mVariableModuleGlobal->VariableGlobal[Physical],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->FvbInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable.CurrPtr == 0x0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->VariableName[Physical][VAR_PLATFORM_KEY],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mVariableModuleGlobal->VariableGlobal[Physical],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->FvbInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable.CurrPtr == 0x0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mPlatformMode = SETUP_MODE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mPlatformMode = USER_MODE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UpdateVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->VariableName[Physical][VAR_SETUP_MODE],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mPlatformMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof(UINT8),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarAttr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GetVariableDataPtr (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.CurrPtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.Volatile,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mVariableModuleGlobal->VariableGlobal[Physical],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->FvbInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (CHAR16 *) &mPlatformMode
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check "SignatureSupport" variable's existence.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If it doesn't exist, then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SIGNATURE_SUPPORT_NAME,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mVariableModuleGlobal->VariableGlobal[Physical],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal->FvbInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable.CurrPtr == 0x0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UpdateVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SIGNATURE_SUPPORT_NAME,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mSignatureSupport,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SIGSUPPORT_NUM * sizeof(EFI_GUID),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarAttr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mVariableModuleGlobal,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Add public key in store and return its index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VirtualMode The current calling mode for this function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Global The context of this Extended SAL Variable Services Class call.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PubKey The input pointer to Public Key data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The index of new added item.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAddPubKeyInStore (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESAL_VARIABLE_GLOBAL *Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *PubKey
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IsFound;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_POINTER_TRACK Variable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PubKey == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->VariableName[VirtualMode][VAR_AUTH_KEY_DB],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->AuthenticatedVariableGuid[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Global->VariableGlobal[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->FvbInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the public key entry does exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFound = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Ptr = Global->PubKeyStore, Index = 1; Index <= mPubKeyNumber; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareMem (Ptr, PubKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFound = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += EFI_CERT_TYPE_RSA2048_SIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsFound) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add public key in database.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mPubKeyNumber == MAX_KEY_NUM) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Notes: Database is full, need enhancement here, currently just return 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Global->PubKeyStore + mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index = ++mPubKeyNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update public key database variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UpdateVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->VariableName[VirtualMode][VAR_AUTH_KEY_DB],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->AuthenticatedVariableGuid[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->PubKeyStore,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256 type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Follow the steps in UEFI2.2.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VirtualMode The current calling mode for this function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Global The context of this Extended SAL Variable Services Class call.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The pointer to data with AuthInfo.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DataSize The size of Data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PubKey The public key used for verification.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Invalid parameter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SECURITY_VIOLATION Authentication failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Authentication successful.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVerifyDataPayload (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESAL_VARIABLE_GLOBAL *Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *Data,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DataSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *PubKey
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_VARIABLE_AUTHENTICATION *CertData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Digest[SHA256_DIGEST_SIZE];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *Rsa;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *HashContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Rsa = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertData = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertBlock = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Data == NULL || PubKey == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync !CompareGuid (&CertData->AuthInfo.CertType, Global->CertRsa2048Sha256Guid[VirtualMode])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SECURITY_VIOLATION;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Hash data payload with SHA256.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (Digest, SHA256_DIGEST_SIZE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HashContext = Global->HashContext[VirtualMode];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Sha256Init (HashContext);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Sha256Update (HashContext, Data + AUTHINFO_SIZE, (UINTN) (DataSize - AUTHINFO_SIZE));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Hash Monotonic Count.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Sha256Update (HashContext, &CertData->MonotonicCount, sizeof (UINT64));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Sha256Final (HashContext, Digest);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Generate & Initialize RSA Context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Rsa = RsaNew ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Rsa != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set RSA Key Components.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // NOTE: Only N and E are needed to be set as RSA public key for signature verification.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = RsaSetKey (Rsa, RsaKeyN, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the signature.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = RsaPkcs1Verify (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Rsa,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Digest,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SHA256_DIGEST_SIZE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertBlock->Signature,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_CERT_TYPE_RSA2048_SHA256_SIZE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDone:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Rsa != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RsaFree (Rsa);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SECURITY_VIOLATION;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Update platform mode.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VirtualMode The current calling mode for this function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Global The context of this Extended SAL Variable Services Class call.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Mode SETUP_MODE or USER_MODE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUpdatePlatformMode (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESAL_VARIABLE_GLOBAL *Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Mode
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_POINTER_TRACK Variable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 VarAttr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->VariableName[VirtualMode][VAR_SETUP_MODE],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->GlobalVariableGuid[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Global->VariableGlobal[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->FvbInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mPlatformMode = Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UpdateVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->VariableName[VirtualMode][VAR_SETUP_MODE],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->GlobalVariableGuid[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mPlatformMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof(UINT8),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarAttr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process variable with platform key for verification.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VariableName The name of Variable to be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VendorGuid The variable vendor GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The data pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DataSize The size of Data found. If size is less than the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync data, this value contains the required size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VirtualMode The current calling mode for this function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Global The context of this Extended SAL Variable Services Class call.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Variable The variable information which is used to keep track of variable usage.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Attributes The attribute value of the variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IsPk Indicates whether to process pk.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Invalid parameter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SECURITY_VIOLATION The variable does NOT pass the validation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync check carried out by the firmware.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The variable passed validation successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncProcessVarWithPk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CHAR16 *VariableName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_GUID *VendorGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Data,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DataSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESAL_VARIABLE_GLOBAL *Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VARIABLE_POINTER_TRACK *Variable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Attributes OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN IsPk
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_POINTER_TRACK PkVariable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SIGNATURE_LIST *OldPkList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SIGNATURE_DATA *OldPkData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_VARIABLE_AUTHENTICATION *CertData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_HEADER VariableHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Valid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldPkList = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // PK and KEK should set EFI_VARIABLE_NON_VOLATILE attribute.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mPlatformMode == USER_MODE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // In user mode, PK and KEK should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable->CurrPtr != 0x0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Valid = IsValidVariableHeader (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable->CurrPtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable->Volatile,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Global->VariableGlobal[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->FvbInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &VariableHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Valid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CertData->MonotonicCount <= VariableHeader.MonotonicCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SECURITY_VIOLATION;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get platform key from variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->VariableName[VirtualMode][VAR_PLATFORM_KEY],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->GlobalVariableGuid[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &PkVariable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Global->VariableGlobal[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->FvbInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (Global->KeyList, MAX_KEYDB_SIZE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GetVariableDataPtr (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PkVariable.CurrPtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PkVariable.Volatile,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Global->VariableGlobal[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->FvbInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (CHAR16 *) Global->KeyList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldPkList = (EFI_SIGNATURE_LIST *) Global->KeyList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldPkData = (EFI_SIGNATURE_DATA *) ((UINT8 *) OldPkList + sizeof (EFI_SIGNATURE_LIST) + OldPkList->SignatureHeaderSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = VerifyDataPayload (VirtualMode, Global, Data, DataSize, OldPkData->SignatureData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UpdateVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VendorGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8*)Data + AUTHINFO_SIZE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataSize - AUTHINFO_SIZE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertData->MonotonicCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If delete PK in user mode, need change to setup mode.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((DataSize == AUTHINFO_SIZE) && IsPk) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UpdatePlatformMode (VirtualMode, Global, SETUP_MODE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, 0, 0, VirtualMode, Global, Variable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If enroll PK in setup mode, need change to user mode.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((DataSize != 0) && IsPk) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UpdatePlatformMode (VirtualMode, Global, USER_MODE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process variable with key exchange key for verification.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VariableName The name of Variable to be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VendorGuid The variable vendor GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The data pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DataSize The size of Data found. If size is less than the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync data, this value contains the required size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VirtualMode The current calling mode for this function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Global The context of this Extended SAL Variable Services Class call.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Variable The variable information which is used to keep track of variable usage.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Attributes The attribute value of the variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Invalid parameter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SECURITY_VIOLATION The variable did NOT pass the validation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync check carried out by the firmware.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The variable passed validation successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncProcessVarWithKek (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CHAR16 *VariableName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_GUID *VendorGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Data,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DataSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESAL_VARIABLE_GLOBAL *Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VARIABLE_POINTER_TRACK *Variable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Attributes OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_POINTER_TRACK KekVariable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SIGNATURE_LIST *KekList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SIGNATURE_DATA *KekItem;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 KekCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_VARIABLE_AUTHENTICATION *CertData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IsFound;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_HEADER VariableHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Valid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KekList = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mPlatformMode == USER_MODE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // In user mode, should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable->CurrPtr != 0x0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Valid = IsValidVariableHeader (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable->CurrPtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable->Volatile,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Global->VariableGlobal[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->FvbInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &VariableHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Valid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CertData->MonotonicCount <= VariableHeader.MonotonicCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SECURITY_VIOLATION;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get KEK database from variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->VariableName[VirtualMode][VAR_KEY_EXCHANGE_KEY],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->GlobalVariableGuid[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &KekVariable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Global->VariableGlobal[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->FvbInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (Global->KeyList, MAX_KEYDB_SIZE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GetVariableDataPtr (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KekVariable.CurrPtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KekVariable.Volatile,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Global->VariableGlobal[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->FvbInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (CHAR16 *) Global->KeyList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Enumerate all Kek items in this list to verify the variable certificate data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If anyone is authenticated successfully, it means the variable is correct!
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KekList = (EFI_SIGNATURE_LIST *) Global->KeyList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFound = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KekCount = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < KekCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareMem (KekItem->SignatureData, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFound = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsFound) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SECURITY_VIOLATION;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = VerifyDataPayload (VirtualMode, Global, Data, DataSize, CertBlock->PublicKey);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UpdateVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VendorGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8*)Data + AUTHINFO_SIZE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataSize - AUTHINFO_SIZE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertData->MonotonicCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If in setup mode, no authentication needed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UpdateVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VendorGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set, and return the index of associated public key.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The data pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DataSize The size of Data found. If size is less than the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync data, this value contains the required size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] VirtualMode The current calling mode for this function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Global The context of this Extended SAL Variable Services Class call.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Variable The variable information which is used to keep track of variable usage.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Attributes The attribute value of the variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] KeyIndex The output index of corresponding public key in database.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] MonotonicCount The output value of corresponding Monotonic Count.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Invalid parameter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_WRITE_PROTECTED The variable is write-protected and needs authentication with
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync set, but the AuthInfo does NOT pass the validation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync check carried out by the firmware.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The variable is not write-protected, or passed validation successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVerifyVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Data,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DataSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN VirtualMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ESAL_VARIABLE_GLOBAL *Global,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VARIABLE_POINTER_TRACK *Variable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Attributes OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT32 *KeyIndex OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *MonotonicCount OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IsDeletion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IsFirstTime;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *PubKey;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_VARIABLE_AUTHENTICATION *CertData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_HEADER VariableHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Valid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertData = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertBlock = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PubKey = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsDeletion = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Valid = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (KeyIndex != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *KeyIndex = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if first time SetVariable with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&VariableHeader, sizeof (VARIABLE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable->CurrPtr != 0x0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Valid = IsValidVariableHeader (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable->CurrPtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable->Volatile,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Global->VariableGlobal[VirtualMode],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Global->FvbInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &VariableHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Valid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (KeyIndex == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine current operation type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DataSize == AUTHINFO_SIZE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsDeletion = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine whether this is the first time with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable->CurrPtr == 0x0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFirstTime = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Valid &&(VariableHeader.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFirstTime = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *KeyIndex = VariableHeader.PubKeyIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFirstTime = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Valid && (VariableHeader.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the variable is already write-protected, it always needs authentication before update.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_WRITE_PROTECTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If without EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, set and attributes collision.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // That means it is not authenticated variable, just return EFI_SUCCESS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get PubKey and check Monotonic Count value corresponding to the variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PubKey = CertBlock->PublicKey;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (MonotonicCount != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update Monotonic Count value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *MonotonicCount = CertData->MonotonicCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsFirstTime) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check input PubKey.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareMem (PubKey, Global->PubKeyStore + (*KeyIndex - 1) * EFI_CERT_TYPE_RSA2048_SIZE, EFI_CERT_TYPE_RSA2048_SIZE) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SECURITY_VIOLATION;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Compare the current monotonic count and ensure that it is greater than the last SetVariable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // operation with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CertData->MonotonicCount <= VariableHeader.MonotonicCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SECURITY_VIOLATION;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the certificate in Data payload.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = VerifyDataPayload (VirtualMode, Global, Data, DataSize, PubKey);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Now, the signature has been verified!
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IsFirstTime && !IsDeletion) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update public key database variable if need and return the index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *KeyIndex = AddPubKeyInStore (VirtualMode, Global, PubKey);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync