return Status;\r
}\r
\r
+/**\r
+ Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2\r
+ descriptor with the input data. NO authentication is required in this function.\r
+ \r
+ @param[in, out] DataSize On input, the size of Data buffer in bytes.\r
+ On output, the size of data returned in Data\r
+ buffer in bytes.\r
+ @param[in, out] Data On input, Pointer to data buffer to be wrapped or \r
+ pointer to NULL to wrap an empty payload.\r
+ On output, Pointer to the new payload date buffer allocated from pool,\r
+ it's caller's responsibility to free the memory when finish using it. \r
+\r
+ @retval EFI_SUCCESS Create time based payload successfully.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough memory resourses to create time based payload.\r
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.\r
+ @retval Others Unexpected error happens.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateTimeBasedPayload (\r
+ IN OUT UINTN *DataSize,\r
+ IN OUT UINT8 **Data\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 *NewData;\r
+ UINT8 *Payload;\r
+ UINTN PayloadSize;\r
+ EFI_VARIABLE_AUTHENTICATION_2 *DescriptorData;\r
+ UINTN DescriptorSize;\r
+ EFI_TIME Time;\r
+ \r
+ if (Data == NULL || DataSize == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ \r
+ //\r
+ // In Setup mode or Custom mode, the variable does not need to be signed but the \r
+ // parameters to the SetVariable() call still need to be prepared as authenticated\r
+ // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate\r
+ // data in it.\r
+ //\r
+ Payload = *Data;\r
+ PayloadSize = *DataSize;\r
+ \r
+ DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);\r
+ NewData = (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize);\r
+ if (NewData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ if ((Payload != NULL) && (PayloadSize != 0)) {\r
+ CopyMem (NewData + DescriptorSize, Payload, PayloadSize);\r
+ }\r
+\r
+ DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData);\r
+\r
+ ZeroMem (&Time, sizeof (EFI_TIME));\r
+ Status = gRT->GetTime (&Time, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool(NewData);\r
+ return Status;\r
+ }\r
+ Time.Pad1 = 0;\r
+ Time.Nanosecond = 0;\r
+ Time.TimeZone = 0;\r
+ Time.Daylight = 0;\r
+ Time.Pad2 = 0;\r
+ CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME));\r
+ \r
+ DescriptorData->AuthInfo.Hdr.dwLength = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);\r
+ DescriptorData->AuthInfo.Hdr.wRevision = 0x0200;\r
+ DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;\r
+ CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid);\r
+ \r
+ if (Payload != NULL) {\r
+ FreePool(Payload);\r
+ }\r
+ \r
+ *DataSize = DescriptorSize + PayloadSize;\r
+ *Data = NewData;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Internal helper function to delete a Variable given its name and GUID, NO authentication\r
required.\r
{\r
EFI_STATUS Status;\r
VOID* Variable;\r
+ UINT8 *Data;\r
+ UINTN DataSize;\r
+ UINT32 Attr;\r
\r
- Variable = GetVariable (VariableName, VendorGuid);\r
+ GetVariable2 (VariableName, VendorGuid, &Variable, NULL);\r
if (Variable == NULL) {\r
return EFI_SUCCESS;\r
}\r
\r
- Status = gRT->SetVariable (\r
- VariableName,\r
- VendorGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- 0,\r
- NULL\r
- );\r
- return Status;\r
-}\r
-\r
-/**\r
- Generate a PK signature list from the public key storing file (*.pbk).\r
-\r
- @param[in] PkKeyFile FileHandle of the public key storing file.\r
- @param[out] PkCert Point to the data buffer to store the signature list.\r
- \r
- @return EFI_UNSUPPORTED Unsupported Key Length.\r
- @return EFI_OUT_OF_RESOURCES There are not enough memory resourses to form the signature list.\r
- \r
-**/\r
-EFI_STATUS\r
-CreatePkRsaSignatureList (\r
- IN EFI_FILE_HANDLE PkKeyFile, \r
- OUT EFI_SIGNATURE_LIST **PkCert \r
- )\r
-{\r
- EFI_STATUS Status; \r
- UINTN KeyBlobSize;\r
- VOID *KeyBlob;\r
- CPL_KEY_INFO *KeyInfo;\r
- EFI_SIGNATURE_DATA *PkCertData;\r
- VOID *KeyBuffer; \r
- UINTN KeyLenInBytes;\r
-\r
- PkCertData = NULL;\r
- KeyBlob = NULL;\r
- KeyBuffer = NULL;\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Get key from PK key file\r
- // \r
- Status = ReadFileContent (PkKeyFile, &KeyBlob, &KeyBlobSize, 0);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((EFI_D_ERROR, "Can't Open the file for PK enrolling.\n"));\r
- goto ON_EXIT;\r
- }\r
- ASSERT (KeyBlob != NULL);\r
-\r
- KeyInfo = (CPL_KEY_INFO *)KeyBlob;\r
- if (KeyInfo->KeyLengthInBits/8 != WIN_CERT_UEFI_RSA2048_SIZE) {\r
- Status = EFI_UNSUPPORTED;\r
- goto ON_EXIT;\r
- }\r
-\r
- //\r
- // Convert the Public key to fix octet string format represented in RSA PKCS#1.\r
- // \r
- KeyLenInBytes = KeyInfo->KeyLengthInBits / 8;\r
- KeyBuffer = AllocateZeroPool(KeyLenInBytes);\r
- if (KeyBuffer == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ON_EXIT;\r
- }\r
- Status = Int2OctStr (\r
- (UINTN*) ((UINTN)KeyBlob + sizeof(CPL_KEY_INFO)), \r
- KeyLenInBytes / sizeof (UINTN), \r
- (UINT8*)KeyBuffer, \r
- KeyLenInBytes\r
- );\r
- if (EFI_ERROR(Status)) {\r
- goto ON_EXIT;\r
- }\r
+ Data = NULL;\r
+ DataSize = 0;\r
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
+ | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
\r
- // Allocate space for PK certificate list and initialize the list.\r
- // Create PK database entry with SignatureHeaderSize equals 0.\r
- //\r
- *PkCert = (EFI_SIGNATURE_LIST*)AllocateZeroPool(\r
- sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1\r
- + WIN_CERT_UEFI_RSA2048_SIZE\r
- );\r
- \r
- if (*PkCert == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ON_EXIT;\r
+ Status = CreateTimeBasedPayload (&DataSize, &Data);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));\r
+ return Status;\r
}\r
\r
- (*PkCert)->SignatureListSize = sizeof(EFI_SIGNATURE_LIST) \r
- + sizeof(EFI_SIGNATURE_DATA) - 1\r
- + WIN_CERT_UEFI_RSA2048_SIZE;\r
- (*PkCert)->SignatureSize = sizeof(EFI_SIGNATURE_DATA) - 1 + WIN_CERT_UEFI_RSA2048_SIZE;\r
- (*PkCert)->SignatureHeaderSize = 0;\r
- CopyGuid (&(*PkCert)->SignatureType, &gEfiCertRsa2048Guid);\r
-\r
- PkCertData = (EFI_SIGNATURE_DATA*)((UINTN)(*PkCert) \r
- + sizeof(EFI_SIGNATURE_LIST)\r
- + (*PkCert)->SignatureHeaderSize);\r
- CopyGuid (&PkCertData->SignatureOwner, &gEfiGlobalVariableGuid);\r
- //\r
- // Fill the PK database with PKpub data from PKKeyFile.\r
- // \r
- CopyMem (&(PkCertData->SignatureData[0]), KeyBuffer, WIN_CERT_UEFI_RSA2048_SIZE);\r
-\r
-ON_EXIT:\r
- \r
- if (KeyBlob != NULL) {\r
- FreePool (KeyBlob);\r
- }\r
- \r
- if (EFI_ERROR(Status) && *PkCert != NULL) {\r
- FreePool (*PkCert);\r
- *PkCert = NULL;\r
- }\r
- \r
- if (KeyBuffer != NULL) {\r
- FreePool (KeyBuffer);\r
+ Status = gRT->SetVariable (\r
+ VariableName,\r
+ VendorGuid,\r
+ Attr,\r
+ DataSize,\r
+ Data\r
+ );\r
+ if (Data != NULL) {\r
+ FreePool (Data);\r
}\r
- \r
return Status;\r
}\r
\r
PkCert = NULL;\r
\r
//\r
- // Parse the file's postfix. Only support *.pbk(RSA2048) and *.cer(X509) files.\r
+ // Parse the file's postfix. Only support *.cer(X509) files.\r
//\r
FilePostFix = Private->FileContext->FileName + StrLen (Private->FileContext->FileName) - 4;\r
- if (CompareMem (FilePostFix, L".pbk",4) && CompareMem (FilePostFix, L".cer",4)) {\r
- DEBUG ((EFI_D_ERROR, "Don't support the file, only *.pbk or *.cer.\n is supported."));\r
+ if (CompareMem (FilePostFix, L".cer",4)) {\r
+ DEBUG ((EFI_D_ERROR, "Don't support the file, only *.cer is supported."));\r
return EFI_INVALID_PARAMETER;\r
}\r
DEBUG ((EFI_D_INFO, "FileName= %s\n", Private->FileContext->FileName));\r
//\r
// Prase the selected PK file and generature PK certificate list.\r
//\r
- if (!CompareMem (FilePostFix, L".pbk",4)) {\r
- Status = CreatePkRsaSignatureList (\r
- Private->FileContext->FHandle, \r
- &PkCert \r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;\r
- }\r
- } else if (!CompareMem (FilePostFix, L".cer",4)) {\r
- Status = CreatePkX509SignatureList (\r
- Private->FileContext->FHandle, \r
- &PkCert \r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;\r
- }\r
+ Status = CreatePkX509SignatureList (\r
+ Private->FileContext->FHandle, \r
+ &PkCert \r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
}\r
ASSERT (PkCert != NULL);\r
\r
// Set Platform Key variable.\r
// \r
Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS \r
- | EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
DataSize = PkCert->SignatureListSize;\r
+ Status = CreateTimeBasedPayload (&DataSize, (UINT8**) &PkCert);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));\r
+ goto ON_EXIT;\r
+ }\r
+ \r
Status = gRT->SetVariable(\r
EFI_PLATFORM_KEY_NAME, \r
&gEfiGlobalVariableGuid, \r
{\r
EFI_STATUS Status;\r
\r
- Status = DeleteVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid);\r
- \r
+ Status = DeleteVariable (\r
+ EFI_PLATFORM_KEY_NAME,\r
+ &gEfiGlobalVariableGuid\r
+ );\r
return Status;\r
}\r
\r
// If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the \r
// new KEK to original variable.\r
// \r
- Attr |= EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
- DataSize = 0;\r
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS \r
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+ Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8**) &KekSigList);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));\r
+ goto ON_EXIT;\r
+ }\r
+\r
Status = gRT->GetVariable(\r
EFI_KEY_EXCHANGE_KEY_NAME, \r
&gEfiGlobalVariableGuid, \r
// new kek to original variable\r
// \r
Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS \r
- | EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
-\r
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+ Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8**) &KekSigList);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));\r
+ goto ON_EXIT;\r
+ }\r
+ \r
Status = gRT->GetVariable(\r
EFI_KEY_EXCHANGE_KEY_NAME, \r
&gEfiGlobalVariableGuid, \r
// new signature data to original variable\r
// \r
Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS \r
- | EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+ Status = CreateTimeBasedPayload (&SigDBSize, (UINT8**) &Data);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));\r
+ goto ON_EXIT;\r
+ }\r
\r
Status = gRT->GetVariable(\r
VariableName, \r
\r
Data = NULL;\r
GuidCertData = NULL;\r
- Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS \r
- | EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
\r
//\r
// Form the SigDB certificate list.\r
CopyGuid (&SigDBCertData->SignatureOwner, Private->SignatureGUID);\r
CopyMem (SigDBCertData->SignatureData, mImageDigest, mImageDigestSize);\r
\r
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS \r
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+ Status = CreateTimeBasedPayload (&SigDBSize, (UINT8**) &Data);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));\r
+ goto ON_EXIT;\r
+ }\r
+ \r
//\r
// Check if SigDB variable has been already existed. \r
// If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the \r
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
}\r
\r
- CertList = (EFI_SIGNATURE_LIST*) OldData;\r
DataSize = Offset;\r
+ if ((Attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ Status = CreateTimeBasedPayload (&DataSize, &OldData);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
\r
Status = gRT->SetVariable(\r
EFI_KEY_EXCHANGE_KEY_NAME, \r
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
}\r
\r
- CertList = (EFI_SIGNATURE_LIST*) OldData;\r
DataSize = Offset;\r
+ if ((Attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ Status = CreateTimeBasedPayload (&DataSize, &OldData);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status));\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
\r
Status = gRT->SetVariable(\r
VariableName, \r
//\r
// Get the SecureBootEnable Variable\r
//\r
- SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid);\r
+ GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, &SecureBootEnable, NULL);\r
\r
//\r
// If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable\r
//\r
// If there is no PK then the Delete Pk button will be gray.\r
//\r
- SetupMode = GetVariable (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid);\r
+ GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, &SetupMode, NULL);\r
if (SetupMode == NULL || (*SetupMode) == 1) {\r
ConfigData->HasPk = FALSE;\r
} else {\r
//\r
// Get the SecureBootMode from CustomMode variable.\r
//\r
- SecureBootMode = GetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid);\r
+ GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, &SecureBootMode, NULL);\r
if (SecureBootMode == NULL) {\r
ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE;\r
} else {\r
UINTN BufferSize;\r
SECUREBOOT_CONFIGURATION *IfrNvData;\r
UINT16 LabelId;\r
+ UINT8 *SecureBootEnable;\r
+\r
+ SecureBootEnable = NULL;\r
\r
if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
\r
switch (QuestionId) {\r
case KEY_SECURE_BOOT_ENABLE:\r
- if (NULL != GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid)) {\r
+ GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, &SecureBootEnable, NULL);\r
+ if (NULL != SecureBootEnable) {\r
if (EFI_ERROR (SaveSecureBootVariable (Value->u8))) {\r
CreatePopUp (\r
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
CreatePopUp (\r
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
&Key,\r
- L"ERROR: The File Type is neither *.cer nor *.pbk!",\r
+ L"ERROR: Unsupported file type, only *.cer is supported!",\r
NULL\r
);\r
} else {\r
break;\r
\r
case KEY_SECURE_BOOT_MODE:\r
- if (NULL != GetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid)) {\r
+ GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, &SecureBootEnable, NULL);\r
+ if (NULL != SecureBootEnable) {\r
Status = gRT->SetVariable ( \r
EFI_CUSTOM_MODE_NAME,\r
&gEfiCustomModeEnableGuid,\r