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