/** Measure CRTM version. @param[in] PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI MeasureCRTMVersion ( IN EFI_PEI_SERVICES **PeiServices ) { TCG_PCR_EVENT_HDR TcgEventHdr; // // Use FirmwareVersion string to represent CRTM version. // OEMs should get real CRTM version string and measure it. // TcgEventHdr.PCRIndex = 0; TcgEventHdr.EventType = EV_S_CRTM_VERSION; TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString)); return HashLogExtendEvent ( PeiServices, (UINT8*)PcdGetPtr (PcdFirmwareVersionString), TcgEventHdr.EventSize, &TcgEventHdr, (UINT8*)PcdGetPtr (PcdFirmwareVersionString) ); }
/** Initialize Unicode Collation support. It tries to locate Unicode Collation 2 protocol and matches it with current platform language code. If for any reason the first attempt fails, it then tries to use Unicode Collation Protocol. @param AgentHandle The handle used to open Unicode Collation (2) protocol. @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located. @retval Others The Unicode Collation (2) protocol has not been located. **/ EFI_STATUS InitializeUnicodeCollationSupport ( IN EFI_HANDLE AgentHandle ) { EFI_STATUS Status; Status = EFI_UNSUPPORTED; // // First try to use RFC 4646 Unicode Collation 2 Protocol. // Status = InitializeUnicodeCollationSupportWorker ( AgentHandle, &gEfiUnicodeCollation2ProtocolGuid, L"PlatformLang", (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang) ); // // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back // on the ISO 639-2 Unicode Collation Protocol. // if (EFI_ERROR (Status)) { Status = InitializeUnicodeCollationSupportWorker ( AgentHandle, &gEfiUnicodeCollationProtocolGuid, L"Lang", (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang) ); } return Status; }
/** This function provides early platform initialization. @param PlatformInfo Pointer to platform Info structure. **/ VOID EFIAPI EarlyPlatformInit ( VOID ) { DEBUG ((EFI_D_INFO, "EarlyBoardInit for PlatType=0x%02x\n", PcdGet16 (PcdPlatformType))); // // Check if system reset due to error condition. // if (CheckForResetDueToErrors (TRUE)) { if(FeaturePcdGet (WaitIfResetDueToError)) { DEBUG ((EFI_D_ERROR, "Press any key to continue.\n")); PlatformDebugPortGetChar8 (); } } // // Display platform info messages. // EarlyPlatformInfoMessages (); // // Early Legacy Gpio Init. // EarlyPlatformLegacyGpioInit (&mBoardLegacyGpioConfigTable); // // Early platform Legacy GPIO manipulation depending on GPIOs // setup by EarlyPlatformLegacyGpioInit. // EarlyPlatformLegacyGpioManipulation (); // // Early platform specific GPIO Controller init & manipulation. // Combined for sharing of temp. memory bar. // EarlyPlatformGpioCtrlerInit (&mBoardGpioControllerConfigTable); EarlyPlatformGpioCtrlerManipulation (); // // Early Thermal Sensor Init. // EarlyPlatformThermalSensorInit (); // // Early Lan Ethernet Mac Init. // EarlyPlatformMacInit ( PcdGetPtr (PcdIohEthernetMac0), PcdGetPtr (PcdIohEthernetMac1) ); }
/** The constructor function. @retval EFI_SUCCESS The constructor successfully . **/ EFI_STATUS EFIAPI EdkiiSystemCapsuleLibConstructor ( VOID ) { mImageFmpInfoSize = PcdGetSize(PcdEdkiiSystemFirmwareImageDescriptor); mImageFmpInfo = AllocateCopyPool (mImageFmpInfoSize, PcdGetPtr(PcdEdkiiSystemFirmwareImageDescriptor)); ASSERT(mImageFmpInfo != NULL); CopyGuid(&mEdkiiSystemFirmwareFileGuid, PcdGetPtr(PcdEdkiiSystemFirmwareFileGuid)); return EFI_SUCCESS; }
/** Determine the current language that will be used based on language related EFI Variables. @param LangCodesSettingRequired - If required to set LangCodes variable **/ VOID InitializeLanguage ( BOOLEAN LangCodesSettingRequired ) { EFI_STATUS Status; CHAR8 *LangCodes; CHAR8 *PlatformLangCodes; ExportFonts (); LangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLangCodes); PlatformLangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes); if (LangCodesSettingRequired) { if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) { // // UEFI 2.0 depricated this variable so we support turning it off // Status = gRT->SetVariable ( L"LangCodes", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, AsciiStrSize (LangCodes), LangCodes ); // // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail. // ASSERT_EFI_ERROR (Status); } Status = gRT->SetVariable ( L"PlatformLangCodes", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, AsciiStrSize (PlatformLangCodes), PlatformLangCodes ); // // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail. // ASSERT_EFI_ERROR (Status); } if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) { // // UEFI 2.0 depricated this variable so we support turning it off // InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang), TRUE); } InitializeLangVariable (L"PlatformLang", PlatformLangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang), FALSE); }
/** Main entry for this driver. @param ImageHandle Image handle this driver. @param SystemTable Pointer to SystemTable. @retval EFI_SUCESS This function always complete successfully. **/ EFI_STATUS EFIAPI PlatfomrSmbiosDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_SMBIOS_HANDLE SmbiosHandle; SMBIOS_STRUCTURE_POINTER Smbios; // Phase 0 - Patch table to make SMBIOS 2.7 structures smaller to conform // to an early version of the specification. // Phase 1 - Initialize SMBIOS tables from template Status = SmbiosLibInitializeFromTemplate (gSmbiosTemplate); ASSERT_EFI_ERROR (Status); // Phase 2 - Patch SMBIOS table entries Smbios.Hdr = SmbiosLibGetRecord (EFI_SMBIOS_TYPE_BIOS_INFORMATION, 0, &SmbiosHandle); if (Smbios.Type0 != NULL) { // 64K * (n+1) bytes Smbios.Type0->BiosSize = (UINT8)DivU64x32 (FixedPcdGet64 (PcdEmuFirmwareFdSize), 64*1024) - 1; SmbiosLibUpdateUnicodeString ( SmbiosHandle, Smbios.Type0->BiosVersion, (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString) ); SmbiosLibUpdateUnicodeString ( SmbiosHandle, Smbios.Type0->BiosReleaseDate, (CHAR16 *) PcdGetPtr (PcdFirmwareReleaseDateString) ); } // Phase 3 - Create tables from scratch // Create Type 13 record from EFI Variables // Do we need this record for EFI as the info is availible from EFI varaibles // Also language types don't always match between EFI and SMBIOS // CreateSmbiosLanguageInformation (1, gSmbiosLangToEfiLang); CreatePlatformSmbiosMemoryRecords (); return EFI_SUCCESS; }
/** This service register TPM2 device. @param Tpm2Device TPM2 device @retval EFI_SUCCESS This TPM2 device is registered successfully. @retval EFI_UNSUPPORTED System does not support register this TPM2 device. @retval EFI_ALREADY_STARTED System already register this TPM2 device. **/ EFI_STATUS EFIAPI Tpm2RegisterTpm2DeviceLib ( IN TPM2_DEVICE_INTERFACE *Tpm2Device ) { TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface; if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &Tpm2Device->ProviderGuid)){ DEBUG ((EFI_D_ERROR, "WARNING: Tpm2RegisterTpm2DeviceLib - does not support %g registration\n", &Tpm2Device->ProviderGuid)); return EFI_UNSUPPORTED; } Tpm2DeviceInterface = InternalGetTpm2DeviceInterface (); if (Tpm2DeviceInterface != NULL) { // // In PEI phase, there will be shadow driver dispatched again. // DEBUG ((EFI_D_INFO, "Tpm2RegisterTpm2DeviceLib - Override\n")); CopyMem (Tpm2DeviceInterface, Tpm2Device, sizeof(*Tpm2Device)); return EFI_SUCCESS; } else { Tpm2Device = BuildGuidDataHob (&mInternalTpm2DeviceInterfaceGuid, Tpm2Device, sizeof(*Tpm2Device)); if (Tpm2Device != NULL) { return EFI_SUCCESS; } else { return EFI_OUT_OF_RESOURCES; } } }
/** The user Entry Point for Application. The user code starts with this function as the real entry point for the application. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { UINT32 Index; Index = 0; // // Three PCD type (FeatureFlag, UINT32 and String) are used as the sample. // if (FeaturePcdGet (PcdHelloWorldPrintEnable)) { for (Index = 0; Index < PcdGet32 (PcdHelloWorldPrintTimes); Index ++) { // // Use UefiLib Print API to print string to UEFI console // Print ((CHAR16*)PcdGetPtr (PcdHelloWorldPrintString)); } } return EFI_SUCCESS; }
/** This is the standard EFI driver point that detects whether there is a MemoryConfigurationData Variable and, if so, reports memory configuration info to the DataHub. @param ImageHandle Handle for the image of this driver @param SystemTable Pointer to the EFI System Table @return EFI_SUCCESS if the data is successfully reported @return EFI_NOT_FOUND if the HOB list could not be located. **/ EFI_STATUS LogMemorySmbiosRecord ( VOID ) { EFI_STATUS Status; UINT64 TotalMemorySize; UINT8 NumSlots; SMBIOS_TABLE_TYPE19 *Type19Record; EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle; EFI_SMBIOS_PROTOCOL *Smbios; CHAR16 *MemString; Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios); ASSERT_EFI_ERROR (Status); NumSlots = 1; // // Process Memory String in form size!size ... // So 64!64 is 128 MB // MemString = (CHAR16 *)PcdGetPtr (PcdEmuMemorySize); for (TotalMemorySize = 0; *MemString != '\0';) { TotalMemorySize += StrDecimalToUint64 (MemString); while (*MemString != '\0') { if (*MemString == '!') { MemString++; break; } MemString++; } } // // Convert Total Memory Size to based on KiloByte // TotalMemorySize = LShiftU64 (TotalMemorySize, 20); // // Generate Memory Array Mapped Address info // Type19Record = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE19) + 2); Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS; Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19); Type19Record->Hdr.Handle = 0; Type19Record->StartingAddress = 0; Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1; Type19Record->MemoryArrayHandle = 0; Type19Record->PartitionWidth = (UINT8)(NumSlots); // // Generate Memory Array Mapped Address info (TYPE 19) // Status = AddSmbiosRecord (Smbios, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type19Record); FreePool(Type19Record); ASSERT_EFI_ERROR (Status); return Status; }
/** Perform the platform diagnostic, such like test memory. OEM/IBV also can customize this function to support specific platform diagnostic. @param MemoryTestLevel The memory test intensive level @param QuietBoot Indicate if need to enable the quiet boot @param BaseMemoryTest A pointer to BdsMemoryTest() **/ VOID PlatformBdsDiagnostics ( IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, IN BOOLEAN QuietBoot, IN BASEM_MEMORY_TEST BaseMemoryTest ) { EFI_STATUS Status; DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n")); // // Here we can decide if we need to show // the diagnostics screen // Notes: this quiet boot code should be remove // from the graphic lib // if (QuietBoot) { EnableQuietBoot (PcdGetPtr(PcdLogoFile)); // // Perform system diagnostic // Status = BaseMemoryTest (MemoryTestLevel); if (EFI_ERROR (Status)) { DisableQuietBoot (); } return; } // // Perform system diagnostic // Status = BaseMemoryTest (MemoryTestLevel); }
EFI_STATUS InitializeConsole ( VOID ) { EFI_STATUS Status; EFI_DEVICE_PATH* ConOutDevicePaths; EFI_DEVICE_PATH* ConInDevicePaths; EFI_DEVICE_PATH* ConErrDevicePaths; // By getting the Console Device Paths from the environment variables before initializing the console pipe, we // create the 3 environment variables (ConIn, ConOut, ConErr) that allows to initialize all the console interface // of newly installed console drivers Status = GetConsoleDevicePathFromVariable (L"ConOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConOutDevicePaths); ASSERT_EFI_ERROR (Status); Status = GetConsoleDevicePathFromVariable (L"ConIn", (CHAR16*)PcdGetPtr(PcdDefaultConInPaths), &ConInDevicePaths); ASSERT_EFI_ERROR (Status); Status = GetConsoleDevicePathFromVariable (L"ErrOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConErrDevicePaths); ASSERT_EFI_ERROR (Status); // Initialize the Consoles Status = InitializeConsolePipe (ConOutDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut); ASSERT_EFI_ERROR (Status); Status = InitializeConsolePipe (ConInDevicePaths, &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn); ASSERT_EFI_ERROR (Status); Status = InitializeConsolePipe (ConErrDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr); if (EFI_ERROR(Status)) { // In case of error, we reuse the console output for the error output gST->StandardErrorHandle = gST->ConsoleOutHandle; gST->StdErr = gST->ConOut; } // Free Memory allocated for reading the UEFI Variables if (ConOutDevicePaths) { FreePool (ConOutDevicePaths); } if (ConInDevicePaths) { FreePool (ConInDevicePaths); } if (ConErrDevicePaths) { FreePool (ConErrDevicePaths); } return EFI_SUCCESS; }
/** The driver's entry point. It install callbacks for TPM physical presence and MemoryClear, and locate SMM variable to be used in the callback function. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval Others Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI InitializeTcgSmm ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch; EFI_SMM_SW_REGISTER_CONTEXT SwContext; EFI_HANDLE SwHandle; if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid)){ DEBUG ((EFI_D_ERROR, "No TPM2 DTPM instance required!\n")); return EFI_UNSUPPORTED; } Status = PublishAcpiTable (); ASSERT_EFI_ERROR (Status); // // Get the Sw dispatch protocol and register SMI callback functions. // Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID**)&SwDispatch); ASSERT_EFI_ERROR (Status); SwContext.SwSmiInputValue = (UINTN) -1; Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue; SwContext.SwSmiInputValue = (UINTN) -1; Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue; // // Locate SmmVariableProtocol. // Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mSmmVariable); ASSERT_EFI_ERROR (Status); // // Set TPM2 ACPI table // Status = PublishTpm2 (); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** Initialize and publish TPM items in ACPI table. @retval EFI_SUCCESS The TCG ACPI table is published successfully. @retval Others The TCG ACPI table is not published. **/ EFI_STATUS PublishAcpiTable ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; EFI_ACPI_DESCRIPTION_HEADER *Table; UINTN TableSize; Status = GetSectionFromFv ( &gEfiCallerIdGuid, EFI_SECTION_RAW, 0, (VOID **) &Table, &TableSize ); ASSERT_EFI_ERROR (Status); // // Measure to PCR[0] with event EV_POST_CODE ACPI DATA // TpmMeasureAndLogData( 0, EV_POST_CODE, EV_POSTCODE_INFO_ACPI_DATA, ACPI_DATA_LEN, Table, TableSize ); ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l')); CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId) ); mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS)); ASSERT (mTcgNvs != NULL); // // Publish the TPM ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); TableKey = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
UINTN GetMaxSystemMemoryCount ( VOID ) { UINTN SystemMemoryCount; SystemMemoryCount = CountSeperatorsInString(PcdGetPtr(PcdWinNtMemorySizeForSecMain), '!') + 1; return SystemMemoryCount; }
/** Print the prompt for the EBL. **/ VOID EblPrompt ( VOID ) { EblSetTextColor (EFI_YELLOW); AsciiPrint ("%a %a",(CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt), EfiGetCwd ()); EblSetTextColor (0); AsciiPrint ("%a", ">"); }
EFI_STATUS BdsLoadOptionFileSystemCreatePcdDevicePath ( OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes ) { EFI_STATUS Status=EFI_SUCCESS; FILEPATH_DEVICE_PATH* FilePathDevicePath; CHAR16* BootFilePath; UINTN BootFilePathSize; if (*(CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath) == L'\0') { BootFilePath=(CHAR16*)PcdGetPtr(PcdDefaultBootInitrdPath); } else { BootFilePath=(CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath); } BootFilePathSize = StrSize (BootFilePath); if (BootFilePathSize == 2) { *DevicePathNodes = NULL; return EFI_NOT_FOUND; } // Create the FilePath Device Path node FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH); if (NULL == FilePathDevicePath) { Print(L"AllocatePool FilePathDevicePath fail!!!\n"); return EFI_OUT_OF_RESOURCES; } FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); //CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); memcpy_s(FilePathDevicePath->PathName, BootFilePathSize,BootFilePath, BootFilePathSize); SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize)); *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath; return Status; }
VOID PlatformBdsDiagnostics ( IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, IN BOOLEAN QuietBoot, IN BASEM_MEMORY_TEST BaseMemoryTest ) /*++ Routine Description: Perform the platform diagnostic, such like test memory. OEM/IBV also can customize this fuction to support specific platform diagnostic. Arguments: MemoryTestLevel - The memory test intensive level QuietBoot - Indicate if need to enable the quiet boot BaseMemoryTest - A pointer to BaseMemoryTest() Returns: None. --*/ { EFI_STATUS Status; DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n")); // // Here we can decide if we need to show // the diagnostics screen // Notes: this quiet boot code should be remove // from the graphic lib // if (QuietBoot) { EnableQuietBoot (PcdGetPtr(PcdLogoFile)); // // Perform system diagnostic // Status = BaseMemoryTest (MemoryTestLevel); if (EFI_ERROR (Status)) { DisableQuietBoot (); } return ; } // // Perform system diagnostic // Status = BaseMemoryTest (MemoryTestLevel); }
STATIC EFI_STATUS SupportedDevicePathsInit ( VOID ) { EFI_STATUS Status; CHAR16* DevicePathListStr; CHAR16* DevicePathStr; CHAR16* NextDevicePathStr; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; EFI_DEVICE_PATH_PROTOCOL *Instance; Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); ASSERT_EFI_ERROR (Status); // Initialize Variable DevicePathListStr = (CHAR16*)PcdGetPtr (PcdBootMonFsSupportedDevicePaths); mBootMonFsSupportedDevicePaths = NULL; // Extract the Device Path instances from the multi-device path string while ((DevicePathListStr != NULL) && (DevicePathListStr[0] != L'\0')) { NextDevicePathStr = StrStr (DevicePathListStr, L";"); if (NextDevicePathStr == NULL) { DevicePathStr = DevicePathListStr; DevicePathListStr = NULL; } else { DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DevicePathListStr + 1) * sizeof (CHAR16), DevicePathListStr); if (DevicePathStr == NULL) { return EFI_OUT_OF_RESOURCES; } *(DevicePathStr + (NextDevicePathStr - DevicePathListStr)) = L'\0'; DevicePathListStr = NextDevicePathStr; if (DevicePathListStr[0] == L';') { DevicePathListStr++; } } Instance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr); ASSERT (Instance != NULL); mBootMonFsSupportedDevicePaths = AppendDevicePathInstance (mBootMonFsSupportedDevicePaths, Instance); if (NextDevicePathStr != NULL) { FreePool (DevicePathStr); } FreePool (Instance); } if (mBootMonFsSupportedDevicePaths == NULL) { return EFI_UNSUPPORTED; } else { return EFI_SUCCESS; } }
/** This service register TPM2 device. @param Tpm2Device TPM2 device @retval EFI_SUCCESS This TPM2 device is registered successfully. @retval EFI_UNSUPPORTED System does not support register this TPM2 device. @retval EFI_ALREADY_STARTED System already register this TPM2 device. **/ EFI_STATUS EFIAPI Tpm2RegisterTpm2DeviceLib ( IN TPM2_DEVICE_INTERFACE *Tpm2Device ) { if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &Tpm2Device->ProviderGuid)){ DEBUG ((DEBUG_WARN, "WARNING: Tpm2RegisterTpm2DeviceLib - does not support %g registration\n", &Tpm2Device->ProviderGuid)); return EFI_UNSUPPORTED; } CopyMem (&mInternalTpm2DeviceInterface, Tpm2Device, sizeof(mInternalTpm2DeviceInterface)); return EFI_SUCCESS; }
/** Publish TPM2 ACPI table @retval EFI_SUCCESS The TPM2 ACPI table is published successfully. @retval Others The TPM2 ACPI table is not published. **/ EFI_STATUS PublishTpm2 ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; UINT64 OemTableId; // // Measure to PCR[0] with event EV_POST_CODE ACPI DATA // TpmMeasureAndLogData( 0, EV_POST_CODE, EV_POSTCODE_INFO_ACPI_DATA, ACPI_DATA_LEN, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate) ); CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId)); OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); mTpm2AcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTpm2AcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTpm2AcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); // // Construct ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate), &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
STATIC VOID PlatformRegisterOptionsAndKeys ( VOID ) { EFI_STATUS Status; EFI_INPUT_KEY Enter; EFI_INPUT_KEY F2; EFI_INPUT_KEY Esc; EFI_BOOT_MANAGER_LOAD_OPTION BootOption; // // Register ENTER as CONTINUE key // Enter.ScanCode = SCAN_NULL; Enter.UnicodeChar = CHAR_CARRIAGE_RETURN; Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); ASSERT_EFI_ERROR (Status); // // Map F2 and ESC to Boot Manager Menu // F2.ScanCode = SCAN_F2; F2.UnicodeChar = CHAR_NULL; Esc.ScanCode = SCAN_ESC; Esc.UnicodeChar = CHAR_NULL; Status = EfiBootManagerGetBootManagerMenu (&BootOption); ASSERT_EFI_ERROR (Status); Status = EfiBootManagerAddKeyOptionVariable ( NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL ); ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED); Status = EfiBootManagerAddKeyOptionVariable ( NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL ); ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED); // // Register UEFI Shell // PlatformRegisterFvBootOption ( PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE ); }
/** Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo. @param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR @return TRUE It is a system FMP. @return FALSE It is a device FMP. **/ BOOLEAN IsSystemFmp ( IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo ) { GUID *Guid; UINTN Count; UINTN Index; Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid); Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof(GUID); for (Index = 0; Index < Count; Index++, Guid++) { if (CompareGuid (&FmpImageInfo->ImageTypeId, Guid)) { return TRUE; } } return FALSE; }
/** Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo. @param[in] FmpImageHeader A pointer to EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER @return TRUE It is a system FMP. @return FALSE It is a device FMP. **/ BOOLEAN IsSystemFmpImage ( IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *FmpImageHeader ) { GUID *Guid; UINTN Count; UINTN Index; Guid = PcdGetPtr(PcdSystemFmpCapsuleImageTypeIdGuid); Count = PcdGetSize(PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof(GUID); for (Index = 0; Index < Count; Index++, Guid++) { if (CompareGuid(&FmpImageHeader->UpdateImageTypeId, Guid)) { return TRUE; } } return FALSE; }
/** Get the chassis type through the PlatformInfoProtocol. @retval UINT8 The chassis type. **/ UINT8 GetChassisType ( VOID ) { EFI_PLATFORM_INFO_HOB *PlatformInfoHob; PlatformInfoHob = PcdGetPtr (PcdPlatformInfo); if ( NULL != PlatformInfoHob) { if (PlatformInfoHob->PlatformFlavor == FlavorMobile) { return MiscChassisTypeLapTop; } else if (PlatformInfoHob->PlatformFlavor == FlavorDesktop) { return MiscChassisTypeDeskTop; } else if (PlatformInfoHob->PlatformFlavor == FlavorTablet) { return MiscChassisTypeHandHeld; } } return MiscChassisTypeLapTop; }
/** Do the platform specific action after the console is ready Possible things that can be done in PlatformBootManagerAfterConsole: > Console post action: > Dynamically switch output mode from 100x31 to 80x25 for certain senarino > Signal console ready platform customized event > Run diagnostics like memory testing > Connect certain devices > Dispatch aditional option roms > Special boot: e.g.: USB boot, enter UI **/ VOID EFIAPI PlatformBootManagerAfterConsole ( VOID ) { // // Show the splash screen. // BootLogoEnableLogo ( ImageFormatBmp, // ImageFormat PcdGetPtr (PcdLogoFile), // Logo EdkiiPlatformLogoDisplayAttributeCenter, // Attribute 0, // OffsetX 0 // OffsetY ); // // Connect the rest of the devices. // EfiBootManagerConnectAll (); // // Process QEMU's -kernel command line option. Note that the kernel booted // this way should receive ACPI tables, which is why we connect all devices // first (see above) -- PCI enumeration blocks ACPI table installation, if // there is a PCI host. // TryRunningQemuKernel (); // // Enumerate all possible boot options, then filter and reorder them based on // the QEMU configuration. // EfiBootManagerRefreshAllBootOption (); SetBootOrderFromQemu (); }
/** The driver's entry point. It publishes EFI TCG Protocol. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI DriverEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_EVENT Event; VOID *Registration; if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n")); return EFI_UNSUPPORTED; } if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { DEBUG ((EFI_D_ERROR, "TPM error!\n")); return EFI_DEVICE_ERROR; } Status = Tpm12RequestUseTpm (); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TPM not detected!\n")); return Status; } Status = GetTpmStatus (&mTcgDxeData.BsCap.TPMDeactivatedFlag); if (EFI_ERROR (Status)) { DEBUG (( EFI_D_ERROR, "Line %d in file " __FILE__ ":\n " "DriverEntry: TPM not working properly\n", __LINE__ )); return Status; } Status = gBS->InstallProtocolInterface ( &ImageHandle, &gEfiTcgProtocolGuid, EFI_NATIVE_INTERFACE, &mTcgDxeData.TcgProtocol ); if (!EFI_ERROR (Status) && (!mTcgDxeData.BsCap.TPMDeactivatedFlag) && mTcgDxeData.BsCap.TPMPresentFlag) { // // Setup the log area and copy event log from hob list to it // Status = SetupEventLog (); ASSERT_EFI_ERROR (Status); // // Measure handoff tables, Boot#### variables etc. // Status = EfiCreateEventReadyToBootEx ( TPL_CALLBACK, OnReadyToBoot, NULL, &Event ); Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, OnExitBootServices, NULL, &gEfiEventExitBootServicesGuid, &Event ); // // Measure Exit Boot Service failed // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, OnExitBootServicesFailed, NULL, &gEventExitBootServicesFailedGuid, &Event ); } // // Install ACPI Table // EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration); return Status; }
/** Install TCG ACPI Table when ACPI Table Protocol is available. A system's firmware uses an ACPI table to identify the system's TCG capabilities to the Post-Boot environment. The information in this ACPI table is not guaranteed to be valid until the Host Platform transitions from pre-boot state to post-boot state. @param[in] Event Event whose notification function is being invoked @param[in] Context Pointer to the notification function's context **/ VOID EFIAPI InstallAcpiTable ( IN EFI_EVENT Event, IN VOID* Context ) { UINTN TableKey; EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINT8 Checksum; UINT64 OemTableId; Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable); if (EFI_ERROR (Status)) { return; } if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) { CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId)); OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); mTcgClientAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTcgClientAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTcgClientAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); // // The ACPI table must be checksumed before calling the InstallAcpiTable() // service of the ACPI table protocol to install it. // Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate)); mTcgClientAcpiTemplate.Header.Checksum = Checksum; Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate), &TableKey ); } else { CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId)); OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); mTcgServerAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTcgServerAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTcgServerAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); // // The ACPI table must be checksumed before calling the InstallAcpiTable() // service of the ACPI table protocol to install it. // Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate)); mTcgServerAcpiTemplate.Header.Checksum = Checksum; mTcgServerAcpiTemplate.BaseAddress.Address = PcdGet64 (PcdTpmBaseAddress); Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate), &TableKey ); } if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure")); } }
/** Entry point of this module. @param[in] FileHandle Handle of the file being invoked. @param[in] PeiServices Describes the list of possible PEI Services. @return Status. **/ EFI_STATUS EFIAPI PeimEntryMA ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_STATUS Status2; EFI_BOOT_MODE BootMode; if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n")); return EFI_UNSUPPORTED; } if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { DEBUG ((EFI_D_ERROR, "TPM error!\n")); return EFI_DEVICE_ERROR; } // // Initialize TPM device // Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); // // In S3 path, skip shadow logic. no measurement is required // if (BootMode != BOOT_ON_S3_RESUME) { Status = (**PeiServices).RegisterForShadow(FileHandle); if (Status == EFI_ALREADY_STARTED) { mImageInMemory = TRUE; } else if (Status == EFI_NOT_FOUND) { ASSERT_EFI_ERROR (Status); } } if (!mImageInMemory) { Status = Tpm12RequestUseTpm (); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "TPM not detected!\n")); goto Done; } if (PcdGet8 (PcdTpmInitializationPolicy) == 1) { if (BootMode == BOOT_ON_S3_RESUME) { Status = Tpm12Startup (TPM_ST_STATE); } else { Status = Tpm12Startup (TPM_ST_CLEAR); } if (EFI_ERROR (Status) ) { goto Done; } } // // TpmSelfTest is optional on S3 path, skip it to save S3 time // if (BootMode != BOOT_ON_S3_RESUME) { Status = Tpm12ContinueSelfTest (); if (EFI_ERROR (Status)) { goto Done; } } // // Only intall TpmInitializedPpi on success // Status = PeiServicesInstallPpi (&mTpmInitializedPpiList); ASSERT_EFI_ERROR (Status); } if (mImageInMemory) { Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices); return Status; } Done: if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TPM error! Build Hob\n")); BuildGuidHob (&gTpmErrorHobGuid,0); REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) ); } // // Always intall TpmInitializationDonePpi no matter success or fail. // Other driver can know TPM initialization state by TpmInitializedPpi. // Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList); ASSERT_EFI_ERROR (Status2); return Status; }
/** Extraction handler tries to extract raw data from the input guided section. It also does authentication check for RSA 2048 SHA 256 signature in the input guided section. It first checks whether the input guid section is supported. If not, EFI_INVALID_PARAMETER will return. @param InputSection Buffer containing the input GUIDed section to be processed. @param OutputBuffer Buffer to contain the output raw data allocated by the caller. @param ScratchBuffer A pointer to a caller-allocated buffer for function internal use. @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the authentication status of the output buffer. @retval EFI_SUCCESS Section Data and Auth Status is extracted successfully. @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid. **/ EFI_STATUS EFIAPI Rsa2048Sha256GuidedSectionHandler ( IN CONST VOID *InputSection, OUT VOID **OutputBuffer, IN VOID *ScratchBuffer, OPTIONAL OUT UINT32 *AuthenticationStatus ) { EFI_STATUS Status; UINT32 OutputBufferSize; VOID *DummyInterface; EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlockRsa2048Sha256; BOOLEAN CryptoStatus; UINT8 Digest[SHA256_DIGEST_SIZE]; UINT8 *PublicKey; UINTN PublicKeyBufferSize; VOID *HashContext; VOID *Rsa; HashContext = NULL; Rsa = NULL; if (IS_SECTION2 (InputSection)) { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCertTypeRsa2048Sha256Guid, &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get the RSA 2048 SHA 256 information. // CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION2_HEADER *) InputSection)->CertBlockRsa2048Sha256; OutputBufferSize = SECTION2_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION2_HEADER); if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) { PERF_START (NULL, "RsaCopy", "DXE", 0); CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER), OutputBufferSize); PERF_END (NULL, "RsaCopy", "DXE", 0); } else { *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER); } // // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set // ASSERT ((((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } else { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCertTypeRsa2048Sha256Guid, &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get the RSA 2048 SHA 256 information. // CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION_HEADER *)InputSection)->CertBlockRsa2048Sha256; OutputBufferSize = SECTION_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION_HEADER); if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) { PERF_START (NULL, "RsaCopy", "DXE", 0); CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER), OutputBufferSize); PERF_END (NULL, "RsaCopy", "DXE", 0); } else { *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER); } // // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set // ASSERT ((((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } // // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID. // Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface); if (!EFI_ERROR (Status)) { // // If SecurityPolicy Protocol exist, AUTH platform override bit is set. // *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE; return EFI_SUCCESS; } // // All paths from here return EFI_SUCESS and result is returned in AuthenticationStatus // Status = EFI_SUCCESS; // // Fail if the HashType is not SHA 256 // if (!CompareGuid (&gEfiHashAlgorithmSha256Guid, &CertBlockRsa2048Sha256->HashType)) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: HASH type of section is not supported\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Allocate hash context buffer required for SHA 256 // HashContext = AllocatePool (Sha256GetContextSize ()); if (HashContext == NULL) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Can not allocate hash context\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Hash public key from data payload with SHA256. // ZeroMem (Digest, SHA256_DIGEST_SIZE); CryptoStatus = Sha256Init (HashContext); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = Sha256Update (HashContext, &CertBlockRsa2048Sha256->PublicKey, sizeof(CertBlockRsa2048Sha256->PublicKey)); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = Sha256Final (HashContext, Digest); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Fail if the PublicKey is not one of the public keys in PcdRsa2048Sha256PublicKeyBuffer // PublicKey = (UINT8 *)PcdGetPtr (PcdRsa2048Sha256PublicKeyBuffer); DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer = %p\n", PublicKey)); ASSERT (PublicKey != NULL); DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Token = %08x\n", PcdToken (PcdRsa2048Sha256PublicKeyBuffer))); PublicKeyBufferSize = LibPcdGetExSize (&gEfiSecurityPkgTokenSpaceGuid, PcdToken (PcdRsa2048Sha256PublicKeyBuffer)); DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Size = %08x\n", PublicKeyBufferSize)); ASSERT ((PublicKeyBufferSize % SHA256_DIGEST_SIZE) == 0); CryptoStatus = FALSE; while (PublicKeyBufferSize != 0) { if (CompareMem (Digest, PublicKey, SHA256_DIGEST_SIZE) == 0) { CryptoStatus = TRUE; break; } PublicKey = PublicKey + SHA256_DIGEST_SIZE; PublicKeyBufferSize = PublicKeyBufferSize - SHA256_DIGEST_SIZE; } if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Public key in section is not supported\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Generate & Initialize RSA Context. // Rsa = RsaNew (); if (Rsa == NULL) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaNew() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Set RSA Key Components. // NOTE: Only N and E are needed to be set as RSA public key for signature verification. // CryptoStatus = RsaSetKey (Rsa, RsaKeyN, CertBlockRsa2048Sha256->PublicKey, sizeof(CertBlockRsa2048Sha256->PublicKey)); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyN) failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE)); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyE) failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Hash data payload with SHA256. // ZeroMem (Digest, SHA256_DIGEST_SIZE); CryptoStatus = Sha256Init (HashContext); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } PERF_START (NULL, "RsaShaData", "DXE", 0); CryptoStatus = Sha256Update (HashContext, *OutputBuffer, OutputBufferSize); PERF_END (NULL, "RsaShaData", "DXE", 0); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = Sha256Final (HashContext, Digest); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Verify the RSA 2048 SHA 256 signature. // PERF_START (NULL, "RsaVerify", "DXE", 0); CryptoStatus = RsaPkcs1Verify ( Rsa, Digest, SHA256_DIGEST_SIZE, CertBlockRsa2048Sha256->Signature, sizeof (CertBlockRsa2048Sha256->Signature) ); PERF_END (NULL, "RsaVerify", "DXE", 0); if (!CryptoStatus) { // // If RSA 2048 SHA 256 signature verification fails, AUTH tested failed bit is set. // DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaPkcs1Verify() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; } Done: // // Free allocated resources used to perform RSA 2048 SHA 256 signature verification // if (Rsa != NULL) { RsaFree (Rsa); } if (HashContext != NULL) { FreePool (HashContext); } DEBUG ((DEBUG_VERBOSE, "DxeRsa2048Sha256: Status = %r AuthenticationStatus = %08x\n", Status, *AuthenticationStatus)); return Status; }
INTN EFIAPI main ( IN INTN Argc, IN CHAR8 **Argv, IN CHAR8 **Envp ) /*++ Routine Description: Main entry point to SEC for WinNt. This is a Windows program Arguments: Argc - Number of command line arguments Argv - Array of command line argument strings Envp - Array of environment variable strings Returns: 0 - Normal exit 1 - Abnormal exit --*/ { EFI_STATUS Status; HANDLE Token; TOKEN_PRIVILEGES TokenPrivileges; EFI_PHYSICAL_ADDRESS InitialStackMemory; UINT64 InitialStackMemorySize; UINTN Index; UINTN Index1; UINTN Index2; CHAR16 *FileName; CHAR16 *FileNamePtr; BOOLEAN Done; VOID *PeiCoreFile; CHAR16 *MemorySizeStr; CHAR16 *FirmwareVolumesStr; UINTN *StackPointer; UINT32 ProcessAffinityMask; UINT32 SystemAffinityMask; INT32 LowBit; // // Enable the privilege so that RTC driver can successfully run SetTime() // OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &Token); if (LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &TokenPrivileges.Privileges[0].Luid)) { TokenPrivileges.PrivilegeCount = 1; TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(Token, FALSE, &TokenPrivileges, 0, (PTOKEN_PRIVILEGES) NULL, 0); } MemorySizeStr = (CHAR16 *) PcdGetPtr (PcdWinNtMemorySizeForSecMain); FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdWinNtFirmwareVolume); SecPrint ("\nEDK II SEC Main NT Emulation Environment from www.TianoCore.org\n"); // // Determine the first thread available to this process. // if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask, &SystemAffinityMask)) { LowBit = (INT32)LowBitSet32 (ProcessAffinityMask); if (LowBit != -1) { // // Force the system to bind the process to a single thread to work // around odd semaphore type crashes. // SetProcessAffinityMask (GetCurrentProcess (), (INTN)(BIT0 << LowBit)); } } // // Make some Windows calls to Set the process to the highest priority in the // idle class. We need this to have good performance. // SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS); SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); // // Allocate space for gSystemMemory Array // gSystemMemoryCount = CountSeparatorsInString (MemorySizeStr, '!') + 1; gSystemMemory = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY)); if (gSystemMemory == NULL) { SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n", MemorySizeStr); exit (1); } // // Allocate space for gSystemMemory Array // gFdInfoCount = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1; gFdInfo = calloc (gFdInfoCount, sizeof (NT_FD_INFO)); if (gFdInfo == NULL) { SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n", FirmwareVolumesStr); exit (1); } // // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION) // SecPrint (" BootMode 0x%02x\n", PcdGet32 (PcdWinNtBootMode)); // // Allocate 128K memory to emulate temp memory for PEI. // on a real platform this would be SRAM, or using the cache as RAM. // Set InitialStackMemory to zero so WinNtOpenFile will allocate a new mapping // InitialStackMemorySize = STACK_SIZE; InitialStackMemory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (InitialStackMemorySize), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (InitialStackMemory == 0) { SecPrint ("ERROR : Can not allocate enough space for SecStack\n"); exit (1); } for (StackPointer = (UINTN*) (UINTN) InitialStackMemory; StackPointer < (UINTN*) ((UINTN)InitialStackMemory + (SIZE_T) InitialStackMemorySize); StackPointer ++) { *StackPointer = 0x5AA55AA5; } SecPrint (" SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize); // // Open All the firmware volumes and remember the info in the gFdInfo global // FileNamePtr = (CHAR16 *)malloc (StrLen ((CHAR16 *)FirmwareVolumesStr) * sizeof(CHAR16)); if (FileNamePtr == NULL) { SecPrint ("ERROR : Can not allocate memory for firmware volume string\n"); exit (1); } StrCpy (FileNamePtr, (CHAR16*)FirmwareVolumesStr); for (Done = FALSE, Index = 0, PeiCoreFile = NULL; !Done; Index++) { FileName = FileNamePtr; for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++) ; if (FileNamePtr[Index1] == 0) { Done = TRUE; } else { FileNamePtr[Index1] = '\0'; FileNamePtr = FileNamePtr + Index1 + 1; } // // Open the FD and remember where it got mapped into our processes address space // Status = WinNtOpenFile ( FileName, 0, OPEN_EXISTING, &gFdInfo[Index].Address, &gFdInfo[Index].Size ); if (EFI_ERROR (Status)) { SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X). Exiting.\n", FileName, Status); exit (1); } SecPrint (" FD loaded from"); // // printf can't print filenames directly as the \ gets interpreted as an // escape character. // for (Index2 = 0; FileName[Index2] != '\0'; Index2++) { SecPrint ("%c", FileName[Index2]); } if (PeiCoreFile == NULL) { // // Assume the beginning of the FD is an FV and look for the PEI Core. // Load the first one we find. // Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile); if (!EFI_ERROR (Status)) { SecPrint (" contains SEC Core"); } } SecPrint ("\n"); } // // Calculate memory regions and store the information in the gSystemMemory // global for later use. The autosizing code will use this data to // map this memory into the SEC process memory space. // for (Index = 0, Done = FALSE; !Done; Index++) { // // Save the size of the memory and make a Unicode filename SystemMemory00, ... // gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * 0x100000; // // Find the next region // for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++) ; if (MemorySizeStr[Index1] == 0) { Done = TRUE; } MemorySizeStr = MemorySizeStr + Index1 + 1; } SecPrint ("\n"); // // Hand off to PEI Core // SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile); // // If we get here, then the PEI Core returned. This is an error as PEI should // always hand off to DXE. // SecPrint ("ERROR : PEI Core returned\n"); exit (1); }