Skip to content

Commit bca645e

Browse files
jic23l1k
authored andcommitted
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>
1 parent bf1aa3d commit bca645e

File tree

9 files changed

+1790
-0
lines changed

9 files changed

+1790
-0
lines changed

MAINTAINERS

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23621,6 +23621,17 @@ M: Security Officers <security@kernel.org>
2362123621
S: Supported
2362223622
F: Documentation/process/security-bugs.rst
2362323623

23624+
SECURITY PROTOCOL AND DATA MODEL (SPDM)
23625+
M: Jonathan Cameron <jic23@kernel.org>
23626+
M: Lukas Wunner <lukas@wunner.de>
23627+
L: linux-coco@lists.linux.dev
23628+
L: linux-cxl@vger.kernel.org
23629+
L: linux-pci@vger.kernel.org
23630+
S: Maintained
23631+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/devsec/spdm.git
23632+
F: include/linux/spdm.h
23633+
F: lib/spdm/
23634+
2362423635
SECURITY SUBSYSTEM
2362523636
M: Paul Moore <paul@paul-moore.com>
2362623637
M: James Morris <jmorris@namei.org>

include/linux/spdm.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* DMTF Security Protocol and Data Model (SPDM)
4+
* https://www.dmtf.org/dsp/DSP0274
5+
*
6+
* Copyright (C) 2021-22 Huawei
7+
* Jonathan Cameron <Jonathan.Cameron@huawei.com>
8+
*
9+
* Copyright (C) 2022-25 Intel Corporation
10+
*/
11+
12+
#ifndef _SPDM_H_
13+
#define _SPDM_H_
14+
15+
#include <linux/types.h>
16+
17+
struct key;
18+
struct device;
19+
struct spdm_state;
20+
21+
typedef ssize_t (spdm_transport)(void *priv, struct device *dev,
22+
const void *request, size_t request_sz,
23+
void *response, size_t response_sz);
24+
25+
struct spdm_state *spdm_create(struct device *dev, spdm_transport *transport,
26+
void *transport_priv, u32 transport_sz,
27+
struct key *keyring);
28+
29+
int spdm_authenticate(struct spdm_state *spdm_state);
30+
31+
void spdm_destroy(struct spdm_state *spdm_state);
32+
33+
#endif

