X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=SecurityPkg%2FVariableAuthenticated%2FSecureBootConfigDxe%2FSecureBootConfigImpl.c;h=2eaf24633db15d880c95c23ae493b12ed551de49;hp=8ca6d623965efa7dcdf53e9813045e34a1effb42;hb=9d9b8b77bc54718a4debfea3a7a3dd59bba16840;hpb=abffadf0ecde6763ceae1fa637629e23d2e9c8f6 diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c index 8ca6d62396..2eaf24633d 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c @@ -1,7 +1,7 @@ /** @file HII Config Access protocol implementation of SecureBoot configuration module. -Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -49,8 +49,6 @@ HII_VENDOR_DEVICE_PATH mSecureBootHiiVendorDevicePath = { BOOLEAN mIsEnterSecureBootForm = FALSE; -BOOLEAN mIsSelectedSecureBootModeForm = FALSE; -BOOLEAN mIsSecureBootModeChanged = FALSE; // // OID ASN.1 Value for Hash Algorithms @@ -65,7 +63,6 @@ UINT8 mHashOidValue[] = { }; HASH_TABLE mHash[] = { - { L"SHA1", 20, &mHashOidValue[8], 5, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final }, { L"SHA224", 28, &mHashOidValue[13], 9, NULL, NULL, NULL, NULL }, { L"SHA256", 32, &mHashOidValue[22], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final}, { L"SHA384", 48, &mHashOidValue[31], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final}, @@ -99,6 +96,31 @@ CHAR16* mSupportX509Suffix = L"*.cer/der/crt"; SECUREBOOT_CONFIG_PRIVATE_DATA *gSecureBootPrivateData = NULL; +/** + This code cleans up enrolled file by closing file & free related resources attached to + enrolled file. + + @param[in] FileContext FileContext cached in SecureBootConfig driver + +**/ +VOID +CloseEnrolledFile( + IN SECUREBOOT_FILE_CONTEXT *FileContext +) +{ + if (FileContext->FHandle != NULL) { + CloseFile (FileContext->FHandle); + FileContext->FHandle = NULL; + } + + if (FileContext->FileName != NULL){ + FreePool(FileContext->FileName); + FileContext->FileName = NULL; + } + FileContext->FileType = UNKNOWN_FILE_TYPE; + +} + /** This code checks if the FileSuffix is one of the possible DER-encoded certificate suffix. @@ -122,6 +144,61 @@ IsDerEncodeCertificate ( return FALSE; } +/** + This code checks if the file content complies with EFI_VARIABLE_AUTHENTICATION_2 format +The function reads file content but won't open/close given FileHandle. + + @param[in] FileHandle The FileHandle to be checked + + @retval TRUE The content is EFI_VARIABLE_AUTHENTICATION_2 format. + @retval FALSE The content is NOT a EFI_VARIABLE_AUTHENTICATION_2 format. + +**/ +BOOLEAN +IsAuthentication2Format ( + IN EFI_FILE_HANDLE FileHandle +) +{ + EFI_STATUS Status; + EFI_VARIABLE_AUTHENTICATION_2 *Auth2; + BOOLEAN IsAuth2Format; + + IsAuth2Format = FALSE; + + // + // Read the whole file content + // + Status = ReadFileContent( + FileHandle, + (VOID **) &mImageBase, + &mImageSize, + 0 + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Auth2 = (EFI_VARIABLE_AUTHENTICATION_2 *)mImageBase; + if (Auth2->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) { + goto ON_EXIT; + } + + if (CompareGuid(&gEfiCertPkcs7Guid, &Auth2->AuthInfo.CertType)) { + IsAuth2Format = TRUE; + } + +ON_EXIT: + // + // Do not close File. simply check file content + // + if (mImageBase != NULL) { + FreePool (mImageBase); + mImageBase = NULL; + } + + return IsAuth2Format; +} + /** Set Secure Boot option into variable space. @@ -477,10 +554,7 @@ ON_EXIT: FreePool(PkCert); } - if (Private->FileContext->FHandle != NULL) { - CloseFile (Private->FileContext->FHandle); - Private->FileContext->FHandle = NULL; - } + CloseEnrolledFile(Private->FileContext); return Status; } @@ -657,13 +731,7 @@ EnrollRsa2048ToKek ( ON_EXIT: - CloseFile (Private->FileContext->FHandle); - Private->FileContext->FHandle = NULL; - - if (Private->FileContext->FileName != NULL){ - FreePool(Private->FileContext->FileName); - Private->FileContext->FileName = NULL; - } + CloseEnrolledFile(Private->FileContext); if (Private->SignatureGUID != NULL) { FreePool (Private->SignatureGUID); @@ -784,13 +852,7 @@ EnrollX509ToKek ( ON_EXIT: - CloseFile (Private->FileContext->FHandle); - if (Private->FileContext->FileName != NULL){ - FreePool(Private->FileContext->FileName); - Private->FileContext->FileName = NULL; - } - - Private->FileContext->FHandle = NULL; + CloseEnrolledFile(Private->FileContext); if (Private->SignatureGUID != NULL) { FreePool (Private->SignatureGUID); @@ -824,7 +886,7 @@ EnrollKeyExchangeKey ( EFI_STATUS Status; UINTN NameLength; - if ((Private->FileContext->FileName == NULL) || (Private->SignatureGUID == NULL)) { + if ((Private->FileContext->FHandle == NULL) || (Private->FileContext->FileName == NULL) || (Private->SignatureGUID == NULL)) { return EFI_INVALID_PARAMETER; } @@ -847,6 +909,11 @@ EnrollKeyExchangeKey ( } else if (CompareMem (FilePostFix, L".pbk",4) == 0) { return EnrollRsa2048ToKek (Private); } else { + // + // File type is wrong, simply close it + // + CloseEnrolledFile(Private->FileContext); + return EFI_INVALID_PARAMETER; } } @@ -958,13 +1025,7 @@ EnrollX509toSigDB ( ON_EXIT: - CloseFile (Private->FileContext->FHandle); - if (Private->FileContext->FileName != NULL){ - FreePool(Private->FileContext->FileName); - Private->FileContext->FileName = NULL; - } - - Private->FileContext->FHandle = NULL; + CloseEnrolledFile(Private->FileContext); if (Private->SignatureGUID != NULL) { FreePool (Private->SignatureGUID); @@ -1522,13 +1583,8 @@ EnrollX509HashtoSigDB ( } ON_EXIT: - CloseFile (Private->FileContext->FHandle); - if (Private->FileContext->FileName != NULL){ - FreePool(Private->FileContext->FileName); - Private->FileContext->FileName = NULL; - } - Private->FileContext->FHandle = NULL; + CloseEnrolledFile(Private->FileContext); if (Private->SignatureGUID != NULL) { FreePool (Private->SignatureGUID); @@ -1611,6 +1667,54 @@ ON_EXIT: return IsFound; } +/** + Reads contents of a PE/COFF image in memory buffer. + + Caution: This function may receive untrusted input. + PE/COFF image is external input, so this function will make sure the PE/COFF image content + read is within the image buffer. + + @param FileHandle Pointer to the file handle to read the PE/COFF image. + @param FileOffset Offset into the PE/COFF image to begin the read operation. + @param ReadSize On input, the size in bytes of the requested read operation. + On output, the number of bytes actually read. + @param Buffer Output buffer that contains the data read from the PE/COFF image. + + @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size +**/ +EFI_STATUS +EFIAPI +SecureBootConfigImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ) +{ + UINTN EndPosition; + + if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (MAX_ADDRESS - FileOffset < *ReadSize) { + return EFI_INVALID_PARAMETER; + } + + EndPosition = FileOffset + *ReadSize; + if (EndPosition > mImageSize) { + *ReadSize = (UINT32)(mImageSize - FileOffset); + } + + if (FileOffset >= mImageSize) { + *ReadSize = 0; + } + + CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize); + + return EFI_SUCCESS; +} + /** Load PE/COFF image information into internal buffer and check its validity. @@ -1627,9 +1731,28 @@ LoadPeImage ( EFI_IMAGE_DOS_HEADER *DosHdr; EFI_IMAGE_NT_HEADERS32 *NtHeader32; EFI_IMAGE_NT_HEADERS64 *NtHeader64; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + EFI_STATUS Status; NtHeader32 = NULL; NtHeader64 = NULL; + + ZeroMem (&ImageContext, sizeof (ImageContext)); + ImageContext.Handle = (VOID *) mImageBase; + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecureBootConfigImageRead; + + // + // Get information about the image being loaded + // + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + // + // The information can't be got from the invalid PeImage + // + DEBUG ((DEBUG_INFO, "SecureBootConfigDxe: PeImage invalid. \n")); + return Status; + } + // // Read the Dos header // @@ -1691,6 +1814,9 @@ LoadPeImage ( Calculate hash of Pe/Coff image based on the authenticode image hashing in PE/COFF Specification 8.0 Appendix A + Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in + the function LoadPeImage (). + @param[in] HashAlg Hash algorithm type. @retval TRUE Successfully hash image. @@ -1718,7 +1844,7 @@ HashPeImage ( SectionHeader = NULL; Status = FALSE; - if ((HashAlg != HASHALG_SHA1) && (HashAlg != HASHALG_SHA256)) { + if (HashAlg != HASHALG_SHA256) { return FALSE; } @@ -1727,13 +1853,8 @@ HashPeImage ( // ZeroMem (mImageDigest, MAX_DIGEST_SIZE); - if (HashAlg == HASHALG_SHA1) { - mImageDigestSize = SHA1_DIGEST_SIZE; - mCertType = gEfiCertSha1Guid; - } else if (HashAlg == HASHALG_SHA256) { - mImageDigestSize = SHA256_DIGEST_SIZE; - mCertType = gEfiCertSha256Guid; - } + mImageDigestSize = SHA256_DIGEST_SIZE; + mCertType = gEfiCertSha256Guid; CtxSize = mHash[HashAlg].GetContextSize(); @@ -1775,12 +1896,12 @@ HashPeImage ( // // Use PE32 offset. // - HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - HashBase); + HashSize = (UINTN) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - (UINTN) HashBase; } else { // // Use PE32+ offset. // - HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - HashBase); + HashSize = (UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - (UINTN) HashBase; } Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize); @@ -1797,13 +1918,13 @@ HashPeImage ( // Use PE32 offset. // HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase); + HashSize = (UINTN) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase; } else { // // Use PE32+ offset. // HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase); + HashSize = (UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase; } Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize); @@ -1819,13 +1940,13 @@ HashPeImage ( // Use PE32 offset // HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase); + HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN) mImageBase); } else { // // Use PE32+ offset. // HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase); + HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN) mImageBase); } Status = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize); @@ -2004,6 +2125,107 @@ HashPeImageByType ( return EFI_SUCCESS; } +/** + Enroll a new executable's signature into Signature Database. + + @param[in] PrivateData The module's private data. + @param[in] VariableName Variable name of signature database, must be + EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1 + or EFI_IMAGE_SECURITY_DATABASE2. + + @retval EFI_SUCCESS New signature is enrolled successfully. + @retval EFI_INVALID_PARAMETER The parameter is invalid. + @retval EFI_UNSUPPORTED Unsupported command. + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. + +**/ +EFI_STATUS +EnrollAuthentication2Descriptor ( + IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private, + IN CHAR16 *VariableName + ) +{ + EFI_STATUS Status; + VOID *Data; + UINTN DataSize; + UINT32 Attr; + + Data = NULL; + + // + // DBT only support DER-X509 Cert Enrollment + // + if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0) { + return EFI_UNSUPPORTED; + } + + // + // Read the whole file content + // + Status = ReadFileContent( + Private->FileContext->FHandle, + (VOID **) &mImageBase, + &mImageSize, + 0 + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + ASSERT (mImageBase != NULL); + + Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS + | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + + // + // Check if SigDB variable has been already existed. + // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the + // new signature data to original variable + // + DataSize = 0; + Status = gRT->GetVariable( + VariableName, + &gEfiImageSecurityDatabaseGuid, + NULL, + &DataSize, + NULL + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + Attr |= EFI_VARIABLE_APPEND_WRITE; + } else if (Status != EFI_NOT_FOUND) { + goto ON_EXIT; + } + + // + // Diretly set AUTHENTICATION_2 data to SetVariable + // + Status = gRT->SetVariable( + VariableName, + &gEfiImageSecurityDatabaseGuid, + Attr, + mImageSize, + mImageBase + ); + + DEBUG((DEBUG_INFO, "Enroll AUTH_2 data to Var:%s Status: %x\n", VariableName, Status)); + +ON_EXIT: + + CloseEnrolledFile(Private->FileContext); + + if (Data != NULL) { + FreePool (Data); + } + + if (mImageBase != NULL) { + FreePool (mImageBase); + mImageBase = NULL; + } + + return Status; + +} + + /** Enroll a new executable's signature into Signature Database. @@ -2173,13 +2395,7 @@ EnrollImageSignatureToSigDB ( ON_EXIT: - CloseFile (Private->FileContext->FHandle); - Private->FileContext->FHandle = NULL; - - if (Private->FileContext->FileName != NULL){ - FreePool(Private->FileContext->FileName); - Private->FileContext->FileName = NULL; - } + CloseEnrolledFile(Private->FileContext); if (Private->SignatureGUID != NULL) { FreePool (Private->SignatureGUID); @@ -2243,9 +2459,11 @@ EnrollSignatureDatabase ( // Supports DER-encoded X509 certificate. // return EnrollX509toSigDB (Private, VariableName); + } else if (IsAuthentication2Format(Private->FileContext->FHandle)){ + return EnrollAuthentication2Descriptor(Private, VariableName); + } else { + return EnrollImageSignatureToSigDB (Private, VariableName); } - - return EnrollImageSignatureToSigDB (Private, VariableName); } /** @@ -2832,256 +3050,6 @@ ON_EXIT: ); } -/** - Perform secure boot mode transition from User Mode by setting AuditMode - or DeployedMode variable. - - @param[in] NewMode New secure boot mode. - - @retval EFI_SUCCESS Secure Boot mode transition is successful. -**/ -EFI_STATUS -TransitionFromUserMode( - IN UINT8 NewMode - ) -{ - UINT8 Data; - EFI_STATUS Status; - - if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) { - Data = 1; - Status = gRT->SetVariable( - EFI_AUDIT_MODE_NAME, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(UINT8), - &Data - ); - return Status; - } else if (NewMode == SECURE_BOOT_MODE_DEPLOYED_MODE) { - Data = 1; - Status = gRT->SetVariable( - EFI_DEPLOYED_MODE_NAME, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(UINT8), - &Data - ); - return Status; - } - - // - // Other case do nothing here. May Goto enroll PK page. - // - return EFI_SUCCESS; -} - -/** - Perform secure boot mode transition from Setup Mode by setting AuditMode - variable. - - @param[in] NewMode New secure boot mode. - - @retval EFI_SUCCESS Secure Boot mode transition is successful. -**/ -EFI_STATUS -TransitionFromSetupMode( - IN UINT8 NewMode - ) -{ - UINT8 Data; - EFI_STATUS Status; - - Status = EFI_INVALID_PARAMETER; - - if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) { - Data = 1; - Status = gRT->SetVariable( - EFI_AUDIT_MODE_NAME, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(UINT8), - &Data - ); - return Status; - } - - // - // Other case do nothing here. May Goto enroll PK page. - // - return EFI_SUCCESS; -} - -/** - Perform secure boot mode transition from Audit Mode. Nothing is done here, - should goto enroll PK page. - - @param[in] NewMode New secure boot mode. - - @retval EFI_SUCCESS Secure Boot mode transition is successful. -**/ -EFI_STATUS -TransitionFromAuditMode( - IN UINT8 NewMode - ) -{ - // - // Other case do nothing here. Should Goto enroll PK page. - // - return EFI_SUCCESS; -} - -/** - Perform secure boot mode transition from Deployed Mode by setting Deployed Mode - variable to 0. - - @param[in] NewMode New secure boot mode. - - @retval EFI_SUCCESS Secure Boot mode transition is successful. -**/ -EFI_STATUS -TransitionFromDeployedMode( - IN UINT8 NewMode - ) -{ - UINT8 Data; - EFI_STATUS Status; - - // - // Platform specific logic. when physical presence, Allow to set DeployedMode =:0 - // to switch back to UserMode - // - if (NewMode == SECURE_BOOT_MODE_USER_MODE) { - Data = 0; - Status = gRT->SetVariable( - EFI_DEPLOYED_MODE_NAME, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(UINT8), - &Data - ); - DEBUG((EFI_D_INFO, "DeployedMode Status %x\n", Status)); - return Status; - } - return EFI_SUCCESS; -} - -/** - Perform main secure boot mode transition. - - @param[in] CurMode New secure boot mode. - @param[in] NewMode New secure boot mode. - - @retval EFI_SUCCESS Secure Boot mode transition is successful. -**/ -EFI_STATUS -SecureBootModeTransition( - IN UINT8 CurMode, - IN UINT8 NewMode - ) -{ - EFI_STATUS Status; - - // - // Set platform to be customized mode to ensure platform specific mode switch sucess - // - Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // SecureBootMode transition - // - switch (CurMode) { - case SECURE_BOOT_MODE_USER_MODE: - Status = TransitionFromUserMode(NewMode); - break; - - case SECURE_BOOT_MODE_SETUP_MODE: - Status = TransitionFromSetupMode(NewMode); - break; - - case SECURE_BOOT_MODE_AUDIT_MODE: - Status = TransitionFromAuditMode(NewMode); - break; - - case SECURE_BOOT_MODE_DEPLOYED_MODE: - Status = TransitionFromDeployedMode(NewMode); - break; - - default: - Status = EFI_INVALID_PARAMETER; - ASSERT(FALSE); - } - - return Status; -} - -/** - Get current secure boot mode by retrieve data from SetupMode/AuditMode/DeployedMode. - - @param[out] SecureBootMode Current secure boot mode. - -**/ -VOID -ExtractSecureBootModeFromVariable( - OUT UINT8 *SecureBootMode - ) -{ - UINT8 *SetupMode; - UINT8 *AuditMode; - UINT8 *DeployedMode; - - SetupMode = NULL; - AuditMode = NULL; - DeployedMode = NULL; - - // - // Get AuditMode/DeployedMode from variable - // - GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL); - GetVariable2 (EFI_AUDIT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&AuditMode, NULL); - GetVariable2 (EFI_DEPLOYED_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&DeployedMode, NULL); - if (SetupMode != NULL && AuditMode != NULL && DeployedMode != NULL) { - if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 0) { - // - // User Mode - // - *SecureBootMode = SECURE_BOOT_MODE_USER_MODE; - } else if (*SetupMode == 1 && *AuditMode == 0 && *DeployedMode == 0) { - // - // Setup Mode - // - *SecureBootMode = SECURE_BOOT_MODE_SETUP_MODE; - } else if (*SetupMode == 1 && *AuditMode == 1 && *DeployedMode == 0) { - // - // Audit Mode - // - *SecureBootMode = SECURE_BOOT_MODE_AUDIT_MODE; - } else if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 1) { - // - // Deployed Mode - // - *SecureBootMode = SECURE_BOOT_MODE_DEPLOYED_MODE; - } else { - ASSERT(FALSE); - } - }else { - ASSERT(FALSE); - } - - if (SetupMode != NULL) { - FreePool (SetupMode); - } - if (DeployedMode != NULL) { - FreePool (DeployedMode); - } - if (AuditMode != NULL) { - FreePool (AuditMode); - } -} - /** Update SecureBoot strings based on new Secure Boot Mode State. String includes STR_SECURE_BOOT_STATE_CONTENT @@ -3098,7 +3066,6 @@ UpdateSecureBootString( IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private ) { - UINT8 CurSecureBootMode; UINT8 *SecureBoot; SecureBoot = NULL; @@ -3116,20 +3083,6 @@ UpdateSecureBootString( } else { HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Disabled", NULL); } - // - // Get current secure boot mode. - // - ExtractSecureBootModeFromVariable(&CurSecureBootMode); - - if (CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE) { - HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"UserMode", NULL); - } else if (CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE) { - HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"SetupMode", NULL); - } else if (CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) { - HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"AuditMode", NULL); - } else if (CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) { - HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"DeployedMode", NULL); - } FreePool(SecureBoot); @@ -3139,19 +3092,23 @@ UpdateSecureBootString( /** This function extracts configuration from variable. + @param[in] Private Point to SecureBoot configuration driver private data. @param[in, out] ConfigData Point to SecureBoot configuration private data. **/ VOID SecureBootExtractConfigFromVariable ( + IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private, IN OUT SECUREBOOT_CONFIGURATION *ConfigData ) { UINT8 *SecureBootEnable; + UINT8 *SetupMode; UINT8 *SecureBootMode; EFI_TIME CurrTime; SecureBootEnable = NULL; + SetupMode = NULL; SecureBootMode = NULL; // @@ -3166,20 +3123,10 @@ SecureBootExtractConfigFromVariable ( ConfigData->RevocationTime.Hour = CurrTime.Hour; ConfigData->RevocationTime.Minute = CurrTime.Minute; ConfigData->RevocationTime.Second = 0; - - // - // If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable - // Checkbox. - // - ConfigData->AttemptSecureBoot = FALSE; - GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL); - if (SecureBootEnable == NULL) { - ConfigData->HideSecureBoot = TRUE; + if (Private->FileContext->FHandle != NULL) { + ConfigData->FileEnrollType = Private->FileContext->FileType; } else { - ConfigData->HideSecureBoot = FALSE; - if ((*SecureBootEnable) == SECURE_BOOT_ENABLE) { - ConfigData->AttemptSecureBoot = TRUE; - } + ConfigData->FileEnrollType = UNKNOWN_FILE_TYPE; } // @@ -3192,33 +3139,51 @@ SecureBootExtractConfigFromVariable ( } // - // Get the SecureBootMode from CustomMode variable. + // If there is no PK then the Delete Pk button will be gray. // - GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID**)&SecureBootMode, NULL); - if (SecureBootMode == NULL) { - ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE; - } else { - ConfigData->SecureBootMode = *(SecureBootMode); + GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL); + if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) { + ConfigData->HasPk = FALSE; + } else { + ConfigData->HasPk = TRUE; } // - // Extact current Secure Boot Mode + // Check SecureBootEnable & Pk status, fix the inconsistence. + // If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable + // Checkbox. + // + ConfigData->AttemptSecureBoot = FALSE; + GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL); + + // + // Fix Pk, SecureBootEnable inconsistence // - ExtractSecureBootModeFromVariable(&ConfigData->CurSecureBootMode); + if ((SetupMode != NULL) && (*SetupMode) == USER_MODE) { + ConfigData->HideSecureBoot = FALSE; + if ((SecureBootEnable != NULL) && (*SecureBootEnable == SECURE_BOOT_ENABLE)) { + ConfigData->AttemptSecureBoot = TRUE; + } + } else { + ConfigData->HideSecureBoot = TRUE; + } // - // If there is no PK then the Delete Pk button will be gray. + // Get the SecureBootMode from CustomMode variable. // - if (ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE || ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) { - ConfigData->HasPk = FALSE; - } else { - ConfigData->HasPk = TRUE; + GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID**)&SecureBootMode, NULL); + if (SecureBootMode == NULL) { + ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE; + } else { + ConfigData->SecureBootMode = *(SecureBootMode); } if (SecureBootEnable != NULL) { FreePool (SecureBootEnable); } - + if (SetupMode != NULL) { + FreePool (SetupMode); + } if (SecureBootMode != NULL) { FreePool (SecureBootMode); } @@ -3285,10 +3250,12 @@ SecureBootExtractConfig ( return EFI_NOT_FOUND; } + ZeroMem(&Configuration, sizeof(SECUREBOOT_CONFIGURATION)); + // // Get Configuration from Variable. // - SecureBootExtractConfigFromVariable (&Configuration); + SecureBootExtractConfigFromVariable (PrivateData, &Configuration); BufferSize = sizeof (SECUREBOOT_CONFIGURATION); ConfigRequest = Request; @@ -3363,10 +3330,10 @@ SecureBootRouteConfig ( OUT EFI_STRING *Progress ) { - UINT8 *SecureBootEnable; - SECUREBOOT_CONFIGURATION IfrNvData; - UINTN BufferSize; - EFI_STATUS Status; + SECUREBOOT_CONFIGURATION IfrNvData; + UINTN BufferSize; + SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData; + EFI_STATUS Status; if (Configuration == NULL || Progress == NULL) { return EFI_INVALID_PARAMETER; @@ -3377,10 +3344,12 @@ SecureBootRouteConfig ( return EFI_NOT_FOUND; } + PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This); + // // Get Configuration from Variable. // - SecureBootExtractConfigFromVariable (&IfrNvData); + SecureBootExtractConfigFromVariable (PrivateData, &IfrNvData); // // Map the Configuration to the configuration block. @@ -3400,10 +3369,7 @@ SecureBootRouteConfig ( // // Store Buffer Storage back to EFI variable if needed // - SecureBootEnable = NULL; - GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL); - if (NULL != SecureBootEnable) { - FreePool (SecureBootEnable); + if (!IfrNvData.HideSecureBoot) { Status = SaveSecureBootVariable (IfrNvData.AttemptSecureBoot); if (EFI_ERROR (Status)) { return Status; @@ -3449,24 +3415,31 @@ SecureBootCallback ( { EFI_INPUT_KEY Key; EFI_STATUS Status; + RETURN_STATUS RStatus; SECUREBOOT_CONFIG_PRIVATE_DATA *Private; UINTN BufferSize; SECUREBOOT_CONFIGURATION *IfrNvData; UINT16 LabelId; UINT8 *SecureBootEnable; + UINT8 *Pk; UINT8 *SecureBootMode; + UINT8 *SetupMode; CHAR16 PromptString[100]; - UINT8 CurSecureBootMode; EFI_DEVICE_PATH_PROTOCOL *File; + UINTN NameLength; + UINT16 *FilePostFix; + SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData; Status = EFI_SUCCESS; SecureBootEnable = NULL; SecureBootMode = NULL; + SetupMode = NULL; File = NULL; if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) { return EFI_INVALID_PARAMETER; } + Private = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This); gSecureBootPrivateData = Private; @@ -3488,15 +3461,20 @@ SecureBootCallback ( // Update secure boot strings when opening this form // Status = UpdateSecureBootString(Private); - SecureBootExtractConfigFromVariable (IfrNvData); + SecureBootExtractConfigFromVariable (Private, IfrNvData); mIsEnterSecureBootForm = TRUE; - } else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE){ + } else { // - // Secure Boot Policy variable changes after transition. Re-sync CurSecureBootMode + // When entering SecureBoot OPTION Form + // always close opened file & free resource // - ExtractSecureBootModeFromVariable(&IfrNvData->CurSecureBootMode); - mIsSelectedSecureBootModeForm = TRUE; - mIsSecureBootModeChanged = FALSE; + if ((QuestionId == KEY_SECURE_BOOT_PK_OPTION) || + (QuestionId == KEY_SECURE_BOOT_KEK_OPTION) || + (QuestionId == KEY_SECURE_BOOT_DB_OPTION) || + (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) || + (QuestionId == KEY_SECURE_BOOT_DBT_OPTION)) { + CloseEnrolledFile(Private->FileContext); + } } goto EXIT; } @@ -3508,12 +3486,7 @@ SecureBootCallback ( Value->u8 = SECURE_BOOT_MODE_STANDARD; Status = EFI_SUCCESS; } - } else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE) { - if (mIsSelectedSecureBootModeForm) { - Value->u8 = IfrNvData->CurSecureBootMode; - Status = EFI_SUCCESS; - } - } + } goto EXIT; } @@ -3555,6 +3528,7 @@ SecureBootCallback ( case KEY_SECURE_BOOT_DB_OPTION: case KEY_SECURE_BOOT_DBX_OPTION: case KEY_SECURE_BOOT_DBT_OPTION: + PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This); // // Clear Signature GUID. // @@ -3566,6 +3540,11 @@ SecureBootCallback ( } } + // + // Cleanup VFRData once leaving PK/KEK/DB/DBX/DBT enroll/delete page + // + SecureBootExtractConfigFromVariable (PrivateData, IfrNvData); + if (QuestionId == KEY_SECURE_BOOT_DB_OPTION) { LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DB; } else if (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) { @@ -3590,23 +3569,55 @@ SecureBootCallback ( break; case FORMID_ENROLL_PK_FORM: - ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdatePKFromFile, &File); + ChooseFile (NULL, NULL, UpdatePKFromFile, &File); break; case FORMID_ENROLL_KEK_FORM: - ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdateKEKFromFile, &File); + ChooseFile (NULL, NULL, UpdateKEKFromFile, &File); break; case SECUREBOOT_ENROLL_SIGNATURE_TO_DB: - ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdateDBFromFile, &File); + ChooseFile (NULL, NULL, UpdateDBFromFile, &File); break; case SECUREBOOT_ENROLL_SIGNATURE_TO_DBX: - ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdateDBXFromFile, &File); + ChooseFile (NULL, NULL, UpdateDBXFromFile, &File); + + if (Private->FileContext->FHandle != NULL) { + // + // Parse the file's postfix. + // + NameLength = StrLen (Private->FileContext->FileName); + if (NameLength <= 4) { + return FALSE; + } + FilePostFix = Private->FileContext->FileName + NameLength - 4; + + if (IsDerEncodeCertificate (FilePostFix)) { + // + // Supports DER-encoded X509 certificate. + // + IfrNvData->FileEnrollType = X509_CERT_FILE_TYPE; + } else if (IsAuthentication2Format(Private->FileContext->FHandle)){ + IfrNvData->FileEnrollType = AUTHENTICATION_2_FILE_TYPE; + } else { + IfrNvData->FileEnrollType = PE_IMAGE_FILE_TYPE; + } + Private->FileContext->FileType = IfrNvData->FileEnrollType; + + // + // Clean up Certificate Format if File type is not X509 DER + // + if (IfrNvData->FileEnrollType != X509_CERT_FILE_TYPE) { + IfrNvData->CertificateFormat = HASHALG_RAW; + } + DEBUG((DEBUG_ERROR, "IfrNvData->FileEnrollType %d\n", Private->FileContext->FileType)); + } + break; case SECUREBOOT_ENROLL_SIGNATURE_TO_DBT: - ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdateDBTFromFile, &File); + ChooseFile (NULL, NULL, UpdateDBTFromFile, &File); break; case KEY_SECURE_BOOT_DELETE_PK: @@ -3712,7 +3723,12 @@ SecureBootCallback ( L"Enrollment failed! Same certificate had already been in the dbx!", NULL ); - break; + + // + // Cert already exists in DBX. Close opened file before exit. + // + CloseEnrolledFile(Private->FileContext); + break; } if ((IfrNvData != NULL) && (IfrNvData->CertificateFormat < HASHALG_MAX)) { @@ -3723,6 +3739,7 @@ SecureBootCallback ( &IfrNvData->RevocationTime, IfrNvData->AlwaysRevocation ); + IfrNvData->CertificateFormat = HASHALG_RAW; } else { Status = EnrollSignatureDatabase (Private, EFI_IMAGE_SECURITY_DATABASE1); } @@ -3731,7 +3748,7 @@ SecureBootCallback ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"ERROR: Unsupported file type!", - L"Only supports DER-encoded X509 certificate and executable EFI image", + L"Only supports DER-encoded X509 certificate, AUTH_2 format data & executable EFI image", NULL ); } @@ -3767,57 +3784,6 @@ SecureBootCallback ( ); } break; - case KEY_TRANS_SECURE_BOOT_MODE: - // - // Pop up to alert user want to change secure boot mode - // - if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && - (Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE || Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE)) - ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && - Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE) - ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && - Value->u8 == SECURE_BOOT_MODE_USER_MODE && IfrNvData->PhysicalPresent == 1)){ - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &Key, - L"Are you sure you want to switch secure boot mode?", - L"Press 'Y' to switch secure boot mode, 'N' to discard change and return", - NULL - ); - if (Key.UnicodeChar != 'y' && Key.UnicodeChar != 'Y') { - // - // If not 'Y'/''y' restore to defualt secure boot mode - // - Value->u8 = IfrNvData->CurSecureBootMode; - goto EXIT; - } - } else if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && Value->u8 == SECURE_BOOT_MODE_USER_MODE) - ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE) - ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE && Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE) - ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)) { - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &Key, - L"Secure boot mode transition requires PK change", - L"Please go to link below to update PK", - NULL - ); - } else { - Status = EFI_INVALID_PARAMETER; - goto EXIT; - } - - Status = SecureBootModeTransition(IfrNvData->CurSecureBootMode, Value->u8); - // - // Secure Boot Policy variable may change after transition. Re-sync CurSecureBootMode - // - ExtractSecureBootModeFromVariable(&CurSecureBootMode); - if (IfrNvData->CurSecureBootMode != CurSecureBootMode) { - IfrNvData->CurSecureBootMode = CurSecureBootMode; - mIsSecureBootModeChanged = TRUE; - } - break; - default: if ((QuestionId >= OPTION_DEL_KEK_QUESTION_ID) && (QuestionId < (OPTION_DEL_KEK_QUESTION_ID + OPTION_CONFIG_RANGE))) { @@ -3863,14 +3829,7 @@ SecureBootCallback ( case KEY_VALUE_NO_SAVE_AND_EXIT_DB: case KEY_VALUE_NO_SAVE_AND_EXIT_DBX: case KEY_VALUE_NO_SAVE_AND_EXIT_DBT: - if (Private->FileContext->FHandle != NULL) { - CloseFile (Private->FileContext->FHandle); - Private->FileContext->FHandle = NULL; - if (Private->FileContext->FileName!= NULL){ - FreePool(Private->FileContext->FileName); - Private->FileContext->FileName = NULL; - } - } + CloseEnrolledFile(Private->FileContext); if (Private->SignatureGUID != NULL) { FreePool (Private->SignatureGUID); @@ -3886,32 +3845,22 @@ SecureBootCallback ( case KEY_SECURE_BOOT_MODE: mIsEnterSecureBootForm = FALSE; break; - case KEY_TRANS_SECURE_BOOT_MODE: - mIsSelectedSecureBootModeForm = FALSE; - if (mIsSecureBootModeChanged) { - *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET; - } - mIsSecureBootModeChanged = FALSE; - break; case KEY_SECURE_BOOT_KEK_GUID: case KEY_SECURE_BOOT_SIGNATURE_GUID_DB: case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX: case KEY_SECURE_BOOT_SIGNATURE_GUID_DBT: ASSERT (Private->SignatureGUID != NULL); - Status = StringToGuid ( - IfrNvData->SignatureGuid, - StrLen (IfrNvData->SignatureGuid), - Private->SignatureGUID - ); - if (EFI_ERROR (Status)) { + RStatus = StrToGuid (IfrNvData->SignatureGuid, Private->SignatureGUID); + if (RETURN_ERROR (RStatus) || (IfrNvData->SignatureGuid[GUID_STRING_LENGTH] != L'\0')) { + Status = EFI_INVALID_PARAMETER; break; } *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; break; - case KEY_SECURE_BOOT_DELETE_PK: - if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE || IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) { + GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL); + if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) { IfrNvData->DeletePk = TRUE; IfrNvData->HasPk = FALSE; *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; @@ -3920,17 +3869,20 @@ SecureBootCallback ( IfrNvData->HasPk = TRUE; *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; } + if (SetupMode != NULL) { + FreePool (SetupMode); + } break; default: break; } } else if (Action == EFI_BROWSER_ACTION_DEFAULT_STANDARD) { if (QuestionId == KEY_HIDE_SECURE_BOOT) { - GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL); - if (SecureBootEnable == NULL) { + GetVariable2 (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, (VOID**)&Pk, NULL); + if (Pk == NULL) { IfrNvData->HideSecureBoot = TRUE; } else { - FreePool (SecureBootEnable); + FreePool (Pk); IfrNvData->HideSecureBoot = FALSE; } Value->b = IfrNvData->HideSecureBoot;