Skip to main content
UEFI 安全启动通过确保在启动期间仅加载经过验证和受信任的软件来增强系统的安全性和可靠性。 安全启动 和 UEFI 安全启动 是不同的安全功能,涵盖不同的镜像进行身份验证。 UEFI 安全启动可以在安全启动设备上启用,也可以出于测试目的在非安全启动设备上启用。

前提条件

主机要求

  1. 在 Linux 主机计算机上安装 OpenSSL 0.9.80 2010 年 6 月(或更高版本)。
  2. 安装以下 efitools:
    • cert-to-efi-sig-list:将 OpenSSL 证书转换为 EFI 签名列表
    • sign-efi-sig-list:签名 EFI 签名列表
    • hash-efi-sig-list:从二进制文件创建哈希签名列表条目

在设备上配置重放保护内存块

启用 UEFI 安全启动必须配置重放保护内存块 (RPMB)。有关更多信息,请参阅 RPMB。

配置 UEFI 安全启动以生成密钥和证书

您可以设置初始的 UEFI 安全启动配置,并将密钥和证书转换为 UEFI 可以理解的格式。请参阅工作流程以了解目标外准备和设备端执行。 图:UEFI 安全启动工作流程 UEFI 安全启动工作流程 注意 OpenSSL 工具包用于安全通信和加密,而 efitool 用于管理 UEFI 安全启动的密钥和签名。

生成密钥和证书

要启用 UEFI 安全启动,请生成一对用于签名和身份验证的密钥和证书。 密钥生成支持以下算法:
  • RSA 2048/4096,SHA-256/SHA384 哈希算法
  • ECDSA secp256r1/secp384r1
以下步骤以 RSA 2048 和 SHA-256 为例提供生成密钥和证书的说明。 注意
  • 在 Linux 机器上执行这些步骤时,请创建一个目录并在同一位置运行命令。
  • 对于 ECC,将 rsa:2048 替换为 ec:secp384r1 或 ec:secp256r1。对于 SHA384,在以下命令中将 -sha256 替换为 -sha384。

生成 UID

您可以生成 GUID 并创建三个新的密钥,采用 CRT/PEM 格式的自签名证书和 .key 格式的密钥: GUID 使用 uuidgen 生成签名所有者 GUID:

创建 PK 密钥

  1. 创建 PK 密钥对 (RSA-2048) 和证书:
  2. 将 .crt 文件转换为 .cer 文件:
  3. 将 .crt 文件转换为 .esl 文件:
  4. 使用 .crt、.esl 和 .key 文件签名并生成 .auth 文件:

创建 KEK 密钥

  1. 创建 KEK 密钥对 (RSA-2048) 和证书:
  2. 将 .crt 文件转换为 .cer 文件:
  3. 将 .crt 文件转换为 .esl 文件:
  4. 使用 .crt、.esl 和 .key 文件签名并生成 .auth 文件:

创建 dB 密钥

  1. 创建 dB 密钥对 (RSA-2048) 和证书:
  2. 将 .crt 文件转换为 .cer 文件:
  3. 将 .crt 文件转换为 .esl 文件:
  4. 使用 .crt、.esl 和 .key 文件签名并生成 .auth 文件:

签名镜像并将 (.auth) 密钥/已签名文件复制到 EFI 分区

EFI 系统分区包含使用 systemd-boot 时与 EFI 相关的 EFI、loader 和 ostree 信息。DTB 分区包含 dtb 目录。 EFI 系统分区包含启动系统和管理更新所必需的文件,而 DTB 分区包含硬件配置信息。本节提供以下说明:
  • 签名各种镜像。
  • 将 (.auth) 密钥和已签名的文件复制到 EFI 分区和 DTB 分区目录。
  • 已签名和可执行的镜像(如 bootaa64.efi 文件 (systemd-boot))放置在 efimountedbin/EFI/BOOT/ 目录中,linux-<target-name>.efi 文件 (Linux) 镜像放置在 efimountedbin/EFI/Linux 目录中。
