xref: /openbmc/docs/designs/redfish-spdm-attestation.md (revision ba560cc31297caddfc157c540ae9e6d760d630e5)
1# Redfish SPDM Attestation Support
2
3Author: Zhichuang Sun
4
5Other contributors: Jerome Glisse, Ed Tanous, Manojkiran Eda
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,
118PCIe-DOE, or TCP setting up the transport layer connection could be easy. In
119this design, we only consider SPDM over standard MCTP,TCP & 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-TCP, SPDM daemon can query [entity-manager][entity-source] for
126information about remote TCP endpoints, including the `hostname / ip-address` &
127`port` details from the `SpdmTcpResponder` interface and create a connection
128either by using the reach out model (or) reach down model as stated in the [SPDM
129over TCP specification][spdm-tcp-spec]
130
131[entity-source]: https://github.com/openbmc/entity-manager
132[spdm-tcp-spec]:
133  https://www.dmtf.org/sites/default/files/standards/documents/DSP0287_1.0.0.pdf
134
135For SPDM-over-PCIe-DOE, SPDM daemon need the PCIe device BDF to handle DOE
136mailbox discovery. Given that not all PCIe devices support DOE support SPDM, we
137cannot query about whether a DOE capable device supports SPDM. Therefore, we
138need a way to pass the device info to the dameon. However, PCIe device
139BDF(Bus:Device:Function) info are dynamically assigned during system boot. The
140same device may get assigned different BDF on different machine. What the daemon
141needs should be the PCIe device ID, which is identified by `VendorId:DeviceId`.
142For the convenience of configuration, we should pass PCIe device ID to the
143daemon, so that the daemon can enumerate all the PCIe devices and find the
144matching devices by their device ID. There are different ways to pass PCIe
145device ID info to the dameon, e.g., configuration file, command line parameters.
146
147For PCIe DOE devices, SPDM daemon can enumerage all PCI devices under sysfs and
148find out all BDFs with matching `VendorId:DeviceId`. SPDM daemon also needs to
149query `InventoryManager` to get all PCI device inventory paths. By querying
150`InventoryManager` managed objects and checking object interface
151`xyz.openbmc_project.Inventory.Item.PCIeDevice`, which has property
152`FunctionXVendorId` and `FunctionXDeviceId` (X represents numbers from 0 to 7),
153we can find all PCI device inventory paths with matching `VendorId:DeviceId`. So
154far, there is no universal way to map a given device's BDF to its inventory
155path. It is up to the vendor to do the association.
156
157For MCTP devices detection, the community has been working on `mctpreactor`
158daemon in dbus-sensors to handle the configuration. The proposed
159[implementation](https://gerrit.openbmc.org/c/openbmc/dbus-sensors/+/69111); the
160related [PR discussion](https://github.com/CodeConstruct/mctp/pull/17). SPDM
161daemon will monitor `mctpd` for `InterfacesAdded` signals providing the
162`xyz.openbmc_project.MCTP.Endpoint` interface, which exposes the message types
163supported by the endpoint in the `SupportedMessageTypes` member. SPDM daemon set
164up a connection with the SPDM-capable endpoints to get certificates and
165measurements. For signals sent before SPDM daemon launches, SPDM daemon should
166query the `mctpd` for any detected endpoints after it gets launched.
167
168For Network based device detection , SPDM daemon would monitor for
169`InterfacesAdded` signal provided by
170`xyz.openbmc_project.Configuration.SpdmTcpResponder` interface, which exposes
171the `Hostname` & `Port` of the remote entity. For signals sent before SPDM
172daemon launches, SPDM daemon should query the `entity-manager` for any detected
173endpoints after it gets launched.
174
175Below is a high-level diagram showing the relationship between different
176components.
177
178```ascii
179    +------+            +---------+
180    |Client|            |Inventory|
181    +--+---+            |Manager  |
182       |                +---^-----+           +-------+
183       |                    |                 |PCIe   |
184    +--v---+            +---+---+------------>|Device |
185    |BMCWeb+----------->|SPDM   |             +-------+
186    +------+            |Daemon |
187                        +---+---+------------>+-------+
188                            |                 |MCTP   |
189                        +---v---+             |Device |
190                        |mctpd  |             +-------+
191                        +-------+
192```
193
194A reference D-Bus Daemon workflow would be like this:
195
1960. (Probing phase) Entity Manager will parse the configuration file for trusted
197   components; mctpd finish discovery of mctp endpoints. These are prerequisites
198   for SPDM daemon.
1991. Check transport layer protocol. For MCTP, it queries mctpd to gather all eids
200   that support SPDM; For PCIe-DOE, it performs DOE mailbox discovery with the
201   PCIe device ID; For TCP, it queries entity-manager to gather the remote IP
202   address & Port.
2032. For each endpoint, which could be MCTP, PCIe-DOE or TCP, SPDM daemon query
204   Entity Manger for the matching trusted component configuration. It then
205   creates and initializes the corresponding D-Bus object for `TrustedComponent`
206   and `ComponentIntegrity` with device specific information.
2073. Create the associations between the above objects and associations with other
208   objects, e.g., protected components, active software images;
2094. Set up a connection between the BMC and each SPDM-capable device;
2105. Initialize the SPDM context on top of the connection.
2116. Exchange SPDM messages to get device certificates.
2127. Create device certificate objects and create certificate associations for
213   trusted component object and component integrity object.
2148. Wait on D-Bus and serve any runtime `SPDMGetSignedMeasurements` requests.
215
216### Device Certificate
217
218In OpenBMC, there is a
219[certificate manager](https://github.com/openbmc/phosphor-certificate-manager),
220which allows users to install or replace server/client certificates. However,
221the existing certificates manager is designed for managing server/client
222certificates for HTTPS/LDAP services. It's not suitable for device certificates.
223Existing cert manager has several limitations:
224
225- Each manager can only manage one certificate.
226- Each manager assumes access to both the private key and the public key (e.g.,
227  for completing CSR request).
228
229Device certificates have different requirements:
230
231- Device certificate manager manages several certificates for a group of
232  devices, for example, four GPUs would have four certificates.
233- Device certificate does not assume private key access. It is used for identity
234  authentication only. It does not provide CSR signing services. The private key
235  should never leave the device Root of Trust(RoT) component.
236
237For device certificates, we only need to create/replace certificate objects, no
238need for a global cert manager that "manages" the device certificates. SPDM
239D-Bus daemon can simply talk to the devices, get the certificates from them, and
240create D-Bus object for the certificates.
241
242In Redfish, device certificates are under Chassis, and are accessible via
243`/redfish/v1/Chassis/{ChassisId}/Certificates/`. Existing cert manager
244constructs cert path following the pattern
245`"/xyz/openbmc_project/certs/{type}/{endpoint}".` To comply with it, we propose
246to put device certificates under
247`/xyz/openbmc_project/certs/chassis/{ChassisId}/{certsId}`. So that for all
248device certificates on a chassis, we can find those certificates with its
249chassisId on D-Bus.
250
251### BMCWeb Support
252
253In BMCWeb, we need to add routes handler for `ComponentIntegrity`,
254`TrustedComponent` and `Certificates`. The corresponding URI are specified as
255follows according to Redfish spec:
256
257- `/redfish/v1/ComponentIntegrity/`
258- `/redfish/v1/Chassis/{ChassisId}/TrustedComponents/`
259
260The TrustedComponent represents a ROT or TPM, and its associated certificates
261should be represented as subordinate resources under TrustedComponent. For the
262proper URI structure for certificates, please refer to the [Redfish Data Model
263Specification][1]. Look for the CertificatesCollection row in the specification.
264
265- `/redfish/v1/Chassis/{ChassisId}/TrustedComponents/{TrustedComponentId}/`
266  `Certificates`
267- `/redfish/v1/Chassis/{ChassisId}/TrustedComponents/{TrustedComponentId}/`
268  `Certificates/{CertificateId}`
269
270On the D-Bus Daemon side, we propose that the dbus objects are organized in the
271following way:
272
273- `/xyz/openbmc_project/ComponentIntegrity/{ComponentIntegrityId}`
274- `/xyz/openbmc_project/TrustedComponents/{TrustedComponentId}`
275- `/xyz/openbmc_project/certs/devices/{ChassisId}/{CertId}`
276
277In BMCWeb, we can reconstruct the following redfish URI by querying the
278associated Chassis from the trusted component:
279
280- `/redfish/v1/Chassis/{ChassisId}/TrustedComponents/{TrustedComponentId}`
281
282## Alternatives Considered
283
284Alternative way to manage device certificates would be modifying existing
285[phosphor-certificate-manager](https://github.com/openbmc/phosphor-certificate-manager).
286
287Device certificates management has two steps:
288
289- Step 1: fetch device certificate by exchange SPDM messages with device.
290- Step 2: create or update a dbus certificate object.
291
292Step 1 can only be handled by the SPDM daemon. Step 2 is simple enough to be
293handled by the D-Bus daemon, too. It would be a over-kill to modify existing
294phosphor-certificate-manager for the sole purpose.
295
296## Impacts
297
298This change will:
299
300- Create a SPDM daemon that can do SPDM attestation for SPDM-capable devices
301  over PCIe DOE, MCTP or TCP.
302- Add `ComponentIntegrity` and `TrustedComponent` related D-Bus interfaces in
303  phosphor-dbus-interfaces.
304- Extend existing certificate service in BMCWeb.
305- Add SPDM support in BMCWeb with new routes.
306
307### Organizational
308
309This repository requires creating a new repository for the SPDM daemon. In
310addition, the following repositories are expected to be modified to execute this
311design:
312
313- <https://github.com/openbmc/bmcweb>
314- <https://github.com/openbmc/phosphor-dbus-interfaces>
315
316## Testing
317
318### Unit Test
319
320For the BMCWeb changes, unit test can be done with the Redfish Service
321Validator.
322
323For the SPDM Attestation D-Bus Daemon, unit tests should cover the following
324cases:
325
326- Set up a transport layer connection with the device.
327- Unit tests should be implemented to ensure the infrastructure functions
328  reliably, regardless of the underlying transport mechanisms.
329- SPDM connection setup, including get capabilities, negotiate algorithms.
330- Get device certificates from device and create D-Bus object.
331- `SPDMGetSignedMeasurements` method test.
332- Enumerate trusted component D-Bus objects and check properties and
333  associations.
334- Enumerate component integraty D-Bus objects and check properties and
335  associations.
336
337### Integration Test
338
339BMCWeb/D-Bus Daemon integration test should cover the following type of
340requests:
341
342- Get a collection of `ComponentIntegrity` resources.
343- Get a collection of `TrustedComponent` resource.
344- Get properties of a `ComponentIntegrity` resources.
345- Get properties of a `TrustedComponent` resource.
346- Follow the resouces link to get the device certificates and verify that they
347  are correctly structured as subordinate resources under the TrustedComponent.
348- Get properties of `Certificate` resource and verify responses match with leaf
349  certificate in the certificate chain.
350- Call Action on the `ComponentIntegrity` resource to get measurements.
351
352[1]:
353  https://www.dmtf.org/sites/default/files/standards/documents/DSP0268_2024.4.html#resource-collection-uris-in-redfish-v16-and-later
354