1# Redfish SPDM Attestation Support
2
3Author: Zhichuang Sun
4
5Other contributors: Jerome Glisse, Ed Tanous
6
7Created: June 27th, 2023 Last Updated: Oct 30th, 2023
8
9## Problem Description
10
11Redfish added schema for
12[ComponentIntegrity](https://redfish.dmtf.org/redfish/schema_index), which
13allows users to use [SPDM](https://www.dmtf.org/standards/spdm) or
14[TPM](https://trustedcomputinggroup.org/resource/trusted-platform-module-tpm-summary/)
15to authenticate device identity, hardware configuration and firmware integrity.
16It would be useful to add SPDM attestation support in BMCWeb, which provides
17unified interface for device security attestation in data centers, and provide a
18generic implementation for the SPDM D-Bus Daemon.
19
20This design focuses on SPDM.
21
22## Background and References
23
24SPDM (Security Protocols and Data Models) is a spec published by
25[DMTF](https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf).
26It is designed for secure attestation of devices. GitHub repo
27[libspdm](https://github.com/DMTF/libspdm) provides an open-source
28implementation of the SPDM protocol. Redfish Schema
29[ComponentIntegrity](https://redfish.dmtf.org/schemas/v1/ComponentIntegrity.v1_2_1.json)
30adds support for doing SPDM-based device attestation over Redfish API.
31
32## Requirements
33
34This feature aims at supporting SPDM attestation through Redfish API and
35providing system administrators and operators an easy way to remotely verify the
36identity and integrity of devices.
37
38This design includes:
39
40- New D-Bus interfaces for Redfish resources `ComponentIntegrity` and
41  `TrustedComponent`.
42- BMCWeb changes for supporting the above Redfish resources.
43- Design for SPDM Attestation D-Bus Daemon, demonstrating how to fetch the
44  attestation results over D-Bus.
45
46## Proposed Design
47
48### Attestation related D-Bus Interfaces
49
50There are three type of information we will need from an attestation daemon on
51D-Bus:
52
531.  Basic information, like attestation protocol, enablement status, update
54    timestamp, etc.
552.  Identity information, e.g., device identity certificates.
563.  Measurements information, e.g., measurements of the component firmware,
57    hardware configuration, etc.
58
59So far, phosphor-dbus-interfaces lacks interfaces defined for attestation
60purpose. Thus, we propose three new interfaces:
61
62- `Attestation.ComponentIntegrity`
63- `Attestation.IdentityAuthentication`
64- `Attestation.MeasurementSet`
65
66`Attestation.ComponentIntegrity` provides basic component integrity information,
67including the protocol to measure the integrity, last updated time, attestation
68enablement status, etc. There are also associations proposed for this interface,
69including a link to the trusted component that the component integrity object is
70reporting, and a link to the systems that the component integrity object is
71protecting. Note, the "trusted component" in this doc refers to a trusted
72device, such as a TPM, an integrated Root of Trust (ROT).
73
74`Attestation.IdentityAuthentication` provides identity verification information.
75Two associations are proposed to link it to the requester and the responder's
76certificates.
77
78`Attestation.MeasurementSet` defines the dbus method to get SPDM measurements.
79It can be extended to measurements fetched using other protocol in the future.
80
81The proposed Phosphor D-Bus Interfaces is here:
82[component-integrity](https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/64354).
83
84### TrustedComponent related D-Bus Interfaces
85
86We also propose to add one Inventory interface for `TrustedComponent`, namely
87`Inventory.Item.TrustedComponent`. `TrustedComponent` represents a trusted
88hardware component, typically known as Root of Trust(ROT). It can be an
89externally attached security chip, like a TPM, or a hardware IP integrated into
90a device. It can securely measure the integrity information of a device.
91
92`Inventory.Item.TrustedComponent` interface defines the following properties
93
94- `AttachmentType`, which gives information on whether this trusted component is
95  integrated into the device or is discrete from the device.
96
97A `TrustedComponent` is typically associated with other hardware components
98which it is protecting. It should also be associated with the component
99integrity object reported by this `TrustedComponent`.
100
101The proposed Phosphor D-Bus Interfaces for `TrustedComponent` is here:
102[trusted-component](https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/64355).
103
104### SPDM Attestation D-Bus Daemon
105
106[Experimental support for SPDM exists for `bmcweb`](https://github.com/openbmc/bmcweb/compare/master...sunzc:bmcweb:spdm),
107which adds routes in the BMCWeb for `ComponentIntegrity` and `TrustedComponent`
108to support it. But BMCWeb collects the information from D-Bus. The SPDM
109Attestation D-Bus Daemon does the actual work.
110
111SPDM protocol needs to be bound to a transport layer protocol, which transmits
112SPDM messages between the BMC and the device. The transport layer protocol can
113be MCTP, PCIe-DOE, or even TCP socket. For MCTP, the lower physical layer can be
114PCI-VDM, SMBus/I2C, and so on. Note,
115[`libspdm` already provides transport layer protocol binding](https://github.com/DMTF/libspdm/blob/main/include/internal/libspdm_common_lib.h#L445-L446)
116with message encoding/decoding support. The device send/receive function is left
117for SPDM daemon to implement If the transport layer is using standard MCTP or
118PCIe-DOE, setting up the transport layer connection could be easy. In this
119design, we only consider SPDM over standard MCTP and PCIe-DOE connection.
120
121For SPDM-over-MCTP, SPDM daemon can query the mctpd for information about MCTP
122endpoint, including the endpoint id(eid) and upper layer responder, and create a
123connection only for endpoint that has SPDM as its upper layer responder.
124
125For SPDM-over-PCIe-DOE, SPDM daemon need the PCIe device BDF to handle DOE
126mailbox discovery. Given that not all PCIe devices support DOE support SPDM, we
127cannot query about whether a DOE capable device supports SPDM. Therefore, we
128need a way to pass the device info to the dameon. However, PCIe device
129BDF(Bus:Device:Function) info are dynamically assigned during system boot. The
130same device may get assigned different BDF on different machine. What the daemon
131needs should be the PCIe device ID, which is identified by `VendorId:DeviceId`.
132For the convenience of configuration, we should pass PCIe device ID to the
133daemon, so that the daemon can enumerate all the PCIe devices and find the
134matching devices by their device ID. There are different ways to pass PCIe
135device ID info to the dameon, e.g., configuration file, command line parameters.
136
137For PCIe DOE devices, SPDM daemon can enumerage all PCI devices under sysfs and
138find out all BDFs with matching `VendorId:DeviceId`. SPDM daemon also needs to
139query `InventoryManager` to get all PCI device inventory paths. By querying
140`InventoryManager` managed objects and checking object interface
141`xyz.openbmc_project.Inventory.Item.PCIeDevice`, which has property
142`FunctionXVendorId` and `FunctionXDeviceId` (X represents numbers from 0 to 7),
143we can find all PCI device inventory paths with matching `VendorId:DeviceId`. So
144far, there is no universal way to map a given device's BDF to its inventory
145path. It is up to the vendor to do the association.
146
147For MCTP devices detection, the community has been working on `mctpreactor`
148daemon in dbus-sensors to handle the configuration. The link to implementation
149is [here](https://gerrit.openbmc.org/c/openbmc/dbus-sensors/+/69111), the
150related PR discussion is [here](https://github.com/CodeConstruct/mctp/pull/17).
151SPDM daemon will monitor `mctpd` for `InterfacesAdded` signals providing the
152`xyz.openbmc_project.MCTP.Endpoint` interface, which exposes the message types
153supported by the endpoint in the `SupportedMessageTypes` member. SPDM daemon set
154up a connection with the SPDM-capable endpoints to get certificates and
155measurements. For signals sent before SPDM daemon launches, SPDM daemon should
156query the `mctpd` for any detected endpoints after it gets launched.
157
158Below is a high-level diagram showing the relationship between different
159components.
160
161```
162    +------+            +---------+
163    |Client|            |Inventory|
164    +--+---+            |Manager  |
165       |                +---^-----+           +-------+
166       |                    |                 |PCIe   |
167    +--v---+            +---+---+------------>|Device |
168    |BMCWeb+----------->|SPDM   |             +-------+
169    +------+            |Daemon |
170                        +---+---+------------>+-------+
171                            |                 |MCTP   |
172                        +---v---+             |Device |
173                        |mctpd  |             +-------+
174                        +-------+
175```
176
177A reference D-Bus Daemon workflow would be like this:
178
1790. (Probing phase) Entity Manager will parse the configuration file for trusted
180   components; mctpd finish discovery of mctp endpoints. These are prerequisites
181   for SPDM daemon.
1821. Check transport layer protocol. For MCTP, it queries mctpd to gather all eids
183   that support SPDM; For PCIe-DOE, it performs DOE mailbox discovery with the
184   PCIe device ID.
1852. For each endpoint, which could be MCTP or PCIe-DOE, SPDM daemon query Entity
186   Manger for the matching trusted component configuration. It then creates and
187   initializes the corresponding D-Bus object for `TrustedComponent` and
188   `ComponentIntegrity` with device specific information.
1893. Create the associations between the above objects and associations with other
190   objects, e.g., protected components, active software images;
1914. Set up a connection between the BMC and each SPDM-capable device;
1925. Initialize the SPDM context on top of the connection.
1936. Exchange SPDM messages to get device certificates.
1947. Create device certificate objects and create certificate associations for
195   trusted component object and component integrity object.
1968. Wait on D-Bus and serve any runtime `SPDMGetSignedMeasurements` requests.
197
198### Device Certificate
199
200In OpenBMC, there is a
201[certificate manager](https://github.com/openbmc/phosphor-certificate-manager),
202which allows users to install or replace server/client certificates. However,
203the existing certificates manager is designed for managing server/client
204certificates for HTTPS/LDAP services. It's not suitable for device certificates.
205Existing cert manager has several limitations:
206
207- Each manager can only manage one certificate.
208- Each manager assumes access to both the private key and the public key (e.g.,
209  for completing CSR request).
210
211Device certificates have different requirements:
212
213- Device certificate manager manages several certificates for a group of
214  devices, for example, four GPUs would have four certificates.
215- Device certificate does not assume private key access. It is used for identity
216  authentication only. It does not provide CSR signing services. The private key
217  should never leave the device Root of Trust(RoT) component.
218
219For device certificates, we only need to create/replace certificate objects, no
220need for a global cert manager that "manages" the device certificates. SPDM
221D-Bus daemon can simply talk to the devices, get the certificates from them, and
222create D-Bus object for the certificates.
223
224In Redfish, device certificates are under Chassis, and are accessible via
225`/redfish/v1/Chassis/{ChassisId}/Certificates/`. Existing cert manager
226constructs cert path following the pattern
227`"/xyz/openbmc_project/certs/{type}/{endpoint}".` To comply with it, we propose
228to put device certificates under
229`/xyz/openbmc_project/certs/chassis/{ChassisId}/{certsId}`. So that for all
230device certificates on a chassis, we can find those certificates with its
231chassisId on D-Bus.
232
233### BMCWeb Support
234
235In BMCWeb, we need to add routes handler for `ComponentIntegrity`,
236`TrustedComponent` and `Certificates`. The corresponding URI are specified as
237follows according to Redfish spec:
238
239- `/redfish/v1/ComponentIntegrity/`
240- `/redfish/v1/Chassis/{ChassisId}/TrustedComponents/`
241- `/redfish/v1/Chassis/{ChassisId}/Certificates/`
242
243On the D-Bus Daemon side, we propose that the dbus objects are organized in the
244following way:
245
246- `/xyz/openbmc_project/ComponentIntegrity/{ComponentIntegrityId}`
247- `/xyz/openbmc_project/TrustedComponents/{TrustedComponentId}`
248- `/xyz/openbmc_project/certs/devices/{ChassisId}/{CertId}`
249
250In BMCWeb, we can reconstruct the following redfish URI by querying the
251associated Chassis from the trusted component:
252
253- `/redfish/v1/Chassis/{ChassisId}/TrustedComponents/{TrustedComponentId}`
254
255## Alternatives Considered
256
257Alternative way to manage device certificates would be modifying existing
258[phosphor-certificate-manager](https://github.com/openbmc/phosphor-certificate-manager).
259
260Device certificates management has two steps:
261
262- Step 1: fetch device certificate by exchange SPDM messages with device.
263- Step 2: create or update a dbus certificate object.
264
265Step 1 can only be handled by the SPDM daemon. Step 2 is simple enough to be
266handled by the D-Bus daemon, too. It would be a over-kill to modify existing
267phosphor-certificate-manager for the sole purpose.
268
269## Impacts
270
271This change will:
272
273- Create a SPDM daemon that can do SPDM attestation for SPDM-capable devices
274  over PCIe DOE or MCTP.
275- Add `ComponentIntegrity` and `TrustedComponent` related D-Bus interfaces in
276  phosphor-dbus-interfaces.
277- Extend existing certificate service in BMCWeb.
278- Add SPDM support in BMCWeb with new routes.
279
280### Organizational
281
282This repository requires creating a new repository for the SPDM daemon. In
283addition, the following repositories are expected to be modified to execute this
284design:
285
286- https://github.com/openbmc/bmcweb
287- https://github.com/openbmc/phosphor-dbus-interfaces
288
289## Testing
290
291### Unit Test
292
293For the BMCWeb changes, unit test can be done with the Redfish Service
294Validator.
295
296For the SPDM Attestation D-Bus Daemon, unit tests should cover the following
297cases:
298
299- Set up a transport layer connection with the device.
300- SPDM connection setup, including get capabilities, negotiate algorithms.
301- Get device certificates from device and create D-Bus object.
302- `SPDMGetSignedMeasurements` method test.
303- Enumerate trusted component D-Bus objects and check properties and
304  associations.
305- Enumerate component integraty D-Bus objects and check properties and
306  associations.
307
308### Integration Test
309
310BMCWeb/D-Bus Daemon integration test should cover the following type of
311requests:
312
313- Get a collection of `ComponentIntegrity` resources.
314- Get a collection of `TrustedComponent` resource.
315- Get properties of a `ComponentIntegrity` resources.
316- Get properties of a `TrustedComponent` resource.
317- Follow the resouces link to get the device certificates.
318- Call Action on the `ComponentIntegrity` resource to get measurements.
319