#file-format #enclave #nitro #aws #build-environment

aws-nitro-enclaves-image-format

本库提供了 AWS Nitro Enclaves 中使用的 enclave 图像格式 (EIF) 文件的定义。

3 个版本 (破坏性更新)

0.3.0 2024年8月2日
0.2.0 2022年9月26日
0.1.0 2022年5月29日

#79 in 硬件支持

Download history 315/week @ 2024-05-01 386/week @ 2024-05-08 295/week @ 2024-05-15 570/week @ 2024-05-22 460/week @ 2024-05-29 580/week @ 2024-06-05 656/week @ 2024-06-12 623/week @ 2024-06-19 465/week @ 2024-06-26 437/week @ 2024-07-03 546/week @ 2024-07-10 453/week @ 2024-07-17 409/week @ 2024-07-24 831/week @ 2024-07-31 496/week @ 2024-08-07 389/week @ 2024-08-14

2,184 每月下载量

Apache-2.0

105KB
1.5K SLoC

aws-nitro-enclaves-image-format

status version docs msrv

本库提供了 enclave 图像格式 (EIF) 文件的定义。

安全性

有关更多信息,请参阅 CONTRIBUTING

许可

本项目采用 Apache-2.0 许可。

构建

要编译 eif_build 工具,运行

$ cargo build --all --release

生成的二进制文件将在 ./target/release/eif_build 下。

用法

此包主要用作库。然而,它还包含 eif_build 工具,您可以使用该工具创建 AWS Nitro Enclave 图像文件。

Enclave image format builder
Builds an eif file

USAGE:
    eif_build [OPTIONS] --kernel <FILE> --cmdline <String> --output <FILE> --ramdisk <FILE>

OPTIONS:
        --arch <(x86_64|aarch64)>
            Sets image architecture [default: x86_64]

        --build-time <build_time>
            Overrides image build time. [default: 2024-07-09T17:16:38.424202433+00:00]

        --build-tool <build_tool>
            Image build tool name. [default: eif_build]

        --build-tool-version <build_tool_version>
            Overrides image build tool version. [default: 0.2.0]

        --cmdline <String>
            Sets the cmdline

    -h, --help
            Print help information

        --img-kernel <img_kernel>
            Overrides image Operating System kernel version. [default: "Unknown version"]

        --img-os <img_os>
            Overrides image Operating System name. [default: "Generic Linux"]

        --kernel <FILE>
            Sets path to a bzImage/Image file for x86_64/aarch64 architecture

        --kernel_config <FILE>
            Sets path to a bzImage.config/Image.config file for x86_64/aarch64 architecture

        --metadata <metadata>
            Path to JSON containing the custom metadata provided by the user.

        --name <image_name>
            Name for enclave image

        --output <FILE>
            Specify output file path

        --private-key <private-key>
            Specify the path to the private-key

        --ramdisk <FILE>
            Sets path to a ramdisk file representing a cpio.gz archive

        --signing-certificate <signing-certificate>
            Specify the path to the signing certificate

        --version <image_version>
            Version of the enclave image

Enclave 图像文件 (EIF) 规范

日期:2024-06-21

背景

AWS Nitro Enclaves (官方文档) 是一种 Amazon EC2 功能,允许您从 Amazon EC2 实例创建隔离的计算环境,称为 enclaves。Enclaves 是独立的、加固的和高度受限的虚拟机。它们仅与其父实例提供安全的本地套接字连接。它们没有持久存储、交互式访问或外部网络。

要在 enclave 中运行您的应用程序,您的应用程序需要打包到 Enclave 图像文件 (EIF) 中。EIF 是自包含的 - 您的应用程序在 enclave 中运行所需的所有内容都包含在文件中(例如,操作系统、您的应用程序、根文件系统)。

文件格式

高级结构

在高级上,Enclave 图像文件由一个通用头部和多个数据部分组成,每个部分都有一个局部头部。