systemd-boot 验证已签名的镜像并用于注册以下内容:
  • UEFI 安全启动密钥放置在 /keys 的特定目录中用于密钥注册。systemd-boot 使用这些密钥,并在 UEFI 启动时服务期间将它们存储在 RPMB 中。
  • 您可以在 systemd-boot 加载器配置中配置等待时间(以秒为单位)。在等待时间内,内核加载被延迟,允许您查看并选择 systemd-boot 菜单中可用的选项。
  • 设备树文件存储在 dtbmountedbin/dtb 目录中。这些文件在运行时由 UEFI 使用,并且设备树文件被初始化。签名时,会创建 .sig 文件并放置在同一目录中,因为这些文件是非 PE 镜像。

将已签名的镜像和密钥放置在 EFI 分区中

请按照以下步骤在 Linux 主机上将已签名的镜像和密钥放置到 EFI 分区中。
  1. 在 contents.xml 文件中定位 efi.bin 和 dtb.bin 文件路径,以从 meta 中获取 efi.bin 和 dtb.bin 文件。
  2. 将 efi.bin 文件挂载到 <workspace> 目录中,并在 <workspace> 目录中创建一个 efimountedbin 目录。
  3. 将 dtb.bin 文件挂载到 <workspace> 目录中,并在 <workspace> 目录中创建一个 dtbmountedbin 目录。
  4. 挂载 efi.bin 文件:
  5. 挂载 dtb.bin 文件:
  6. 在 <workspace>/efimountedbin/ 中创建 loader/keys/authkeys 目录链以注册密钥。
  7. 选择 .auth 文件(PK.auth、KEK.auth 和 db.auth)并将其复制到 efimountedbin 中的 authkeys 目录。
  8. 使用密钥签名 bootaa64.efi、linux-<target-name>.efi 和 qclinux_fit.img(或 combined-dtb.dtb)二进制文件,并复制到 efimountedbin 和 dtbmountedbin 目录中的相应目录。
    1. 签名 efi 镜像:
      sbsign 工具专为签名遵循 EFI 规范的 EFI 启动镜像(如 bootaa64.efi)而设计。此工具用于 UEFI 安全启动签名,可在 Linux 系统上下载和使用。需要注意的是,sbsign 只能签名扩展名为 .efi 的 PE 镜像。
      1. 将 bootaa64.efi 文件从 /efimountedbin/EFI/BOOT 目录以及 linux-<target-name>.efi 文件从 efimountedbin/Linux/ 目录复制到 Linux 机器上的 <workspace>/images 目录。
      2. 签名镜像:
    1. 签名 dtb 镜像: UEFI 安全启动认证的所有镜像都是常规 API,通常采用 PE 格式。签名头和大小附加到现有的 PE 头,签名附加在已签名文件的末尾。 但是,当非 PE 格式的镜像需要 UEFI 安全启动身份验证时,由于缺少 PE 头及其识别镜像格式的魔术数字,身份验证会失败。因此,无法使用标准工具和路径进行镜像验证。 目前,在 UEFI 安全启动验证的镜像列表中,只有 dtb 文件是非 PE 格式的镜像。作为 sbsign 工具的替代方案,您可以使用 OpenSSL cms 命令为非 PE 格式的镜像生成签名文件以进行签名。 按照以下步骤签名非 EFI 镜像:
      1. 要签名 dtb 文件和签名文件,请运行以下命令:
      1. 要签名镜像,请运行以下命令:
  9. 将已签名的 qclinux_fit.img、linux-<target-name>.efi 和 bootaa64.efi 镜像复制回它们各自的目录 (dtbmountedbin/、efimountedbin/Linux/ 和 efimountedbin/EFI/BOOT/)。
  10. 配置 systemd-boot 管理器的超时时间以显示菜单:
    1. 使用 sudo 访问权限打开并编辑 /loader/loader.conf 中的 loader.conf 文件:
    1. 添加 timeout 10 行以设置启动菜单超时并保存文件。
  11. 要卸载 EFI 二进制文件以检索最新的 efi.bin 文件,请运行命令:
  1. 要卸载 DTB 二进制文件以检索最新的 dtb.bin 文件,请运行命令:
  1. 要在目标上刷写已签名的镜像和密钥,请将设备进入 Fastboot 模式,使用以下命令刷写更新的 efi.bin 和 dtb.bin 镜像:

