319 lines
14 KiB
Markdown
319 lines
14 KiB
Markdown
# Redfish SPDM Attestation Support
|
|
|
|
Author: Zhichuang Sun
|
|
|
|
Other contributors: Jerome Glisse, Ed Tanous
|
|
|
|
Created: June 27th, 2023 Last Updated: Oct 30th, 2023
|
|
|
|
## Problem Description
|
|
|
|
Redfish added schema for
|
|
[ComponentIntegrity](https://redfish.dmtf.org/redfish/schema_index), which
|
|
allows users to use [SPDM](https://www.dmtf.org/standards/spdm) or
|
|
[TPM](https://trustedcomputinggroup.org/resource/trusted-platform-module-tpm-summary/)
|
|
to authenticate device identity, hardware configuration and firmware integrity.
|
|
It would be useful to add SPDM attestation support in BMCWeb, which provides
|
|
unified interface for device security attestation in data centers, and provide a
|
|
generic implementation for the SPDM D-Bus Daemon.
|
|
|
|
This design focuses on SPDM.
|
|
|
|
## Background and References
|
|
|
|
SPDM (Security Protocols and Data Models) is a spec published by
|
|
[DMTF](https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf).
|
|
It is designed for secure attestation of devices. GitHub repo
|
|
[libspdm](https://github.com/DMTF/libspdm) provides an open-source
|
|
implementation of the SPDM protocol. Redfish Schema
|
|
[ComponentIntegrity](https://redfish.dmtf.org/schemas/v1/ComponentIntegrity.v1_2_1.json)
|
|
adds support for doing SPDM-based device attestation over Redfish API.
|
|
|
|
## Requirements
|
|
|
|
This feature aims at supporting SPDM attestation through Redfish API and
|
|
providing system administrators and operators an easy way to remotely verify the
|
|
identity and integrity of devices.
|
|
|
|
This design includes:
|
|
|
|
- New D-Bus interfaces for Redfish resources `ComponentIntegrity` and
|
|
`TrustedComponent`.
|
|
- BMCWeb changes for supporting the above Redfish resources.
|
|
- Design for SPDM Attestation D-Bus Daemon, demonstrating how to fetch the
|
|
attestation results over D-Bus.
|
|
|
|
## Proposed Design
|
|
|
|
### Attestation related D-Bus Interfaces
|
|
|
|
There are three type of information we will need from an attestation daemon on
|
|
D-Bus:
|
|
|
|
1. Basic information, like attestation protocol, enablement status, update
|
|
timestamp, etc.
|
|
2. Identity information, e.g., device identity certificates.
|
|
3. Measurements information, e.g., measurements of the component firmware,
|
|
hardware configuration, etc.
|
|
|
|
So far, phosphor-dbus-interfaces lacks interfaces defined for attestation
|
|
purpose. Thus, we propose three new interfaces:
|
|
|
|
- `Attestation.ComponentIntegrity`
|
|
- `Attestation.IdentityAuthentication`
|
|
- `Attestation.MeasurementSet`
|
|
|
|
`Attestation.ComponentIntegrity` provides basic component integrity information,
|
|
including the protocol to measure the integrity, last updated time, attestation
|
|
enablement status, etc. There are also associations proposed for this interface,
|
|
including a link to the trusted component that the component integrity object is
|
|
reporting, and a link to the systems that the component integrity object is
|
|
protecting. Note, the "trusted component" in this doc refers to a trusted
|
|
device, such as a TPM, an integrated Root of Trust (ROT).
|
|
|
|
`Attestation.IdentityAuthentication` provides identity verification information.
|
|
Two associations are proposed to link it to the requester and the responder's
|
|
certificates.
|
|
|
|
`Attestation.MeasurementSet` defines the dbus method to get SPDM measurements.
|
|
It can be extended to measurements fetched using other protocol in the future.
|
|
|
|
The proposed Phosphor D-Bus Interfaces is here:
|
|
[component-integrity](https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/64354).
|
|
|
|
### TrustedComponent related D-Bus Interfaces
|
|
|
|
We also propose to add one Inventory interface for `TrustedComponent`, namely
|
|
`Inventory.Item.TrustedComponent`. `TrustedComponent` represents a trusted
|
|
hardware component, typically known as Root of Trust(ROT). It can be an
|
|
externally attached security chip, like a TPM, or a hardware IP integrated into
|
|
a device. It can securely measure the integrity information of a device.
|
|
|
|
`Inventory.Item.TrustedComponent` interface defines the following properties
|
|
|
|
- `AttachmentType`, which gives information on whether this trusted component is
|
|
integrated into the device or is discrete from the device.
|
|
|
|
A `TrustedComponent` is typically associated with other hardware components
|
|
which it is protecting. It should also be associated with the component
|
|
integrity object reported by this `TrustedComponent`.
|
|
|
|
The proposed Phosphor D-Bus Interfaces for `TrustedComponent` is here:
|
|
[trusted-component](https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/64355).
|
|
|
|
### SPDM Attestation D-Bus Daemon
|
|
|
|
[Experimental support for SPDM exists for `bmcweb`](https://github.com/openbmc/bmcweb/compare/master...sunzc:bmcweb:spdm),
|
|
which adds routes in the BMCWeb for `ComponentIntegrity` and `TrustedComponent`
|
|
to support it. But BMCWeb collects the information from D-Bus. The SPDM
|
|
Attestation D-Bus Daemon does the actual work.
|
|
|
|
SPDM protocol needs to be bound to a transport layer protocol, which transmits
|
|
SPDM messages between the BMC and the device. The transport layer protocol can
|
|
be MCTP, PCIe-DOE, or even TCP socket. For MCTP, the lower physical layer can be
|
|
PCI-VDM, SMBus/I2C, and so on. Note,
|
|
[`libspdm` already provides transport layer protocol binding](https://github.com/DMTF/libspdm/blob/main/include/internal/libspdm_common_lib.h#L445-L446)
|
|
with message encoding/decoding support. The device send/receive function is left
|
|
for SPDM daemon to implement If the transport layer is using standard MCTP or
|
|
PCIe-DOE, setting up the transport layer connection could be easy. In this
|
|
design, we only consider SPDM over standard MCTP and PCIe-DOE connection.
|
|
|
|
For SPDM-over-MCTP, SPDM daemon can query the mctpd for information about MCTP
|
|
endpoint, including the endpoint id(eid) and upper layer responder, and create a
|
|
connection only for endpoint that has SPDM as its upper layer responder.
|
|
|
|
For SPDM-over-PCIe-DOE, SPDM daemon need the PCIe device BDF to handle DOE
|
|
mailbox discovery. Given that not all PCIe devices support DOE support SPDM, we
|
|
cannot query about whether a DOE capable device supports SPDM. Therefore, we
|
|
need a way to pass the device info to the dameon. However, PCIe device
|
|
BDF(Bus:Device:Function) info are dynamically assigned during system boot. The
|
|
same device may get assigned different BDF on different machine. What the daemon
|
|
needs should be the PCIe device ID, which is identified by `VendorId:DeviceId`.
|
|
For the convenience of configuration, we should pass PCIe device ID to the
|
|
daemon, so that the daemon can enumerate all the PCIe devices and find the
|
|
matching devices by their device ID. There are different ways to pass PCIe
|
|
device ID info to the dameon, e.g., configuration file, command line parameters.
|
|
|
|
For PCIe DOE devices, SPDM daemon can enumerage all PCI devices under sysfs and
|
|
find out all BDFs with matching `VendorId:DeviceId`. SPDM daemon also needs to
|
|
query `InventoryManager` to get all PCI device inventory paths. By querying
|
|
`InventoryManager` managed objects and checking object interface
|
|
`xyz.openbmc_project.Inventory.Item.PCIeDevice`, which has property
|
|
`FunctionXVendorId` and `FunctionXDeviceId` (X represents numbers from 0 to 7),
|
|
we can find all PCI device inventory paths with matching `VendorId:DeviceId`. So
|
|
far, there is no universal way to map a given device's BDF to its inventory
|
|
path. It is up to the vendor to do the association.
|
|
|
|
For MCTP devices detection, the community has been working on `mctpreactor`
|
|
daemon in dbus-sensors to handle the configuration. The link to implementation
|
|
is [here](https://gerrit.openbmc.org/c/openbmc/dbus-sensors/+/69111), the
|
|
related PR discussion is [here](https://github.com/CodeConstruct/mctp/pull/17).
|
|
SPDM daemon will monitor `mctpd` for `InterfacesAdded` signals providing the
|
|
`xyz.openbmc_project.MCTP.Endpoint` interface, which exposes the message types
|
|
supported by the endpoint in the `SupportedMessageTypes` member. SPDM daemon set
|
|
up a connection with the SPDM-capable endpoints to get certificates and
|
|
measurements. For signals sent before SPDM daemon launches, SPDM daemon should
|
|
query the `mctpd` for any detected endpoints after it gets launched.
|
|
|
|
Below is a high-level diagram showing the relationship between different
|
|
components.
|
|
|
|
```
|
|
+------+ +---------+
|
|
|Client| |Inventory|
|
|
+--+---+ |Manager |
|
|
| +---^-----+ +-------+
|
|
| | |PCIe |
|
|
+--v---+ +---+---+------------>|Device |
|
|
|BMCWeb+----------->|SPDM | +-------+
|
|
+------+ |Daemon |
|
|
+---+---+------------>+-------+
|
|
| |MCTP |
|
|
+---v---+ |Device |
|
|
|mctpd | +-------+
|
|
+-------+
|
|
```
|
|
|
|
A reference D-Bus Daemon workflow would be like this:
|
|
|
|
0. (Probing phase) Entity Manager will parse the configuration file for trusted
|
|
components; mctpd finish discovery of mctp endpoints. These are prerequisites
|
|
for SPDM daemon.
|
|
1. Check transport layer protocol. For MCTP, it queries mctpd to gather all eids
|
|
that support SPDM; For PCIe-DOE, it performs DOE mailbox discovery with the
|
|
PCIe device ID.
|
|
2. For each endpoint, which could be MCTP or PCIe-DOE, SPDM daemon query Entity
|
|
Manger for the matching trusted component configuration. It then creates and
|
|
initializes the corresponding D-Bus object for `TrustedComponent` and
|
|
`ComponentIntegrity` with device specific information.
|
|
3. Create the associations between the above objects and associations with other
|
|
objects, e.g., protected components, active software images;
|
|
4. Set up a connection between the BMC and each SPDM-capable device;
|
|
5. Initialize the SPDM context on top of the connection.
|
|
6. Exchange SPDM messages to get device certificates.
|
|
7. Create device certificate objects and create certificate associations for
|
|
trusted component object and component integrity object.
|
|
8. Wait on D-Bus and serve any runtime `SPDMGetSignedMeasurements` requests.
|
|
|
|
### Device Certificate
|
|
|
|
In OpenBMC, there is a
|
|
[certificate manager](https://github.com/openbmc/phosphor-certificate-manager),
|
|
which allows users to install or replace server/client certificates. However,
|
|
the existing certificates manager is designed for managing server/client
|
|
certificates for HTTPS/LDAP services. It's not suitable for device certificates.
|
|
Existing cert manager has several limitations:
|
|
|
|
- Each manager can only manage one certificate.
|
|
- Each manager assumes access to both the private key and the public key (e.g.,
|
|
for completing CSR request).
|
|
|
|
Device certificates have different requirements:
|
|
|
|
- Device certificate manager manages several certificates for a group of
|
|
devices, for example, four GPUs would have four certificates.
|
|
- Device certificate does not assume private key access. It is used for identity
|
|
authentication only. It does not provide CSR signing services. The private key
|
|
should never leave the device Root of Trust(RoT) component.
|
|
|
|
For device certificates, we only need to create/replace certificate objects, no
|
|
need for a global cert manager that "manages" the device certificates. SPDM
|
|
D-Bus daemon can simply talk to the devices, get the certificates from them, and
|
|
create D-Bus object for the certificates.
|
|
|
|
In Redfish, device certificates are under Chassis, and are accessible via
|
|
`/redfish/v1/Chassis/{ChassisId}/Certificates/`. Existing cert manager
|
|
constructs cert path following the pattern
|
|
`"/xyz/openbmc_project/certs/{type}/{endpoint}".` To comply with it, we propose
|
|
to put device certificates under
|
|
`/xyz/openbmc_project/certs/chassis/{ChassisId}/{certsId}`. So that for all
|
|
device certificates on a chassis, we can find those certificates with its
|
|
chassisId on D-Bus.
|
|
|
|
### BMCWeb Support
|
|
|
|
In BMCWeb, we need to add routes handler for `ComponentIntegrity`,
|
|
`TrustedComponent` and `Certificates`. The corresponding URI are specified as
|
|
follows according to Redfish spec:
|
|
|
|
- `/redfish/v1/ComponentIntegrity/`
|
|
- `/redfish/v1/Chassis/{ChassisId}/TrustedComponents/`
|
|
- `/redfish/v1/Chassis/{ChassisId}/Certificates/`
|
|
|
|
On the D-Bus Daemon side, we propose that the dbus objects are organized in the
|
|
following way:
|
|
|
|
- `/xyz/openbmc_project/ComponentIntegrity/{ComponentIntegrityId}`
|
|
- `/xyz/openbmc_project/TrustedComponents/{TrustedComponentId}`
|
|
- `/xyz/openbmc_project/certs/devices/{ChassisId}/{CertId}`
|
|
|
|
In BMCWeb, we can reconstruct the following redfish URI by querying the
|
|
associated Chassis from the trusted component:
|
|
|
|
- `/redfish/v1/Chassis/{ChassisId}/TrustedComponents/{TrustedComponentId}`
|
|
|
|
## Alternatives Considered
|
|
|
|
Alternative way to manage device certificates would be modifying existing
|
|
[phosphor-certificate-manager](https://github.com/openbmc/phosphor-certificate-manager).
|
|
|
|
Device certificates management has two steps:
|
|
|
|
- Step 1: fetch device certificate by exchange SPDM messages with device.
|
|
- Step 2: create or update a dbus certificate object.
|
|
|
|
Step 1 can only be handled by the SPDM daemon. Step 2 is simple enough to be
|
|
handled by the D-Bus daemon, too. It would be a over-kill to modify existing
|
|
phosphor-certificate-manager for the sole purpose.
|
|
|
|
## Impacts
|
|
|
|
This change will:
|
|
|
|
- Create a SPDM daemon that can do SPDM attestation for SPDM-capable devices
|
|
over PCIe DOE or MCTP.
|
|
- Add `ComponentIntegrity` and `TrustedComponent` related D-Bus interfaces in
|
|
phosphor-dbus-interfaces.
|
|
- Extend existing certificate service in BMCWeb.
|
|
- Add SPDM support in BMCWeb with new routes.
|
|
|
|
### Organizational
|
|
|
|
This repository requires creating a new repository for the SPDM daemon. In
|
|
addition, the following repositories are expected to be modified to execute this
|
|
design:
|
|
|
|
- https://github.com/openbmc/bmcweb
|
|
- https://github.com/openbmc/phosphor-dbus-interfaces
|
|
|
|
## Testing
|
|
|
|
### Unit Test
|
|
|
|
For the BMCWeb changes, unit test can be done with the Redfish Service
|
|
Validator.
|
|
|
|
For the SPDM Attestation D-Bus Daemon, unit tests should cover the following
|
|
cases:
|
|
|
|
- Set up a transport layer connection with the device.
|
|
- SPDM connection setup, including get capabilities, negotiate algorithms.
|
|
- Get device certificates from device and create D-Bus object.
|
|
- `SPDMGetSignedMeasurements` method test.
|
|
- Enumerate trusted component D-Bus objects and check properties and
|
|
associations.
|
|
- Enumerate component integraty D-Bus objects and check properties and
|
|
associations.
|
|
|
|
### Integration Test
|
|
|
|
BMCWeb/D-Bus Daemon integration test should cover the following type of
|
|
requests:
|
|
|
|
- Get a collection of `ComponentIntegrity` resources.
|
|
- Get a collection of `TrustedComponent` resource.
|
|
- Get properties of a `ComponentIntegrity` resources.
|
|
- Get properties of a `TrustedComponent` resource.
|
|
- Follow the resouces link to get the device certificates.
|
|
- Call Action on the `ComponentIntegrity` resource to get measurements.
|