+-------------------------+
|        EifHeader        |
+-------------------------+
|   EifSectionHeader 0    |
+-------------------------+
|      Data Section 0     |
+-------------------------+
|   EifSectionHeader 1    |
+-------------------------+
|      Data Section 1     |
+-------------------------+
>          ...            <
+-------------------------+
|   EifSectionHeader n    |
+-------------------------+
|      Data Section n     |
+-------------------------+

Enclave Image 文件格式支持多种数据段类型。数据段类型可以是必需的或可选的。每个段包含运行您在 Nitro Enclave 中的应用程序所需的具体类型数据,具体内容如下在数据段中指定。

EifHeader

EifHeader 是对 enclave 图像文件的一般描述,并提供整个文件的元数据。它具有固定的 548 字节大小,所有多字节字段的字节顺序均为大端。EifHeader 的结构如下

0x0000  +--------+--------+--------+--------+
        |               magic               |
0x0004  +--------+--------+--------+--------+
        |     version     |      flags      |
0x0008  +--------+--------+--------+--------+
        |                                   |
        +            default_mem            +
        |                                   |
0x0010  +--------+--------+--------+--------+
        |                                   |
        +            default_cpus           +
        |                                   |
0x0018  +--------+--------+--------+--------+
        |    reserved     |   num_sections  |
0x001c  +--------+--------+--------+--------+
        |                                   |
        +          section_offset 0         +
        |                                   |
        +--------+--------+--------+--------+
        >                ...                <
        +--------+--------+--------+--------+
        |                                   |
        +          section_offset 31        +
        |                                   |
0x011c  +--------+--------+--------+--------+
        |                                   |
        +           section_size 0          +
        |                                   |
        +--------+--------+--------+--------+
        >                ...                <
        +--------+--------+--------+--------+
        |                                   |
        +           section_size 31         +
        |                                   |
0x021c  +--------+--------+--------+--------+
        +             reserved              |
0x0220  +--------+--------+--------+--------+
        |              crc_32               |
0x0224  +--------+--------+--------+--------+

虚拟化堆栈忽略所有保留字段。

magic

magic 字段是一个常量值,用于轻松识别 enclave 图像文件。该值等同于 ASCII 字符串 .eif 或字节序列 [0x2e, 0x65, 0x69, 0x66]

version

version 字段编码了 enclave 图像文件的规范版本。这是确定文件格式版本并根据它选择正确处理所必需的。

EIF 格式的最新版本是 4。每当引入与文件格式不兼容的更改或添加时,版本都会增加。

EIF 格式版本历史
  • 版本 0
  • 版本 1
  • 版本 2:作为于 2020-08-13 发布在 aws-nitro-enclaves-cli v0.1.0(初步公开预发布)中的初始公开版本发布。这个初始版本设置了基本的文件格式结构,并支持基本的段类型 EifSectionKernelEifSectionCmdlineEifSectionRamdisk
  • 版本 3:作为于 2021-04-29 发布在 aws-nitro-enclaves-cli v1.0.10(初步公开生产发布)中的版本发布。这个版本增加了对通过段类型 EifSectionSignature 进行图像签名的可选支持。
  • 版本 4:作为于 2022-03-08 发布在 aws-nitro-enclaves-cli v1.2.0 中的版本发布。这个版本增加了一个新的必需段类型 EifSectionMetadata,它包含有关 EIF 构建环境的元数据。

版本 01 没有作为任何工具包发布的一部分发布。它们不再受支持,并在加载 enclave 图像文件的 crc 检查阶段失败。

版本 23 的行为相同。由于在版本 2 中没有定义 EifSectionSignature 段类型,并且在版本 3 中它是可选的,因此它们被有效处理为相同。

版本 4 引入了 EifSectionMetadata 作为必需段,并检查它是否是 enclave 图像文件的一部分。除此之外,它被处理得与版本 3 相同。

版本 >4 保留供将来使用,并产生未定义的行为。

flags

