[TOC]
这一章将提供系统固件的概述。尽管系统固件的实现空间非常广泛,但我们讲论固件安全构造的相关细节。
固件VS嵌入式系统VS操作系统内核VS操作系统应用
固件是平台软件中最底层的软件。现代固件,比如基于UEFI平台初始化的固件,还有EDK II、U-Boot、coreboot、Open Power的skiboot等等主要是C语言编写并带有小部分的汇编代码。这些代码经常存储在跟平台绑定的非易失性存储容器中。固件与平台软件栈剩余部分的关系如图1-1所示。
鉴于固件是基于C代码,因此也就更容易收到攻击而影响更上层的软件。这些攻击包括内存安全问题,涉及到多种缓存区溢出,例如栈溢出,堆溢出,和整型溢出。此外,针对应用或者操作系统空间的C代码的控制流攻击能对系统固件的做出改动。除了内存问题,针对固件的攻击也可在其他方面发生,包括机密性的问题,例如偷取机密。除此之外,固件常常参与系统的信任根的流程,由于平台的任何非认证的代码流程都能拒绝平台承诺的服务(特性),因此完整性考虑至关重要。平台启动可能包括访问网络,因此网络安全的考虑也能包含在平台固件中。而且,很少有平台(如果有的话)在片上系统(SOC)中只有一个中央处理器(CPU)核心,因此固件必须支持多进程处理(MP),并抵御该应用程序中存在的各种攻击,如竞争条件。最后,平台固件还必须防御其他类型的攻击,如侧通道、混淆代理和检查时间/计时(TOC/TOU)攻击。
鉴于列出的这些弱点,固件可能具有类似的平台强化策略,有针对这些弱点的定制实现。其中包括强化策略,如堆栈cookie检查、数据执行保护(DEP)、地址空间布局随机化(ASLR)、控制流保护/完整性(CFG/CFI)、代码签名强制检查、带解释器的沙箱、访问控制(用户认证和授权)、网络安全以及适用于固件执行环境的密码学。
除了这些防御策略,固件可能有类似软件的安全验证策略,但与上层的软件组织相比有不同的实现。这些验证方法包括静态代码分析、动态代码分析(地址错误检查Address Sanitizer,ASan)、模糊化、符号执行和可能的形式验证。
尽管固件通常是用C这样的高级语言编写的,但它通常有特殊的需求。这些需求从环境开始。具体来说,固件的大小限制来源于微控制器中的较小的只读存储器(ROM)和较小的随机存取存储器(RAM),在动态随机存取存储器(DRAM)准备好之前只有静态随机存取存储器(SRAM)或高速缓存(cache)可用,管理模式(MM)的大小平衡于系统内存和有限的堆栈大小。
其他限制包括早期代码的就地执行(XIP)代码。也就是说,一些代码在只读存储器(ROM)中执行。一方面这是些只读存储器中的代码(ROM code),其中的一部分代码在数据段中没有可写的全局变量。并且对于这些早期的代码,例如UEFI平台初始化的PI阶段,Slim Boot的第一阶段,和coreboot的romstage, 尽管可以使用页表,但没有内存管理,包括虚拟内存。
除了内存管理,在早期代码流程中还有执行隔离的挑战。例如,Ring分隔(ring level in x86)可能可用也可能不可用。如此,一些固件的实现是仅仅让所有代码在特权模式下运行。尽管硬件可能包含多个CPU核心,但多进程处理(MP)可能启用,也可能不启用。事实上,主机固件的大多数实现是在单个处理器上执行服务。与多进程处理一样,其他常用的能力,如中断可能会被使能,但只能用于比那些操作系统简单得多的用途上。并且不像操作系统,固件通常与硬件直接交互。最后,固件拥有自己的执行基础, 例如内核和引导程序,与像Windows或Linux或管理程序(hypervisor)等高级操作系统(HLOSs)有所区别。
鉴于这些限制,固件可能有一类安全问题需要关注,但却不会出现在高级操作系统中。这些需要关注的安全包括来自硬件的攻击,例如寄存器、设备直接内存访问(DMAs)、缓存等。除了这些威胁,主机固件必须防范ROM【1】中永久拒绝服务(PDoS)攻击,恢复服务通常需要复杂且特殊的恢复机制。并且如果对永久拒绝服务(PDoS)攻击的关注不够,固件可能会受到ROM【1】中的永久根套件的影响,(有问题的套件)很难被病毒扫描工具发现。
固件是计算机系统安全的基础。针对系统的硬件/固件辅助的攻击越来越多。鉴于固件的领域-特定方面,可能需要特殊的强化策略。总结了三个方向,固件弹性,固件测量和证明,和安全的设备通信,见图1-2。
固件弹性包括图1-3中显示的保护、检测、恢复三个维度。平台固件需要保护自身,检测篡改,并且恢复到已知的良好状态。保护是指固件保持一种完整的状态,并且防止损坏和攻击。检测发生在系统启动阶段来确定固件是否损坏或受到攻击。如果检测到损坏或攻击,信任根固件通过鉴权机制把固件恢复到完整状态。另外,还有固件领域-特定检查,包括硬件寄存器配置检查,例如锁定位的设置,以保持平台固件的时间隔离保证。我们将在第3、4和5章中讨论细节。
在平台固件使能弹性保护自身之后,固件需要上报其身份并允许远程代理验证其完整性状态,这一过程称之为证明。当原始设备制造商(OEM)或独立 软件供应商(ISV)部署系统时,他们还发布平台属性和系统的特别的测量值。系统运行时,系统信任根创建测量日志。因此,远程验证器验证测量,并对其使用特别的测量值来验证来了解平台是否处于可信状态,见图1-4。我们将在第7章中讨论细节。
除了弹性和证明,平台固件需要拥有安全的方式与板上的其他固件或硬件组件通信。请求端对响应端认证,并且响应端可能会选择性地要求双向认证。然后,两端就创建了会话进行通信,保证数据的完整性与机密性,从而抵御硬件总线上劫持攻击,见图1-5。我们将在第8章讨论细节。
主机固件包括运行在主要的或主机的CPU上的固件,与运行在SOC上的非主机固件与运行在外设上的设备固件不同。主机固件承担平台的多项责任,包括两个主要的角色,初始化硬件和启动下一阶段的系统。前一项的任务是初始化硬件,包括跨越设置中央处理器(CPU)的状态,初始化动态随机存取存储器(DRAM),和枚举I/O总线。主机固件的后一项角色包括访问本地块存储或网络来下载操作系统。这两个阶段都存在各自的威胁模型和硬件依赖。传统的平台包括主机固件和其他设备固件以及非主机固件, 如图1-6所示。
固件的行业标准有好些个。一些标准旨在I/O设备的相互操作性,例如通用串行总线(USB)和外围组件互联(PCI)。这些允许针对硬件接口编程、具有更多一致性的系统软件与具有抽象每个接口能力的唯一设备驱动程序不同。除了这些设备到主机的硬件接口标准外,也存在主机固件与操作系统之间的标准。这些标准包括高级配置与电源接口(ACPI),ACPI详细说明了平台的不可枚举方面以及一组运行时解释表,用于在运行时配置和管理平台状态。另一个重要的标准是系统管理BIOS(SMBIOS)标准,该标准提供了详细说明平台清单的静态表。最后,为了从操作系统加载程序中抽象平台的系统方块、网络和控制台设备,出现了统一可扩展固件接口(UEFI)。 UEFI通过提供众所周知的机制来发现内容完成了类似ACPI,SMBIOS的其他标准,但UEFI更进一步。具体而言,UEFI提供了丰富的能力、接口的集合来发掘在PCI适配卡的可选只读存储器(OROMs)和存储设备上可执行的内容或“.efi”文件。这允许平台的制造商解耦,例如原始设备制造商(OEM)和操作系统供应商(OSV)。
有多种方法来重启系统。这些包括冷启动,例如S5,只重置CPU,例如热启动,内存保留重启,例如S3,或基于休眠的重启,例如ACPI S4。
通常,固件至少有三个阶段,包括提供信任根,开启SOC和系统的主要存储,初始化系统,引导操作系统。
通常有一些最小的固件要求,例如为测量、验证和更新提供一些信任根。这确保固件能在启动和使用平台制造商批准的内容更新自身时汇报固件环境状态。
通常,平台的启动被分解成三个阶段。第一个阶段包括开启芯片复合体上的基本系统,包括系统的动态随机存取存储器。这也是核心的信任根测量(CRTM)和静态更新和着手验证信任根的地方。这一早期阶段可以表现多种固件架构,例如UEFI平台初始化(PI)安全(SEC)和预先可扩展固件接口(Pre-EFI)初始化(PEI),coreboot boot block和romstage,Slime Bootloader阶段1,Open Power自启动引擎(self-boot engine, SBE)和hostboot, 和U-Boot第一阶段引导加载程序(FSBL)。理想情况下,这一阶段主要是SOC特定的代码,很少有供应商的代码。仅有SOC的供应商的一个实例是SOC的启动ROM【1】代码,混合了板级和SOC的代码的方案包括英特尔固件支持包(FSP)。
执行的下一阶段包括更丰富的软件抽象,因为固件是必然要去初始化系统存储,该存储能在平台的整个生命周期内维持其配置。例如,UEFI平台初始化(PI)驱动执行环境(DXE),U-Boot第二阶段加载程序(SPL),Open Power的skiboot,Slim Bootloader阶段2,和coreboot的RAM stage,就有更丰富的算法流程。这一阶段通常承担为PC类系统设置应用,创建ACPI和SMBIOS表和为其他板级特殊功能编程的任务。这一阶段,不像之前那个,更少的SOC代码特性,更多的系统板级和产品的特性。但这个阶段的执行必须继续信任根的测量、更新和验证,并且代码必须在平台制造商授权下提供。这一阶段通常可以提供平台的运行时阶段的最新时间点,包括但不限于为管理模式分配存储器,例如X86系统管理模式(SMM)随机存取存储器(SMRAM),用于运行时可访问的ACPI和SMBIOS表的数据空间,以及最后用于UEFI运行时服务的数据和代码空间。
在板级特定的初始化后,进入操作启动角色。这个角色包括符合UEFI的执行环境,该环境允许来自磁盘、PCI主机总线适配器和网络等第三方扩展可执行程序执行。引导设备选择(BDS)是围绕这些第三方代码开始执行策略的传统点和被称之为瞬时系统加载(TSL)执行阶段。对于coreboot和Slim Bootloader而言,这一执行阶段的特点是启动有效负载。有效负载包含UEFI风格的环境,例如EDK II DXE,或包含基于Linux的启动环境,例如LinuxBoot。除了前两个阶段,有效负载通常被当作固件可信计算基础(TCB)的一部分。
固件执行的最后阶段的主要作用是为下一个执行阶段或高级操作系统(HLOS)运行时发现和潜在地抽象服务。因此,在退出这个执行阶段时,操作系统前期阶段应该停止大部分硬件,并为高级操作系统(HLOS)接管(硬件)做准备。在UEFI系统中,瞬时系统加载(TSL)的结束是操作系统的加载程序或操作系统内核调用推出启动服务(ExitBootServices)。
一旦高级操作系统(HLOS)从有效负载或UEFI启动服务环境接管(硬件),主机固件起的作用就微乎其微。事实上,操作系统内核或管理程序有自己的驱动程序栈来管理处理器、SOC和I/O设备的状态。主机固件很大程度上是被动的接受来自操作系统的同步调用而有限地回调进入固件,例如UEFI运行时服务,通过硬件邮箱(mailbox)从可信执行环境(TEE)外的代理同步陷入到管理模式,或通过可信执行环境(TEE)特定的时钟源或其他SOC特定的硬件激活的边缘跳变异步调用进入可信执行环境(TEE)。可信执行环境的运行时完整性,例如管理模式,仍然是主机固件可信计算基础(TCB)的一部分,并且只能为制造商批准的更新提供服务。
有代表性的固件的典型启动流程如图1-7所示。
主机固件,例如EDK II或coreboot,并不是平台上的唯一固件实体。其他固件通常在平台制造商的控制下,包括服务器上的基板管理控制器(BMC)和客户端产品上的嵌入式控制器(ECs)。这些设备通常在执行的早期阶段与主机固件交互,并且可能实际上在主机固件之前运行,因为他们能为主机固件提供信任根或对平台的电源能力排序。
如果可能的话,这些非主机固件元素应该由主机固件信任根记录从而进行测量,并且这些非主机元素可以通过主机代理更新和验证信任根。在任何一种情况下,这些元素通常是平台制造商的一部分,并且不应该暴露于任意的第三方更新。
OpenBMC项目和Chrome EC是市面上可用的开源非主机平台的实例。考虑到这两者被包含在制造商的可信计算基础(TCB)中,遵循固件开发安全实践是拥有健壮产品的关键。
除了制造商的主机固件(有时称为BIOS)和非主机平台(EC、BMC等)之外,PCI卡、USB设备和系统板上的其他组件,例如复杂可编程逻辑器件(CPLD)、现场可编程门阵列(FPGA)或数字信号处理(DSP),可能有自己的固件。实际上,回顾现代客户端平台,列出了16个不同的固件元素,而服务器上的固件将是之前列出的数倍。
有一些设备固件的例子,例如可编程音频设备的Open Sound firmware,但通常设备固件对主机固件是不透明的,并且独立于主机固件。如此,存在查询这些设备的状态并将其添加到安全策略的协议,使得主机固件可以向高级操作系统(HLOS提)供平台状态的整体视图。
并且鉴于设备固件是属于平台安全范畴(姿态)内,像其他非主机固件一样,该固件的构建对于拥有健壮的平台体验是必不可少的。
这一章描述了主机固件的各个方面,包括它在平台中的作用。鉴于当代固件主要由C编写,描述了影响更高级别的应用软件的多种安全考量。在下一章中,将讨论主动固件安全开发。
书
[B-1] Jiming Sun, Vincent Zimmer, Marc Jones, Stefan Reinauer, Embedded Firmware Solutions, 2015, Apress
[B-2] Vincent Zimmer, Michael Rothman, Suresh Marisetty, Beyond BIOS: Developing with the Unified Extensible Firmware Interface, 3rd edition, 2017, DeG
[B-3] Vincent Zimmer, Michael Rothman, Robert Hale, UEFI: From Reset Vector to Operating System, in Chapter 3 of Hardware-Dependent Software, Springer, 2009
[B-4] Sunil Cheruvu, Anil Kumar, Ned Smith, David M. Wheeler, Demystifying Internet of Things Security, 2020, Apress
会议、期刊与论文
[P-1] David Weston, “Hardening With Hardware,” in BlueHat 2018 https://github.com/microsoft/MSRC-Security-Research/blob/master/presentations/2018_01_BlueHatIL/BlueHatIL18_Weston_Hardening_With_Hardware.pdf
[P-2] David Weston, “Advanced Windows Security,” in Platform Security Summit 2019, https://www.platformsecuritysummit.com/2019/speaker/weston/
[P-3] Eclypsium, “Anatomy of a Firmware Attack,” 2019, https://eclypsium.com/2019/12/20/anatomy-of-a-firmware-attack/
[P-4] Eclypsium, “FISMA compliance firmware security best practices,” 2019, https://eclypsium.com/2019/05/13/fisma-compliance-firmware-security-bestpractices/
[P-5] NIST, “Hardware-Enabled Security for Server Platforms,” in NIST whitepaper, 2020, available at https://nvlpubs.nist.gov/nistpubs/CSWP/NIST.CSWP.04282020-draft.pdf
规范和指南
[S-1] UEFI Organization, “UEFI Specification,” 2019, available at https://uefi.org/
[S-2] UEFI Organization, “UEFI Platform Initialization Specification,” 2019, available at https://uefi.org/
[S-3] UEFI Organization, “ACPI Specification,” 2019, available at https://uefi.org/
[S-4] PCI-SIG, “PCI Express Base Specification,” 2019, https://pcisig.com/
[S-5] CXL Org, “Compute Express Link Specification,” 2019, https://www.computeexpresslink.org/
网页
[W-1] EDK II, https://www.tianocore.org/
[W-2] coreboot, https://www.coreboot.org/
【1】 译者注 文中的ROM指的是ROM中的可执行代码