]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
Update common authenticated variable (non PK/KEK/DB/DBX) support to comply with lates...
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / RuntimeDxe / AuthService.c
index 4036885570a04c737fca4273ceb109c3361f10c7..12587af7b2db90f946dd3462a869d4475c1693b5 100644 (file)
@@ -164,6 +164,7 @@ AutenticatedVariableServiceInitialize (
   UINT8                   SecureBootMode;\r
   UINT8                   SecureBootEnable;\r
   UINT8                   CustomMode;\r
+  UINT32                  ListSize;\r
 \r
   //\r
   // Initialize hash context.\r
@@ -388,6 +389,36 @@ AutenticatedVariableServiceInitialize (
   \r
   DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_CUSTOM_MODE_NAME, CustomMode));\r
 \r
+  //\r
+  // Check "certdb" variable's existence.\r
+  // If it doesn't exist, then create a new one with \r
+  // EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.\r
+  //\r
+  Status = FindVariable (\r
+             EFI_CERT_DB_NAME,\r
+             &gEfiCertDbGuid,\r
+             &Variable,\r
+             &mVariableModuleGlobal->VariableGlobal,\r
+             FALSE\r
+             );\r
+\r
+  if (Variable.CurrPtr == NULL) {\r
+    VarAttr  = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+    ListSize = 0;\r
+    Status   = UpdateVariable (\r
+                 EFI_CERT_DB_NAME,\r
+                 &gEfiCertDbGuid,\r
+                 &ListSize,\r
+                 sizeof (UINT32),\r
+                 VarAttr,\r
+                 0,\r
+                 0,\r
+                 &Variable,\r
+                 NULL\r
+                 );\r
+\r
+  }  \r
+\r
   return Status;\r
 }\r
 \r
