-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is an attempt to formalize the boot protocol while also proposing a new name for this implementation of the Secure Loader for SKINIT. Signed-off-by: Daniel P. Smith <[email protected]>
- Loading branch information
Showing
1 changed file
with
232 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
Security Kernel Loader | ||
###################### | ||
|
||
The Security Kernel Loader (SKL) is an implementation of AMD's Secure Loader | ||
Block (SLB) specification for the SKINIT CPU instruction and DRTM measurements. | ||
The SKL loader takes a minimal approach relying on the DRTM Preamble, e.g. the | ||
system bootloader, to load into memory and configure the Security Kernel that | ||
the SKL will measure and execute. This document details the boot protocol that | ||
a DRTM Preamble must implement to properly launch the SKL. This protocol is | ||
versioned and future revisions may be expanded in a manner that provides | ||
backwards compatibility. | ||
|
||
+----------+---------------------------------------------------------+ | ||
| Protocol | Notes | | ||
| Version | | | ||
+==========+=========================================================+ | ||
| 1 | Initial protocol | | ||
+----------+---------------------------------------------------------+ | ||
|
||
SKL Setup | ||
********* | ||
|
||
The DRTM Preamble is responsible for allocating a contiguous block of physical | ||
memory and will ensure it is marked as reserved in the system memory map. The | ||
necessary size for the allocation will be found in the SKL header. The DRTM | ||
Preamble will place the SKL at the beginning of the allocation. | ||
|
||
Below is a representation of SKL memory for visual purposes. The boot tags will | ||
always be the last region, otherwise there are no guaranteed locations for the | ||
remaining segments and must be located thorugh the SKL header.:: | ||
|
||
+--- Security Kernel Loader (64kb) ---+ | ||
| | | ||
v v | ||
+--------+----------+----------+-----------+--------------+ | ||
| Header | Code | Log Area | Boot Tags | Scratch Area | | ||
+--------+----------+----------+-----------+--------------+ | ||
^ ^ ^ ^ ^ | ||
| | | | | | ||
+ + + + + | ||
skl_base hdr.log hdr.tags <60kb hdr.alloc_size | ||
|
||
|
||
SKL Header | ||
========== | ||
|
||
The SKL header is the SLB header which has been extended to meet the | ||
needs of the SKL. The first two fields are mandated by the SLB and the SKL adds | ||
two additional fields which can be seen in the following representative struct, | ||
:: | ||
|
||
struct skl_hdr { | ||
u16 entry_point; /* Code Entry */ | ||
u16 length; /* RoT Measurement Length */ | ||
u16 alloc_size; /* Allocation Size */ | ||
u16 info_table_offset; /* Offset for the SKL Info Table */ | ||
u16 logs_offset; /* Offset for the SKL Info Table */ | ||
u16 boot_tags_offset; /* RoT Measurement Length */ | ||
}; | ||
|
||
SKL Allocation Size | ||
------------------- | ||
|
||
The allocation size reflects the amount of memory required for the SLK and its scratch | ||
area. The DRTM Preamble should allocate at least header.alloc_size bytes of contiguous memory | ||
and make the area reserved in the system memory map. | ||
|
||
Info Table | ||
========== | ||
|
||
The Info Table contains a description of the SKL, specifically a unique | ||
identifier and the version for the SKL. This is version 1 of Future versions may | ||
extend this structure in a backwards compatible manor. | ||
:: | ||
|
||
struct skl_info { | ||
u8 uuid[16]; /* 78 f1 26 8e 04 92 11 e9 83 2a c8 5b 76 c4 cc 02 */ | ||
u8 major; /* Version major of the SKL */ | ||
u8 minor; /* Version minor of the SKL */ | ||
u16 protocol; /* Boot protocol supported */ | ||
} __packed; | ||
|
||
Boot Tags | ||
========= | ||
|
||
The Boot Tags are a series of Tag/Length/Value entries for the DRTM Preamble to | ||
pass information to the SKL. As a result the Boot Tags will be the last segment | ||
before the Scratch Area and therefore cannot exceed a byte offset of 61440 | ||
bytes | ||
|
||
Each Boot Tag has its first element, a `struct skl_tag_hdr`, where the `type` | ||
consists of a four bit class and a four bit subtype. This provides a single | ||
tier hierarchy which enable each class to have different rules dictating their | ||
usage, e.g. there can only be one boot class tag. | ||
:: | ||
|
||
struct skl_tag_hdr { | ||
u8 type; | ||
u8 len; | ||
} __packed; | ||
|
||
|
||
Boot Class | ||
---------- | ||
|
||
The Boot Class tags are for selecting the which boot protocol to use to start | ||
the target kernel. Currently only two boot protocols are supported, the Linux | ||
boot protocol and the Multiboot2 protocol. | ||
|
||
Linux Boot Tag | ||
^^^^^^^^^^^^^^ | ||
|
||
The SKL relies on the DRTM Preamble to setup and stage the Linux kernel for | ||
booting, therefore the SKL only requires to be provided the location of the | ||
kernel's zero page to enable measuring and starting the Linux kernel. | ||
:: | ||
|
||
struct skl_tag_boot_linux { | ||
struct skl_tag_hdr hdr; | ||
u32 zero_page; | ||
} __packed; | ||
|
||
Multiboot2 Boot Tag | ||
^^^^^^^^^^^^^^^^^^^ | ||
|
||
The SKL relies on the DRTM Preamble to setup the Multiboot2 module list and | ||
must be provided the address for the Multiboot2 Boot Information (MBI) module | ||
and may optionally include the entry address and size of the kernel to be | ||
started. | ||
:: | ||
|
||
struct lz_tag_boot_mb2 { | ||
struct skl_tag_hdr hdr; | ||
u32 mbi; | ||
u32 kernel_entry; | ||
u32 kernel_size; | ||
} __packed; | ||
|
||
Linux Class | ||
----------- | ||
|
||
This class is for any boot information created/generated by the SKL that needs | ||
to be passed along to the Linux kernel. | ||
|
||
Setup Data Tag | ||
^^^^^^^^^^^^^^ | ||
|
||
The Linux Secure Launch protocol requires a Setup Indirect setup data entry to | ||
pass information to Secure Launch. This resulting structure is chained into | ||
Linux's `struct setup_header->setup_data` linked list. | ||
:: | ||
|
||
struct skl_tag_setup_data { | ||
struct skl_tag_hdr hdr; | ||
struct setup_data data; | ||
} __packed; | ||
|
||
Logging Class | ||
------------- | ||
|
||
The logging class holds the tags related to the TPM Event log and SKL's | ||
internal logging facilities. | ||
|
||
Event Log Tag | ||
^^^^^^^^^^^^^ | ||
|
||
The Event Log tag provides three controls, policy, scheme, and the address/size | ||
of the event log. The policy controls how and what algorithms will be used, | ||
scheme allows for selecting the PCR usage scheme, and address/size provides the | ||
address and size of the event log buffer setup by the DRTM Preamble. The DRTM | ||
Preamble will use the address/size from the DRTM ACPI table or it will allocate | ||
and reserve a memory region to be used as the event log buffer. | ||
:: | ||
|
||
struct skl_tag_evtlog { | ||
struct skl_tag_hdr hdr; | ||
u16 policy; | ||
u16 scheme; | ||
u32 address; | ||
u32 size; | ||
} __packed; | ||
|
||
CRTM Hash Tag | ||
^^^^^^^^^^^^^ | ||
|
||
The SKINIT instruction does not provide the measurement it made of the SKL to | ||
the SKL iteslf, but the value needs to be present in the Event Log for | ||
attestation purposes. This tag provides the option for the DRTM Preamble to | ||
hash the SKL and provide the measurement to the SKL for recording into the log. | ||
:: | ||
|
||
struct skl_tag_crtm_hash { | ||
struct skl_tag_hdr hdr; | ||
u16 algo_id; | ||
u8 digest[]; | ||
} __packed; | ||
|
||
MSB Class | ||
--------- | ||
|
||
The Measured Secure Boot (MSB) is an upcoming optional operational mode of the | ||
SKL. It allows for the SKL to function as the Root of Trust for Verification | ||
(RTV) for a SecureBoot trust chain using a public key provided to SKL. The MSB | ||
Class is for all tags relating to configuring MSB. | ||
|
||
MSB Key Tag | ||
^^^^^^^^^^^ | ||
|
||
The MSK Key tag is to allow embedding an MSB key directly into SKL. | ||
:: | ||
|
||
struct skl_tag_msb_key { | ||
struct skl_tag_hdr hdr; | ||
u16 algo_id; | ||
u8 key[]; | ||
} __packed; | ||
|
||
MSB Key DB Tag | ||
^^^^^^^^^^^^^^ | ||
|
||
The MSK Key DB tag points to a key db list external to the SKL along with a | ||
hash of the db list. | ||
:: | ||
|
||
struct skl_tag_msb_keydb { | ||
struct skl_tag_hdr hdr; | ||
u32 keydb; | ||
u32 size; | ||
u16 algo_id; | ||
u8 digest[]; | ||
} __packed; |