From 8c1babfd28b7fd34fa85aac39c25c57a301d7717 Mon Sep 17 00:00:00 2001 From: sfu5 Date: Mon, 14 May 2012 07:36:20 +0000 Subject: Update auth-variable and secure boot UI driver to support only time-based PK, KEK and Signature Database variable variable according to UEFI Spec requirement. Signed-off-by: Fu Siyuan Reviewed-by: Dong Guo Reviewed-by: Ye Ting git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13310 6f19259b-4bc3-4df7-8a09-765794883524 --- .../VariableAuthenticated/RuntimeDxe/AuthService.c | 307 ++++---------------- .../SecureBootConfigDxe/SecureBootConfigDxe.inf | 1 + .../SecureBootConfigDxe/SecureBootConfigImpl.c | 314 +++++++++++---------- 3 files changed, 217 insertions(+), 405 deletions(-) diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c index 784afae93b..a3b620f02a 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c @@ -879,151 +879,49 @@ ProcessVarWithPk ( ) { EFI_STATUS Status; - VARIABLE_POINTER_TRACK PkVariable; - EFI_SIGNATURE_LIST *OldPkList; - EFI_SIGNATURE_DATA *OldPkData; - EFI_VARIABLE_AUTHENTICATION *CertData; - BOOLEAN TimeBase; BOOLEAN Del; UINT8 *Payload; UINTN PayloadSize; - UINT64 MonotonicCount; - EFI_TIME *TimeStamp; - if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) { + if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 || + (Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) { // - // PK and KEK should set EFI_VARIABLE_NON_VOLATILE attribute. + // PK and KEK should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based + // authenticated variable. // return EFI_INVALID_PARAMETER; } if (mPlatformMode == USER_MODE && !(InCustomMode() && UserPhysicalPresent())) { - - if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { - // - // EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute means time-based X509 Cert PK. - // - TimeBase = TRUE; - } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) { - // - // EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute means counter-based RSA-2048 Cert PK. - // - TimeBase = FALSE; - } else { - return EFI_INVALID_PARAMETER; - } - - if (TimeBase) { - // - // Verify against X509 Cert PK. - // - Del = FALSE; - 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. - // - if (Del && IsPk) { - Status = UpdatePlatformMode (SETUP_MODE); - } - } - return Status; - } else { - // - // Verify against RSA2048 Cert PK. - // - CertData = (EFI_VARIABLE_AUTHENTICATION *) Data; - if ((Variable->CurrPtr != NULL) && (CertData->MonotonicCount <= Variable->CurrPtr->MonotonicCount)) { - // - // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION. - // - return EFI_SECURITY_VIOLATION; - } + // + // Verify against X509 Cert PK. + // + Del = FALSE; + Status = VerifyTimeBasedPayload ( + VariableName, + VendorGuid, + Data, + DataSize, + Variable, + Attributes, + AuthVarTypePk, + &Del + ); + if (!EFI_ERROR (Status)) { // - // Get platform key from variable. + // If delete PK in user mode, need change to setup mode. // - Status = FindVariable ( - EFI_PLATFORM_KEY_NAME, - &gEfiGlobalVariableGuid, - &PkVariable, - &mVariableModuleGlobal->VariableGlobal, - FALSE - ); - ASSERT_EFI_ERROR (Status); - - OldPkList = (EFI_SIGNATURE_LIST *) GetVariableDataPtr (PkVariable.CurrPtr); - OldPkData = (EFI_SIGNATURE_DATA *) ((UINT8 *) OldPkList + sizeof (EFI_SIGNATURE_LIST) + OldPkList->SignatureHeaderSize); - Status = VerifyCounterBasedPayload (Data, DataSize, OldPkData->SignatureData); - if (!EFI_ERROR (Status)) { - Status = CheckSignatureListFormat( - VariableName, - VendorGuid, - (UINT8*)Data + AUTHINFO_SIZE, - DataSize - AUTHINFO_SIZE); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = UpdateVariable ( - VariableName, - VendorGuid, - (UINT8*)Data + AUTHINFO_SIZE, - DataSize - AUTHINFO_SIZE, - Attributes, - 0, - CertData->MonotonicCount, - Variable, - NULL - ); - - if (!EFI_ERROR (Status)) { - // - // If delete PK in user mode, need change to setup mode. - // - if ((DataSize == AUTHINFO_SIZE) && IsPk) { - Status = UpdatePlatformMode (SETUP_MODE); - } - } + if (Del && IsPk) { + Status = UpdatePlatformMode (SETUP_MODE); } } + return Status; } else { // // Process PK or KEK in Setup mode or Custom Secure Boot mode. // - if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { - // - // Time-based Authentication descriptor. - // - MonotonicCount = 0; - TimeStamp = &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp; - Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data); - PayloadSize = DataSize - AUTHINFO2_SIZE (Data); - } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) { - // - // Counter-based Authentication descriptor. - // - MonotonicCount = ((EFI_VARIABLE_AUTHENTICATION *) Data)->MonotonicCount; - TimeStamp = NULL; - Payload = (UINT8*) Data + AUTHINFO_SIZE; - PayloadSize = DataSize - AUTHINFO_SIZE; - } else { - // - // No Authentication descriptor. - // - MonotonicCount = 0; - TimeStamp = NULL; - Payload = Data; - PayloadSize = DataSize; - } + Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data); + PayloadSize = DataSize - AUTHINFO2_SIZE (Data); Status = CheckSignatureListFormat(VariableName, VendorGuid, Payload, PayloadSize); if (EFI_ERROR (Status)) { @@ -1037,9 +935,9 @@ ProcessVarWithPk ( PayloadSize, Attributes, 0, - MonotonicCount, + 0, Variable, - TimeStamp + &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp ); if (IsPk) { @@ -1088,148 +986,39 @@ ProcessVarWithKek ( ) { EFI_STATUS Status; - VARIABLE_POINTER_TRACK KekVariable; - EFI_SIGNATURE_LIST *KekList; - EFI_SIGNATURE_DATA *KekItem; - UINT32 KekCount; - EFI_VARIABLE_AUTHENTICATION *CertData; - EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock; - BOOLEAN IsFound; - UINT32 Index; - UINT32 KekDataSize; UINT8 *Payload; UINTN PayloadSize; - UINT64 MonotonicCount; - EFI_TIME *TimeStamp; - if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) { + if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 || + (Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) { // - // DB and DBX should set EFI_VARIABLE_NON_VOLATILE attribute. + // DB and DBX should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based + // authenticated variable. // return EFI_INVALID_PARAMETER; } Status = EFI_SUCCESS; if (mPlatformMode == USER_MODE && !(InCustomMode() && UserPhysicalPresent())) { - if (((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) && - ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0)){ - // - // In user mode, should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS or - // EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute. - // - return EFI_INVALID_PARAMETER; - } - - if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { - // - // Time-based, verify against X509 Cert KEK. - // - 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. - // - CertData = (EFI_VARIABLE_AUTHENTICATION *) Data; - CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData); - if ((Variable->CurrPtr != NULL) && (CertData->MonotonicCount <= Variable->CurrPtr->MonotonicCount)) { - // - // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION. - // - return EFI_SECURITY_VIOLATION; - } - // - // Get KEK database from variable. - // - Status = FindVariable ( - EFI_KEY_EXCHANGE_KEY_NAME, - &gEfiGlobalVariableGuid, - &KekVariable, - &mVariableModuleGlobal->VariableGlobal, - FALSE - ); - ASSERT_EFI_ERROR (Status); - - KekDataSize = KekVariable.CurrPtr->DataSize; - KekList = (EFI_SIGNATURE_LIST *) GetVariableDataPtr (KekVariable.CurrPtr); - - // - // Enumerate all Kek items in this list to verify the variable certificate data. - // If anyone is authenticated successfully, it means the variable is correct! - // - IsFound = FALSE; - while ((KekDataSize > 0) && (KekDataSize >= KekList->SignatureListSize)) { - if (CompareGuid (&KekList->SignatureType, &gEfiCertRsa2048Guid)) { - KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize); - KekCount = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize; - for (Index = 0; Index < KekCount; Index++) { - if (CompareMem (KekItem->SignatureData, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) { - IsFound = TRUE; - break; - } - KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize); - } - } - KekDataSize -= KekList->SignatureListSize; - KekList = (EFI_SIGNATURE_LIST *) ((UINT8 *) KekList + KekList->SignatureListSize); - } - - if (!IsFound) { - return EFI_SECURITY_VIOLATION; - } - - Status = VerifyCounterBasedPayload (Data, DataSize, CertBlock->PublicKey); - if (!EFI_ERROR (Status)) { - Status = UpdateVariable ( - VariableName, - VendorGuid, - (UINT8*)Data + AUTHINFO_SIZE, - DataSize - AUTHINFO_SIZE, - Attributes, - 0, - CertData->MonotonicCount, - Variable, - NULL - ); - } - } + // + // Time-based, verify against X509 Cert KEK. + // + return VerifyTimeBasedPayload ( + VariableName, + VendorGuid, + Data, + DataSize, + Variable, + Attributes, + AuthVarTypeKek, + NULL + ); } else { // // If in setup mode or custom secure boot mode, no authentication needed. // - if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { - // - // Time-based Authentication descriptor. - // - MonotonicCount = 0; - TimeStamp = &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp; - Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data); - PayloadSize = DataSize - AUTHINFO2_SIZE (Data); - } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) { - // - // Counter-based Authentication descriptor. - // - MonotonicCount = ((EFI_VARIABLE_AUTHENTICATION *) Data)->MonotonicCount; - TimeStamp = NULL; - Payload = (UINT8*) Data + AUTHINFO_SIZE; - PayloadSize = DataSize - AUTHINFO_SIZE; - } else { - // - // No Authentication descriptor. - // - MonotonicCount = 0; - TimeStamp = NULL; - Payload = Data; - PayloadSize = DataSize; - } + Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data); + PayloadSize = DataSize - AUTHINFO2_SIZE (Data); Status = UpdateVariable ( VariableName, @@ -1238,9 +1027,9 @@ ProcessVarWithKek ( PayloadSize, Attributes, 0, - MonotonicCount, + 0, Variable, - TimeStamp + &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp ); } diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf index a6a207efe6..a0f497f559 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf @@ -60,6 +60,7 @@ gEfiCustomModeEnableGuid gEfiSecureBootEnableDisableGuid gSecureBootConfigFormSetGuid + gEfiCertPkcs7Guid gEfiCertRsa2048Guid ## CONSUMES gEfiCertX509Guid ## CONSUMES gEfiCertSha1Guid ## CONSUMES diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c index cdfc08acc2..f740c0ae75 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c @@ -108,6 +108,90 @@ SaveSecureBootVariable ( return Status; } +/** + Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2 + descriptor with the input data. NO authentication is required in this function. + + @param[in, out] DataSize On input, the size of Data buffer in bytes. + On output, the size of data returned in Data + buffer in bytes. + @param[in, out] Data On input, Pointer to data buffer to be wrapped or + pointer to NULL to wrap an empty payload. + On output, Pointer to the new payload date buffer allocated from pool, + it's caller's responsibility to free the memory when finish using it. + + @retval EFI_SUCCESS Create time based payload successfully. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resourses to create time based payload. + @retval EFI_INVALID_PARAMETER The parameter is invalid. + @retval Others Unexpected error happens. + +**/ +EFI_STATUS +CreateTimeBasedPayload ( + IN OUT UINTN *DataSize, + IN OUT UINT8 **Data + ) +{ + EFI_STATUS Status; + UINT8 *NewData; + UINT8 *Payload; + UINTN PayloadSize; + EFI_VARIABLE_AUTHENTICATION_2 *DescriptorData; + UINTN DescriptorSize; + EFI_TIME Time; + + if (Data == NULL || DataSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // In Setup mode or Custom mode, the variable does not need to be signed but the + // parameters to the SetVariable() call still need to be prepared as authenticated + // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate + // data in it. + // + Payload = *Data; + PayloadSize = *DataSize; + + DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); + NewData = (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize); + if (NewData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if ((Payload != NULL) && (PayloadSize != 0)) { + CopyMem (NewData + DescriptorSize, Payload, PayloadSize); + } + + DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData); + + ZeroMem (&Time, sizeof (EFI_TIME)); + Status = gRT->GetTime (&Time, NULL); + if (EFI_ERROR (Status)) { + FreePool(NewData); + return Status; + } + Time.Pad1 = 0; + Time.Nanosecond = 0; + Time.TimeZone = 0; + Time.Daylight = 0; + Time.Pad2 = 0; + CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME)); + + DescriptorData->AuthInfo.Hdr.dwLength = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); + DescriptorData->AuthInfo.Hdr.wRevision = 0x0200; + DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; + CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid); + + if (Payload != NULL) { + FreePool(Payload); + } + + *DataSize = DescriptorSize + PayloadSize; + *Data = NewData; + return EFI_SUCCESS; +} + /** Internal helper function to delete a Variable given its name and GUID, NO authentication required. @@ -127,130 +211,36 @@ DeleteVariable ( { EFI_STATUS Status; VOID* Variable; + UINT8 *Data; + UINTN DataSize; + UINT32 Attr; Variable = GetVariable (VariableName, VendorGuid); if (Variable == NULL) { return EFI_SUCCESS; } - Status = gRT->SetVariable ( - VariableName, - VendorGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, - 0, - NULL - ); - return Status; -} - -/** - Generate a PK signature list from the public key storing file (*.pbk). - - @param[in] PkKeyFile FileHandle of the public key storing file. - @param[out] PkCert Point to the data buffer to store the signature list. - - @return EFI_UNSUPPORTED Unsupported Key Length. - @return EFI_OUT_OF_RESOURCES There are not enough memory resourses to form the signature list. - -**/ -EFI_STATUS -CreatePkRsaSignatureList ( - IN EFI_FILE_HANDLE PkKeyFile, - OUT EFI_SIGNATURE_LIST **PkCert - ) -{ - EFI_STATUS Status; - UINTN KeyBlobSize; - VOID *KeyBlob; - CPL_KEY_INFO *KeyInfo; - EFI_SIGNATURE_DATA *PkCertData; - VOID *KeyBuffer; - UINTN KeyLenInBytes; - - PkCertData = NULL; - KeyBlob = NULL; - KeyBuffer = NULL; - Status = EFI_SUCCESS; - - // - // Get key from PK key file - // - Status = ReadFileContent (PkKeyFile, &KeyBlob, &KeyBlobSize, 0); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "Can't Open the file for PK enrolling.\n")); - goto ON_EXIT; - } - ASSERT (KeyBlob != NULL); - - KeyInfo = (CPL_KEY_INFO *)KeyBlob; - if (KeyInfo->KeyLengthInBits/8 != WIN_CERT_UEFI_RSA2048_SIZE) { - Status = EFI_UNSUPPORTED; - goto ON_EXIT; - } - - // - // Convert the Public key to fix octet string format represented in RSA PKCS#1. - // - KeyLenInBytes = KeyInfo->KeyLengthInBits / 8; - KeyBuffer = AllocateZeroPool(KeyLenInBytes); - if (KeyBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - Status = Int2OctStr ( - (UINTN*) ((UINTN)KeyBlob + sizeof(CPL_KEY_INFO)), - KeyLenInBytes / sizeof (UINTN), - (UINT8*)KeyBuffer, - KeyLenInBytes - ); - if (EFI_ERROR(Status)) { - goto ON_EXIT; - } + Data = NULL; + DataSize = 0; + Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; - // Allocate space for PK certificate list and initialize the list. - // Create PK database entry with SignatureHeaderSize equals 0. - // - *PkCert = (EFI_SIGNATURE_LIST*)AllocateZeroPool( - sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 - + WIN_CERT_UEFI_RSA2048_SIZE - ); - - if (*PkCert == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; + Status = CreateTimeBasedPayload (&DataSize, &Data); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status)); + return Status; } - (*PkCert)->SignatureListSize = sizeof(EFI_SIGNATURE_LIST) - + sizeof(EFI_SIGNATURE_DATA) - 1 - + WIN_CERT_UEFI_RSA2048_SIZE; - (*PkCert)->SignatureSize = sizeof(EFI_SIGNATURE_DATA) - 1 + WIN_CERT_UEFI_RSA2048_SIZE; - (*PkCert)->SignatureHeaderSize = 0; - CopyGuid (&(*PkCert)->SignatureType, &gEfiCertRsa2048Guid); - - PkCertData = (EFI_SIGNATURE_DATA*)((UINTN)(*PkCert) - + sizeof(EFI_SIGNATURE_LIST) - + (*PkCert)->SignatureHeaderSize); - CopyGuid (&PkCertData->SignatureOwner, &gEfiGlobalVariableGuid); - // - // Fill the PK database with PKpub data from PKKeyFile. - // - CopyMem (&(PkCertData->SignatureData[0]), KeyBuffer, WIN_CERT_UEFI_RSA2048_SIZE); - -ON_EXIT: - - if (KeyBlob != NULL) { - FreePool (KeyBlob); - } - - if (EFI_ERROR(Status) && *PkCert != NULL) { - FreePool (*PkCert); - *PkCert = NULL; - } - - if (KeyBuffer != NULL) { - FreePool (KeyBuffer); + Status = gRT->SetVariable ( + VariableName, + VendorGuid, + Attr, + DataSize, + Data + ); + if (Data != NULL) { + FreePool (Data); } - return Status; } @@ -357,11 +347,11 @@ EnrollPlatformKey ( PkCert = NULL; // - // Parse the file's postfix. Only support *.pbk(RSA2048) and *.cer(X509) files. + // Parse the file's postfix. Only support *.cer(X509) files. // FilePostFix = Private->FileContext->FileName + StrLen (Private->FileContext->FileName) - 4; - if (CompareMem (FilePostFix, L".pbk",4) && CompareMem (FilePostFix, L".cer",4)) { - DEBUG ((EFI_D_ERROR, "Don't support the file, only *.pbk or *.cer.\n is supported.")); + if (CompareMem (FilePostFix, L".cer",4)) { + DEBUG ((EFI_D_ERROR, "Don't support the file, only *.cer is supported.")); return EFI_INVALID_PARAMETER; } DEBUG ((EFI_D_INFO, "FileName= %s\n", Private->FileContext->FileName)); @@ -370,22 +360,12 @@ EnrollPlatformKey ( // // Prase the selected PK file and generature PK certificate list. // - if (!CompareMem (FilePostFix, L".pbk",4)) { - Status = CreatePkRsaSignatureList ( - Private->FileContext->FHandle, - &PkCert - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - } else if (!CompareMem (FilePostFix, L".cer",4)) { - Status = CreatePkX509SignatureList ( - Private->FileContext->FHandle, - &PkCert - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } + Status = CreatePkX509SignatureList ( + Private->FileContext->FHandle, + &PkCert + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; } ASSERT (PkCert != NULL); @@ -393,8 +373,14 @@ EnrollPlatformKey ( // Set Platform Key variable. // Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_BOOTSERVICE_ACCESS; + | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; DataSize = PkCert->SignatureListSize; + Status = CreateTimeBasedPayload (&DataSize, (UINT8**) &PkCert); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status)); + goto ON_EXIT; + } + Status = gRT->SetVariable( EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, @@ -437,8 +423,10 @@ DeletePlatformKey ( { EFI_STATUS Status; - Status = DeleteVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid); - + Status = DeleteVariable ( + EFI_PLATFORM_KEY_NAME, + &gEfiGlobalVariableGuid + ); return Status; } @@ -551,8 +539,14 @@ EnrollRsa2048ToKek ( // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the // new KEK to original variable. // - Attr |= EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS; - DataSize = 0; + Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS + | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8**) &KekSigList); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status)); + goto ON_EXIT; + } + Status = gRT->GetVariable( EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, @@ -672,8 +666,13 @@ EnrollX509ToKek ( // new kek to original variable // Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_BOOTSERVICE_ACCESS; - + | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8**) &KekSigList); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status)); + goto ON_EXIT; + } + Status = gRT->GetVariable( EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, @@ -826,7 +825,12 @@ EnrollX509toSigDB ( // new signature data to original variable // Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_BOOTSERVICE_ACCESS; + | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + Status = CreateTimeBasedPayload (&SigDBSize, (UINT8**) &Data); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status)); + goto ON_EXIT; + } Status = gRT->GetVariable( VariableName, @@ -1281,8 +1285,6 @@ EnrollImageSignatureToSigDB ( Data = NULL; GuidCertData = NULL; - Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_BOOTSERVICE_ACCESS; // // Form the SigDB certificate list. @@ -1374,6 +1376,14 @@ EnrollImageSignatureToSigDB ( CopyGuid (&SigDBCertData->SignatureOwner, Private->SignatureGUID); CopyMem (SigDBCertData->SignatureData, mImageDigest, mImageDigestSize); + Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS + | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + Status = CreateTimeBasedPayload (&SigDBSize, (UINT8**) &Data); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status)); + goto ON_EXIT; + } + // // Check if SigDB variable has been already existed. // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the @@ -1799,8 +1809,14 @@ DeleteKeyExchangeKey ( CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); } - CertList = (EFI_SIGNATURE_LIST*) OldData; DataSize = Offset; + if ((Attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { + Status = CreateTimeBasedPayload (&DataSize, &OldData); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status)); + goto ON_EXIT; + } + } Status = gRT->SetVariable( EFI_KEY_EXCHANGE_KEY_NAME, @@ -1986,8 +2002,14 @@ DeleteSignature ( CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); } - CertList = (EFI_SIGNATURE_LIST*) OldData; DataSize = Offset; + if ((Attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { + Status = CreateTimeBasedPayload (&DataSize, &OldData); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fail to create time-based data payload: %r", Status)); + goto ON_EXIT; + } + } Status = gRT->SetVariable( VariableName, @@ -2465,7 +2487,7 @@ SecureBootCallback ( CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, - L"ERROR: The File Type is neither *.cer nor *.pbk!", + L"ERROR: Unsupported file type, only *.cer is supported!", NULL ); } else { -- cgit v1.2.3