@@ -887,7 +918,16 @@ ProcessVarWithPk (
       // Verify against X509 Cert PK.\r
       //\r
       Del    = FALSE;\r
-      Status = VerifyTimeBasedPayload (VariableName, VendorGuid, Data, DataSize, Variable, Attributes, TRUE, &Del);\r
+      Status = VerifyTimeBasedPayload (\r
+                 VariableName,\r
+                 VendorGuid,\r
+                 Data,\r
+                 DataSize,\r
+                 Variable,\r
+                 Attributes,\r
+                 AuthVarTypePk,\r
+                 &Del\r
+                 );\r
       if (!EFI_ERROR (Status)) {\r
         //\r
         // If delete PK in user mode, need change to setup mode.\r
@@ -1084,7 +1124,16 @@ ProcessVarWithKek (
       //\r
       // Time-based, verify against X509 Cert KEK.\r
       //\r
-      return VerifyTimeBasedPayload (VariableName, VendorGuid, Data, DataSize, Variable, Attributes, FALSE, NULL);\r
+      return VerifyTimeBasedPayload (\r
+               VariableName,\r
+               VendorGuid,\r
+               Data,\r
+               DataSize,\r
+               Variable,\r
+               Attributes,\r
+               AuthVarTypeKek,\r
+               NULL\r
+               );\r
     } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
       //\r
       // Counter-based, verify against RSA2048 Cert KEK.\r
@@ -1255,7 +1304,16 @@ ProcessVariable (
   // Process Time-based Authenticated variable.\r
   //\r
   if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
-    return VerifyTimeBasedPayload (VariableName, VendorGuid, Data, DataSize, Variable, Attributes, FALSE, NULL);\r
+    return VerifyTimeBasedPayload (\r
+             VariableName,\r
+             VendorGuid,\r
+             Data,\r
+             DataSize,\r
+             Variable,\r
+             Attributes,\r
+             AuthVarTypePriv,\r
+             NULL\r
+             );\r
   }\r
 \r
   //\r
@@ -1489,6 +1547,470 @@ CompareTimeStamp (
   return (BOOLEAN) (FirstTime->Second <= SecondTime->Second);\r
 }\r
 \r
+/**\r
+  Find matching signer's certificates for common authenticated variable\r
+  by corresponding VariableName and VendorGuid from "certdb".\r
+\r
+  The data format of "certdb":\r
+  //\r
+  //     UINT32 CertDbListSize;\r
+  // /// AUTH_CERT_DB_DATA Certs1[];\r
+  // /// AUTH_CERT_DB_DATA Certs2[];\r
+  // /// ...\r
+  // /// AUTH_CERT_DB_DATA Certsn[];\r
+  //\r
+\r
+  @param[in]  VariableName   Name of authenticated Variable.\r
+  @param[in]  VendorGuid     Vendor GUID of authenticated Variable.\r
+  @param[in]  Data           Pointer to variable "certdb".\r
+  @param[in]  DataSize       Size of variable "certdb".\r
+  @param[out] CertOffset     Offset of matching CertData, from starting of Data.\r
+  @param[out] CertDataSize   Length of CertData in bytes.\r
+  @param[out] CertNodeOffset Offset of matching AUTH_CERT_DB_DATA , from\r
+                             starting of Data.\r
+  @param[out] CertNodeSize   Length of AUTH_CERT_DB_DATA in bytes.\r
+\r
+  @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.\r
+  @retval  EFI_NOT_FOUND         Fail to find matching certs.\r
+  @retval  EFI_SUCCESS           Find matching certs and output parameters.\r
+\r
+**/\r
+EFI_STATUS\r
+FindCertsFromDb (\r
+  IN     CHAR16           *VariableName,\r
+  IN     EFI_GUID         *VendorGuid,\r
+  IN     UINT8            *Data,\r
+  IN     UINTN            DataSize,\r
+  OUT    UINT32           *CertOffset,    OPTIONAL\r
+  OUT    UINT32           *CertDataSize,  OPTIONAL\r
+  OUT    UINT32           *CertNodeOffset,OPTIONAL\r
+  OUT    UINT32           *CertNodeSize   OPTIONAL\r
+  )\r
+{\r
+  UINT32                  Offset;\r
+  AUTH_CERT_DB_DATA       *Ptr;\r
+  UINT32                  CertSize;\r
+  UINT32                  NameSize;\r
+  UINT32                  NodeSize;\r
+  UINT32                  CertDbListSize;\r
+\r
+  if ((VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check whether DataSize matches recorded CertDbListSize.\r
+  //\r
+  if (DataSize < sizeof (UINT32)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CertDbListSize = ReadUnaligned32 ((UINT32 *) Data);\r
+\r
+  if (CertDbListSize != (UINT32) DataSize) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Offset = sizeof (UINT32);\r
+\r
+  //\r
+  // Get corresponding certificates by VendorGuid and VariableName.\r
+  //\r
+  while (Offset < (UINT32) DataSize) {\r
+    Ptr = (AUTH_CERT_DB_DATA *) (Data + Offset);\r
+    //\r
+    // Check whether VendorGuid matches.\r
+    //\r
+    if (CompareGuid (&Ptr->VendorGuid, VendorGuid)) {\r
+      NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);\r
+      NameSize = ReadUnaligned32 (&Ptr->NameSize);\r
+      CertSize = ReadUnaligned32 (&Ptr->CertDataSize);\r
+\r
+      if (NodeSize != sizeof (EFI_GUID) + sizeof (UINT32) * 3 + CertSize +\r
+          sizeof (CHAR16) * NameSize) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      Offset = Offset + sizeof (EFI_GUID) + sizeof (UINT32) * 3;\r
+      //\r
+      // Check whether VariableName matches.\r
+      //\r
+      if ((NameSize == StrLen (VariableName)) && \r
+          (CompareMem (Data + Offset, VariableName, NameSize * sizeof (CHAR16)) == 0)) {\r
+        Offset = Offset + NameSize * sizeof (CHAR16);\r
+\r
+        if (CertOffset != NULL) {\r
+          *CertOffset = Offset;\r
+        }\r
+\r
+        if (CertDataSize != NULL) {\r
+          *CertDataSize = CertSize;        \r
+        }\r
+\r
+        if (CertNodeOffset != NULL) {\r
+          *CertNodeOffset = (UINT32) ((UINT8 *) Ptr - Data);\r
+        }\r
+\r
+        if (CertNodeSize != NULL) {\r
+          *CertNodeSize = NodeSize;\r
+        }\r
+\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        Offset = Offset + NameSize * sizeof (CHAR16) + CertSize;\r
+      }\r
+    } else {\r
+      NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);\r
+      Offset   = Offset + NodeSize;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;  \r
+}\r
+\r
+/**\r
+  Retrieve signer's certificates for common authenticated variable\r
+  by corresponding VariableName and VendorGuid from "certdb".\r
+\r
+  @param[in]  VariableName   Name of authenticated Variable.\r
+  @param[in]  VendorGuid     Vendor GUID of authenticated Variable.\r
+  @param[out] CertData       Pointer to signer's certificates.\r
+  @param[out] CertDataSize   Length of CertData in bytes.\r
+\r
+  @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.\r
+  @retval  EFI_NOT_FOUND         Fail to find "certdb" or matching certs.\r
+  @retval  EFI_SUCCESS           Get signer's certificates successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+GetCertsFromDb (\r
+  IN     CHAR16           *VariableName,\r
+  IN     EFI_GUID         *VendorGuid,\r
+  OUT    UINT8            **CertData,\r
+  OUT    UINT32           *CertDataSize\r
+  )\r
+{\r
+  VARIABLE_POINTER_TRACK  CertDbVariable;\r
+  EFI_STATUS              Status;\r
+  UINT8                   *Data;\r
+  UINTN                   DataSize;\r
+  UINT32                  CertOffset;\r
+\r
+  if ((VariableName == NULL) || (VendorGuid == NULL) || (CertData == NULL) || (CertDataSize == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  //\r
+  // Get variable "certdb".\r
+  //\r
+  Status = FindVariable (\r
+             EFI_CERT_DB_NAME,\r
+             &gEfiCertDbGuid,\r
+             &CertDbVariable,\r
+             &mVariableModuleGlobal->VariableGlobal,\r
+             FALSE\r
+             );      \r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DataSize  = DataSizeOfVariable (CertDbVariable.CurrPtr);\r
+  Data      = GetVariableDataPtr (CertDbVariable.CurrPtr);\r
+  if ((DataSize == 0) || (Data == NULL)) {\r
+    ASSERT (FALSE);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Status = FindCertsFromDb (\r
+             VariableName,\r
+             VendorGuid,\r
+             Data,\r
+             DataSize,\r
+             &CertOffset,\r
+             CertDataSize,\r
+             NULL,\r
+             NULL\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *CertData = Data + CertOffset;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Delete matching signer's certificates when deleting common authenticated\r
+  variable by corresponding VariableName and VendorGuid from "certdb".\r
+\r
+  @param[in]  VariableName   Name of authenticated Variable.\r
+  @param[in]  VendorGuid     Vendor GUID of authenticated Variable.\r
+\r
+  @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.\r
+  @retval  EFI_NOT_FOUND         Fail to find "certdb" or matching certs.\r
+  @retval  EFI_OUT_OF_RESOURCES  The operation is failed due to lack of resources.\r
+  @retval  EFI_SUCCESS           The operation is completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+DeleteCertsFromDb (\r
+  IN     CHAR16           *VariableName,\r
+  IN     EFI_GUID         *VendorGuid\r
+  )\r
+{\r
+  VARIABLE_POINTER_TRACK  CertDbVariable;\r
+  EFI_STATUS              Status;\r
+  UINT8                   *Data;\r
+  UINTN                   DataSize;\r
+  UINT32                  VarAttr;\r
+  UINT32                  CertNodeOffset;\r
+  UINT32                  CertNodeSize;\r
+  UINT8                   *NewCertDb;\r
+  UINT32                  NewCertDbSize;\r
+\r
+  if ((VariableName == NULL) || (VendorGuid == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  //\r
+  // Get variable "certdb".\r
+  //\r
+  Status = FindVariable (\r
+             EFI_CERT_DB_NAME,\r
+             &gEfiCertDbGuid,\r
+             &CertDbVariable,\r
+             &mVariableModuleGlobal->VariableGlobal,\r
+             FALSE\r
+             );      \r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DataSize  = DataSizeOfVariable (CertDbVariable.CurrPtr);\r
+  Data      = GetVariableDataPtr (CertDbVariable.CurrPtr);\r
+  if ((DataSize == 0) || (Data == NULL)) {\r
+    ASSERT (FALSE);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (DataSize == sizeof (UINT32)) {\r
+    //\r
+    // There is no certs in certdb.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Get corresponding cert node from certdb.\r
+  //\r
+  Status = FindCertsFromDb (\r
+             VariableName,\r
+             VendorGuid,\r
+             Data,\r
+             DataSize,\r
+             NULL,\r
+             NULL,\r
+             &CertNodeOffset,\r
+             &CertNodeSize\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (DataSize < (CertNodeOffset + CertNodeSize)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Construct new data content of variable "certdb".\r
+  //\r
+  NewCertDbSize = (UINT32) DataSize - CertNodeSize;\r
+  NewCertDb     = AllocateZeroPool (NewCertDbSize);\r
+  if (NewCertDb == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Copy the DB entries before deleting node.\r
+  //\r
+  CopyMem (NewCertDb, Data, CertNodeOffset);\r
+  //\r
+  // Update CertDbListSize.\r
+  //\r
+  CopyMem (NewCertDb, &NewCertDbSize, sizeof (UINT32));\r
+  //\r
+  // Copy the DB entries after deleting node.\r
+  //\r
+  if (DataSize > (CertNodeOffset + CertNodeSize)) {\r
+    CopyMem (\r
+      NewCertDb + CertNodeOffset,\r
+      Data + CertNodeOffset + CertNodeSize,\r
+      DataSize - CertNodeOffset - CertNodeSize\r
+      );\r
+  }\r
+\r
+  //\r
+  // Set "certdb".\r
+  // \r
+  VarAttr  = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;  \r
+  Status   = UpdateVariable (\r
+               EFI_CERT_DB_NAME,\r
+               &gEfiCertDbGuid,\r
+               NewCertDb,\r
+               NewCertDbSize,\r
+               VarAttr,\r
+               0,\r
+               0,\r
+               &CertDbVariable,\r
+               NULL\r
+               );\r
+\r
+  FreePool (NewCertDb);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Insert signer's certificates for common authenticated variable with VariableName\r
+  and VendorGuid in AUTH_CERT_DB_DATA to "certdb".\r
+\r
+  @param[in]  VariableName   Name of authenticated Variable.\r
+  @param[in]  VendorGuid     Vendor GUID of authenticated Variable.\r
+  @param[in]  CertData       Pointer to signer's certificates.\r
+  @param[in]  CertDataSize   Length of CertData in bytes.\r
+\r
+  @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.\r
+  @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry with same VariableName\r
+                                 and VendorGuid already exists.\r
+  @retval  EFI_OUT_OF_RESOURCES  The operation is failed due to lack of resources.\r
+  @retval  EFI_SUCCESS           Insert an AUTH_CERT_DB_DATA entry to "certdb"\r
+\r
+**/\r
+EFI_STATUS\r
+InsertCertsToDb (\r
+  IN     CHAR16           *VariableName,\r
+  IN     EFI_GUID         *VendorGuid,\r
+  IN     UINT8            *CertData,\r
+  IN     UINTN            CertDataSize\r
+  )\r
+{\r
+  VARIABLE_POINTER_TRACK  CertDbVariable;\r
+  EFI_STATUS              Status;\r
+  UINT8                   *Data;\r
+  UINTN                   DataSize;\r
+  UINT32                  VarAttr;\r
+  UINT8                   *NewCertDb;\r
+  UINT32                  NewCertDbSize;\r
+  UINT32                  CertNodeSize;\r
+  UINT32                  NameSize;\r
+  AUTH_CERT_DB_DATA       *Ptr;\r
+\r
+  if ((VariableName == NULL) || (VendorGuid == NULL) || (CertData == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  //\r
+  // Get variable "certdb".\r
+  //\r
+  Status = FindVariable (\r
+             EFI_CERT_DB_NAME,\r
+             &gEfiCertDbGuid,\r
+             &CertDbVariable,\r
+             &mVariableModuleGlobal->VariableGlobal,\r
+             FALSE\r
+             );      \r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DataSize  = DataSizeOfVariable (CertDbVariable.CurrPtr);\r
+  Data      = GetVariableDataPtr (CertDbVariable.CurrPtr);\r
+  if ((DataSize == 0) || (Data == NULL)) {\r
+    ASSERT (FALSE);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Find whether matching cert node already exists in "certdb".\r
+  // If yes return error.\r
+  //\r
+  Status = FindCertsFromDb (\r
+             VariableName,\r
+             VendorGuid,\r
+             Data,\r
+             DataSize,\r
+             NULL,\r
+             NULL,\r
+             NULL,\r
+             NULL\r
+             );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    ASSERT (FALSE);\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+\r
+  //\r
+  // Construct new data content of variable "certdb".\r
+  //\r
+  NameSize      = (UINT32) StrLen (VariableName);\r
+  CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32) CertDataSize + NameSize * sizeof (CHAR16); \r
+  NewCertDbSize = (UINT32) DataSize + CertNodeSize;                  \r
+  NewCertDb     = AllocateZeroPool (NewCertDbSize);\r
+  if (NewCertDb == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Copy the DB entries before deleting node.\r
+  //\r
+  CopyMem (NewCertDb, Data, DataSize);\r
+  //\r
+  // Update CertDbListSize.\r
+  //\r
+  CopyMem (NewCertDb, &NewCertDbSize, sizeof (UINT32));\r
+  //\r
+  // Construct new cert node.\r
+  //\r
+  Ptr = (AUTH_CERT_DB_DATA *) (NewCertDb + DataSize);\r
+  CopyGuid (&Ptr->VendorGuid, VendorGuid);\r
+  CopyMem (&Ptr->CertNodeSize, &CertNodeSize, sizeof (UINT32));\r
+  CopyMem (&Ptr->NameSize, &NameSize, sizeof (UINT32));\r
+  CopyMem (&Ptr->CertDataSize, &CertDataSize, sizeof (UINT32));\r
+  \r
+  CopyMem (\r
+    (UINT8 *) Ptr + sizeof (AUTH_CERT_DB_DATA),\r
+    VariableName,\r
+    NameSize * sizeof (CHAR16)\r
+    );\r
+\r
+  CopyMem (\r
+    (UINT8 *) Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),\r
+    CertData,\r
+    CertDataSize\r
+    );\r
+  \r
+  //\r
+  // Set "certdb".\r
+  // \r
+  VarAttr  = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;  \r
+  Status   = UpdateVariable (\r
+               EFI_CERT_DB_NAME,\r
+               &gEfiCertDbGuid,\r
+               NewCertDb,\r
+               NewCertDbSize,\r
+               VarAttr,\r
+               0,\r
+               0,\r
+               &CertDbVariable,\r
+               NULL\r
+               );\r
+\r
+  FreePool (NewCertDb);\r
+  return Status;\r
+}\r
+\r
 /**\r
   Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\r
 \r
@@ -1499,7 +2021,7 @@ CompareTimeStamp (
                                           data, this value contains the required size.\r
   @param[in]  Variable                    The variable information which is used to keep track of variable usage.\r
   @param[in]  Attributes                  Attribute value of the variable.\r
-  @param[in]  Pk                          Verify against PK or KEK database.\r
+  @param[in]  AuthVarType                 Verify against PK or KEK database or private database.\r
   @param[out] VarDel                      Delete the variable or not.\r
 \r
   @retval EFI_INVALID_PARAMETER           Invalid parameter.\r
@@ -1518,7 +2040,7 @@ VerifyTimeBasedPayload (
   IN     UINTN                              DataSize,\r
   IN     VARIABLE_POINTER_TRACK             *Variable,\r
   IN     UINT32                             Attributes,\r
-  IN     BOOLEAN                            Pk,\r
+  IN     AUTHVAR_TYPE                       AuthVarType,\r
   OUT    BOOLEAN                            *VarDel\r
   )\r
 {\r
@@ -1532,7 +2054,6 @@ VerifyTimeBasedPayload (
   UINT32                           Attr;\r
   UINT32                           SigDataSize;\r
   UINT32                           KekDataSize;\r
-  BOOLEAN                          Result;\r
   BOOLEAN                          VerifyStatus;\r
   EFI_STATUS                       Status;\r
   EFI_SIGNATURE_LIST               *CertList;\r
@@ -1544,12 +2065,19 @@ VerifyTimeBasedPayload (
   VARIABLE_POINTER_TRACK           PkVariable;\r
   UINT8                            *Buffer;\r
   UINTN                            Length;\r
+  UINT8                            *SignerCerts;\r
+  UINT8                            *WrapSigData;\r
+  UINTN                            CertStackSize;\r
+  UINT8                            *CertsInCertDb;\r
+  UINT32                           CertsSizeinDb;\r
 \r
-  Result                 = FALSE;\r
   VerifyStatus           = FALSE;\r
   CertData               = NULL;\r
   NewData                = NULL;\r
   Attr                   = Attributes;\r
+  WrapSigData            = NULL;\r
+  SignerCerts            = NULL;\r
+  RootCert               = NULL;\r
 \r
   //\r
   // When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is\r
@@ -1633,7 +2161,7 @@ VerifyTimeBasedPayload (
 \r
   CopyMem (Buffer, PayloadPtr, PayloadSize);\r
 \r
-  if (Pk) {\r
+  if (AuthVarType == AuthVarTypePk) {\r
     //\r
     // Get platform key from variable.\r
     //\r
@@ -1666,7 +2194,7 @@ VerifyTimeBasedPayload (
                      NewDataSize\r
                      );\r
 \r
-  } else {\r
+  } else if (AuthVarType == AuthVarTypeKek) {\r
 \r
     //\r
     // Get KEK database from variable.\r
@@ -1718,10 +2246,85 @@ VerifyTimeBasedPayload (
       KekDataSize -= CertList->SignatureListSize;\r
       CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
     }\r
+  } else if (AuthVarType == AuthVarTypePriv) {\r
+\r
+    //\r
+    // Process common authenticated variable except PK/KEK/DB/DBX.\r
+    // Get signer's certificates from SignedData.\r
+    //\r
+    VerifyStatus = Pkcs7GetSigners (\r
+                     SigData,\r
+                     SigDataSize,\r
+                     &SignerCerts,\r
+                     &CertStackSize,\r
+                     &RootCert,\r
+                     &RootCertSize\r
+                     );\r
+    if (!VerifyStatus) {\r
+      goto Exit;\r
+    }\r
+\r
+    //\r
+    // Get previously stored signer's certificates from certdb for existing\r
+    // variable. Check whether they are identical with signer's certificates\r
+    // in SignedData. If not, return error immediately.\r
+    //\r
+    if ((Variable->CurrPtr != NULL)) {\r
+      VerifyStatus = FALSE;\r
+\r
+      Status = GetCertsFromDb (VariableName, VendorGuid, &CertsInCertDb, &CertsSizeinDb);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Exit;\r
+      }\r
+    \r
+      if ((CertStackSize != CertsSizeinDb) ||\r
+          (CompareMem (SignerCerts, CertsInCertDb, CertsSizeinDb) != 0)) {\r
+        goto Exit;\r
+      }\r
+    }\r
+\r
+    VerifyStatus = Pkcs7Verify (\r
+                     SigData,\r
+                     SigDataSize,\r
+                     RootCert,\r
+                     RootCertSize,\r
+                     NewData,\r
+                     NewDataSize\r
+                     );\r
+    if (!VerifyStatus) {\r
+      goto Exit;\r
+    }\r
+\r
+    //\r
+    // Delete signer's certificates when delete the common authenticated variable.\r
+    //\r
+    if ((PayloadSize == 0) && (Variable->CurrPtr != NULL)) {\r
+      Status = DeleteCertsFromDb (VariableName, VendorGuid);\r
+      if (EFI_ERROR (Status)) {\r
+        VerifyStatus = FALSE;\r
+        goto Exit;\r
+      }\r
+    } else if (Variable->CurrPtr == NULL) {\r
+      //\r
+      // Insert signer's certificates when adding a new common authenticated variable.\r
+      //\r
+      Status = InsertCertsToDb (VariableName, VendorGuid, SignerCerts, CertStackSize);\r
+      if (EFI_ERROR (Status)) {\r
+        VerifyStatus = FALSE;\r
+        goto Exit;\r
+      }\r
+    }\r
+  } else {\r
+    return EFI_SECURITY_VIOLATION;\r
   }\r
 \r
 Exit:\r
 \r
+  if (AuthVarType == AuthVarTypePriv) {\r
+    Pkcs7FreeSigners (RootCert);\r
+    Pkcs7FreeSigners (SignerCerts);\r
+  }\r
+\r
   if (!VerifyStatus) {\r
     return EFI_SECURITY_VIOLATION;\r
   }\r
@@ -1738,15 +2341,16 @@ Exit:
   //\r
   // Final step: Update/Append Variable if it pass Pkcs7Verify\r
   //\r
-  return   UpdateVariable (\r
-             VariableName,\r
-             VendorGuid,\r
-             PayloadPtr,\r
-             PayloadSize,\r
-             Attributes,\r
-             0,\r
-             0,\r
-             Variable,\r
-             &CertData->TimeStamp\r
-             );\r
+  return UpdateVariable (\r
+           VariableName,\r
+           VendorGuid,\r
+           PayloadPtr,\r
+           PayloadSize,\r
+           Attributes,\r
+           0,\r
+           0,\r
+           Variable,\r
+           &CertData->TimeStamp\r
+           );\r
 }\r
+\r