flags》位域编码了文件及其目标环境的属性。标志字段的结构如下

 f e d c b a 9 8 7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             |a|
|                             |r|
|          reserved           |c|
|                             |h|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • arch:确定此映像文件针对的隐私区CPU架构:0表示x86_641表示aarch64。此标志是必需的,并且具有与隐私区架构不同的架构的EIF将被拒绝。
default_mem

default_mem字段描述了此映像将运行的隐私区的主内存默认字节数。目前,虚拟化堆栈和aws-nitro-enclaves-cli未使用此字段。

default_cpus

default_cpus字段描述了此映像将运行的隐私区的默认vCPU数量。目前,虚拟化堆栈和aws-nitro-enclaves-cli未使用此字段。

num_sections

num_sections字段描述了隐私区映像文件包含的数据段数量。此字段的值范围为2到32(《MAX_NUM_SECTIONS》)。

section_offsets

section_offsets字段是一个包含32(《MAX_NUM_SECTIONS》)个8字节值的数组。此数组中的前num_secions个条目分别描述了文件中每个数据段的起始位置(以字节为单位)。所有使用条目都必须按照与文件中对应数据段相同的顺序排列,即section_offsets[0]描述了文件中第一个数据段的文件偏移量,section_offset[1]描述了文件中第二个数据段的文件偏移量,依此类推。

section_sizes

section_sizes字段是一个包含32(《MAX_NUM_SECTIONS》)个8字节值的数组。此数组中的前num_sections个条目分别描述了文件中每个数据段的大小(以字节为单位)。所有使用条目都必须按照与文件中对应数据段相同的顺序排列,即section_sizes[0]描述了文件中第一个数据段的大小,section_sizes[1]描述了文件中第二个数据段的大小,依此类推。此数组中设置的《section sizes仅覆盖数据部分的大小,不包括段头的大小。

eif_crc32

eif_crc32字段包含整个文件的crc32校验和,但不包括此《eif_crc32字段本身;此校验和包括《EifHeader》和所有段,包括它们的各自段头,并按其在文件中出现的顺序排列。

数据段

隐私区映像文件包含多种类型的数据段,每个数据段都有其独特的目的。所有段类型之间的高层格式是通用的,由一个《EifSectionHeader》和二进制数据组成。段不能相互重叠,并且不得超出64位地址空间。

一个隐私区映像文件中不同类型段之间的顺序通常不受限制。对段顺序的唯一限制是,所有《EifSectionRamdisk》段都必须位于《EifSectionKernel》段之后。

EifSectionHeader

节标题是该节的基本描述

0x0000  +--------+--------+--------+--------+
        |  section_type   |      flags      |
0x0004  +--------+--------+--------+--------+
        |                                   |
        +           section_size            +
        |                                   |
0x000c  +--------+--------+--------+--------+
section_type

section_type字段描述了节的类型。以下是一个有效节类型及其数值列表。以下是对每个节类型的详细描述。

  • EifSectionInvalid(0x00)
  • EifSectionKernel(0x01)
  • EifSectionCmdline(0x02)
  • EifSectionRamdisk(0x03)
  • EifSectionSignature (0x04)(自 EIF 格式第 3 版引入)
  • EifSectionMetadata (0x05)(自 EIF 格式第 4 版引入)

包含 EifSectionInvalid 节或类型超出上述范围(>= 6)的节,虚拟化堆栈将拒绝。

flags

flags位字段可用于对节中二进制数据的属性进行编码。目前没有任何节类型使用它,且预留供将来使用。

section_size

section_size字段描述了节数据的字节数。它必须与全局 EifHeader 结构中对应的 section_sizes 条目匹配。

EifSectionKernel

EifSectionKernel节数据包含要在 enclave 中运行的 Linux 内核映像。该文件格式取决于实例和 enclave 的 CPU 架构。对于 x86_64实例,内核节数据必须是 bzImage(有关详细信息,请参阅x86_64引导协议)。对于 aarch64实例,内核节数据必须是未压缩的内核 Image 文件(有关详细信息,请参阅arm64引导协议)。

