]> git.proxmox.com Git - mirror_edk2.git/commitdiff
SecurityPkg: Update VariableAuthenticated driver with following changes:
authorxdu2 <xdu2@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 28 Oct 2011 09:55:09 +0000 (09:55 +0000)
committerxdu2 <xdu2@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 28 Oct 2011 09:55:09 +0000 (09:55 +0000)
1. Remove memory allocation code in runtime.
2. Exclude NULL terminator in VariableName for serialization data in time-based variable authentication.
3. Add support for enroll PK with WRITE_ACCESS attribute.
4. Initialize SetupMode variable with correct NV attribute.
5. Add support for APPEND_WRITE attribute for non-existing Variable.
6. Clear KEK, DB and DBX as well as PK when user request to clear platform keys.
7. Check duplicated EFI_SIGNATURE_DATA for Variable formatted as EFI_SIGNATURE_LIST when APPEND_WRITE attribute is set.
8. Not change SecureBoot Variable in runtime, only update it in boot time since this Variable indicates firmware operating mode.
9. Save time stamp of PK when PK is set with TIME_BASED_WRITE_ACCESS attribute in setup mode.
10. Update to use PcdMaxVariableSize instead of PcdMaxAppendVariableSize for append operation.

Signed-off-by: xdu2
Reviewed-by: tye
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12599 6f19259b-4bc3-4df7-8a09-765794883524

SecurityPkg/VariableAuthenticated/Pei/Variable.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h
SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf

