spdm: Introduce library to authenticate devices
The Security Protocol and Data Model (SPDM) allows for device
authentication, measurement, key exchange and encrypted sessions.
SPDM was conceived by the Distributed Management Task Force (DMTF).
Its specification defines a request/response protocol spoken between
host and attached devices over a variety of transports:
https://www.dmtf.org/dsp/DSP0274
This implementation supports SPDM 1.0 through 1.3 (the latest version).
It is designed to be transport-agnostic as the kernel already supports
four different SPDM-capable transports:
* PCIe Data Object Exchange, which is a mailbox in PCI config space
(PCIe r6.2 sec 6.30, drivers/pci/doe.c)
* Management Component Transport Protocol
(MCTP, Documentation/networking/mctp.rst)
* TCP/IP (in draft stage)
https://www.dmtf.org/sites/default/files/standards/documents/DSP0287_1.0.0WIP99.pdf
* SCSI and ATA (in draft stage)
"SECURITY PROTOCOL IN/OUT" and "TRUSTED SEND/RECEIVE" commands
Use cases for SPDM include, but are not limited to:
* PCIe Component Measurement and Authentication (PCIe r6.2 sec 6.31)
* Compute Express Link (CXL r3.0 sec 14.11.6)
* Open Compute Project (Attestation of System Components v1.0)
https://www.opencompute.org/documents/attestation-v1-0-20201104-pdf
* Open Compute Project (Datacenter NVMe SSD Specification v2.0)
https://www.opencompute.org/documents/datacenter-nvme-ssd-specification-v2-0r21-pdf
The initial focus of this implementation is enabling PCIe CMA device
authentication. As such, only a subset of the SPDM specification is
contained herein, namely the request/response sequence GET_VERSION,
GET_CAPABILITIES, NEGOTIATE_ALGORITHMS, GET_DIGESTS, GET_CERTIFICATE
and CHALLENGE.
This sequence first negotiates the SPDM protocol version, capabilities
and algorithms with the device. It then retrieves the up to eight
certificate chains which may be provisioned on the device. Finally it
performs challenge-response authentication with the device using one of
those eight certificate chains and the algorithms negotiated before.
The challenge-response authentication comprises computing a hash over
all exchanged messages to detect modification by a man-in-the-middle
or media error. The hash is then signed with the device's private key
and the resulting signature is verified by the kernel using the device's
public key from the certificate chain. Nonces are included in the
message sequence to protect against replay attacks.
A simple API is provided for subsystems wishing to authenticate devices:
spdm_create(), spdm_authenticate() (can be called repeatedly for
reauthentication) and spdm_destroy(). Certificates presented by devices
are validated against an in-kernel keyring of trusted root certificates.
A pointer to the keyring is passed to spdm_create().
The set of supported cryptographic algorithms is limited to those
declared mandatory in PCIe r6.2 sec 6.31.3. Adding more algorithms
is straightforward as long as the crypto subsystem supports them.
Future commits will extend this implementation with support for
measurement, key exchange and encrypted sessions.
So far, only the SPDM requester role is implemented. Care was taken to
allow for effortless addition of the responder role at a later stage.
This could be needed for a PCIe host bridge operating in endpoint mode.
The responder role will be able to reuse struct definitions and helpers
such as spdm_create_combined_prefix().
Credits: Jonathan wrote a proof-of-concept of this SPDM implementation.
Lukas reworked it for upstream.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Co-developed-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
8 files changed