3 个版本 (破坏性更新)
0.3.0 | 2024年8月2日 |
---|---|
0.2.0 | 2022年9月26日 |
0.1.0 | 2022年5月29日 |
#79 in 硬件支持
2,184 每月下载量
105KB
1.5K SLoC
aws-nitro-enclaves-image-format
本库提供了 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(初步公开预发布)中的初始公开版本发布。这个初始版本设置了基本的文件格式结构,并支持基本的段类型EifSectionKernel
、EifSectionCmdline
和EifSectionRamdisk
。 - 版本
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 构建环境的元数据。
版本 0
和 1
没有作为任何工具包发布的一部分发布。它们不再受支持,并在加载 enclave 图像文件的 crc 检查阶段失败。
版本 2
和 3
的行为相同。由于在版本 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_64
,1
表示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为这两种架构提供预构建的内核映像
x86_64
:blobs/x86_64/bzImage
aarch64
:blobs/aarch64/Image
EifSectionKernel
节是必选节,每个 enclave 映像文件必须恰好包含一个 EifSectionKernel
节。
EifSectionCmdline
EifSectionCmdline
节数据包含用于 enclave 内核的 Linux 内核命令行参数的字符串。内核命令行可用于在引导时配置内核的某些方面(内核参数文档)。
aws-nitro-enclaves-cli为这两种架构提供内核命令行(与同一位置的预构建内核映像兼容)
x86_64
:blobs/x86_64/cmdline
aarch64
:blobs/aarch64/cmdline
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为两种架构提供了预编译的执行文件
x86_64
:blobs/x86_64/init
aarch64
:blobs/aarch64/init
nsm.ko
驱动程序:这是一个Linux内核的可加载驱动模块,它便于访问Nitro安全模块(NSM)。该驱动程序在enclave中暴露一个特殊设备,以便与虚拟机管理程序通信,获取证明enclave身份的证明文件。NSM驱动程序的源代码可以在aws-nitro-enclaves-sdk-bootstrap中找到,从Linux内核系列v6.8开始,该驱动程序是上游Linux内核的一部分。《aws-nitro-enclaves-cli》为两种架构提供了预编译的此驱动程序版本(与同一位置的预构建内核映像兼容)x86_64
:blobs/x86_64/nsm.ko
aarch64
:blobs/aarch64/nsm.ko
第二个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 描述了它。它们是 PCR0
、PCR1
、PCR2
和 PCR8
。
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_digest
和 content_digest
的连接。
PCRX = sha384sum( initial_digest.content_digest )
initial_digest
对于所有 PCR 都是相同的,由 48 个零字节组成。而 content_digest
包含有关 EIF 不同部分的根据 PCR 的数据。
PCR0
PCR0
包含了影响 EIF 中代码运行的所有数据的测量。它包括对 EifSectionKernel
、EifSectionCmdline
和 enclave 图像文件中按顺序出现的所有 EifSectionRamdisk
部分的连续数据的 sha384 消息摘要。对于 PCR0
,这意味着 content_digest
的计算如下
content_digest[PCR0] = sha384sum( data(EifSectionKernel).data(EifSectionCmdline).data(EifSectionRamdisk[..]) )
注意:该计算中元素的顺序取决于 EIF 中部分的顺序。仅包含每个部分的计算,不包括头。
PCR1
PCR1
包含了影响 EIF 中引导和内核的所有数据的测量。它包括对 EifSectionKernel
、EifSectionCmdline
和 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