aws-nitro-enclaves-cli为这两种架构提供预构建的内核映像

EifSectionKernel节是必选节,每个 enclave 映像文件必须恰好包含一个 EifSectionKernel节。

EifSectionCmdline

EifSectionCmdline节数据包含用于 enclave 内核的 Linux 内核命令行参数的字符串。内核命令行可用于在引导时配置内核的某些方面(内核参数文档)。

aws-nitro-enclaves-cli为这两种架构提供内核命令行(与同一位置的预构建内核映像兼容)

EifSectionCmdline节是必选节,每个 enclave 映像文件必须恰好包含一个 EifSectionCmdline节。

EifSectionRamdisk

EifSectionRamdisk部分包含将要成为enclave根文件系统的数据,这些数据以cpio或压缩格式cpio.gz(压缩)存储。所有EifSectionRamdisk部分的数据被连接在一起,共同作为单个initramfs(见下文关于ramdisk组成和加载的背景)。

所有EifSectionRamdisk部分必须位于enclave镜像文件中的EifSectionKernel部分之后。

示例:使用aws-nitro-enclaves-cli创建的ramdisk

通过aws-nitro-enclaves-cli创建enclave镜像文件时,会创建两个EifSectionRamdisk部分。第一个ramdisk对所有应用程序都相同,包含两个主要部分

  • init可执行文件:init进程是内核启动的第一个用户空间进程。init进程的任务是启动系统的用户空间并启动相关服务。对于Nitro Enclaves,init进程的任务简化为挂载特殊文件系统(即procfs、sysfs、/dev)、初始化控制台设备、加载与Nitro安全模块交互的驱动程序,并启动用户应用程序。最小化init进程的代码可以在aws-nitro-enclaves-sdk-bootstrap中找到,而aws-nitro-enclaves-cli为两种架构提供了预编译的执行文件
  • nsm.ko驱动程序:这是一个Linux内核的可加载驱动模块,它便于访问Nitro安全模块(NSM)。该驱动程序在enclave中暴露一个特殊设备,以便与虚拟机管理程序通信,获取证明enclave身份的证明文件。NSM驱动程序的源代码可以在aws-nitro-enclaves-sdk-bootstrap中找到,从Linux内核系列v6.8开始,该驱动程序是上游Linux内核的一部分。《aws-nitro-enclaves-cli》为两种架构提供了预编译的此驱动程序版本(与同一位置的预构建内核映像兼容)

第二个ramdisk包含特定于应用程序的数据,有三个主要部分

  • 根文件系统:这是一个文件系统,提供应用程序Docker镜像中所需的所有软件和运行时环境。
  • cmd文件:cmd文件包含应用程序的默认入口点,该入口点通过Dockerfile中的CMD指定(如果没有指定CMD,则为ENTRYPOINT)。
  • env文件:env文件包含应用程序的环境变量,这些变量通过Dockerfile中的ENV指定。
关于ramdisk组成和加载的背景

Linux内核支持各种系统引导和用户空间启动的模式。其中一种机制是通过Linux内核的initramfs格式(参见Linux内核文档driver-api/early-userspace/buffer-format.rst)。一个initramfs由一组cpio文件组成,可以是未压缩的(.cpio)或压缩的(.cpio.gz)。Linux内核包含一个最小的解释器来加载initramfs并从这些文件中构建根文件系统。通常,initramfs包含一个基本的用户空间,用于引导系统并将额外的设备(如硬盘)启动,以便从磁盘切换到最终的文件系统。在Nitro Enclaves的情况下,没有对持久存储(如硬盘)的支持,因此整个系统都是从initramfs引导和包含的。

对于Nitro Enclaves,没有使用引导加载程序来将内核和ramdisk加载到内存中。这部分由虚拟机管理程序执行,它在启动enclaves之前将内核和ramdisk数据加载到enclaves内存中。启动时创建的enclaves内存如下所示(以下是一个包含三个ramdisk段的示例EIF)

                                                        Enclave Memory Layout
