UEFI架构
UEFI提供系统化的标准方法,加载驱动并管理他们之间的交互。
UEFI 提供了一个标准接口,以便在硬件发生变更时固件能提供足够信息而保证操作系统不受影响。它包含有芯片组和外设芯片驱动程序,并通过系统表提供引导时服务和运行时服务。
图一中展示了依赖于UEFI所提供的服务来工作的操作系统装载器(即 EFI OS Loader) 是如何启动操作系统内核的。其他工业标准接口,如ACPI和SMBIOS等,和UEFI也是并行不悖的。
UEFI提供了一个有序的方法来加载驱动程序和处理它们之间的相互依赖性。当必要的驱动程序被加载后,引导管理器或调度器会尝试(查询)一系列预配置好的引导路径或引导设备。在进行该操作时,一个调用了UEFI引导时服务的文件会被加载和执行。这个文件的加载操作是确保安全的一个重要支撑点,如果你看过我们以前的文章,就会反应过来,它就是——安全引导(Secure Boot)。
如果引导失败,会返回到UEFI引导管理器对此进行处理。但我们,一旦引导程序试图执行退出UEFI引导时环境的OS引导加载程序,那这个退出的引导时环境不能再次进入(re-entered),如图二所示。
服务
1。引导时服务
下表显示了UEFI应用程序可用的引导时服务类别。其中最重要的是以映像处理为主的服务,因为它是加载和执行模块的必由之路。
2。运行时服务
下表展示了在UEFI环境中可用的运行时服务类别。这些调用(calls)可以修改易失性数据,非易失性数据和实时时钟设置,从而改变平台的状态。平台状态的控制则是平台安全性方面的另一个重要领域。
UEFI的早期版本(如UEFI2.0)几乎不提供安全服务。比如:不提供保存平台数据的安全方法(保证只有数据的创建者可以进行数据的修改或删除操作);没有提供基本的身份验证工具,如散列或解密功能。问题的发现为增强UEFI环境安全性指明了研究方向,一个涉及增强UEFI安全能力(安全启动),另一个涉及测量和记录平台状态(可信计算)。
基础实现
首先来看一个小问题:implement,都知道是实现的意思,那究竟什么算实现,何种程度可以称之为实现呢?我们首先来理解这个词,这样会对后面的内容有所帮助。以下内容来自维基百科:在计算机科学中,实现是作为程序,软件组件或通过计算机编程和部署的其他计算机系统的技术规范或算法的实现。 对于给定的规范或标准可能存在许多实现。 例如,web浏览器包含万维网联盟推荐的规范的实现,软件开发工具包含编程语言的实现。或许看完这段你会有所理解,简言之:实现是且仅指规范的软件实现。接下来,我们开始讲针对于UEFI规范的实现。
尽管前面我们大讲UEFI各个方面,实际上,UEFI建立在被称为平台初始化(Platform Initialization,简称PI)标准的框架之上。PI标准为前期硬件初始化提供了标准流程和架构。此处我们讨论PI安全问题中与UEFI相关的方面。
按照UEFI设计者们的想法,UEFI应当可以从系统中的任意位置发现和运行文件(这是老旧的BIOS无法做到的)。 以下是这一特性如何实现的功能概述,以及在引导过程中,文件加载背后潜藏的安全风险。
1。SEC,PEI和DXE
PI规范允许基于UEFI的系统遵循标准固件架构。 这种系统的引导过程包括一系列阶段。 每个阶段既有自己独特的安全优势,也包含着不同的风险。
PI平台启动的安全(Security,简称SEC)阶段必须处理不同类型的平台重置(Reset)事件。 SEC还是系统的信任根,它为系统上进一步启动固件提供了控制点(Control Point)。 SEC阶段的优点在于:它可以提供一个锚点,基于这个锚点来构建一个已验证的引导过程。一旦临时存储器可用,SEC必须找到引导进程的下一个阶段:EFI预初始化(Pre-EFI Initialization简称PEI)阶段,并将控制权限移交。当然,根据PEI代码的位置以及平台策略,PEI代码必须在执行之前经过认证。
PEI阶段的目标是为PEI模块的执行搭建合适的环境。 因此,在PEI阶段初期,PEI调度器就已启动。 PEI模块通常对设备和芯片组的底层平台进行初始化,例如串行端口和内存的初始化。 该阶段的的另一个职责是搜索平台信息,在切换块(hand-off blocks,简称HOB)中为此信息创建数据库,并将数据库传递给平台引导的下一阶段:DXE阶段。 和上一阶段相同的是,PEI模块也必须在运行模块之前进行验证。 一般来说,PEI模块是平台的核心固件的一部分,并且对于特定平台模型,可以认为这个模块是静态且可信的。 不过,在PI规范中没有关于PEI模块位置的要求,因此可以存在其中一些或所有PEI模块将需要被认证以维持平台完整性的平台。有些平台为了维持其完整性,会对所有的PEI模块进行验证。
当PEI阶段找到并开始执行DXE的初始化程序加载时,标志着引导程序进入了PI规范要求的最终阶段。DXE阶段通过HOB来查询平台的相关信息,并为驱动程序搭建一个更加完整的环境。 DXE调度程序负责查找和启动DXE驱动程序,这些驱动程序可能有很多来源。但PI代码和UEFI核心仅来自系统板制造商,并且不能由第三方任意扩展。平台制造商必须为符合PI规范而且采用了UEFI服务的固件负责,保障其从生产到交付后的真实性和安全性。 为了保持平台完整性,对固件的更改必须处于平台制造商的控制监督之下。在不同的平台下,这一控制的实现或许会有所不同,但不管是什么平台,都必须实现散列和加密认证等方式,否则其安全性无法得以真正保障。 在较新版本的UEFI规范(从哪一版开始?)中,都提供了一些用于固件更新的工具。 对安全引导来说,固件更新必须是受控的(如何实现这一要求在本公众号的前几期文章有讲到,看过的读者不妨回忆一下)。固件受控对于TCG测量引导(TCG Measured Boot)也同样必要。
科普几个名词,可信计算组(Trusted Computing Group,简称TCG),与其相关的标准名字很简单,就叫TCG标准,该标准中定义了这样一个名词:受信操作的核心根(Core Root of Trust for Measurement,简称CRTM)。 实现CRTM的一种方法是使用静态CRTM(Static CRTM,S-CRTM),它是位于系统附带的闪存部分中的核心平台固件。 S-CRTM负责检测在S-CRTM之后执行的任何代码。 不要认为它与安全引导的职责是相同的,测量引导仅提供所有运行过的固件模块的记录,并且不提供有关固件模块完整性的任何判断,简言之就是:只记录,不负责。
2。BDS,OS loader和RT
在DXE结束后,BDS得以运行。BDS(Boot Device Select),顾名思义,就是发现引导设备(全部或者部分),并作出选择(用户选择或者根据设定)。它负责初始化所有启动OS所需的设备(输入、输出和存储)。在更高层面上讲,它负责执行所有符合UEFI驱动模型(UEFI driver model)的驱动。这是一个发现并一个个连接的过程。譬如,首先发现PCI root,接着发现PCI bus,在PCI bus下发现SATA controller和USB controller。。。一个个启动设备被发现,其设备路径(device path)也被连接起来。在万事俱备后,一个界面被显示出来(嵌入式系统上可以没有),供用户进行设置和选择启动设备,这就是大家熟悉的BIOS界面。
在用户选择或者用预设的设备被挑出来后,BDS加载OS loader,而OS loader负责找到并运行OS。在OS启动后,所有的启动时服务都不可用了,只有运行时服务得以留存。