include/uapi/linux/spdm.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2+
/*
3+
* DMTF Security Protocol and Data Model (SPDM)
4+
* https://www.dmtf.org/dsp/DSP0274
5+
*
6+
* Copyright (C) 2021-22 Huawei
7+
* Jonathan Cameron <Jonathan.Cameron@huawei.com>
8+
*
9+
* Copyright (C) 2022-25 Intel Corporation
10+
*/
11+
12+
#ifndef _UAPI_SPDM_H_
13+
#define _UAPI_SPDM_H_
14+
15+
enum spdm_reqrsp_code {
16+
SPDM_DIGESTS = 0x01, /* 1.0 */
17+
SPDM_CERTIFICATE = 0x02, /* 1.0 */
18+
SPDM_CHALLENGE_AUTH = 0x03, /* 1.0 */
19+
SPDM_VERSION = 0x04, /* 1.0 */
20+
SPDM_CHUNK_SEND_ACK = 0x05, /* 1.2 */
21+
SPDM_CHUNK_RSP = 0x06, /* 1.2 */
22+
SPDM_ENDPOINT_INFO = 0x07, /* 1.3 */
23+
SPDM_SLOT_MANAGEMENT_RSP = 0x08, /* 1.4 */
24+
SPDM_MEASUREMENTS = 0x60, /* 1.0 */
25+
SPDM_CAPABILITIES = 0x61, /* 1.0 */
26+
SPDM_SUPPORTED_EVENTS = 0x62, /* 1.3 */
27+
SPDM_ALGORITHMS = 0x63, /* 1.0 */
28+
SPDM_KEY_EXCHANGE_RSP = 0x64, /* 1.1 */
29+
SPDM_FINISH_RSP = 0x65, /* 1.1 */
30+
SPDM_PSK_EXCHANGE_RSP = 0x66, /* 1.1 */
31+
SPDM_PSK_FINISH_RSP = 0x67, /* 1.1 */
32+
SPDM_HEARTBEAT_ACK = 0x68, /* 1.1 */
33+
SPDM_KEY_UPDATE_ACK = 0x69, /* 1.1 */
34+
SPDM_ENCAP_REQ = 0x6a, /* 1.1 */
35+
SPDM_ENCAP_RSP_ACK = 0x6b, /* 1.1 */
36+
SPDM_END_SESSION_ACK = 0x6c, /* 1.1 */
37+
SPDM_CSR = 0x6d, /* 1.2 */
38+
SPDM_SET_CERTIFICATE_RSP = 0x6e, /* 1.2 */
39+
SPDM_MEAS_EXT_LOG = 0x6f, /* 1.3 */
40+
SPDM_SUBSCRIBE_EVENTS_ACK = 0x70, /* 1.3 */
41+
SPDM_EVENT_ACK = 0x71, /* 1.3 */
42+
SPDM_KEY_PAIR_INFO = 0x7c, /* 1.3 */
43+
SPDM_SET_KEY_PAIR_INFO_ACK = 0x7d, /* 1.3 */
44+
SPDM_VENDOR_RSP = 0x7e, /* 1.0 */
45+
SPDM_ERROR = 0x7f, /* 1.0 */
46+
47+
SPDM_REQ = 0x80,
48+
49+
SPDM_GET_DIGESTS = 0x81, /* 1.0 */
50+
SPDM_GET_CERTIFICATE = 0x82, /* 1.0 */
51+
SPDM_CHALLENGE = 0x83, /* 1.0 */
52+
SPDM_GET_VERSION = 0x84, /* 1.0 */
53+
SPDM_CHUNK_SEND = 0x85, /* 1.2 */
54+
SPDM_CHUNK_GET = 0x86, /* 1.2 */
55+
SPDM_GET_ENDPOINT_INFO = 0x87, /* 1.3 */
56+
SPDM_SLOT_MANAGEMENT = 0x88, /* 1.4 */
57+
SPDM_GET_MEASUREMENTS = 0xe0, /* 1.0 */
58+
SPDM_GET_CAPABILITIES = 0xe1, /* 1.0 */
59+
SPDM_GET_SUPP_EVENTS = 0xe2, /* 1.3 */
60+
SPDM_NEGOTIATE_ALGS = 0xe3, /* 1.0 */
61+
SPDM_KEY_EXCHANGE = 0xe4, /* 1.1 */
62+
SPDM_FINISH = 0xe5, /* 1.1 */
63+
SPDM_PSK_EXCHANGE = 0xe6, /* 1.1 */
64+
SPDM_PSK_FINISH = 0xe7, /* 1.1 */
65+
SPDM_HEARTBEAT = 0xe8, /* 1.1 */
66+
SPDM_KEY_UPDATE = 0xe9, /* 1.1 */
67+
SPDM_GET_ENCAP_REQ = 0xea, /* 1.1 */
68+
SPDM_DELIVER_ENCAP_RSP = 0xeb, /* 1.1 */
69+
SPDM_END_SESSION = 0xec, /* 1.1 */
70+
SPDM_GET_CSR = 0xed, /* 1.2 */
71+
SPDM_SET_CERTIFICATE = 0xee, /* 1.2 */
72+
SPDM_GET_MEAS_EXT_LOG = 0xef, /* 1.3 */
73+
SPDM_SUBSCRIBE_EVENTS = 0xf0, /* 1.3 */
74+
SPDM_SEND_EVENT = 0xf1, /* 1.3 */
75+
SPDM_GET_KEY_PAIR_INFO = 0xfc, /* 1.3 */
76+
SPDM_SET_KEY_PAIR_INFO = 0xfd, /* 1.3 */
77+
SPDM_VENDOR_REQ = 0xfe, /* 1.0 */
78+
SPDM_RESPOND_IF_READY = 0xff, /* 1.0 */
79+
};
80+
81+
#endif /* _UAPI_SPDM_H_ */

lib/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,3 +649,18 @@ config UNION_FIND
649649

650650
config MIN_HEAP
651651
bool
652+
653+
config SPDM
654+
tristate
655+
select CRYPTO
656+
select KEYS
657+
select ASYMMETRIC_KEY_TYPE
658+
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
659+
select X509_CERTIFICATE_PARSER
660+
help
661+
The Security Protocol and Data Model (SPDM) allows for device
662+
authentication, measurement, key exchange and encrypted sessions.
663+
664+
Crypto algorithms negotiated with SPDM are limited to those enabled
665+
in .config. Drivers selecting SPDM therefore need to also select
666+
any algorithms they deem mandatory.

lib/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ obj-$(CONFIG_PERCPU_TEST) += percpu_test.o
283283
obj-$(CONFIG_ASN1) += asn1_decoder.o
284284
obj-$(CONFIG_ASN1_ENCODER) += asn1_encoder.o
285285

286+
obj-$(CONFIG_SPDM) += spdm/
287+
286288
obj-$(CONFIG_FONT_SUPPORT) += fonts/
287289

288290
#

lib/spdm/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
#
3+
# DMTF Security Protocol and Data Model (SPDM)
4+
# https://www.dmtf.org/dsp/DSP0274
5+
#
6+
# Copyright (C) 2025 Intel Corporation
7+
8+
obj-$(CONFIG_SPDM) += spdm.o
9+
10+
spdm-y := core.o req-authenticate.o

0 commit comments

Comments
 (0)