+-------------------------+                             +--------------------+
|        EifHeader        |                             |       zeroes       | 0x0
+-------------------------+                             >         ...        <
|   EifSectionHeader 0    |                             |                    |
+-------------------------+>--------------------------->+--------------------+
|      Kernel Image       |                             |    Kernel Image    |
+-------------------------+   +------------------------>+--------------------+ --+
|   EifSectionHeader 1    |   |                         |   Ramdisk (init)   |   |
+-------------------------+   |   +-------------------->+--------------------+   |
|      Kernel Cmdline     |   |   |                     |   Ramdisk (user0)  |    > initramfs
+-------------------------+   |   |   +---------------->+--------------------+   |
|   EifSectionHeader 2    |   |   |   |                 |   Ramdisk (user1)  |   |
+-------------------------+>--+   |   |                 +--------------------+ --
|      Ramdisk (init)     |       |   |                 |                    |
+-------------------------+       |   |                 |       zeroes       |
|   EifSectionHeader 3    |       |   |                 >        ...         <
+-------------------------+>------+   |                 |                    | 0xffffffffffffffff
|      Ramdisk (user0)    |           |                 +--------------------+
+-------------------------+           |
|   EifSectionHeader 4    |           |
+-------------------------+>----------+
|      Ramdisk (user1)    |
+-------------------------+
|   EifSectionHeader 5    |
+-------------------------+
|      Signature Data     |
+-------------------------+
|   EifSectionHeader 6    |
+-------------------------+
|         Metadata        |
+-------------------------+
EifSectionSignature

EifSectionSignature部分作为可选部分在文件格式版本3中被引入。该部分数据最大大小为32768字节(SIGNATURE_MAX_SIZE)。

EifSectionSignature部分的格式数据是简洁二进制对象表示(CBOR),如RFC8949中所述。CBOR数据包含一个包含两个元组的数组,每个元组包含一个序列化的签名证书和一个序列化的CBOR对象签名加密(COSE)Sign1对象,如RFC8152中所述。虽然EifSectionSignature部分允许有多个此类元组,但目前只有这些对象中的第一个被用于验证PCR0。这意味着要签名并添加到EifSectionSignature部分的相关数据只有元组(0, PCR0)

EifSectionSignature中的CBOR数据的总体结构可以描述如下,其中>>>><<<<描述嵌套序列化CBOR数据的入口和出口边界