从 systemd-boot 菜单启用 UEFI 安全启动

确保先生成 EFI 已签名的镜像和安全启动密钥,然后将其刷写到目标设备上,以及 systemd-boot 管理器超时配置。有关更多详细信息,请参阅 签名镜像并将 (.auth) 密钥/已签名文件复制到 EFI 分区。 注意 使用 systemd-boot 管理器将密钥存储到 RPMB 的密钥注册是一次性操作。成功注册密钥后,无法重新配置和更新 UEFI 安全启动密钥。 以下步骤在设备上启用 UEFI 安全启动。
  1. 在下次启动时加载并运行 UEFI 后,systemd-boot 管理器会在串行日志上显示以下交互式菜单。
  2. 使用 vol- 键停止超时,这将显示 Enroll Secure Boot keys: authkeys。
  3. 使用 power 键开始注册。随后会出现超时,可以选择中止此注册操作,在此超时期间不要按任何键。此超时完成后,将执行密钥注册操作。以下日志显示了成功的密钥注册。
  4. 密钥成功注册后,UEFI 会自动从 SetupMode 切换到 UserMode。然后 systemd-boot 触发设备重启。
  5. 在下次设备启动时,UEFI 以 UserMode 启动并启用 UEFI 安全启动。以下串行日志显示了 UEFI 安全启动的成功启用。
  6. UEFI 安全启动成功启用后,请恢复 systemd-boot 管理器超时配置。

对未签名的镜像进行哈希处理并更新 DB 以进行镜像身份验证

UEFI 安全启动允许镜像身份验证。即使镜像未签名或镜像中的证书未出现在 dB 中,也可以通过存储在签名数据库 (dB) 中的镜像哈希实现此身份验证。 此过程保留用于无法从供应商提供的状态签名或修改的内容。如果镜像哈希在数据库拒绝 (dBX) 列表中可用,则可以在不撤销相应证书或密钥的情况下移除已签名二进制文件的信任。这在处理易受最新漏洞攻击的早期签名启动加载程序时很有用。 对同一二进制文件应用签名并创建 dB 哈希是多余的。如果镜像组成不需要任何更改,即镜像中未添加或修改新密钥和证书,并且现有镜像不需要 UEFI 安全启动身份验证,请按照以下步骤操作。 您可以计算镜像的哈希并生成允许的签名 dB 文件。

为未签名的镜像生成 db.auth 文件

  1. 生成所有要验证的镜像的哈希,并将哈希转换为 .esl 文件:
  2. 使用 dB 密钥签名 .esl 哈希文件:
  3. 将生成的 db.auth 文件复制到 EFI 二进制文件中,并将密钥配置到设备中。
例如,在 Linux 主机上:
  1. 将 efi.bin 文件挂载到 <workspace> 目录中,并在 <workspace> 目录中创建 efimountedbin 文件夹。
  2. 在 Linux 机器上的 <workspace> 目录中创建 testkeys 文件夹,并将预先存在的密钥复制到其中。
  3. 签名镜像:
  4. 将 db.auth 文件复制到 <workspace>/efimountedbin/loader/keys/qckeys 中的 qckeys 文件夹。
  5. 按照 dtb 签名步骤签名 dtb 镜像以生成新的 efi.bin 文件。有关更多信息,请参阅 签名镜像并将 (.auth) 密钥/已签名文件复制到 EFI 分区。
  6. 对于目标上的 Linux 主机:
    1. 擦除任何现有的 UEFI 安全启动密钥,并使用 fastboot 刷写 EFI 二进制文件。
    2. 使用 systemd-boot 配置密钥。有关更多信息,请参阅 从 systemd-boot 菜单启用 UEFI 安全启动。 注意 使用此方法,所有未签名的文件都会使用其他密钥签名并使用 UEFI 进行身份验证。

后续步骤