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