Array(1) {
    Map(2) {
        [0] {
            Text(19)                                                 // key = "signing_certificate"
            Array<Uint8>(len(cbor_serialize(cert)))                  // value = CBOR serialized certificate
        },
        [1] {
            Text(9)                                                  // key = "signature"
            Array<Uint8>(len(cbor_serialize(cose_sign1))             // value = CBOR serialized COSE_Sign1 object
            >>>>
                Array(4) {
                    [0] ByteString(len(cbor_serialize(protected))),  // CBOR serialized COSE protected header
                    >>>>
                        Map(1) {
                            unsigned(1)                              // key = 1 (alg)
                            negative(<val>)                          // value = Signing Algorithm (-7 for ES256, -35 for ES384, -36 for ES512)
                        }
                    <<<<
                    [1] Map(0),                                      // CBOR serialized COSE unprotected header (empty)
                    [2] BytesString(len(cbor_serialize(payload))),   // CBOR serialized COSE_Sign1 payload
                    >>>>
                        Map(2) {
                            [0] {
                                Text(14)                             // key = "register_index"
                                Unsigned(<idx>)                      // value = <idx> (Index of which PCR got signed)
                            },
                            [1] {
                                Text(14)                             // key = "register_value"
                                Array<Uint8>(48)                     // value = PCR<idx> value bytes
                            },
                        }
                    <<<<
                    [3] BytesString(len(<signature>))                // Signature bytes
                }
            <<<<
        }
    }
}
关于COSE Sign1的背景及其在EIF中的使用

COSE Sign1提供了一个签名结构,以便由单个签名者对消息进行签名

+-------------------------+-----------------+-------------------+
|      COSE Headers       |     Payload     |     Signature     |
+- - - - - - - - - - - - -+- - - - - - - - -+- - - - - - - - - -+
| protected | unprotected |    plaintext    |  signature bytes  |
+-------------------------+-----------------+-------------------+

COSE头部分为两个桶,受保护的桶包含签名层的元数据,该层是待签名数据的一部分(被签名所覆盖/保护),而未受保护的桶包含不参与签名的元数据。每个桶都是键值对的映射。有效载荷是待签名的明文数据。签名包含签名字节。

对于在EIF中的使用,COSE Sign1对象不同部分包含的数据如下

  • COSE头部的受保护桶只包含一个键值对,用于标识所使用的签名算法。
  • COSE头部的未受保护桶为空。
  • 有效负载包含一个元组,描述了一个用于 EIF 文件的平台配置寄存器(PCR),具体来说是一个包含 PCR 索引及其值的二元组。(关于 PCR 的更多详细信息,请参见下文“EIF 测量”部分EIF 测量)。
  • 签名包含使用以下 ECDSA 变体之一(ES256、ES384 和 ES512)对受保护的头和有效负载进行椭圆曲线数字签名算法(ECDSA)签名的签名。
EifSectionMetadata

在文件格式版本 4 中,将 EifSectionMetadata 部分引入为必选部分。该部分数据包含 JSON,描述了根据以下 JSON 模式生成 enclave 图像文件的构建环境。

{
    "$schema": "https://json-schema.fullstack.org.cn/draft/2020-12/schema",
    "$id": "https://github.com/aws/aws-nitro-enclaves-image-format",
    "title": "EIF Metadata Content",
    "description": "Format Content of EIFSection of type EifSectionMetadata",
    "type": "object",
    "properties": {
        "ImageName": {
            "type": "string",
            "description": "Name of the EIF image"
        },
        "ImageVersion": {
            "type": "string",
            "description": "EIF version for this image file"
        },
        "BuildMetadata": {
            "type": "object",
            "description": "Metadata on the build environment",
            "properties": {
                "BuildTime": {
                    "type": "string",
                    "description": "Time the image was build at"
                },
                "BuildTool": {
                    "type": "string",
                    "description": "Name of the tool that produced the image"
                },
                "BuildToolVersion": {
                    "type": "string",
                    "description": "Version of the tool that produced the image"
                },
                "OperatingSystem": {
                    "type": "string",
                    "description": "Name of the OS the image was build on"
                },
                "KernelVersion": {
                    "type": "string",
                    "description": "Kernel version of the build host"
                }
            },
            "required": [ "BuildTime", "BuildTool", "BuildToolVersion", "OperatingSystem", "KernelVersion" ]
        },
        "DockerInfo": {
            "type": "object",
            "description": "Metadata on the docker image this EIF was based on, as produced by `docker image inspect`"
        },
        "CustomMetadata": {
            "type": "object",
            "description": "Optional custom metadata to annotate the EIF with"
        }
    },
    "required": [ "ImageName", "ImageVersion", "BuildMetadata", "DockerInfo" ]
}

EifSectionMetadata 部分不是任何 enclave 测量的组成部分,并且 hypervisor 不会对其进行验证,仅检查其存在性,条件是文件格式版本为 4 或更高。

EIF 测量

Nitro Enclaves 包含证明其身份并与其他服务建立信任的认证机制。作为这些测量的组成部分,enclave 公开了一组平台配置寄存器(PCRs),每个 PCR 提供了有关 enclave 配置和代码的识别数据的哈希集合。对于 EIF 文件,有四个 PCR 描述了它。它们是 PCR0PCR1PCR2PCR8

PCR0                                  PCR1  PCR2  PCR8*
  |     +-------------------------+     |     |     |
  |     |        EifHeader        |     |     |     |
  |     +-------------------------+     |     |     |
  |     |   EifSectionHeader 0    |     |     |     |
  |     +-------------------------+     |     |     |
  +----<|      Kernel Image       |>----+     |     |
  |     +-------------------------+     |     |     |
  |     |   EifSectionHeader 1    |     |     |     |
  |     +-------------------------+     |     |     |
  +----<|      Kernel Cmdline     |>----+     |     |
  |     +-------------------------+     |     |     |
  |     |   EifSectionHeader 2    |     |     |     |
  |     +-------------------------+     |     |     |
  +----<|      Ramdisk (init)     |>----+     |     |
  |     +-------------------------+           |     |
  |     |   EifSectionHeader 3    |           |     |
  |     +-------------------------+           |     |
  +----<|     Ramdisk (user0)     |>----------+     |
  |     +-------------------------+           |     |
  |     |   EifSectionHeader 4    |           |     |
  |     +-------------------------+           |     |
  +----<|     Ramdisk (user1)     |>----------+     |
        +-------------------------+                 |
        |   EifSectionHeader 5    |                 |
        +-------------------------+                 |
        |      Signature Data     |>----------------+
        +-------------------------+
        |   EifSectionHeader 6    |
        +-------------------------+
        |         Metadata        |
        +-------------------------+

所有特定的 EIF PCR 都在包含固定初始状态和 EIF 特定部分的摘要的多级方案中计算。它们作为 sha384 消息摘要(在 RFC6234 中描述)计算,内容是 initial_digestcontent_digest 的连接。

PCRX = sha384sum( initial_digest.content_digest )

initial_digest 对于所有 PCR 都是相同的,由 48 个零字节组成。而 content_digest 包含有关 EIF 不同部分的根据 PCR 的数据。

PCR0

PCR0 包含了影响 EIF 中代码运行的所有数据的测量。它包括对 EifSectionKernelEifSectionCmdline 和 enclave 图像文件中按顺序出现的所有 EifSectionRamdisk 部分的连续数据的 sha384 消息摘要。对于 PCR0,这意味着 content_digest 的计算如下

content_digest[PCR0] = sha384sum( data(EifSectionKernel).data(EifSectionCmdline).data(EifSectionRamdisk[..]) )

注意:该计算中元素的顺序取决于 EIF 中部分的顺序。仅包含每个部分的计算,不包括头。

PCR1

PCR1 包含了影响 EIF 中引导和内核的所有数据的测量。它包括对 EifSectionKernelEifSectionCmdline 和 enclave 图像文件中按顺序出现的第一个 EifSectionRamdisk 部分的连续数据的 sha384 消息摘要。对于 PCR1,这意味着 content_digest 的计算如下

content_digest[PCR1] = sha384sum( data(EifSectionKernel).data(EifSectionCmdline).data(EifSectionRamdiks[0]) )

注意:该计算中元素的顺序取决于 EIF 中部分的顺序。仅包含每个部分的计算,不包括头。

PCR2

PCR2 包含了影响 EIF 中用户应用程序的所有数据的测量。它包括对 excluding the first EifSectionRamdisk 部分的所有 EifSectionRamdisk 部分的连续数据的 sha384 消息摘要。对于 PCR2,这意味着 content_digest 的计算如下

content_digest[PCR2] = sha384sum( data(EifSectionRamdisk[1..]) )

注意:该计算中元素的顺序取决于 EIF 中部分的顺序。仅包含每个部分的计算,不包括头。

PCR8

PCR8 只有当 EifSectionSignature 部分是 enclave 图像文件的一部分时才会填充。在这种情况下,PCR8 包含了用于签名 PCR0 并包含在 EifSectionSignature 中的证书的 DER 表示形式的度量。对于 PCR8 这意味着 content_digest 的计算方法如下:

content_digest[PCR8] = sha384sum( signing_certificate_in_DER )

依赖项

~6–13MB
~159K SLoC