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