index 240bc8aa432675733e0cff289f0580f097b29450..7549be2dca45ca02930b5bad5d02c9767652afc7 100644 (file)
@@ -323,7 +323,7 @@ CompareWithValidVariable (
 /**\r
   Return the variable store header and the index table based on the Index.\r
 \r
-  @param Index      The index of the variable store.\r
+  @param Type      The type of the variable store.\r
   @param IndexTable Return the index table.\r
 \r
   @return  Pointer to the variable store header.\r
index ff5c6539125af152a47bedfaf276107c492fec22..bb625ff2c0ca8bf2a25e42f079ca40a0b36178c6 100644 (file)
@@ -3,12 +3,12 @@
   service in UEFI2.2.\r
 \r
 Copyright (c) 2009 - 2011, 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
+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
+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
@@ -18,7 +18,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 ///\r
 /// Global database array for scratch\r
-/// \r
+///\r
 UINT8    mPubKeyStore[MAX_KEYDB_SIZE];\r
 UINT32   mPubKeyNumber;\r
 UINT32   mPlatformMode;\r
@@ -32,28 +32,50 @@ CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };
 //\r
 VOID  *mHashCtx = NULL;\r
 \r
-\r
 //\r
-// Pointer to runtime buffer. \r
-// For "Append" operation to an existing variable, a read/modify/write operation \r
-// is supported by firmware internally. Reserve runtime buffer to cache previous \r
+// Pointer to runtime buffer.\r
+// For "Append" operation to an existing variable, a read/modify/write operation\r
+// is supported by firmware internally. Reserve runtime buffer to cache previous\r
 // variable data in runtime phase because memory allocation is forbidden in virtual mode.\r
 //\r
 VOID  *mStorageArea = NULL;\r
 \r
+//\r
+// The serialization of the values of the VariableName, VendorGuid and Attributes\r
+// parameters of the SetVariable() call and the TimeStamp component of the\r
+// EFI_VARIABLE_AUTHENTICATION_2 descriptor followed by the variable's new value\r
+// i.e. (VariableName, VendorGuid, Attributes, TimeStamp, Data)\r
+//\r
+UINT8 *mSerializationRuntimeBuffer = NULL;\r
+\r
 /**\r
-  Update platform mode.\r
+  Internal function to delete a Variable given its name and GUID, no authentication\r
+  required.\r
 \r
-  @param[in]      Mode                    SETUP_MODE or USER_MODE.\r
+  @param[in]      VariableName            Name of the Variable.\r
+  @param[in]      VendorGuid              GUID of the Variable.\r
 \r
-  @return EFI_INVALID_PARAMETER           Invalid parameter.\r
-  @return EFI_SUCCESS                     Update platform mode successfully.\r
+  @retval EFI_SUCCESS              Variable deleted successfully.\r
+  @retval Others                   The driver failded to start the device.\r
 \r
 **/\r
 EFI_STATUS\r
-UpdatePlatformMode (\r
-  IN  UINT32                    Mode\r
-  );\r
+DeleteVariable (\r
+  IN  CHAR16                    *VariableName,\r
+  IN  EFI_GUID                  *VendorGuid\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  VARIABLE_POINTER_TRACK  Variable;\r
+\r
+  Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  ASSERT (Variable.CurrPtr != NULL);\r
+  return UpdateVariable (VariableName, VendorGuid, NULL, 0, 0, 0, 0, &Variable, NULL);\r
+}\r
 \r
 /**\r
   Initializes for authenticated varibale service.\r
@@ -69,7 +91,6 @@ AutenticatedVariableServiceInitialize (
 {\r
   EFI_STATUS              Status;\r
   VARIABLE_POINTER_TRACK  Variable;\r
-  VARIABLE_POINTER_TRACK  Variable2;\r
   UINT8                   VarValue;\r
   UINT32                  VarAttr;\r
   UINT8                   *Data;\r
@@ -77,7 +98,7 @@ AutenticatedVariableServiceInitialize (
   UINTN                   CtxSize;\r
   UINT8                   SecureBootMode;\r
   UINT8                   SecureBootEnable;\r
-  \r
+\r
   //\r
   // Initialize hash context.\r
   //\r
@@ -90,19 +111,28 @@ AutenticatedVariableServiceInitialize (
   //\r
   // Reserved runtime buffer for "Append" operation in virtual mode.\r
   //\r
-  mStorageArea  = AllocateRuntimePool (PcdGet32 (PcdMaxAppendVariableSize));\r
+  mStorageArea  = AllocateRuntimePool (PcdGet32 (PcdMaxVariableSize));\r
   if (mStorageArea == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \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
+  // Prepare runtime buffer for serialized data of time-based authenticated\r
+  // Variable, i.e. (VariableName, VendorGuid, Attributes, TimeStamp, Data).\r
+  //\r
+  mSerializationRuntimeBuffer = AllocateRuntimePool (PcdGet32 (PcdMaxVariableSize) + sizeof (EFI_GUID) + sizeof (UINT32) + sizeof (EFI_TIME));\r
+  if (mSerializationRuntimeBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\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
-             AUTHVAR_KEYDB_NAME, \r
-             &gEfiAuthenticatedVariableGuid, \r
-             &Variable, \r
+             AUTHVAR_KEYDB_NAME,\r
+             &gEfiAuthenticatedVariableGuid,\r
+             &Variable,\r
              &mVariableModuleGlobal->VariableGlobal\r
              );\r
 \r
@@ -135,31 +165,31 @@ AutenticatedVariableServiceInitialize (
     mPubKeyNumber = (UINT32) (DataSize / EFI_CERT_TYPE_RSA2048_SIZE);\r
   }\r
   //\r
-  // Check "SetupMode" variable's existence. \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
+  // Then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
   //\r
   Status = FindVariable (\r
-             EFI_SETUP_MODE_NAME, \r
-             &gEfiGlobalVariableGuid, \r
-             &Variable, \r
+             EFI_SETUP_MODE_NAME,\r
+             &gEfiGlobalVariableGuid,\r
+             &Variable,\r
              &mVariableModuleGlobal->VariableGlobal\r
              );\r
 \r
   if (Variable.CurrPtr == NULL) {\r
     Status = FindVariable (\r
-               EFI_PLATFORM_KEY_NAME, \r
-               &gEfiGlobalVariableGuid, \r
-               &Variable2, \r
+               EFI_PLATFORM_KEY_NAME,\r
+               &gEfiGlobalVariableGuid,\r
+               &Variable,\r
                &mVariableModuleGlobal->VariableGlobal\r
                );\r
-    if (Variable2.CurrPtr == NULL) {\r
+    if (Variable.CurrPtr == NULL) {\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
+    VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
     Status  = UpdateVariable (\r
                 EFI_SETUP_MODE_NAME,\r
                 &gEfiGlobalVariableGuid,\r
@@ -178,17 +208,16 @@ AutenticatedVariableServiceInitialize (
     mPlatformMode = *(GetVariableDataPtr (Variable.CurrPtr));\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
+  // 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
+             EFI_SIGNATURE_SUPPORT_NAME,\r
+             &gEfiGlobalVariableGuid,\r
+             &Variable,\r
              &mVariableModuleGlobal->VariableGlobal\r
              );\r
 \r
-\r
   if (Variable.CurrPtr == NULL) {\r
     VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
     Status  = UpdateVariable (\r
@@ -206,26 +235,26 @@ AutenticatedVariableServiceInitialize (
 \r
   //\r
   // If "SecureBootEnable" variable exists, then update "SecureBoot" variable.\r
-  // If "SecureBootEnable" variable is SECURE_BOOT_ENABLE, Set "SecureBoot" variable to SECURE_BOOT_MODE_ENABLE.\r
+  // If "SecureBootEnable" variable is SECURE_BOOT_ENABLE and in USER_MODE, Set "SecureBoot" variable to SECURE_BOOT_MODE_ENABLE.\r
   // If "SecureBootEnable" variable is SECURE_BOOT_DISABLE, Set "SecureBoot" variable to SECURE_BOOT_MODE_DISABLE.\r
   //\r
+  SecureBootEnable = SECURE_BOOT_MODE_DISABLE;\r
   FindVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
   if (Variable.CurrPtr != NULL) {\r
     SecureBootEnable = *(GetVariableDataPtr (Variable.CurrPtr));\r
-    if (SecureBootEnable == SECURE_BOOT_ENABLE) {\r
-      SecureBootMode = SECURE_BOOT_MODE_ENABLE;\r
-    } else {\r
-      SecureBootMode = SECURE_BOOT_MODE_DISABLE;\r
-    }\r
-    FindVariable (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
+  } else if (mPlatformMode == USER_MODE) {\r
+    //\r
+    // "SecureBootEnable" not exist, initialize it in USER_MODE.\r
+    //\r
+    SecureBootEnable = SECURE_BOOT_MODE_ENABLE;\r
     Status = UpdateVariable (\r
-               EFI_SECURE_BOOT_MODE_NAME, \r
-               &gEfiGlobalVariableGuid, \r
-               &SecureBootMode, \r
-               sizeof(UINT8), \r
-               EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, \r
-               0, \r
-               0, \r
+               EFI_SECURE_BOOT_ENABLE_NAME,\r
+               &gEfiSecureBootEnableDisableGuid,\r
+               &SecureBootEnable,\r
+               sizeof (UINT8),\r
+               EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+               0,\r
+               0,\r
                &Variable,\r
                NULL\r
                );\r
@@ -234,44 +263,54 @@ AutenticatedVariableServiceInitialize (
     }\r
   }\r
 \r
+  if (SecureBootEnable == SECURE_BOOT_ENABLE && mPlatformMode == USER_MODE) {\r
+    SecureBootMode = SECURE_BOOT_MODE_ENABLE;\r
+  } else {\r
+    SecureBootMode = SECURE_BOOT_MODE_DISABLE;\r
+  }\r
+  FindVariable (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
+  Status = UpdateVariable (\r
+             EFI_SECURE_BOOT_MODE_NAME,\r
+             &gEfiGlobalVariableGuid,\r
+             &SecureBootMode,\r
+             sizeof (UINT8),\r
+             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,\r
+             0,\r
+             0,\r
+             &Variable,\r
+             NULL\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   //\r
   // Detect whether a secure platform-specific method to clear PK(Platform Key)\r
-  // is configured by platform owner. This method is provided for users force to clear PK \r
+  // is configured by platform owner. This method is provided for users force to clear PK\r
   // in case incorrect enrollment mis-haps.\r
   //\r
   if (ForceClearPK ()) {\r
     //\r
-    // 1. Check whether PK is existing, and clear PK if existing\r
+    // 1. Clear PK.\r
     //\r
-    FindVariable (\r
-      EFI_PLATFORM_KEY_NAME, \r
-      &gEfiGlobalVariableGuid, \r
-      &Variable, \r
-      &mVariableModuleGlobal->VariableGlobal\r
-      );\r
-    if (Variable.CurrPtr != NULL) {\r
-      VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
-      Status  = UpdateVariable (\r
-                  EFI_PLATFORM_KEY_NAME,\r
-                  &gEfiGlobalVariableGuid,\r
-                  NULL,\r
-                  0,\r
-                  VarAttr,\r
-                  0,\r
-                  0,\r
-                  &Variable,\r
-                  NULL\r
-                  );\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
+    Status = DeleteVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
     }\r
 \r
     //\r
-    // 2. Update "SetupMode" variable to SETUP_MODE\r
+    // 2. Update "SetupMode" variable to SETUP_MODE.\r
     //\r
     UpdatePlatformMode (SETUP_MODE);\r
+\r
+    //\r
+    // 3. Clear KEK, DB and DBX.\r
+    //\r
+    DeleteVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid);\r
+    DeleteVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid);\r
+    DeleteVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid);\r
   }\r
+\r
   return Status;\r
 }\r
 \r
@@ -358,9 +397,9 @@ AddPubKeyInStore (
   @param[in]      DataSize                Size of Data.\r
   @param[in]      PubKey                  Public key used for verification.\r
 \r
-  @return EFI_INVALID_PARAMETER       Invalid parameter.\r
+  @retval EFI_INVALID_PARAMETER       Invalid parameter.\r
   @retval EFI_SECURITY_VIOLATION      If authentication failed.\r
-  @return EFI_SUCCESS                 Authentication successful.\r
+  @retval EFI_SUCCESS                 Authentication successful.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -427,7 +466,7 @@ VerifyCounterBasedPayload (
   //\r
   Rsa = RsaNew ();\r
   ASSERT (Rsa != NULL);\r
-  // \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
@@ -443,10 +482,10 @@ VerifyCounterBasedPayload (
   // Verify the signature.\r
   //\r
   Status = RsaPkcs1Verify (\r
-             Rsa, \r
-             Digest, \r
-             SHA256_DIGEST_SIZE, \r
-             CertBlock->Signature, \r
+             Rsa,\r
+             Digest,\r
+             SHA256_DIGEST_SIZE,\r
+             CertBlock->Signature,\r
              EFI_CERT_TYPE_RSA2048_SHA256_SIZE\r
              );\r
 \r
@@ -461,7 +500,6 @@ Done:
   }\r
 }\r
 \r
-\r
 /**\r
   Update platform mode.\r
 \r
@@ -482,11 +520,11 @@ UpdatePlatformMode (
   UINT8                   SecureBootMode;\r
   UINT8                   SecureBootEnable;\r
   UINTN                   VariableDataSize;\r
-  \r
+\r
   Status = FindVariable (\r
-             EFI_SETUP_MODE_NAME, \r
-             &gEfiGlobalVariableGuid, \r
-             &Variable, \r
+             EFI_SETUP_MODE_NAME,\r
+             &gEfiGlobalVariableGuid,\r
+             &Variable,\r
              &mVariableModuleGlobal->VariableGlobal\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -494,7 +532,7 @@ UpdatePlatformMode (
   }\r
 \r
   mPlatformMode  = Mode;\r
-  VarAttr        = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
+  VarAttr        = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
   Status         = UpdateVariable (\r
                      EFI_SETUP_MODE_NAME,\r
                      &gEfiGlobalVariableGuid,\r
@@ -510,15 +548,24 @@ UpdatePlatformMode (
     return Status;\r
   }\r
 \r
+  if (AtRuntime ()) {\r
+    //\r
+    // SecureBoot Variable indicates whether the platform firmware is operating\r
+    // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
+    // Variable in runtime.\r
+    //\r
+    return Status;\r
+  }\r
+\r
   //\r
   // Check "SecureBoot" variable's existence.\r
   // If it doesn't exist, firmware has no capability to perform driver signing verification,\r
   // then set "SecureBoot" to 0.\r
   //\r
   Status = FindVariable (\r
-             EFI_SECURE_BOOT_MODE_NAME, \r
-             &gEfiGlobalVariableGuid, \r
-             &Variable, \r
+             EFI_SECURE_BOOT_MODE_NAME,\r
+             &gEfiGlobalVariableGuid,\r
+             &Variable,\r
              &mVariableModuleGlobal->VariableGlobal\r
              );\r
   //\r
@@ -538,7 +585,7 @@ UpdatePlatformMode (
     }\r
   }\r
 \r
-  VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
+  VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
   Status  = UpdateVariable (\r
               EFI_SECURE_BOOT_MODE_NAME,\r
               &gEfiGlobalVariableGuid,\r
@@ -550,7 +597,6 @@ UpdatePlatformMode (
               &Variable,\r
               NULL\r
               );\r
-\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -559,12 +605,12 @@ UpdatePlatformMode (
   // Check "SecureBootEnable" variable's existence. It can enable/disable secure boot feature.\r
   //\r
   Status = FindVariable (\r
-             EFI_SECURE_BOOT_ENABLE_NAME, \r
-             &gEfiSecureBootEnableDisableGuid, \r
-             &Variable, \r
+             EFI_SECURE_BOOT_ENABLE_NAME,\r
+             &gEfiSecureBootEnableDisableGuid,\r
+             &Variable,\r
              &mVariableModuleGlobal->VariableGlobal\r
              );\r
\r
+\r
   if (SecureBootMode == SECURE_BOOT_MODE_ENABLE) {\r
     //\r
     // Create the "SecureBootEnable" variable as secure boot is enabled.\r
@@ -573,7 +619,7 @@ UpdatePlatformMode (
     VariableDataSize = sizeof (SecureBootEnable);\r
   } else {\r
     //\r
-    // Delete the "SecureBootEnable" variable if this variable exist as "SecureBoot" \r
+    // Delete the "SecureBootEnable" variable if this variable exist as "SecureBoot"\r
     // variable is not in secure boot state.\r
     //\r
     if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
@@ -582,15 +628,15 @@ UpdatePlatformMode (
     SecureBootEnable = SECURE_BOOT_DISABLE;\r
     VariableDataSize = 0;\r
   }\r
-  \r
+\r
   Status = UpdateVariable (\r
-             EFI_SECURE_BOOT_ENABLE_NAME, \r
-             &gEfiSecureBootEnableDisableGuid, \r
-             &SecureBootEnable, \r
-             VariableDataSize, \r
-             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, \r
-             0, \r
-             0, \r
+             EFI_SECURE_BOOT_ENABLE_NAME,\r
+             &gEfiSecureBootEnableDisableGuid,\r
+             &SecureBootEnable,\r
+             VariableDataSize,\r
+             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+             0,\r
+             0,\r
              &Variable,\r
              NULL\r
              );\r
@@ -610,8 +656,8 @@ UpdatePlatformMode (
   @param[in]  IsPk                        Indicate whether it is to process pk.\r
 \r
   @return EFI_INVALID_PARAMETER           Invalid parameter.\r
-  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation. \r
-                                          check carried out by the firmware. \r
+  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation.\r
+                                          check carried out by the firmware.\r
   @return EFI_SUCCESS                     Variable passed validation successfully.\r
 \r
 **/\r
@@ -633,6 +679,10 @@ ProcessVarWithPk (
   EFI_VARIABLE_AUTHENTICATION *CertData;\r
   BOOLEAN                     TimeBase;\r
   BOOLEAN                     Del;\r
+  UINT8                       *Payload;\r
+  UINTN                       PayloadSize;\r
+  UINT64                      MonotonicCount;\r
+  EFI_TIME                    *TimeStamp;\r
 \r
   if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
     //\r
@@ -687,29 +737,29 @@ ProcessVarWithPk (
       // Get platform key from variable.\r
       //\r
       Status = FindVariable (\r
-                 EFI_PLATFORM_KEY_NAME, \r
-                 &gEfiGlobalVariableGuid, \r
-                 &PkVariable, \r
+                 EFI_PLATFORM_KEY_NAME,\r
+                 &gEfiGlobalVariableGuid,\r
+                 &PkVariable,\r
                  &mVariableModuleGlobal->VariableGlobal\r
                  );\r
       ASSERT_EFI_ERROR (Status);\r
-  \r
+\r
       OldPkList = (EFI_SIGNATURE_LIST *) GetVariableDataPtr (PkVariable.CurrPtr);\r
       OldPkData = (EFI_SIGNATURE_DATA *) ((UINT8 *) OldPkList + sizeof (EFI_SIGNATURE_LIST) + OldPkList->SignatureHeaderSize);\r
       Status    = VerifyCounterBasedPayload (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
+                   VariableName,\r
+                   VendorGuid,\r
+                   (UINT8*)Data + AUTHINFO_SIZE,\r
+                   DataSize - AUTHINFO_SIZE,\r
+                   Attributes,\r
+                   0,\r
+                   CertData->MonotonicCount,\r
                    Variable,\r
                    NULL\r
                    );\r
-  \r
+\r
         if (!EFI_ERROR (Status)) {\r
           //\r
           // If delete PK in user mode, need change to setup mode.\r
@@ -721,7 +771,46 @@ ProcessVarWithPk (
       }\r
     }\r
   } else {\r
-    Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, 0, 0, Variable, NULL);\r
+    //\r
+    // Process PK or KEK in Setup mode.\r
+    //\r
+    if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+      //\r
+      // Time-based Authentication descriptor.\r
+      //\r
+      MonotonicCount = 0;\r
+      TimeStamp = &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp;\r
+      Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data);\r
+      PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
+    } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+      //\r
+      // Counter-based Authentication descriptor.\r
+      //\r
+      MonotonicCount = ((EFI_VARIABLE_AUTHENTICATION *) Data)->MonotonicCount;\r
+      TimeStamp = NULL;\r
+      Payload = (UINT8*) Data + AUTHINFO_SIZE;\r
+      PayloadSize = DataSize - AUTHINFO_SIZE;\r
+    } else {\r
+      //\r
+      // No Authentication descriptor.\r
+      //\r
+      MonotonicCount = 0;\r
+      TimeStamp = NULL;\r
+      Payload = Data;\r
+      PayloadSize = DataSize;\r
+    }\r
+\r
+    Status = UpdateVariable (\r
+               VariableName,\r
+               VendorGuid,\r
+               Payload,\r
+               PayloadSize,\r
+               Attributes,\r
+               0,\r
+               MonotonicCount,\r
+               Variable,\r
+               TimeStamp\r
+               );\r
     //\r
     // If enroll PK in setup mode, need change to user mode.\r
     //\r
