Skip to content

Commit

Permalink
doc: documenting the boot protocol
Browse files Browse the repository at this point in the history
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
dpsmith committed Aug 5, 2021
1 parent bd4f9f0 commit 6f10f0f
Showing 1 changed file with 232 additions and 0 deletions.
232 changes: 232 additions & 0 deletions doc/boot_protocol.rst
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;

0 comments on commit 6f10f0f

Please sign in to comment.