Skip to content

Commit b5c28bb

Browse files
committed
spdm: Add support for key exchange
Signed-off-by: Jonathan Cameron <[email protected]> Signed-off-by: Lukas Wunner <[email protected]>
1 parent f87035c commit b5c28bb

File tree

2 files changed

+72
-5
lines changed

2 files changed

+72
-5
lines changed

lib/spdm/req-authenticate.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,21 +227,54 @@ static int spdm_negotiate_algs(struct spdm_state *spdm_state)
227227
struct spdm_negotiate_algs_req *req = spdm_state->transcript_end;
228228
struct spdm_negotiate_algs_rsp *rsp;
229229
struct spdm_req_alg_struct *req_alg_struct;
230-
size_t req_sz = sizeof(*req);
231-
size_t rsp_sz = sizeof(*rsp);
232-
int rc, length;
230+
size_t req_sz, rsp_sz;
231+
int rc, length, i = 0;
232+
233+
req_sz = sizeof(*req) +
234+
sizeof(*req_alg_struct) * SPDM_MAX_REQ_ALG_STRUCT;
233235

234236
/* Request length shall be <= 128 bytes (SPDM 1.1.0 margin no 185) */
235237
BUILD_BUG_ON(req_sz > 128);
236238

237239
*req = (struct spdm_negotiate_algs_req) {
238240
.code = SPDM_NEGOTIATE_ALGS,
239-
.length = cpu_to_le16(req_sz),
240241
.measurement_specification = SPDM_MEAS_SPEC_DMTF,
241242
.base_asym_algo = cpu_to_le32(SPDM_ASYM_ALGOS),
242243
.base_hash_algo = cpu_to_le32(SPDM_HASH_ALGOS),
243244
};
244245

246+
/*
247+
* Only OpaqueDataFmt1 is supported with SPDM 1.2 or later
248+
* (Secured Messages using SPDM Spec 1.1.0 margin no 118)
249+
*/
250+
if (spdm_state->version >= 0x12 &&
251+
spdm_state->rsp_caps & SPDM_KEY_EX_CAP)
252+
req->other_params_support = SPDM_OPAQUE_DATA_FMT_GENERAL;
253+
254+
req_alg_struct = (struct spdm_req_alg_struct *)(req + 1);
255+
if (spdm_state->rsp_caps & SPDM_KEY_EX_CAP) {
256+
req_alg_struct[i++] = (struct spdm_req_alg_struct) {
257+
.alg_type = SPDM_REQ_ALG_STRUCT_DHE,
258+
.alg_count = 0x20,
259+
.alg_supported = cpu_to_le16(SPDM_DHE_ALGOS),
260+
};
261+
req_alg_struct[i++] = (struct spdm_req_alg_struct) {
262+
.alg_type = SPDM_REQ_ALG_STRUCT_AEAD,
263+
.alg_count = 0x20,
264+
.alg_supported = cpu_to_le16(SPDM_AEAD_ALGOS),
265+
};
266+
req_alg_struct[i++] = (struct spdm_req_alg_struct) {
267+
.alg_type = SPDM_REQ_ALG_STRUCT_KEY_SCHEDULE,
268+
.alg_count = 0x20,
269+
.alg_supported = cpu_to_le16(SPDM_KEY_SCHEDULE_SPDM),
270+
};
271+
}
272+
WARN_ON(i > SPDM_MAX_REQ_ALG_STRUCT);
273+
req_sz = sizeof(*req) + i * sizeof(*req_alg_struct);
274+
rsp_sz = sizeof(*rsp) + i * sizeof(*req_alg_struct);
275+
req->length = cpu_to_le16(req_sz);
276+
req->param1 = i;
277+
245278
rsp = spdm_state->transcript_end += req_sz;
246279