@@ -745,8 +834,8 @@ ProcessVarWithPk (
   @param[in]  Attributes                  Attribute value of the variable.\r
 \r
   @return EFI_INVALID_PARAMETER           Invalid parameter.\r
-  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation \r
-                                          check carried out by the firmware. \r
+  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation\r
+                                          check carried out by the firmware.\r
   @return EFI_SUCCESS                     Variable pass validation successfully.\r
 \r
 **/\r
@@ -770,6 +859,9 @@ ProcessVarWithKek (
   BOOLEAN                         IsFound;\r
   UINT32                          Index;\r
   UINT32                          KekDataSize;\r
+  UINT8                           *Payload;\r
+  UINTN                           PayloadSize;\r
+  UINT64                          MonotonicCount;\r
 \r
   if (mPlatformMode == USER_MODE) {\r
     if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
@@ -791,9 +883,9 @@ ProcessVarWithKek (
     // Get KEK database from variable.\r
     //\r
     Status = FindVariable (\r
-               EFI_KEY_EXCHANGE_KEY_NAME, \r
-               &gEfiGlobalVariableGuid, \r
-               &KekVariable, \r
+               EFI_KEY_EXCHANGE_KEY_NAME,\r
+               &gEfiGlobalVariableGuid,\r
+               &KekVariable,\r
                &mVariableModuleGlobal->VariableGlobal\r
                );\r
     ASSERT_EFI_ERROR (Status);\r
@@ -821,7 +913,7 @@ ProcessVarWithKek (
       KekDataSize -= KekList->SignatureListSize;\r
       KekList = (EFI_SIGNATURE_LIST *) ((UINT8 *) KekList + KekList->SignatureListSize);\r
     }\r
-    \r
+\r
     if (!IsFound) {\r
       return EFI_SECURITY_VIOLATION;\r
     }\r
@@ -829,13 +921,13 @@ ProcessVarWithKek (
     Status = VerifyCounterBasedPayload (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
+                 VariableName,\r
+                 VendorGuid,\r
+                 (UINT8*)Data + AUTHINFO_SIZE,\r
+                 DataSize - AUTHINFO_SIZE,\r
+                 Attributes,\r
+                 0,\r
+                 CertData->MonotonicCount,\r
                  Variable,\r
                  NULL\r
                  );\r
@@ -844,14 +936,30 @@ ProcessVarWithKek (
     //\r
     // If in setup mode, no authentication needed.\r
     //\r
+    if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+      //\r
+      // Counter-based Authentication descriptor.\r
+      //\r
+      MonotonicCount = ((EFI_VARIABLE_AUTHENTICATION *) Data)->MonotonicCount;\r
+      Payload = (UINT8*) Data + AUTHINFO_SIZE;\r
+      PayloadSize = DataSize - AUTHINFO_SIZE;\r
+    } else {\r
+      //\r
+      // No Authentication descriptor.\r
+      //\r
+      MonotonicCount = 0;\r
+      Payload = Data;\r
+      PayloadSize = DataSize;\r
+    }\r
+\r
     Status = UpdateVariable (\r
-               VariableName, \r
-               VendorGuid, \r
-               Data, \r
-               DataSize, \r
-               Attributes, \r
-               0, \r
-               0, \r
+               VariableName,\r
+               VendorGuid,\r
+               Payload,\r
+               PayloadSize,\r
+               Attributes,\r
+               0,\r
+               MonotonicCount,\r
                Variable,\r
                NULL\r
                );\r
@@ -876,8 +984,8 @@ ProcessVarWithKek (
   @return EFI_WRITE_PROTECTED             Variable is write-protected and needs authentication with\r
                                           EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
   @return 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
+                                          set, but the AuthInfo does NOT pass the validation\r
+                                          check carried out by the firmware.\r
   @return EFI_SUCCESS                     Variable is not write-protected or pass validation successfully.\r
 \r
 **/\r
@@ -900,7 +1008,7 @@ ProcessVariable (
   UINT32                          KeyIndex;\r
   UINT64                          MonotonicCount;\r
 \r
-  KeyIndex    = 0;  \r
+  KeyIndex    = 0;\r
   CertData    = NULL;\r
   CertBlock   = NULL;\r
   PubKey      = NULL;\r
@@ -912,7 +1020,7 @@ ProcessVariable (
   if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
     return VerifyTimeBasedPayload (VariableName, VendorGuid, Data, DataSize, Variable, Attributes, FALSE, NULL);\r
   }\r
-  \r
+\r
   //\r
   // Determine if first time SetVariable with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS.\r
   //\r
@@ -979,7 +1087,7 @@ ProcessVariable (
       //\r
       return EFI_SECURITY_VIOLATION;\r
     }\r
-  } \r
+  }\r
   //\r
   // Verify the certificate in Data payload.\r
   //\r
@@ -987,7 +1095,7 @@ ProcessVariable (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Now, the signature has been verified!\r
   //\r
@@ -1004,6 +1112,114 @@ ProcessVariable (
   return UpdateVariable (VariableName, VendorGuid, (UINT8*)Data + AUTHINFO_SIZE, DataSize - AUTHINFO_SIZE, Attributes, KeyIndex, MonotonicCount, Variable, NULL);\r
 }\r
 \r
+/**\r
+  Merge two buffers which formatted as EFI_SIGNATURE_LIST. Only the new EFI_SIGNATURE_DATA\r
+  will be appended to the original EFI_SIGNATURE_LIST, duplicate EFI_SIGNATURE_DATA\r
+  will be ignored.\r
+\r
+  @param[in, out]  Data            Pointer to original EFI_SIGNATURE_LIST.\r
+  @param[in]       DataSize        Size of Data buffer.\r
+  @param[in]       NewData         Pointer to new EFI_SIGNATURE_LIST to be appended.\r
+  @param[in]       NewDataSize     Size of NewData buffer.\r
+\r
+  @return Size of the merged buffer.\r
+\r
+**/\r
+UINTN\r
+AppendSignatureList (\r
+  IN  OUT VOID            *Data,\r
+  IN  UINTN               DataSize,\r
+  IN  VOID                *NewData,\r
+  IN  UINTN               NewDataSize\r
+  )\r
+{\r
+  EFI_SIGNATURE_LIST  *CertList;\r
+  EFI_SIGNATURE_DATA  *Cert;\r
+  UINTN               CertCount;\r
+  EFI_SIGNATURE_LIST  *NewCertList;\r
+  EFI_SIGNATURE_DATA  *NewCert;\r
+  UINTN               NewCertCount;\r
+  UINTN               Index;\r
+  UINTN               Index2;\r
+  UINTN               Size;\r
+  UINT8               *Tail;\r
+  UINTN               CopiedCount;\r
+  UINTN               SignatureListSize;\r
+  BOOLEAN             IsNewCert;\r
+\r
+  Tail = (UINT8 *) Data + DataSize;\r
+\r
+  NewCertList = (EFI_SIGNATURE_LIST *) NewData;\r
+  while ((NewDataSize > 0) && (NewDataSize >= NewCertList->SignatureListSize)) {\r
+    NewCert      = (EFI_SIGNATURE_DATA *) ((UINT8 *) NewCertList + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);\r
+    NewCertCount = (NewCertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - NewCertList->SignatureHeaderSize) / NewCertList->SignatureSize;\r
+\r
+    CopiedCount = 0;\r
+    for (Index = 0; Index < NewCertCount; Index++) {\r
+      IsNewCert = TRUE;\r
+\r
+      Size = DataSize;\r
+      CertList = (EFI_SIGNATURE_LIST *) Data;\r
+      while ((Size > 0) && (Size >= CertList->SignatureListSize)) {\r
+        if (CompareGuid (&CertList->SignatureType, &NewCertList->SignatureType) &&\r
+           (CertList->SignatureSize == NewCertList->SignatureSize)) {\r
+          Cert      = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+          CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+          for (Index2 = 0; Index2 < CertCount; Index2++) {\r
+            //\r
+            // Iterate each Signature Data in this Signature List.\r
+            //\r
+            if (CompareMem (NewCert, Cert, CertList->SignatureSize) == 0) {\r
+              IsNewCert = FALSE;\r
+              break;\r
+            }\r
+            Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+          }\r
+        }\r
+\r
+        if (!IsNewCert) {\r
+          break;\r
+        }\r
+        Size -= CertList->SignatureListSize;\r
+        CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+      }\r
+\r
+      if (IsNewCert) {\r
+        //\r
+        // New EFI_SIGNATURE_DATA, append it.\r
+        //\r
+        if (CopiedCount == 0) {\r
+          //\r
+          // Copy EFI_SIGNATURE_LIST header for only once.\r
+          //\r
+          CopyMem (Tail, NewCertList, sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);\r
+          Tail = Tail + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize;\r
+        }\r
+\r
+        CopyMem (Tail, NewCert, NewCertList->SignatureSize);\r
+        Tail += NewCertList->SignatureSize;\r
+        CopiedCount++;\r
+      }\r
+\r
+      NewCert = (EFI_SIGNATURE_DATA *) ((UINT8 *) NewCert + NewCertList->SignatureSize);\r
+    }\r
+\r
+    //\r
+    // Update SignatureListSize in newly appended EFI_SIGNATURE_LIST.\r
+    //\r
+    if (CopiedCount != 0) {\r
+      SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize + (CopiedCount * NewCertList->SignatureSize);\r
+      CertList = (EFI_SIGNATURE_LIST *) (Tail - SignatureListSize);\r
+      CertList->SignatureListSize = (UINT32) SignatureListSize;\r
+    }\r
+\r
+    NewDataSize -= NewCertList->SignatureListSize;\r
+    NewCertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) NewCertList + NewCertList->SignatureListSize);\r
+  }\r
+\r
+  return (Tail - (UINT8 *) Data);\r
+}\r
+\r
 /**\r
   Compare two EFI_TIME data.\r
 \r
@@ -1031,7 +1247,7 @@ CompareTimeStamp (
     return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour);\r
   } else if (FirstTime->Minute != SecondTime->Minute) {\r
     return (BOOLEAN) (FirstTime->Minute < FirstTime->Minute);\r
-  } \r
+  }\r
 \r
   return (BOOLEAN) (FirstTime->Second <= SecondTime->Second);\r
 }\r
@@ -1050,8 +1266,8 @@ CompareTimeStamp (
   @param[out] VarDel                      Delete the variable or not.\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_SECURITY_VIOLATION          The variable does NOT pass the validation\r
+                                          check carried out by the firmware.\r
   @retval EFI_OUT_OF_RESOURCES            Failed to process variable due to lack\r
                                           of resources.\r
   @retval EFI_SUCCESS                     Variable pass validation successfully.\r
@@ -1071,11 +1287,11 @@ VerifyTimeBasedPayload (
 {\r
   UINT8                            *RootCert;\r
   UINT8                            *SigData;\r
-  UINT8                            *PayLoadPtr;\r
+  UINT8                            *PayloadPtr;\r
   UINTN                            RootCertSize;\r
   UINTN                            Index;\r
-  UINTN                            CertCount;  \r
-  UINTN                            PayLoadSize;  \r
+  UINTN                            CertCount;\r
+  UINTN                            PayloadSize;\r
   UINT32                           Attr;\r
   UINT32                           SigDataSize;\r
   UINT32                           KekDataSize;\r
@@ -1089,7 +1305,8 @@ VerifyTimeBasedPayload (
   UINT8                            *NewData;\r
   UINTN                            NewDataSize;\r
   VARIABLE_POINTER_TRACK           PkVariable;\r
-\r
+  UINT8                            *Buffer;\r
+  UINTN                            Length;\r
 \r
   Result                 = FALSE;\r
   VerifyStatus           = FALSE;\r
@@ -1098,15 +1315,27 @@ VerifyTimeBasedPayload (
   Attr                   = Attributes;\r
 \r
   //\r
-  // When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is \r
+  // When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is\r
   // set, then the Data buffer shall begin with an instance of a complete (and serialized)\r
-  // EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new \r
-  // variable value and DataSize shall reflect the combined size of the descriptor and the new \r
-  // variable value. The authentication descriptor is not part of the variable data and is not \r
+  // EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new\r
+  // variable value and DataSize shall reflect the combined size of the descriptor and the new\r
+  // variable value. The authentication descriptor is not part of the variable data and is not\r
   // returned by subsequent calls to GetVariable().\r
   //\r
   CertData = (EFI_VARIABLE_AUTHENTICATION_2 *) Data;\r
-  \r
+\r
+  //\r
+  // Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components of the\r
+  // TimeStamp value are set to zero.\r
+  //\r
+  if ((CertData->TimeStamp.Pad1 != 0) ||\r
+      (CertData->TimeStamp.Nanosecond != 0) ||\r
+      (CertData->TimeStamp.TimeZone != 0) ||\r
+      (CertData->TimeStamp.Daylight != 0) ||\r
+      (CertData->TimeStamp.Pad2 != 0)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   if ((Variable->CurrPtr != NULL) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {\r
     if (CompareTimeStamp (&CertData->TimeStamp, &Variable->CurrPtr->TimeStamp)) {\r
       //\r
@@ -1121,84 +1350,60 @@ VerifyTimeBasedPayload (
   // Cert type should be EFI_CERT_TYPE_PKCS7_GUID.\r
   //\r
   if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||\r
-      !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertPkcs7Guid)\r
-        ) {\r
+      !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertPkcs7Guid)) {\r
     //\r
     // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.\r
     //\r
     return EFI_SECURITY_VIOLATION;\r
   }\r
\r
+\r
   //\r
   // Find out Pkcs7 SignedData which follows the EFI_VARIABLE_AUTHENTICATION_2 descriptor.\r
   // AuthInfo.Hdr.dwLength is the length of the entire certificate, including the length of the header.\r
   //\r
-  SigData = (UINT8*) ((UINTN)Data + OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));\r
+  SigData = CertData->AuthInfo.CertData;\r
+  SigDataSize = CertData->AuthInfo.Hdr.dwLength - (UINT32) (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));\r
 \r
-  //\r
-  // Sanity check to avoid corrupted certificate input.\r
-  //\r
-  if (CertData->AuthInfo.Hdr.dwLength < (UINT32)(OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData))) {\r
-    return EFI_SECURITY_VIOLATION;\r
-  }\r
-\r
-\r
-\r
-  SigDataSize = CertData->AuthInfo.Hdr.dwLength - (UINT32)(OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));\r
-  \r
   //\r
   // Find out the new data payload which follows Pkcs7 SignedData directly.\r
   //\r
-  PayLoadPtr = (UINT8*) ((UINTN) SigData + (UINTN) SigDataSize);\r
-\r
-  //\r
-  // Sanity check to avoid corrupted certificate input.\r
-  //\r
-  if (DataSize < (OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)+ (UINTN) SigDataSize)) {\r
-    return EFI_SECURITY_VIOLATION;\r
-  }\r
-  \r
-  PayLoadSize = DataSize - OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) - OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData) - (UINTN) SigDataSize;\r
-\r
+  PayloadPtr = SigData + SigDataSize;\r
+  PayloadSize = DataSize - OFFSET_OF_AUTHINFO2_CERT_DATA - (UINTN) SigDataSize;\r
 \r
   //\r
   // Construct a buffer to fill with (VariableName, VendorGuid, Attributes, TimeStamp, Data).\r
   //\r
-  NewDataSize = PayLoadSize + sizeof (EFI_TIME) + sizeof (UINT32) +\r
-                sizeof (EFI_GUID) + StrSize (VariableName);\r
-  NewData     = (UINT8 *) AllocateZeroPool (NewDataSize);\r
-\r
-  if (NewData == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  CopyMem (NewData, VariableName, StrSize (VariableName));\r
+  NewDataSize = PayloadSize + sizeof (EFI_TIME) + sizeof (UINT32) +\r
+                sizeof (EFI_GUID) + StrSize (VariableName) - sizeof (CHAR16);\r
+  NewData = mSerializationRuntimeBuffer;\r
 \r
-  CopyMem (NewData + StrSize (VariableName), VendorGuid, sizeof (EFI_GUID));\r
+  Buffer = NewData;\r
+  Length = StrLen (VariableName) * sizeof (CHAR16);\r
+  CopyMem (Buffer, VariableName, Length);\r
+  Buffer += Length;\r
 \r
-  CopyMem (\r
-    NewData + StrSize (VariableName) + sizeof (EFI_GUID),\r
-    &Attr,\r
-    sizeof (UINT32)\r
-    );\r
+  Length = sizeof (EFI_GUID);\r
+  CopyMem (Buffer, VendorGuid, Length);\r
+  Buffer += Length;\r
 \r
-  CopyMem (\r
-    NewData + StrSize (VariableName) + sizeof (EFI_GUID) + sizeof (UINT32),\r
-    &CertData->TimeStamp,\r
-    sizeof (EFI_TIME)\r
-    );\r
+  Length = sizeof (UINT32);\r
+  CopyMem (Buffer, &Attr, Length);\r
+  Buffer += Length;\r
 \r
-  CopyMem (NewData + (NewDataSize - PayLoadSize), PayLoadPtr, PayLoadSize);\r
+  Length = sizeof (EFI_TIME);\r
+  CopyMem (Buffer, &CertData->TimeStamp, Length);\r
+  Buffer += Length;\r
 \r
+  CopyMem (Buffer, PayloadPtr, PayloadSize);\r
 \r
   if (Pk) {\r
     //\r
     // Get platform key from variable.\r
     //\r
     Status = FindVariable (\r
-               EFI_PLATFORM_KEY_NAME, \r
-               &gEfiGlobalVariableGuid, \r
-               &PkVariable, \r
+               EFI_PLATFORM_KEY_NAME,\r
+               &gEfiGlobalVariableGuid,\r
+               &PkVariable,\r
                &mVariableModuleGlobal->VariableGlobal\r
                );\r
     if (EFI_ERROR (Status)) {\r
@@ -1224,14 +1429,14 @@ VerifyTimeBasedPayload (
                      );\r
 \r
   } else {\r
-  \r
+\r
     //\r
     // Get KEK database from variable.\r
     //\r
     Status = FindVariable (\r
-               EFI_KEY_EXCHANGE_KEY_NAME, \r
-               &gEfiGlobalVariableGuid, \r
-               &KekVariable, \r
+               EFI_KEY_EXCHANGE_KEY_NAME,\r
+               &gEfiGlobalVariableGuid,\r
+               &KekVariable,\r
                &mVariableModuleGlobal->VariableGlobal\r
                );\r
     if (EFI_ERROR (Status)) {\r
@@ -1240,7 +1445,7 @@ VerifyTimeBasedPayload (
 \r
     //\r
     // Ready to verify Pkcs7 SignedData. Go through KEK Signature Database to find out X.509 CertList.\r
-    // \r
+    //\r
     KekDataSize      = KekVariable.CurrPtr->DataSize;\r
     CertList         = (EFI_SIGNATURE_LIST *) GetVariableDataPtr (KekVariable.CurrPtr);\r
     while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {\r
@@ -1253,7 +1458,7 @@ VerifyTimeBasedPayload (
           //\r
           RootCert      = Cert->SignatureData;\r
           RootCertSize  = CertList->SignatureSize;\r
-       \r
+\r
           //\r
           // Verify Pkcs7 SignedData via Pkcs7Verify library.\r
           //\r
@@ -1278,27 +1483,25 @@ VerifyTimeBasedPayload (
 \r
 Exit:\r
 \r
-  FreePool (NewData);\r
-\r
   if (!VerifyStatus) {\r
     return EFI_SECURITY_VIOLATION;\r
   }\r
 \r
-  if ((PayLoadSize == 0) && (VarDel != NULL)) {\r
+  if ((PayloadSize == 0) && (VarDel != NULL)) {\r
     *VarDel = TRUE;\r
   }\r
-  \r
+\r
   //\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
+             VariableName,\r
+             VendorGuid,\r
+             PayloadPtr,\r
+             PayloadSize,\r
+             Attributes,\r
+             0,\r
+             0,\r
              Variable,\r
              &CertData->TimeStamp\r
              );\r
index 6b0db74c8195b5bbefbf0466c9e339cf73e4e220..54e2ac0a435b7912b1a5c8645874995bbe860dab 100644 (file)
@@ -3,12 +3,12 @@
   internal structure and functions used by AuthService module.\r
 \r
 Copyright (c) 2009 - 2011, 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
+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
+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
@@ -20,9 +20,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define EFI_CERT_TYPE_RSA2048_SIZE        256\r
 \r
 ///\r
-/// Size of AuthInfo prior to the data payload\r
+/// Size of AuthInfo prior to the data payload.\r
 ///\r
-#define AUTHINFO_SIZE (((UINTN)(((EFI_VARIABLE_AUTHENTICATION *) 0)->AuthInfo.CertData)) + sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256))\r
+#define AUTHINFO_SIZE ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION, AuthInfo)) + \\r
+                       (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) + \\r
+                       sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256))\r
+\r
+#define AUTHINFO2_SIZE(VarAuth2) ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo)) + \\r
+                                  (UINTN) ((EFI_VARIABLE_AUTHENTICATION_2 *) (VarAuth2))->AuthInfo.Hdr.dwLength)\r
+\r
+#define OFFSET_OF_AUTHINFO2_CERT_DATA ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo)) + \\r
+                                       (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)))\r
 \r
 ///\r
 /// "AuthVarKeyDatabase" variable for the Public Key store.\r
@@ -58,8 +66,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
   @return EFI_WRITE_PROTECTED             Variable is write-protected and needs authentication with\r
                                           EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
   @return 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
+                                          set, but the AuthInfo does NOT pass the validation\r
+                                          check carried out by the firmware.\r
   @return EFI_SUCCESS                     Variable is not write-protected, or passed validation successfully.\r
 \r
 **/\r
@@ -73,6 +81,20 @@ ProcessVariable (
   IN     UINT32                             Attributes\r
   );\r
 \r
+/**\r
+  Update platform mode.\r
+\r
+  @param[in]      Mode                    SETUP_MODE or USER_MODE.\r
+\r
+  @return EFI_INVALID_PARAMETER           Invalid parameter.\r
+  @return EFI_SUCCESS                     Update platform mode successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdatePlatformMode (\r
+  IN  UINT32                    Mode\r
+  );\r
+\r
 /**\r
   Initializes for authenticated varibale service.\r
 \r
@@ -107,8 +129,8 @@ CryptLibraryInitialize (
   @param[in]  IsPk                        Indicate whether it is to process pk.\r
 \r
   @return EFI_INVALID_PARAMETER           Invalid parameter\r
-  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation \r
-                                          check carried out by the firmware. \r
+  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation\r
+                                          check carried out by the firmware.\r
   @return EFI_SUCCESS                     Variable passed validation successfully.\r
 \r
 **/\r
@@ -135,8 +157,8 @@ ProcessVarWithPk (
   @param[in]  Attributes                  Attribute value of the variable.\r
 \r
   @return EFI_INVALID_PARAMETER           Invalid parameter.\r
-  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation \r
-                                          check carried out by the firmware. \r
+  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation\r
+                                          check carried out by the firmware.\r
   @return EFI_SUCCESS                     Variable passed validation successfully.\r
 \r
 **/\r
@@ -150,6 +172,27 @@ ProcessVarWithKek (
   IN  UINT32                    Attributes OPTIONAL\r
   );\r
 \r
+/**\r
+  Merge two buffers which formatted as EFI_SIGNATURE_LIST. Only the new EFI_SIGNATURE_DATA\r
+  will be appended to the original EFI_SIGNATURE_LIST, duplicate EFI_SIGNATURE_DATA\r
+  will be ignored.\r
+\r
+  @param[in, out]  Data            Pointer to original EFI_SIGNATURE_LIST.\r
+  @param[in]       DataSize        Size of Data buffer.\r
+  @param[in]       NewData         Pointer to new EFI_SIGNATURE_LIST to be appended.\r
+  @param[in]       NewDataSize     Size of NewData buffer.\r
+\r
+  @return Size of the merged buffer.\r
+\r
+**/\r
+UINTN\r
+AppendSignatureList (\r
+  IN  OUT VOID            *Data,\r
+  IN  UINTN               DataSize,\r
+  IN  VOID                *NewData,\r
+  IN  UINTN               NewDataSize\r
+  );\r
+\r
 /**\r
   Compare two EFI_TIME data.\r
 \r
@@ -182,8 +225,8 @@ CompareTimeStamp (
   @param[out] VarDel                      Delete the variable or not.\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_SECURITY_VIOLATION          The variable does NOT pass the validation\r
+                                          check carried out by the firmware.\r
   @retval EFI_OUT_OF_RESOURCES            Failed to process variable due to lack\r
                                           of resources.\r
   @retval EFI_SUCCESS                     Variable pass validation successfully.\r
@@ -205,5 +248,6 @@ extern UINT8  mPubKeyStore[MAX_KEYDB_SIZE];
 extern UINT32 mPubKeyNumber;\r
 extern VOID   *mHashCtx;\r
 extern VOID   *mStorageArea;\r
-  \r
+extern UINT8  *mSerializationRuntimeBuffer;\r
+\r
 #endif\r
index 32bddbcb02fd5ed62b8e5c43345170f6a0080f4c..7d0d21502af63e9383625168f8ce6cf45aa91902 100644 (file)
@@ -1,14 +1,14 @@
 /** @file\r
-  The common variable operation routines shared by DXE_RINTIME variable \r
+  The common variable operation routines shared by DXE_RINTIME variable\r
   module and DXE_SMM variable module.\r
 \r
 Copyright (c) 2009 - 2011, 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
+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
+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
@@ -30,13 +30,13 @@ VARIABLE_INFO_ENTRY    *gVariableInfo    = NULL;
 \r
 \r
 /**\r
-  Routine used to track statistical information about variable usage. \r
+  Routine used to track statistical information about variable usage.\r
   The data is stored in the EFI system table so it can be accessed later.\r
-  VariableInfo.efi can dump out the table. Only Boot Services variable \r
+  VariableInfo.efi can dump out the table. Only Boot Services variable\r
   accesses are tracked by this code. The PcdVariableCollectStatistics\r
-  build flag controls if this feature is enabled. \r
+  build flag controls if this feature is enabled.\r
 \r
-  A read that hits in the cache will have Read and Cache true for \r
+  A read that hits in the cache will have Read and Cache true for\r
   the transaction. Data is allocated by this routine, but never\r
   freed.\r
 \r
@@ -84,7 +84,7 @@ UpdateVariableInfo (
       gVariableInfo->Volatile = Volatile;\r
     }\r
 \r
-    \r
+\r
     for (Entry = gVariableInfo; Entry != NULL; Entry = Entry->Next) {\r
       if (CompareGuid (VendorGuid, &Entry->VendorGuid)) {\r
         if (StrCmp (VariableName, Entry->Name) == 0) {\r
@@ -230,14 +230,14 @@ UpdateVariableStore (
     if ((DataPtr + DataSize) >= ((UINTN) ((UINT8 *) VolatileBase + VolatileBase->Size))) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
-    \r
+\r
     //\r
     // If Volatile Variable just do a simple mem copy.\r
-    //    \r
+    //\r
     CopyMem ((UINT8 *)(UINTN)DataPtr, Buffer, DataSize);\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   //\r
   // If we are here we are dealing with Non-Volatile Variables.\r
   //\r
@@ -412,7 +412,7 @@ GetVariableDataPtr (
   )\r
 {\r
   UINTN Value;\r
-  \r
+\r
   //\r
   // Be careful about pad size for alignment.\r
   //\r
@@ -483,7 +483,7 @@ GetStartPointer (
 \r
   @param VarStoreHeader  Pointer to the Variable Store Header.\r
 \r
-  @return Pointer to the end of the variable storage area. \r
+  @return Pointer to the end of the variable storage area.\r
 \r
 **/\r
 VARIABLE_HEADER *\r
@@ -557,7 +557,7 @@ Reclaim (
 \r
   while (IsValidVariableHeader (Variable)) {\r
     NextVariable = GetNextVariablePtr (Variable);\r
-    if (Variable->State == VAR_ADDED || \r
+    if (Variable->State == VAR_ADDED ||\r
         Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)\r
        ) {\r
       VariableSize = (UINTN) NextVariable - (UINTN) Variable;\r
@@ -568,9 +568,9 @@ Reclaim (
   }\r
 \r
   //\r
-  // Reserve the 1 Bytes with Oxff to identify the \r
-  // end of the variable buffer. \r
-  // \r
+  // Reserve the 1 Bytes with Oxff to identify the\r
+  // end of the variable buffer.\r
+  //\r
   MaximumBufferSize += 1;\r
   ValidBuffer = AllocatePool (MaximumBufferSize);\r
   if (ValidBuffer == NULL) {\r
@@ -587,7 +587,7 @@ Reclaim (
 \r
   //\r
   // Reinstall all ADDED variables as long as they are not identical to Updating Variable.\r
-  // \r
+  //\r
   Variable = GetStartPointer (VariableStoreHeader);\r
   while (IsValidVariableHeader (Variable)) {\r
     NextVariable = GetNextVariablePtr (Variable);\r
@@ -638,18 +638,18 @@ Reclaim (
 \r
   //\r
   // Reinstall all in delete transition variables.\r
-  // \r
+  //\r
   Variable      = GetStartPointer (VariableStoreHeader);\r
   while (IsValidVariableHeader (Variable)) {\r
     NextVariable = GetNextVariablePtr (Variable);\r
     if (Variable != UpdatingVariable && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
 \r
       //\r
-      // Buffer has cached all ADDED variable. \r
+      // Buffer has cached all ADDED variable.\r
       // Per IN_DELETED variable, we have to guarantee that\r
-      // no ADDED one in previous buffer. \r
-      // \r
-     \r
+      // no ADDED one in previous buffer.\r
+      //\r
+\r
       FoundAdded = FALSE;\r
       AddedVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer);\r
       while (IsValidVariableHeader (AddedVariable)) {\r
@@ -744,7 +744,7 @@ FindVariableEx (
       ; (PtrTrack->CurrPtr < PtrTrack->EndPtr) && IsValidVariableHeader (PtrTrack->CurrPtr)\r
       ; PtrTrack->CurrPtr = GetNextVariablePtr (PtrTrack->CurrPtr)\r
       ) {\r
-    if (PtrTrack->CurrPtr->State == VAR_ADDED || \r
+    if (PtrTrack->CurrPtr->State == VAR_ADDED ||\r
         PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)\r
        ) {\r
       if (!AtRuntime () || ((PtrTrack->CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {\r
@@ -875,7 +875,7 @@ GetIndexFromSupportedLangCodes(
   IN  CHAR8            *SupportedLang,\r
   IN  CHAR8            *Lang,\r
   IN  BOOLEAN          Iso639Language\r
-  ) \r
+  )\r
 {\r
   UINTN    Index;\r
   UINTN    CompareLength;\r
@@ -910,8 +910,8 @@ GetIndexFromSupportedLangCodes(
       // Determine the length of the next language code in SupportedLang\r
       //\r
       for (CompareLength = 0; SupportedLang[CompareLength] != '\0' && SupportedLang[CompareLength] != ';'; CompareLength++);\r
-      \r
-      if ((CompareLength == LanguageLength) && \r
+\r
+      if ((CompareLength == LanguageLength) &&\r
           (AsciiStrnCmp (Lang, SupportedLang, CompareLength) == 0)) {\r
         //\r
         // Successfully find the index of Lang string in SupportedLang string.\r
@@ -972,7 +972,7 @@ GetLangFromSupportedLangCodes (
     CompareLength = ISO_639_2_ENTRY_SIZE;\r
     mVariableModuleGlobal->Lang[CompareLength] = '\0';\r
     return CopyMem (mVariableModuleGlobal->Lang, SupportedLang + Index * CompareLength, CompareLength);\r
-      \r
+\r
   } else {\r
     while (TRUE) {\r
       //\r
@@ -1009,10 +1009,10 @@ GetLangFromSupportedLangCodes (
 }\r
 \r
 /**\r
-  Returns a pointer to an allocated buffer that contains the best matching language \r
-  from a set of supported languages.  \r
-  \r
-  This function supports both ISO 639-2 and RFC 4646 language codes, but language \r
+  Returns a pointer to an allocated buffer that contains the best matching language\r
+  from a set of supported languages.\r
+\r
+  This function supports both ISO 639-2 and RFC 4646 language codes, but language\r
   code types may not be mixed in a single call to this function. This function\r
   supports a variable argument list that allows the caller to pass in a prioritized\r
   list of language codes to test against all the language codes in SupportedLanguages.\r
@@ -1020,37 +1020,37 @@ GetLangFromSupportedLangCodes (
   If SupportedLanguages is NULL, then ASSERT().\r
 \r
   @param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string that\r
-                                  contains a set of language codes in the format \r
+                                  contains a set of language codes in the format\r
                                   specified by Iso639Language.\r
   @param[in]  Iso639Language      If TRUE, then all language codes are assumed to be\r
                                   in ISO 639-2 format.  If FALSE, then all language\r
                                   codes are assumed to be in RFC 4646 language format\r
-  @param[in]  ...                 A variable argument list that contains pointers to \r
+  @param[in]  ...                 A variable argument list that contains pointers to\r
                                   Null-terminated ASCII strings that contain one or more\r
                                   language codes in the format specified by Iso639Language.\r
                                   The first language code from each of these language\r
                                   code lists is used to determine if it is an exact or\r
-                                  close match to any of the language codes in \r
+                                  close match to any of the language codes in\r
                                   SupportedLanguages.  Close matches only apply to RFC 4646\r
                                   language codes, and the matching algorithm from RFC 4647\r
-                                  is used to determine if a close match is present.  If \r
+                                  is used to determine if a close match is present.  If\r
                                   an exact or close match is found, then the matching\r
                                   language code from SupportedLanguages is returned.  If\r
                                   no matches are found, then the next variable argument\r
-                                  parameter is evaluated.  The variable argument list \r
+                                  parameter is evaluated.  The variable argument list\r
                                   is terminated by a NULL.\r
 \r
   @retval NULL   The best matching language could not be found in SupportedLanguages.\r
-  @retval NULL   There are not enough resources available to return the best matching \r
+  @retval NULL   There are not enough resources available to return the best matching\r
                  language.\r
-  @retval Other  A pointer to a Null-terminated ASCII string that is the best matching \r
+  @retval Other  A pointer to a Null-terminated ASCII string that is the best matching\r
                  language in SupportedLanguages.\r
 \r
 **/\r
 CHAR8 *\r
 EFIAPI\r
 VariableGetBestLanguage (\r
-  IN CONST CHAR8  *SupportedLanguages, \r
+  IN CONST CHAR8  *SupportedLanguages,\r
   IN BOOLEAN      Iso639Language,\r
   ...\r
   )\r
@@ -1127,7 +1127,7 @@ VariableGetBestLanguage (
         LanguageLength = 0;\r
       } else {\r
         //\r
-        // If RFC 4646 mode, then trim Language from the right to the next '-' character \r
+        // If RFC 4646 mode, then trim Language from the right to the next '-' character\r
         //\r
         for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);\r
       }\r
@@ -1136,7 +1136,7 @@ VariableGetBestLanguage (
   VA_END (Args);\r
 \r
   //\r
-  // No matches were found \r
+  // No matches were found\r
   //\r
   return NULL;\r
 }\r
@@ -1201,7 +1201,7 @@ AutoUpdateLangVariable(
     ASSERT (mVariableModuleGlobal->PlatformLangCodes != NULL);\r
 \r
     //\r
-    // PlatformLang holds a single language from PlatformLangCodes, \r
+    // PlatformLang holds a single language from PlatformLangCodes,\r
     // so the size of PlatformLangCodes is enough for the PlatformLang.\r
     //\r
     if (mVariableModuleGlobal->PlatformLang != NULL) {\r
@@ -1231,7 +1231,7 @@ AutoUpdateLangVariable(
     ASSERT (mVariableModuleGlobal->LangCodes != NULL);\r
   }\r
 \r
-  if (SetLanguageCodes \r
+  if (SetLanguageCodes\r
       && (mVariableModuleGlobal->PlatformLangCodes != NULL)\r
       && (mVariableModuleGlobal->LangCodes != NULL)) {\r
     //\r
@@ -1263,7 +1263,7 @@ AutoUpdateLangVariable(
       }\r
     }\r
   }\r
-  \r
+\r
   //\r
   // According to UEFI spec, "Lang" and "PlatformLang" is NV|BS|RT attributions.\r
   //\r
@@ -1328,7 +1328,7 @@ AutoUpdateLangVariable(
         //\r
         FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
 \r
-        Status = UpdateVariable (L"PlatformLang", &gEfiGlobalVariableGuid, BestPlatformLang, \r
+        Status = UpdateVariable (L"PlatformLang", &gEfiGlobalVariableGuid, BestPlatformLang,\r
                                  AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL);\r
 \r
         DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang));\r
@@ -1351,7 +1351,7 @@ AutoUpdateLangVariable(
   @param[in] MonotonicCount     Value of associated monotonic count.\r
   @param[in] CacheVariable      The variable information which is used to keep track of variable usage.\r
   @param[in] TimeStamp          Value of associated TimeStamp.\r
-  \r
+\r
   @retval EFI_SUCCESS           The update operation is success.\r
   @retval EFI_OUT_OF_RESOURCES  Variable region is full, can not write other data into this region.\r
 \r
@@ -1417,12 +1417,12 @@ UpdateVariable (
     // Now let Variable points to the same variable in Flash area.\r
     //\r
     VariableStoreHeader  = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
-    Variable = &NvVariable;    \r
+    Variable = &NvVariable;\r
     Variable->StartPtr = GetStartPointer (VariableStoreHeader);\r
     Variable->EndPtr   = GetEndPointer (VariableStoreHeader);\r
     Variable->CurrPtr  = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->CurrPtr - (UINTN)CacheVariable->StartPtr));\r
     Variable->Volatile = FALSE;\r
-  } \r
+  }\r
 \r
   Fvb       = mVariableModuleGlobal->FvbInstance;\r
   Reclaimed = FALSE;\r
@@ -1439,10 +1439,10 @@ UpdateVariable (
     //\r
     // Update/Delete existing variable.\r
     //\r
-    if (AtRuntime ()) {        \r
+    if (AtRuntime ()) {\r
       //\r
-      // If AtRuntime and the variable is Volatile and Runtime Access,  \r
-      // the volatile is ReadOnly, and SetVariable should be aborted and \r
+      // If AtRuntime and the variable is Volatile and Runtime Access,\r
+      // the volatile is ReadOnly, and SetVariable should be aborted and\r
       // return EFI_WRITE_PROTECTED.\r
       //\r
       if (Variable->Volatile) {\r
@@ -1454,17 +1454,17 @@ UpdateVariable (
       //\r
       if ((Variable->CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
-        goto Done;      \r
+        goto Done;\r
       }\r
     }\r
 \r
     //\r
     // Setting a data variable with no access, or zero DataSize attributes\r
     // causes it to be deleted.\r
-    // When the EFI_VARIABLE_APPEND_WRITE attribute is set, DataSize of zero will \r
-    // not delete the variable.    \r
+    // When the EFI_VARIABLE_APPEND_WRITE attribute is set, DataSize of zero will\r
+    // not delete the variable.\r
     //\r
-    if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0))|| ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0)) {    \r
+    if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0))|| ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0)) {\r
       State = Variable->CurrPtr->State;\r
       State &= VAR_DELETED;\r
 \r
@@ -1476,14 +1476,14 @@ UpdateVariable (
                  (UINTN) &Variable->CurrPtr->State,\r
                  sizeof (UINT8),\r
                  &State\r
-                 ); \r
+                 );\r
       if (!EFI_ERROR (Status)) {\r
         UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, FALSE, TRUE, FALSE);\r
         if (!Variable->Volatile) {\r
           CacheVariable->CurrPtr->State = State;\r
         }\r
       }\r
-      goto Done;     \r
+      goto Done;\r
     }\r
     //\r
     // If the variable is marked valid, and the same data has been passed in,\r
@@ -1491,8 +1491,11 @@ UpdateVariable (
     //\r
     if (DataSizeOfVariable (Variable->CurrPtr) == DataSize &&\r
         (CompareMem (Data, GetVariableDataPtr (Variable->CurrPtr), DataSize) == 0)  &&\r
-        ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {\r
-      \r
+        ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) &&\r
+        (TimeStamp == NULL)) {\r
+      //\r
+      // Variable content unchanged and no need to update timestamp, just return.\r
+      //\r
       UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, TRUE, FALSE, FALSE);\r
       Status = EFI_SUCCESS;\r
       goto Done;\r
@@ -1503,10 +1506,40 @@ UpdateVariable (
       // EFI_VARIABLE_APPEND_WRITE attribute only effects for existing variable\r
       //\r
       if ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0) {\r
-    \r
-        BufSize = Variable->CurrPtr->DataSize +  DataSize;\r
-        RevBufSize = MIN (PcdGet32 (PcdMaxAppendVariableSize), ScratchDataSize);\r
-    \r
+        //\r
+        // Cache the previous variable data into StorageArea.\r
+        //\r
+        DataOffset = sizeof (VARIABLE_HEADER) + Variable->CurrPtr->NameSize + GET_PAD_SIZE (Variable->CurrPtr->NameSize);\r
+        CopyMem (mStorageArea, (UINT8*)((UINTN) Variable->CurrPtr + DataOffset), Variable->CurrPtr->DataSize);\r
+\r
+        if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) ||\r
+               (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) {\r
+          //\r
+          // For variables with the GUID EFI_IMAGE_SECURITY_DATABASE_GUID (i.e. where the data\r
+          // buffer is formatted as EFI_SIGNATURE_LIST), the driver shall not perform an append of\r
+          // EFI_SIGNATURE_DATA values that are already part of the existing variable value.\r
+          //\r
+          BufSize = AppendSignatureList (mStorageArea, Variable->CurrPtr->DataSize, Data, DataSize);\r
+          if (BufSize == Variable->CurrPtr->DataSize) {\r
+            if ((TimeStamp == NULL) || CompareTimeStamp (TimeStamp, &Variable->CurrPtr->TimeStamp)) {\r
+              //\r
+              // New EFI_SIGNATURE_DATA is not found and timestamp is not later\r
+              // than current timestamp, return EFI_SUCCESS directly.\r
+              //\r
+              UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, TRUE, FALSE, FALSE);\r
+              Status = EFI_SUCCESS;\r
+              goto Done;\r
+            }\r
+          }\r
+        } else {\r
+          //\r
+          // For other Variables, append the new data to the end of previous data.\r
+          //\r
+          CopyMem ((UINT8*)((UINTN) mStorageArea + Variable->CurrPtr->DataSize), Data, DataSize);\r
+          BufSize = Variable->CurrPtr->DataSize + DataSize;\r
+        }\r
+\r
+        RevBufSize = MIN (PcdGet32 (PcdMaxVariableSize), ScratchDataSize);\r
         if (BufSize > RevBufSize) {\r
           //\r
           // If variable size (previous + current) is bigger than reserved buffer in runtime,\r
@@ -1514,19 +1547,7 @@ UpdateVariable (
           //\r
           return EFI_OUT_OF_RESOURCES;\r
         }\r
-       \r
-        SetMem (mStorageArea, PcdGet32 (PcdMaxAppendVariableSize), 0xff);\r
-        //\r
-        // Cache the previous variable data into StorageArea.\r
-        //\r
-        DataOffset = sizeof (VARIABLE_HEADER) + Variable->CurrPtr->NameSize + GET_PAD_SIZE (Variable->CurrPtr->NameSize);\r
-        CopyMem (mStorageArea, (UINT8*)((UINTN)Variable->CurrPtr + DataOffset), Variable->CurrPtr->DataSize);\r
-        \r
-        //\r
-        // Append the new data to the end of previous data.\r
-        // \r
-        CopyMem ((UINT8*)((UINTN)mStorageArea + Variable->CurrPtr->DataSize), Data, DataSize);\r
-    \r
+\r
         //\r
         // Override Data and DataSize which are used for combined data area including previous and new data.\r
         //\r
@@ -1548,36 +1569,33 @@ UpdateVariable (
                  (UINTN) &Variable->CurrPtr->State,\r
                  sizeof (UINT8),\r
                  &State\r
-                 );      \r
+                 );\r
       if (EFI_ERROR (Status)) {\r
-        goto Done;  \r
-      } \r
+        goto Done;\r
+      }\r
       if (!Variable->Volatile) {\r
         CacheVariable->CurrPtr->State = State;\r
       }\r
-    }    \r
+    }\r
   } else {\r
     //\r
     // Not found existing variable. Create a new variable.\r
-    //  \r
-\r
-    //\r
-    // EFI_VARIABLE_APPEND_WRITE attribute only set for existing variable\r
     //\r
-    if ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0) {\r
-      Status = EFI_INVALID_PARAMETER;\r
+\r
+    if ((DataSize == 0) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0)) {\r
+      Status = EFI_SUCCESS;\r
       goto Done;\r
     }\r
-    \r
+\r
     //\r
     // Make sure we are trying to create a new variable.\r
-    // Setting a data variable with zero DataSize or no access attributes means to delete it.    \r
+    // Setting a data variable with zero DataSize or no access attributes means to delete it.\r
     //\r
     if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {\r
       Status = EFI_NOT_FOUND;\r
       goto Done;\r
     }\r
-        \r
+\r
     //\r
     // Only variable have NV|RT attribute can be created in Runtime.\r
     //\r
@@ -1585,7 +1603,7 @@ UpdateVariable (
         (((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) || ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0))) {\r
       Status = EFI_INVALID_PARAMETER;\r
       goto Done;\r
-    }         \r
+    }\r
   }\r
 \r
   //\r
@@ -1601,10 +1619,10 @@ UpdateVariable (
   NextVariable->Reserved        = 0;\r
   NextVariable->PubKeyIndex     = KeyIndex;\r
   NextVariable->MonotonicCount  = MonotonicCount;\r
-  SetMem (&NextVariable->TimeStamp, sizeof (EFI_TIME), 0);\r
+  ZeroMem (&NextVariable->TimeStamp, sizeof (EFI_TIME));\r
 \r
   if (((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) &&\r
-        TimeStamp != NULL) {\r
+      (TimeStamp != NULL)) {\r
     if ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) {\r
       CopyMem (&NextVariable->TimeStamp, TimeStamp, sizeof (EFI_TIME));\r
     } else {\r
@@ -1613,18 +1631,20 @@ UpdateVariable (
       // when the new TimeStamp value is later than the current timestamp associated\r
       // with the variable, we need associate the new timestamp with the updated value.\r
       //\r
-      if (CompareTimeStamp (&Variable->CurrPtr->TimeStamp, TimeStamp)) {\r
-        CopyMem (&NextVariable->TimeStamp, TimeStamp, sizeof (EFI_TIME));\r
+      if (Variable->CurrPtr != NULL) {\r
+        if (CompareTimeStamp (&Variable->CurrPtr->TimeStamp, TimeStamp)) {\r
+          CopyMem (&NextVariable->TimeStamp, TimeStamp, sizeof (EFI_TIME));\r
+        }\r
       }\r
     }\r
   }\r
 \r
   //\r
-  // The EFI_VARIABLE_APPEND_WRITE attribute will never be set in the returned \r
+  // The EFI_VARIABLE_APPEND_WRITE attribute will never be set in the returned\r
   // Attributes bitmask parameter of a GetVariable() call.\r
   //\r
   NextVariable->Attributes  = Attributes & (~EFI_VARIABLE_APPEND_WRITE);\r
-  \r
+\r
   VarNameOffset                 = sizeof (VARIABLE_HEADER);\r
   VarNameSize                   = StrSize (VariableName);\r
   CopyMem (\r
@@ -1658,9 +1678,9 @@ UpdateVariable (
     //\r
     Volatile = FALSE;\r
     NonVolatileVarableStoreSize = ((VARIABLE_STORE_HEADER *)(UINTN)(mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase))->Size;\r
-    if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) \r
+    if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0)\r
       && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))\r
-      || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) \r
+      || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0)\r
       && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {\r
       if (AtRuntime ()) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
@@ -1669,7 +1689,7 @@ UpdateVariable (
       //\r
       // Perform garbage collection & reclaim operation.\r
       //\r
-      Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, \r
+      Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,\r
                         &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr);\r
       if (EFI_ERROR (Status)) {\r
         goto Done;\r
@@ -1677,9 +1697,9 @@ UpdateVariable (
       //\r
       // If still no enough space, return out of resources.\r
       //\r
-      if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) \r
+      if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0)\r
         && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))\r
-        || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) \r
+        || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0)\r
         && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
@@ -1689,7 +1709,7 @@ UpdateVariable (
     //\r
     // Four steps\r
     // 1. Write variable header\r
-    // 2. Set variable state to header valid  \r
+    // 2. Set variable state to header valid\r
     // 3. Write variable data\r
     // 4. Set variable state to valid\r
     //\r
@@ -1776,7 +1796,7 @@ UpdateVariable (
   } else {\r
     //\r
     // Create a volatile variable.\r
-    //      \r
+    //\r
     Volatile = TRUE;\r
 \r
     if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >\r
@@ -1784,7 +1804,7 @@ UpdateVariable (
       //\r
       // Perform garbage collection & reclaim operation.\r
       //\r
-      Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, \r
+      Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,\r
                           &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr);\r
       if (EFI_ERROR (Status)) {\r
         goto Done;\r
@@ -1835,7 +1855,7 @@ UpdateVariable (
              sizeof (UINT8),\r
              &State\r
              );\r
-    if (!EFI_ERROR (Status) && !Variable->Volatile) {         \r
+    if (!EFI_ERROR (Status) && !Variable->Volatile) {\r
       CacheVariable->CurrPtr->State = State;\r
     }\r
   }\r
@@ -1858,7 +1878,7 @@ Done:
   @param DataSize                   Size of Data found. If size is less than the\r
                                     data, this value contains the required size.\r
   @param Data                       Data pointer.\r
-                      \r
+\r
   @return EFI_INVALID_PARAMETER     Invalid parameter.\r
   @return EFI_SUCCESS               Find the specified variable.\r
   @return EFI_NOT_FOUND             Not found.\r
@@ -1884,7 +1904,7 @@ VariableServiceGetVariable (
   }\r
 \r
   AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
-  \r
+\r
   Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
   if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
     goto Done;\r
@@ -1909,7 +1929,7 @@ VariableServiceGetVariable (
 \r
     *DataSize = VarDataSize;\r
     UpdateVariableInfo (VariableName, VendorGuid, Variable.Volatile, TRUE, FALSE, FALSE, FALSE);\r
\r
+\r
     Status = EFI_SUCCESS;\r
     goto Done;\r
   } else {\r
@@ -2007,7 +2027,7 @@ VariableServiceGetNextVariableName (
         }\r
       }\r
       //\r
-      // Capture the case that \r
+      // Capture the case that\r
       // 1. current storage is the last one, or\r
       // 2. no further storage\r
       //\r
@@ -2029,7 +2049,7 @@ VariableServiceGetNextVariableName (
         //\r
         // Don't return NV variable when HOB overrides it\r
         //\r
-        if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) && (VariableStoreHeader[VariableStoreTypeNv] != NULL) && \r
+        if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) && (VariableStoreHeader[VariableStoreTypeNv] != NULL) &&\r
             (Variable.StartPtr == GetStartPointer (VariableStoreHeader[VariableStoreTypeNv]))\r
            ) {\r
           VariableInHob.StartPtr = GetStartPointer (VariableStoreHeader[VariableStoreTypeHob]);\r
@@ -2108,7 +2128,7 @@ VariableServiceSetVariable (
   //\r
   if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
-  } \r
+  }\r
 \r
   if (DataSize != 0 && Data == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2122,25 +2142,36 @@ VariableServiceSetVariable (
   }\r
 \r
   //\r
-  // EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS and EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute \r
+  // EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS and EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute\r
   // cannot be set both.\r
   //\r
-  if (((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)             \\r
+  if (((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)\r
      && ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {\r
     return EFI_INVALID_PARAMETER;\r
-  }  \r
+  }\r
 \r
   if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) {\r
     if (DataSize < AUTHINFO_SIZE) {\r
       //\r
-      // Try to write Authencated Variable without AuthInfo.\r
+      // Try to write Authenticated Variable without AuthInfo.\r
       //\r
       return EFI_SECURITY_VIOLATION;\r
-    } \r
-    PayloadSize = DataSize - AUTHINFO_SIZE; \r
+    }\r
+    PayloadSize = DataSize - AUTHINFO_SIZE;\r
+  } else if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {\r
+    //\r
+    // Sanity check for EFI_VARIABLE_AUTHENTICATION_2 descriptor.\r
+    //\r
+    if (DataSize < OFFSET_OF_AUTHINFO2_CERT_DATA ||\r
+       DataSize < AUTHINFO2_SIZE (Data) ||\r
+       ((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->AuthInfo.Hdr.dwLength < OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) {\r
+      return EFI_SECURITY_VIOLATION;\r
+    }\r
+    PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
   } else {\r
-    PayloadSize = DataSize; \r
+    PayloadSize = DataSize;\r
   }\r
+\r
   //\r
   //  The size of the VariableName, including the Unicode Null in bytes plus\r
   //  the DataSize is limited to maximum size of PcdGet32 (PcdMaxHardwareErrorVariableSize)\r
@@ -2165,8 +2196,8 @@ VariableServiceSetVariable (
     if ((PayloadSize > PcdGet32 (PcdMaxVariableSize)) ||\r
         (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxVariableSize))) {\r
       return EFI_INVALID_PARAMETER;\r
-    }  \r
-  }  \r
+    }\r
+  }\r
 \r
   AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
 \r
@@ -2179,7 +2210,7 @@ VariableServiceSetVariable (
     // Parse non-volatile variable data and get last variable offset.\r
     //\r
     NextVariable  = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point);\r
-    while ((NextVariable < GetEndPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point)) \r
+    while ((NextVariable < GetEndPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point))\r
         && IsValidVariableHeader (NextVariable)) {\r
       NextVariable = GetNextVariablePtr (NextVariable);\r
     }\r
@@ -2259,7 +2290,7 @@ VariableServiceQueryVariableInfo (
     //\r
     // Make sure the Attributes combination is supported by the platform.\r
     //\r
-    return EFI_UNSUPPORTED;  \r
+    return EFI_UNSUPPORTED;\r
   } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {\r
     //\r
     // Make sure if runtime bit is set, boot service bit is set also.\r
@@ -2378,7 +2409,7 @@ VariableServiceQueryVariableInfo (
 \r
 /**\r
   This function reclaims variable storage if free size is below the threshold.\r
-  \r
+\r
 **/\r
 VOID\r
 ReclaimForOS(\r
@@ -2390,7 +2421,7 @@ ReclaimForOS(
   UINTN                          RemainingCommonVariableSpace;\r
   UINTN                          RemainingHwErrVariableSpace;\r
 \r
-  Status  = EFI_SUCCESS; \r
+  Status  = EFI_SUCCESS;\r
 \r
   CommonVariableSpace = ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)))->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32(PcdHwErrStorageSize); //Allowable max size of common variable storage space\r
 \r
@@ -2401,7 +2432,7 @@ ReclaimForOS(
   // Check if the free area is blow a threshold.\r
   //\r
   if ((RemainingCommonVariableSpace < PcdGet32 (PcdMaxVariableSize))\r
-    || ((PcdGet32 (PcdHwErrStorageSize) != 0) && \r
+    || ((PcdGet32 (PcdHwErrStorageSize) != 0) &&\r
        (RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize)))){\r
     Status = Reclaim (\r
             mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,\r
@@ -2436,7 +2467,7 @@ VariableWriteServiceInitialize (
 \r
   VariableStoreBase   = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;\r
   VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;\r
\r
+\r
   //\r
   // Check if the free area is really free.\r
   //\r
@@ -2459,7 +2490,7 @@ VariableWriteServiceInitialize (
     }\r
   }\r
 \r
-  \r
+\r
   //\r
   // Flush the HOB variable to flash and invalidate HOB variable.\r
   //\r
@@ -2533,7 +2564,7 @@ VariableCommonInitialize (
   //\r
   // Note that in EdkII variable driver implementation, Hardware Error Record type variable\r
   // is stored with common variable in the same NV region. So the platform integrator should\r
-  // ensure that the value of PcdHwErrStorageSize is less than or equal to the value of \r
+  // ensure that the value of PcdHwErrStorageSize is less than or equal to the value of\r
   // PcdFlashNvStorageVariableSize.\r
   //\r
   ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdFlashNvStorageVariableSize));\r
@@ -2596,9 +2627,9 @@ VariableCommonInitialize (
     Status = EFI_VOLUME_CORRUPTED;\r
     DEBUG((EFI_D_INFO, "Variable Store header is corrupted\n"));\r
     goto Done;\r
-  }  \r
+  }\r
   ASSERT(VariableStoreHeader->Size == VariableStoreLength);\r
-    \r
+\r
   //\r
   // Parse non-volatile variable data and get last variable offset.\r
   //\r
@@ -2615,7 +2646,7 @@ VariableCommonInitialize (
   }\r
 \r
   mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) VariableStoreBase;\r
-    \r
+\r
   //\r
   // Allocate runtime memory used for a memory copy of the FLASH region.\r
   // Keep the memory and the FLASH in sync as updates occur\r
@@ -2661,7 +2692,7 @@ GetFvbInfoByAddress (
   EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL      *Fvb;\r
   EFI_FIRMWARE_VOLUME_HEADER              *FwVolHeader;\r
   EFI_FVB_ATTRIBUTES_2                    Attributes;\r
\r
+\r
   //\r
   // Get all FVB handles.\r
   //\r
@@ -2686,9 +2717,9 @@ GetFvbInfoByAddress (
     //\r
     Status = Fvb->GetAttributes (Fvb, &Attributes);\r
     if (EFI_ERROR (Status) || ((Attributes & EFI_FVB2_WRITE_STATUS) == 0)) {\r
-      continue;     \r
+      continue;\r
     }\r
-    \r
+\r
     //\r
     // Compare the address and select the right one.\r
     //\r
@@ -2714,7 +2745,7 @@ GetFvbInfoByAddress (
   if (Fvb == NULL) {\r
     Status = EFI_NOT_FOUND;\r
   }\r
-  \r
-  return Status;  \r
+\r
+  return Status;\r
 }\r
 \r
index 7b88f15163b52eb27561d759f605466cb563de28..f91cb5dc565228ea992a2d44e05ccbdc34e7816a 100644 (file)
@@ -3,12 +3,12 @@
   and volatile storage space and install variable architecture protocol.\r
 \r
 Copyright (c) 2009 - 2011, 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
+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
+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
@@ -24,7 +24,7 @@ EFI_EVENT                           mFtwRegistration           = NULL;
 \r
 /**\r
   Return TRUE if ExitBootServices () has been called.\r
-  \r
+\r
   @retval TRUE If ExitBootServices () has been called.\r
 **/\r
 BOOLEAN\r
@@ -39,8 +39,8 @@ AtRuntime (
 /**\r
   Initializes a basic mutual exclusion lock.\r
 \r
-  This function initializes a basic mutual exclusion lock to the released state \r
-  and returns the lock.  Each lock provides mutual exclusion access at its task \r
+  This function initializes a basic mutual exclusion lock to the released state\r
+  and returns the lock.  Each lock provides mutual exclusion access at its task\r
   priority level.  Since there is no preemption or multiprocessor support in EFI,\r
   acquiring the lock only consists of raising to the locks TPL.\r
   If Lock is NULL, then ASSERT().\r
@@ -131,7 +131,7 @@ GetFtwProtocol (
                   &gEfiFaultTolerantWriteProtocolGuid,\r
                   NULL,\r
                   FtwProtocol\r
-                  );                    \r
+                  );\r
   return Status;\r
 }\r
 \r
@@ -145,7 +145,7 @@ GetFtwProtocol (
   @retval EFI_SUCCESS           The interface information for the specified protocol was returned.\r
   @retval EFI_UNSUPPORTED       The device does not support the FVB protocol.\r
   @retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 GetFvbByHandle (\r
@@ -166,7 +166,7 @@ GetFvbByHandle (
 \r
 /**\r
   Function returns an array of handles that support the FVB protocol\r
-  in a buffer allocated from pool. \r
+  in a buffer allocated from pool.\r
 \r
   @param[out]  NumberHandles    The number of handles returned in Buffer.\r
   @param[out]  Buffer           A pointer to the buffer to return the requested\r
@@ -177,7 +177,7 @@ GetFvbByHandle (
   @retval EFI_NOT_FOUND         No FVB handle was found.\r
   @retval EFI_OUT_OF_RESOURCES  There is not enough pool memory to store the matching results.\r
   @retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 GetFvbCountAndBuffer (\r
@@ -233,8 +233,9 @@ VariableClassAddressChangeEvent (
   EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
   EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);\r
   EfiConvertPointer (0x0, (VOID **) &mHashCtx);\r
-  EfiConvertPointer (0x0, (VOID **) &mStorageArea);  \r
-  EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);  \r
+  EfiConvertPointer (0x0, (VOID **) &mStorageArea);\r
+  EfiConvertPointer (0x0, (VOID **) &mSerializationRuntimeBuffer);\r
+  EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);\r
 }\r
 \r
 \r
@@ -266,12 +267,12 @@ OnReadyToBoot (
 /**\r
   Fault Tolerant Write protocol notification event handler.\r
 \r
-  Non-Volatile variable write may needs FTW protocol to reclaim when \r
+  Non-Volatile variable write may needs FTW protocol to reclaim when\r
   writting variable.\r
 \r
   @param[in] Event    Event whose notification function is being invoked.\r
   @param[in] Context  Pointer to the notification function's context.\r
-  \r
+\r
 **/\r
 VOID\r
 EFIAPI\r
@@ -297,7 +298,7 @@ FtwNotificationEvent (
   if (EFI_ERROR (Status)) {\r
     return ;\r
   }\r
-  \r
+\r
   //\r
   // Find the proper FVB protocol for variable.\r
   //\r
@@ -333,21 +334,21 @@ FtwNotificationEvent (
       DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));\r
     }\r
   }\r
-  \r
+\r
   Status = VariableWriteServiceInitialize ();\r
   ASSERT_EFI_ERROR (Status);\r
\r
+\r
   //\r
   // Install the Variable Write Architectural protocol.\r
   //\r
   Status = gBS->InstallProtocolInterface (\r
                   &mHandle,\r
-                  &gEfiVariableWriteArchProtocolGuid, \r
+                  &gEfiVariableWriteArchProtocolGuid,\r
                   EFI_NATIVE_INTERFACE,\r
                   NULL\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
-  \r
+\r
   //\r
   // Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.\r
   //\r
@@ -358,13 +359,13 @@ FtwNotificationEvent (
 \r
 /**\r
   Variable Driver main entry point. The Variable driver places the 4 EFI\r
-  runtime services in the EFI System Table and installs arch protocols \r
+  runtime services in the EFI System Table and installs arch protocols\r
   for variable read and write services being available. It also registers\r
   a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
 \r
-  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
   @param[in] SystemTable    A pointer to the EFI System Table.\r
-  \r
+\r
   @retval EFI_SUCCESS       Variable service successfully initialized.\r
 \r
 **/\r
@@ -376,7 +377,7 @@ VariableServiceInitialize (
   )\r
 {\r
   EFI_STATUS                            Status;\r
-  EFI_EVENT                             ReadyToBootEvent;    \r
+  EFI_EVENT                             ReadyToBootEvent;\r
 \r
   Status = VariableCommonInitialize ();\r
   ASSERT_EFI_ERROR (Status);\r
@@ -385,13 +386,13 @@ VariableServiceInitialize (
   SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;\r
   SystemTable->RuntimeServices->SetVariable         = VariableServiceSetVariable;\r
   SystemTable->RuntimeServices->QueryVariableInfo   = VariableServiceQueryVariableInfo;\r
-    \r
+\r
   //\r
   // Now install the Variable Runtime Architectural protocol on a new handle.\r
   //\r
   Status = gBS->InstallProtocolInterface (\r
                   &mHandle,\r
-                  &gEfiVariableArchProtocolGuid, \r
+                  &gEfiVariableArchProtocolGuid,\r
                   EFI_NATIVE_INTERFACE,\r
                   NULL\r
                   );\r
@@ -399,7 +400,7 @@ VariableServiceInitialize (
 \r
   //\r
   // Register FtwNotificationEvent () notify function.\r
-  // \r
+  //\r
   EfiCreateProtocolNotifyEvent (\r
     &gEfiFaultTolerantWriteProtocolGuid,\r
     TPL_CALLBACK,\r
@@ -422,9 +423,9 @@ VariableServiceInitialize (
   // Register the event handling function to reclaim variable for OS usage.\r
   //\r
   Status = EfiCreateEventReadyToBootEx (\r
-             TPL_NOTIFY, \r
-             OnReadyToBoot, \r
-             NULL, \r
+             TPL_NOTIFY,\r
+             OnReadyToBoot,\r
+             NULL,\r
              &ReadyToBootEvent\r
              );\r
 \r
index d2a2025b66f46e7596cb2d6c9b9b1887245ddc99..5e741d204adcc0919620ef982d29b444474d500a 100644 (file)
@@ -64,7 +64,7 @@
   gEfiFaultTolerantWriteProtocolGuid            ## SOMETIMES_CONSUMES\r
 \r
 [Guids]\r
-  gEfiAuthenticatedVariableGuid                 ## PRODUCES ## Configuration Table Guid \r
+  gEfiAuthenticatedVariableGuid                 ## PRODUCES ## Configuration Table Guid\r
   gEfiGlobalVariableGuid                        ## PRODUCES ## Variable Guid\r
   gEfiEventVirtualAddressChangeGuid             ## PRODUCES ## Event\r
   gEfiCertRsa2048Sha256Guid\r
@@ -82,8 +82,7 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize\r
-  gEfiSecurityPkgTokenSpaceGuid.PcdMaxAppendVariableSize\r
-  \r
+\r
 [FeaturePcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## SOMETIME_CONSUMES (statistic the information of variable.)\r
 \r
@@ -97,4 +96,4 @@
 #   EVENT_TYPE_NOTIFY_SIGNAL                    ## PRODUCES\r
 #\r
 #\r
-    \r
+\r
index 86f6e9234774d1c14515b882b0cbd11529a6696a..c43cf2d61909da382c208617febe7825e58fe4a4 100644 (file)
@@ -2,11 +2,11 @@
 #  Component description file for SMM Authenticated Variable module.\r
 #\r
 #  This module installs SMM variable protocol into SMM protocol database,\r
-#  which can be used by SMM driver, and installs SMM variable protocol \r
+#  which can be used by SMM driver, and installs SMM variable protocol\r
 #  into BS protocol database, which can be used to notify the SMM Runtime\r
 #  Dxe driver that the SMM variable service is ready.\r
-#  This module should be used with SMM Runtime DXE module together. The \r
-#  SMM Runtime DXE module would install variable arch protocol and variable \r
+#  This module should be used with SMM Runtime DXE module together. The\r
+#  SMM Runtime DXE module would install variable arch protocol and variable\r
 #  write arch protocol based on SMM variable module.\r
 #\r
 # Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
@@ -60,7 +60,7 @@
   DebugLib\r
   DxeServicesTableLib\r
   BaseCryptLib\r
-  PlatformSecureLib  \r
+  PlatformSecureLib\r
   HobLib\r
 \r
 [Protocols]\r
@@ -69,9 +69,9 @@
   gEfiSmmFaultTolerantWriteProtocolGuid         ## SOMETIMES_CONSUMES\r
 \r
 [Guids]\r
-  gEfiAuthenticatedVariableGuid                 ## PRODUCES ## Configuration Table Guid \r
+  gEfiAuthenticatedVariableGuid                 ## PRODUCES ## Configuration Table Guid\r
   gEfiGlobalVariableGuid                        ## PRODUCES ## Variable Guid\r
-  gSmmVariableWriteGuid                         ## PRODUCES ## SMM Variable Write Guid \r
+  gSmmVariableWriteGuid                         ## PRODUCES ## SMM Variable Write Guid\r
   gEfiCertRsa2048Sha256Guid\r
   gEfiImageSecurityDatabaseGuid\r
   gEfiCertX509Guid\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize\r
-  gEfiSecurityPkgTokenSpaceGuid.PcdMaxAppendVariableSize  \r
-  \r
+\r
 [FeaturePcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## SOMETIME_CONSUMES (statistic the information of variable.)\r
 \r
 [Depex]\r
-  TRUE \r
+  TRUE\r
+\r
 \r
-    \r