+/**\r
+ Clean up signer's certificates for common authenticated variable\r
+ by corresponding VariableName and VendorGuid from "certdb".\r
+ System may break down during Timebased Variable update & certdb update,\r
+ make them inconsistent, this function is called in AuthVariable Init\r
+ to ensure consistency.\r
+\r
+ @retval EFI_NOT_FOUND Fail to find variable "certdb".\r
+ @retval EFI_OUT_OF_RESOURCES The operation is failed due to lack of resources.\r
+ @retval EFI_SUCCESS The operation is completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+CleanCertsFromDb (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Offset;\r
+ AUTH_CERT_DB_DATA *Ptr;\r
+ UINT32 NameSize;\r
+ UINT32 NodeSize;\r
+ CHAR16 *VariableName;\r
+ EFI_STATUS Status;\r
+ BOOLEAN CertCleaned;\r
+ UINT8 *Data;\r
+ UINTN DataSize;\r
+ EFI_GUID AuthVarGuid;\r
+ AUTH_VARIABLE_INFO AuthVariableInfo;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Get corresponding certificates by VendorGuid and VariableName.\r
+ //\r
+ do {\r
+ CertCleaned = FALSE;\r
+\r
+ //\r
+ // Get latest variable "certdb"\r
+ //\r
+ Status = AuthServiceInternalFindVariable (\r
+ EFI_CERT_DB_NAME,\r
+ &gEfiCertDbGuid,\r
+ (VOID **) &Data,\r
+ &DataSize\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if ((DataSize == 0) || (Data == NULL)) {\r
+ ASSERT (FALSE);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Offset = sizeof (UINT32);\r
+\r
+ while (Offset < (UINT32) DataSize) {\r
+ Ptr = (AUTH_CERT_DB_DATA *) (Data + Offset);\r
+ NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);\r
+ NameSize = ReadUnaligned32 (&Ptr->NameSize);\r
+\r
+ //\r
+ // Get VarName tailed with '\0'\r
+ //\r
+ VariableName = AllocateZeroPool((NameSize + 1) * sizeof(CHAR16));\r
+ if (VariableName == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (VariableName, (UINT8 *) Ptr + sizeof (AUTH_CERT_DB_DATA), NameSize * sizeof(CHAR16));\r
+ //\r
+ // Keep VarGuid aligned\r
+ //\r
+ CopyMem (&AuthVarGuid, &Ptr->VendorGuid, sizeof(EFI_GUID));\r
+\r
+ //\r
+ // Find corresponding time auth variable\r
+ //\r
+ ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
+ Status = mAuthVarLibContextIn->FindVariable (\r
+ VariableName,\r
+ &AuthVarGuid,\r
+ &AuthVariableInfo\r
+ );\r
+\r
+ if (EFI_ERROR(Status) || (AuthVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
+ Status = DeleteCertsFromDb(\r
+ VariableName,\r
+ &AuthVarGuid,\r
+ AuthVariableInfo.Attributes\r
+ );\r
+ CertCleaned = TRUE;\r
+ DEBUG((EFI_D_INFO, "Recovery!! Cert for Auth Variable %s Guid %g is removed for consistency\n", VariableName, &AuthVarGuid));\r
+ FreePool(VariableName);\r
+ break;\r
+ }\r
+\r
+ FreePool(VariableName);\r
+ Offset = Offset + NodeSize;\r
+ }\r
+ } while (CertCleaned);\r
+\r
+ return Status;\r
+}\r
+\r