247280
rc = spdm_exchange(spdm_state, req, req_sz, rsp, rsp_sz);
@@ -279,6 +312,7 @@ static int spdm_negotiate_algs(struct spdm_state *spdm_state)
279312
rsp->ext_asym_sel_count != 0 ||
280313
rsp->ext_hash_sel_count != 0 ||
281314
rsp->param1 > req->param1 ||
315+
rsp->other_params_sel != req->other_params_support ||
282316
(spdm_state->rsp_caps & SPDM_MEAS_CAP_MASK &&
283317
(hweight32(spdm_state->meas_hash_alg) != 1 ||
284318
rsp->measurement_specification_sel != SPDM_MEAS_SPEC_DMTF))) {

lib/spdm/spdm.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,31 @@
116116
#define SPDM_MEAS_HASH_SHA3_512 BIT(6) /* 1.0 */
117117
#define SPDM_MEAS_HASH_SM3_257 BIT(7) /* 1.2 */
118118

119+
/* SPDM Diffie-Hellman Ephemeral groups (SPDM 1.1.0 margin no 189) */
120+
#define SPDM_REQ_ALG_STRUCT_DHE 2 /* 1.1 */
121+
#define SPDM_DHE_FFDHE_2048 BIT(0) /* 1.1 */
122+
#define SPDM_DHE_FFDHE_3072 BIT(1) /* 1.1 */
123+
#define SPDM_DHE_FFDHE_4096 BIT(2) /* 1.1 */
124+
#define SPDM_DHE_SECP_256R1 BIT(3) /* 1.1 */
125+
#define SPDM_DHE_SECP_384R1 BIT(4) /* 1.1 */
126+
#define SPDM_DHE_SECP_521R1 BIT(5) /* 1.1 */
127+
#define SPDM_DHE_SM2_P256 BIT(6) /* 1.2 */
128+
129+
/* SPDM Authenticated Encryption w/ AD algorithms (SPDM 1.1.0 margin no 190) */
130+
#define SPDM_REQ_ALG_STRUCT_AEAD 3 /* 1.1 */
131+
#define SPDM_AEAD_AES_128_GCM BIT(0) /* 1.1 */
132+
#define SPDM_AEAD_AES_256_GCM BIT(1) /* 1.1 */
133+
#define SPDM_AEAD_CHACHA20_POLY1305 BIT(2) /* 1.1 */
134+
#define SPDM_AEAD_SM4_GCM BIT(3) /* 1.2 */
135+
136+
/* SPDM key schedule algorithms (SPDM 1.1.0 margin no 192) */
137+
#define SPDM_REQ_ALG_STRUCT_KEY_SCHEDULE 5 /* 1.1 */
138+
#define SPDM_KEY_SCHEDULE_SPDM BIT(0) /* 1.1 */
139+
140+
/* SPDM opaque data formats (SPDM 1.2.0 margin no 261) */
141+
#define SPDM_OPAQUE_DATA_FMT_VENDOR BIT(0) /* 1.2 */
142+
#define SPDM_OPAQUE_DATA_FMT_GENERAL BIT(1) /* 1.2 */
143+
119144
#if IS_ENABLED(CONFIG_CRYPTO_RSA)
120145
#define SPDM_ASYM_RSA SPDM_ASYM_RSASSA_2048 | \
121146
SPDM_ASYM_RSASSA_3072 | \
@@ -152,6 +177,14 @@
152177
#define SPDM_HASH_ALGOS (SPDM_HASH_SHA2_256 | \
153178
SPDM_HASH_SHA2_384_512)
154179

180+
#define SPDM_DHE_ALGOS (SPDM_DHE_FFDHE_2048 | \
181+
SPDM_DHE_FFDHE_3072 | \
182+
SPDM_DHE_SECP_256R1 | \
183+
SPDM_DHE_SECP_384R1)
184+
185+
#define SPDM_AEAD_ALGOS (SPDM_AEAD_AES_256_GCM | \
186+
SPDM_AEAD_CHACHA20_POLY1305)
187+
155188
/*
156189
* Common header shared by all messages.
157190
* Note that the meaning of param1 and param2 is message dependent.
@@ -288,7 +321,7 @@ struct spdm_negotiate_algs_rsp {
288321
} __packed;
289322

290323
/* Maximum number of ReqAlgStructs sent by this implementation */
291-
#define SPDM_MAX_REQ_ALG_STRUCT 0
324+
#define SPDM_MAX_REQ_ALG_STRUCT 3
292325

293326
struct spdm_req_alg_struct {
294327
u8 alg_type;

0 commit comments

Comments
 (0)