Implement authentication services for the authenticated variable\r
service in UEFI2.2.\r
\r
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2012, 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
UINT8 mPubKeyStore[MAX_KEYDB_SIZE];\r
UINT32 mPubKeyNumber;\r
UINT32 mPlatformMode;\r
-EFI_GUID mSignatureSupport[SIGSUPPORT_NUM] = {EFI_CERT_RSA2048_SHA256_GUID, EFI_CERT_RSA2048_SHA1_GUID};\r
+EFI_GUID mSignatureSupport[] = {EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID, EFI_CERT_X509_GUID};\r
//\r
// Public Exponent of RSA Key.\r
//\r
{EFI_CERT_SHA512_GUID, 0, 64 }\r
};\r
\r
+/**\r
+ Determine whether this operation needs a physical present user.\r
+\r
+ @param[in] VariableName Name of the Variable.\r
+ @param[in] VendorGuid GUID of the Variable.\r
+\r
+ @retval TRUE This variable is protected, only a physical present user could set this variable.\r
+ @retval FALSE This variable is not protected.\r
+ \r
+**/\r
+BOOLEAN\r
+NeedPhysicallyPresent(\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid\r
+ )\r
+{\r
+ if ((CompareGuid (VendorGuid, &gEfiSecureBootEnableDisableGuid) && (StrCmp (VariableName, EFI_SECURE_BOOT_ENABLE_NAME) == 0))\r
+ || (CompareGuid (VendorGuid, &gEfiCustomModeEnableGuid) && (StrCmp (VariableName, EFI_CUSTOM_MODE_NAME) == 0))) {\r
+ return TRUE;\r
+ }\r
+ \r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Determine whether the platform is operating in Custom Secure Boot mode.\r
+\r
+ @retval TRUE The platform is operating in Custom mode.\r
+ @retval FALSE The platform is operating in Standard mode.\r
+\r
+**/\r
+BOOLEAN\r
+InCustomMode (\r
+ VOID\r
+ )\r
+{\r
+ VARIABLE_POINTER_TRACK Variable;\r
+\r
+ FindVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+ if (Variable.CurrPtr != NULL && *(GetVariableDataPtr (Variable.CurrPtr)) == CUSTOM_SECURE_BOOT_MODE) {\r
+ return TRUE;\r
+ }\r
+ \r
+ return FALSE;\r
+}\r
+\r
+\r
/**\r
Internal function to delete a Variable given its name and GUID, no authentication\r
required.\r
EFI_STATUS Status;\r
VARIABLE_POINTER_TRACK Variable;\r
\r
- Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
+ Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
if (EFI_ERROR (Status)) {\r
return EFI_SUCCESS;\r
}\r
UINTN CtxSize;\r
UINT8 SecureBootMode;\r
UINT8 SecureBootEnable;\r
+ UINT8 CustomMode;\r
+ UINT32 ListSize;\r
\r
//\r
// Initialize hash context.\r
AUTHVAR_KEYDB_NAME,\r
&gEfiAuthenticatedVariableGuid,\r
&Variable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
\r
if (Variable.CurrPtr == NULL) {\r
mPubKeyNumber = (UINT32) (DataSize / EFI_CERT_TYPE_RSA2048_SIZE);\r
}\r
\r
- FindVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, &PkVariable, &mVariableModuleGlobal->VariableGlobal);\r
+ FindVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, &PkVariable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
if (PkVariable.CurrPtr == NULL) {\r
DEBUG ((EFI_D_INFO, "Variable %s does not exist.\n", EFI_PLATFORM_KEY_NAME));\r
} else {\r
EFI_SETUP_MODE_NAME,\r
&gEfiGlobalVariableGuid,\r
&Variable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
\r
if (Variable.CurrPtr == NULL) {\r
EFI_SIGNATURE_SUPPORT_NAME,\r
&gEfiGlobalVariableGuid,\r
&Variable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
\r
if (Variable.CurrPtr == NULL) {\r
EFI_SIGNATURE_SUPPORT_NAME,\r
&gEfiGlobalVariableGuid,\r
mSignatureSupport,\r
- SIGSUPPORT_NUM * sizeof(EFI_GUID),\r
+ sizeof(mSignatureSupport),\r
VarAttr,\r
0,\r
0,\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
+ FindVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
if (Variable.CurrPtr != NULL) {\r
SecureBootEnable = *(GetVariableDataPtr (Variable.CurrPtr));\r
} else if (mPlatformMode == USER_MODE) {\r
} else {\r
SecureBootMode = SECURE_BOOT_MODE_DISABLE;\r
}\r
- FindVariable (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
+ FindVariable (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
Status = UpdateVariable (\r
EFI_SECURE_BOOT_MODE_NAME,\r
&gEfiGlobalVariableGuid,\r
DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_SECURE_BOOT_ENABLE_NAME, SecureBootEnable));\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
- // in case incorrect enrollment mis-haps.\r
+ // Check "CustomMode" variable's existence.\r
//\r
- if (ForceClearPK ()) {\r
- DEBUG ((EFI_D_INFO, "Variable PK/KEK/DB/DBX will be cleared in clear PK mode.\n"));\r
-\r
+ FindVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+ if (Variable.CurrPtr != NULL) {\r
+ CustomMode = *(GetVariableDataPtr (Variable.CurrPtr));\r
+ } else {\r
//\r
- // 1. Clear PK.\r
+ // "CustomMode" not exist, initialize it in STANDARD_SECURE_BOOT_MODE.\r
//\r
- Status = DeleteVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid);\r
+ CustomMode = STANDARD_SECURE_BOOT_MODE;\r
+ Status = UpdateVariable (\r
+ EFI_CUSTOM_MODE_NAME,\r
+ &gEfiCustomModeEnableGuid,\r
+ &CustomMode,\r
+ sizeof (UINT8),\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+ 0,\r
+ 0,\r
+ &Variable,\r
+ NULL\r
+ );\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+ }\r
+ \r
+ DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_CUSTOM_MODE_NAME, CustomMode));\r
\r
- //\r
- // 2. Update "SetupMode" variable to SETUP_MODE.\r
- //\r
- UpdatePlatformMode (SETUP_MODE);\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
- //\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
+ 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
AUTHVAR_KEYDB_NAME,\r
&gEfiAuthenticatedVariableGuid,\r
&Variable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
ASSERT_EFI_ERROR (Status);\r
//\r
}\r
\r
/**\r
- Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256 type.\r
+ Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256_GUID type.\r
Follow the steps in UEFI2.2.\r
\r
@param[in] Data Pointer to data with AuthInfo.\r
\r
//\r
// wCertificateType should be WIN_CERT_TYPE_EFI_GUID.\r
- // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256.\r
+ // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256_GUID.\r
//\r
if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||\r
- !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertRsa2048Sha256Guid)\r
+ !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid)\r
) {\r
//\r
// Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.\r
EFI_SETUP_MODE_NAME,\r
&gEfiGlobalVariableGuid,\r
&Variable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
EFI_SECURE_BOOT_MODE_NAME,\r
&gEfiGlobalVariableGuid,\r
&Variable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
//\r
// If "SecureBoot" variable exists, then check "SetupMode" variable update.\r
EFI_SECURE_BOOT_ENABLE_NAME,\r
&gEfiSecureBootEnableDisableGuid,\r
&Variable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
\r
if (SecureBootMode == SECURE_BOOT_MODE_ENABLE) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (mPlatformMode == USER_MODE) {\r
+ if (mPlatformMode == USER_MODE && !(InCustomMode() && UserPhysicalPresent())) {\r
\r
if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\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
EFI_PLATFORM_KEY_NAME,\r
&gEfiGlobalVariableGuid,\r
&PkVariable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
}\r
} else {\r
//\r
- // Process PK or KEK in Setup mode.\r
+ // Process PK or KEK in Setup mode or Custom Secure Boot mode.\r
//\r
if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
//\r
Variable,\r
TimeStamp\r
);\r
- //\r
- // If enroll PK in setup mode, need change to user mode.\r
- //\r
- if ((DataSize != 0) && IsPk) {\r
- Status = UpdatePlatformMode (USER_MODE);\r
- }\r
+\r
+ if (IsPk) {\r
+ if (PayloadSize != 0) {\r
+ //\r
+ // If enroll PK in setup mode, need change to user mode.\r
+ //\r
+ Status = UpdatePlatformMode (USER_MODE);\r
+ } else {\r
+ //\r
+ // If delete PK in custom mode, need change to setup mode.\r
+ //\r
+ UpdatePlatformMode (SETUP_MODE);\r
+ }\r
+ } \r
}\r
\r
return Status;\r
UINT8 *Payload;\r
UINTN PayloadSize;\r
UINT64 MonotonicCount;\r
+ EFI_TIME *TimeStamp;\r
\r
- if (mPlatformMode == USER_MODE) {\r
- if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
+ //\r
+ // DB and DBX should set EFI_VARIABLE_NON_VOLATILE attribute.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+ if (mPlatformMode == USER_MODE && !(InCustomMode() && UserPhysicalPresent())) {\r
+ if (((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) &&\r
+ ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0)){\r
//\r
- // In user mode, should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute.\r
+ // In user mode, should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS or\r
+ // EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute.\r
//\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;\r
- CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);\r
- if ((Variable->CurrPtr != NULL) && (CertData->MonotonicCount <= Variable->CurrPtr->MonotonicCount)) {\r
+ if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
//\r
- // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.\r
+ // Time-based, verify against X509 Cert KEK.\r
//\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- //\r
- // Get KEK database from variable.\r
- //\r
- Status = FindVariable (\r
- EFI_KEY_EXCHANGE_KEY_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &KekVariable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ return VerifyTimeBasedPayload (\r
+ VariableName,\r
+ VendorGuid,\r
+ Data,\r
+ DataSize,\r
+ Variable,\r
+ Attributes,\r
+ AuthVarTypeKek,\r
+ NULL\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ //\r
+ // Counter-based, verify against RSA2048 Cert KEK.\r
+ //\r
+ CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;\r
+ CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);\r
+ if ((Variable->CurrPtr != NULL) && (CertData->MonotonicCount <= Variable->CurrPtr->MonotonicCount)) {\r
+ //\r
+ // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.\r
+ //\r
+ return EFI_SECURITY_VIOLATION;\r
+ }\r
+ //\r
+ // Get KEK database from variable.\r
+ //\r
+ Status = FindVariable (\r
+ EFI_KEY_EXCHANGE_KEY_NAME,\r
+ &gEfiGlobalVariableGuid,\r
+ &KekVariable,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- KekDataSize = KekVariable.CurrPtr->DataSize;\r
- KekList = (EFI_SIGNATURE_LIST *) GetVariableDataPtr (KekVariable.CurrPtr);\r
+ KekDataSize = KekVariable.CurrPtr->DataSize;\r
+ KekList = (EFI_SIGNATURE_LIST *) GetVariableDataPtr (KekVariable.CurrPtr);\r
\r
- //\r
- // Enumerate all Kek items in this list to verify the variable certificate data.\r
- // If anyone is authenticated successfully, it means the variable is correct!\r
- //\r
- IsFound = FALSE;\r
- while ((KekDataSize > 0) && (KekDataSize >= KekList->SignatureListSize)) {\r
- if (CompareGuid (&KekList->SignatureType, &gEfiCertRsa2048Guid)) {\r
- KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize);\r
- KekCount = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize;\r
- for (Index = 0; Index < KekCount; Index++) {\r
- if (CompareMem (KekItem->SignatureData, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
- IsFound = TRUE;\r
- break;\r
+ //\r
+ // Enumerate all Kek items in this list to verify the variable certificate data.\r
+ // If anyone is authenticated successfully, it means the variable is correct!\r
+ //\r
+ IsFound = FALSE;\r
+ while ((KekDataSize > 0) && (KekDataSize >= KekList->SignatureListSize)) {\r
+ if (CompareGuid (&KekList->SignatureType, &gEfiCertRsa2048Guid)) {\r
+ KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize);\r
+ KekCount = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize;\r
+ for (Index = 0; Index < KekCount; Index++) {\r
+ if (CompareMem (KekItem->SignatureData, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
+ IsFound = TRUE;\r
+ break;\r
+ }\r
+ KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize);\r
}\r
- KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize);\r
}\r
+ KekDataSize -= KekList->SignatureListSize;\r
+ KekList = (EFI_SIGNATURE_LIST *) ((UINT8 *) KekList + KekList->SignatureListSize);\r
}\r
- KekDataSize -= KekList->SignatureListSize;\r
- KekList = (EFI_SIGNATURE_LIST *) ((UINT8 *) KekList + KekList->SignatureListSize);\r
- }\r
\r
- if (!IsFound) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
+ if (!IsFound) {\r
+ return EFI_SECURITY_VIOLATION;\r
+ }\r
\r
- 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
- Variable,\r
- NULL\r
- );\r
+ 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
+ Variable,\r
+ NULL\r
+ );\r
+ }\r
}\r
} else {\r
//\r
- // If in setup mode, no authentication needed.\r
+ // If in setup mode or custom secure boot mode, no authentication needed.\r
//\r
- if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\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
// No Authentication descriptor.\r
//\r
MonotonicCount = 0;\r
+ TimeStamp = NULL;\r
Payload = Data;\r
PayloadSize = DataSize;\r
}\r
0,\r
MonotonicCount,\r
Variable,\r
- NULL\r
+ TimeStamp\r
);\r
}\r
\r
PubKey = NULL;\r
IsDeletion = FALSE;\r
\r
+ if (NeedPhysicallyPresent(VariableName, VendorGuid) && !UserPhysicalPresent()) {\r
+ //\r
+ // This variable is protected, only physical present user could modify its value.\r
+ //\r
+ return EFI_SECURITY_VIOLATION;\r
+ }\r
+ \r
//\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
(CertData->TimeStamp.TimeZone != 0) ||\r
(CertData->TimeStamp.Daylight != 0) ||\r
(CertData->TimeStamp.Pad2 != 0)) {\r
- return EFI_INVALID_PARAMETER;\r
+ return EFI_SECURITY_VIOLATION;\r
}\r
\r
if ((Variable->CurrPtr != NULL) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {\r
\r
CopyMem (Buffer, PayloadPtr, PayloadSize);\r
\r
- if (Pk) {\r
+ if (AuthVarType == AuthVarTypePk) {\r
//\r
// Get platform key from variable.\r
//\r
EFI_PLATFORM_KEY_NAME,\r
&gEfiGlobalVariableGuid,\r
&PkVariable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
NewDataSize\r
);\r
\r
- } else {\r
+ } else if (AuthVarType == AuthVarTypeKek) {\r
\r
//\r
// Get KEK database from variable.\r
EFI_KEY_EXCHANGE_KEY_NAME,\r
&gEfiGlobalVariableGuid,\r
&KekVariable,\r
- &mVariableModuleGlobal->VariableGlobal\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\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