UINT32 mPubKeyNumber;\r
UINT8 mCertDbStore[MAX_CERTDB_SIZE];\r
UINT32 mPlatformMode;\r
+UINT8 mVendorKeyState;\r
+\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
// Reserved runtime buffer for "Append" operation in virtual mode.\r
//\r
- mStorageArea = AllocateRuntimePool (PcdGet32 (PcdMaxVariableSize));\r
+ mStorageArea = AllocateRuntimePool (MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)));\r
if (mStorageArea == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
}\r
\r
//\r
- // Create "SetupMode" varable with BS+RT attribute set.\r
+ // Create "SetupMode" variable with BS+RT attribute set.\r
//\r
FindVariable (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
if (PkVariable.CurrPtr == NULL) {\r
}\r
\r
//\r
- // Create "SignatureSupport" varable with BS+RT attribute set.\r
+ // Create "SignatureSupport" variable with BS+RT attribute set.\r
//\r
FindVariable (EFI_SIGNATURE_SUPPORT_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
Status = UpdateVariable (\r
}\r
\r
//\r
- // Create "SecureBoot" varable with BS+RT attribute set.\r
+ // Create "SecureBoot" variable with BS+RT attribute set.\r
//\r
if (SecureBootEnable == SECURE_BOOT_ENABLE && mPlatformMode == USER_MODE) {\r
SecureBootMode = SECURE_BOOT_MODE_ENABLE;\r
DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_SECURE_BOOT_ENABLE_NAME, SecureBootEnable));\r
\r
//\r
- // Check "CustomMode" variable's existence.\r
+ // Initialize "CustomMode" in STANDARD_SECURE_BOOT_MODE state.\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
- // "CustomMode" not exist, initialize it in STANDARD_SECURE_BOOT_MODE.\r
- //\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
+ 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
DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_CUSTOM_MODE_NAME, CustomMode));\r
}\r
} \r
\r
+ //\r
+ // Check "VendorKeysNv" variable's existence and create "VendorKeys" variable accordingly.\r
+ //\r
+ FindVariable (EFI_VENDOR_KEYS_NV_VARIABLE_NAME, &gEfiVendorKeysNvGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+ if (Variable.CurrPtr != NULL) {\r
+ mVendorKeyState = *(GetVariableDataPtr (Variable.CurrPtr));\r
+ } else {\r
+ //\r
+ // "VendorKeysNv" not exist, initialize it in VENDOR_KEYS_VALID state.\r
+ //\r
+ mVendorKeyState = VENDOR_KEYS_VALID;\r
+ Status = UpdateVariable (\r
+ EFI_VENDOR_KEYS_NV_VARIABLE_NAME,\r
+ &gEfiVendorKeysNvGuid,\r
+ &mVendorKeyState,\r
+ sizeof (UINT8),\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,\r
+ 0,\r
+ 0,\r
+ &Variable,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Create "VendorKeys" variable with BS+RT attribute set.\r
+ //\r
+ FindVariable (EFI_VENDOR_KEYS_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+ Status = UpdateVariable (\r
+ EFI_VENDOR_KEYS_VARIABLE_NAME,\r
+ &gEfiGlobalVariableGuid,\r
+ &mVendorKeyState,\r
+ sizeof (UINT8),\r
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+ 0,\r
+ 0,\r
+ &Variable,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_VENDOR_KEYS_VARIABLE_NAME, mVendorKeyState));\r
+\r
return Status;\r
}\r
\r
FALSE\r
);\r
ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ return 0;\r
+ }\r
+\r
//\r
// Check whether the public key entry does exist.\r
//\r
FALSE\r
);\r
ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ return 0;\r
+ }\r
\r
DataSize = DataSizeOfVariable (Variable.CurrPtr);\r
Data = GetVariableDataPtr (Variable.CurrPtr);\r
{\r
EFI_STATUS Status;\r
VARIABLE_POINTER_TRACK Variable;\r
- UINT32 VarAttr;\r
UINT8 SecureBootMode;\r
UINT8 SecureBootEnable;\r
UINTN VariableDataSize;\r
}\r
}\r
\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
&SecureBootMode,\r
sizeof(UINT8),\r
- VarAttr,\r
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
0,\r
0,\r
&Variable,\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Update "VendorKeys" variable to record the out of band secure boot key modification.\r
+\r
+ @return EFI_SUCCESS Variable is updated successfully.\r
+ @return Others Failed to update variable.\r
+ \r
+**/\r
+EFI_STATUS\r
+VendorKeyIsModified (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VARIABLE_POINTER_TRACK Variable;\r
+\r
+ if (mVendorKeyState == VENDOR_KEYS_MODIFIED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ mVendorKeyState = VENDOR_KEYS_MODIFIED;\r
+ \r
+ FindVariable (EFI_VENDOR_KEYS_NV_VARIABLE_NAME, &gEfiVendorKeysNvGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+ Status = UpdateVariable (\r
+ EFI_VENDOR_KEYS_NV_VARIABLE_NAME,\r
+ &gEfiVendorKeysNvGuid,\r
+ &mVendorKeyState,\r
+ sizeof (UINT8),\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,\r
+ 0,\r
+ 0,\r
+ &Variable,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ FindVariable (EFI_VENDOR_KEYS_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+ return UpdateVariable (\r
+ EFI_VENDOR_KEYS_VARIABLE_NAME,\r
+ &gEfiGlobalVariableGuid,\r
+ &mVendorKeyState,\r
+ sizeof (UINT8),\r
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+ 0,\r
+ 0,\r
+ &Variable,\r
+ NULL\r
+ );\r
+}\r
+\r
/**\r
Process variable with platform key for verification.\r
\r
Variable,\r
&((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp\r
);\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if ((mPlatformMode != SETUP_MODE) || IsPk) {\r
+ Status = VendorKeyIsModified ();\r
+ }\r
} else if (mPlatformMode == USER_MODE) {\r
//\r
// Verify against X509 Cert in PK database.\r
Variable,\r
&((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp\r
);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (mPlatformMode != SETUP_MODE) {\r
+ Status = VendorKeyIsModified ();\r
+ }\r
}\r
\r
return Status;\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
+ @param[in, out] Data Pointer to original EFI_SIGNATURE_LIST.\r
+ @param[in] DataSize Size of Data buffer.\r
+ @param[in] FreeBufSize Size of free data buffer \r
+ @param[in] NewData Pointer to new EFI_SIGNATURE_LIST to be appended.\r
+ @param[in] NewDataSize Size of NewData buffer.\r
+ @param[out] MergedBufSize Size of the merged buffer\r
\r
- @return Size of the merged buffer.\r
+ @return EFI_BUFFER_TOO_SMALL if input Data buffer overflowed\r
\r
**/\r
-UINTN\r
+EFI_STATUS\r
AppendSignatureList (\r
IN OUT VOID *Data,\r
IN UINTN DataSize,\r
+ IN UINTN FreeBufSize,\r
IN VOID *NewData,\r
- IN UINTN NewDataSize\r
+ IN UINTN NewDataSize,\r
+ OUT UINTN *MergedBufSize\r
)\r
{\r
EFI_SIGNATURE_LIST *CertList;\r
// New EFI_SIGNATURE_DATA, append it.\r
//\r
if (CopiedCount == 0) {\r
+ if (FreeBufSize < sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize) {\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
//\r
// Copy EFI_SIGNATURE_LIST header for only once.\r
//\r
+\r
CopyMem (Tail, NewCertList, sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);\r
Tail = Tail + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize;\r
+ FreeBufSize -= sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize;\r
}\r
\r
+ if (FreeBufSize < NewCertList->SignatureSize) {\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
CopyMem (Tail, NewCert, NewCertList->SignatureSize);\r
Tail += NewCertList->SignatureSize;\r
+ FreeBufSize -= NewCertList->SignatureSize;\r
CopiedCount++;\r
}\r
\r
NewCertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) NewCertList + NewCertList->SignatureListSize);\r
}\r
\r
- return (Tail - (UINT8 *) Data);\r
+ *MergedBufSize = (Tail - (UINT8 *) Data);\r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r
\r
if (AuthVarType == AuthVarTypePk) {\r
//\r
- // Get platform key from variable.\r
+ // Verify that the signature has been made with the current Platform Key (no chaining for PK).\r
+ // First, 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
+ // Second, get the current platform key from variable. Check whether it's identical with signer's certificates\r
+ // in SignedData. If not, return error immediately.\r
//\r
Status = FindVariable (\r
EFI_PLATFORM_KEY_NAME,\r
FALSE\r
);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ VerifyStatus = FALSE;\r
+ goto Exit;\r
}\r
-\r
CertList = (EFI_SIGNATURE_LIST *) GetVariableDataPtr (PkVariable.CurrPtr);\r
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
- RootCert = Cert->SignatureData;\r
- RootCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);\r
-\r
+ if ((RootCertSize != (CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1))) ||\r
+ (CompareMem (Cert->SignatureData, RootCert, RootCertSize) != 0)) {\r
+ VerifyStatus = FALSE;\r
+ goto Exit;\r
+ }\r
\r
//\r
// Verify Pkcs7 SignedData via Pkcs7Verify library.\r
\r
Exit:\r
\r
- if (AuthVarType == AuthVarTypePriv) {\r
+ if (AuthVarType == AuthVarTypePk || AuthVarType == AuthVarTypePriv) {\r
Pkcs7FreeSigners (RootCert);\r
Pkcs7FreeSigners (SignerCerts);\r
}\r