Skip to content

Commit f87035c

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

File tree

6 files changed

+53
-28
lines changed

6 files changed

+53
-28
lines changed

Documentation/ABI/testing/sysfs-devices-spdm

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ Description:
157157

158158
Note: To ease signature verification, the "transcript" file
159159
does not contain the trailing signature. However the signature
160-
is part of the final CHALLENGE_AUTH message, so the protocol
161-
dissector needs to be fed the concatenation of "transcript"
162-
and "signature".
160+
is part of the final CHALLENGE_AUTH or MEASUREMENT message,
161+
so the protocol dissector needs to be fed the concatenation of
162+
"transcript" and "signature".
163163

164164
Signatures are added to the log even if the kernel was unable
165165
to verify them (e.g. due to a missing trusted root certificate
@@ -190,6 +190,7 @@ Description:
190190
generation. It is one of (sans quotes):
191191

192192
"responder-challenge_auth signing"
193+
"responder-measurements signing"
193194

194195

195196
What: /sys/devices/.../signatures/[0-9]*_requester_nonce
@@ -223,13 +224,13 @@ Contact: Lukas Wunner <[email protected]>
223224
Description:
224225
If you do not trust the kernel to always use a fresh nonce,
225226
write 32 bytes to this file to set the requester nonce used
226-
in the next SPDM authentication sequence.
227+
in the next SPDM authentication or measurement sequence.
227228

228229
Meant for remote attestation services. You are responsible
229230
for providing a nonce with sufficient entropy. The kernel
230231
only uses the nonce once, so provide a new one every time
231-
you reauthenticate the device. If you do not provide a
232-
nonce, the kernel generates a random one.
232+
you reauthenticate or measure the device. If you do not
233+
provide a nonce, the kernel generates a random one.
233234

234235
After the nonce has been consumed, it becomes readable as
235236
the newest [0-9]*_requester_nonce, which proves its usage::

Documentation/admin-guide/sysctl/spdm.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ The log is meant for re-verification of signatures by remote attestation
2020
services which do not trust the kernel to have verified the signatures
2121
correctly or which want to apply policy constraints of their own.
2222
A signature is computed over the transcript (a concatenation of all
23-
SPDM messages exchanged with the device during an authentication
24-
sequence). The transcript can be a few kBytes or up to several MBytes
25-
in size, hence this parameter prevents the log from consuming too much
26-
memory.
23+
SPDM messages exchanged with the device during an authentication or
24+
measurement sequence). The transcript can be a few kBytes or up to
25+
several MBytes in size, hence this parameter prevents the log from
26+
consuming too much memory.
2727

2828
The kernel always stores the most recent signature in the log even if it
2929
exceeds ``max_signatures_size``. Additionally as many older signatures

lib/spdm/core.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ ssize_t spdm_exchange(struct spdm_state *spdm_state,
162162
* @spdm_state: SPDM session state
163163
*
164164
* Allocate a buffer to accommodate the concatenation of all SPDM messages
165-
* exchanged during an authentication sequence. Used to verify the signature,
166-
* as it is computed over the hashed transcript.
165+
* exchanged during an authentication or measurement sequence. Used to verify
166+
* the signature, as it is computed over the hashed transcript.
167167
*
168168
* Transcript size is initially one page. It grows by additional pages as
169169
* needed. Minimum size of an authentication sequence is 1k (only one slot
@@ -189,8 +189,9 @@ int spdm_alloc_transcript(struct spdm_state *spdm_state)
189189
*
190190
* @spdm_state: SPDM session state
191191
*
192-
* Free the transcript buffer after performing authentication. Reset the
193-
* pointer to the current end of transcript as well as the allocation size.
192+
* Free the transcript buffer after performing authentication or measurement.
193+
* Reset the pointer to the current end of transcript as well as the allocation
194+
* size.
194195
*/
195196
void spdm_free_transcript(struct spdm_state *spdm_state)
196197
{

lib/spdm/req-authenticate.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ static int spdm_negotiate_algs(struct spdm_state *spdm_state)
237237
*req = (struct spdm_negotiate_algs_req) {
238238
.code = SPDM_NEGOTIATE_ALGS,
239239
.length = cpu_to_le16(req_sz),
240+
.measurement_specification = SPDM_MEAS_SPEC_DMTF,
240241
.base_asym_algo = cpu_to_le32(SPDM_ASYM_ALGOS),
241242
.base_hash_algo = cpu_to_le32(SPDM_HASH_ALGOS),
242243
};
@@ -264,6 +265,7 @@ static int spdm_negotiate_algs(struct spdm_state *spdm_state)
264265

265266
spdm_state->base_asym_alg = le32_to_cpu(rsp->base_asym_sel);
266267
spdm_state->base_hash_alg = le32_to_cpu(rsp->base_hash_sel);
268+
spdm_state->meas_hash_alg = le32_to_cpu(rsp->measurement_hash_algo);
267269

268270
if ((spdm_state->base_asym_alg & SPDM_ASYM_ALGOS) == 0 ||
269271
(spdm_state->base_hash_alg & SPDM_HASH_ALGOS) == 0) {
@@ -276,7 +278,10 @@ static int spdm_negotiate_algs(struct spdm_state *spdm_state)
276278
hweight32(spdm_state->base_hash_alg) != 1 ||
277279
rsp->ext_asym_sel_count != 0 ||
278280
rsp->ext_hash_sel_count != 0 ||
279-
rsp->param1 > req->param1) {
281+
rsp->param1 > req->param1 ||
282+
(spdm_state->rsp_caps & SPDM_MEAS_CAP_MASK &&
283+
(hweight32(spdm_state->meas_hash_alg) != 1 ||
284+
rsp->measurement_specification_sel != SPDM_MEAS_SPEC_DMTF))) {
280285
dev_err(spdm_state->dev, "Malformed algorithms response\n");
281286
return -EPROTO;
282287
}

lib/spdm/req-sysfs.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,9 @@ static unsigned int spdm_max_log_sz = SZ_16M; /* per device */
231231
* @req_nonce: sysfs attribute of requester nonce (located within transcript).
232232
* @rsp_nonce: sysfs attribute of responder nonce (located within transcript).
233233
* @transcript: sysfs attribute of transcript (concatenation of all SPDM
234-
* messages exchanged during an authentication sequence) sans trailing
235-
* signature (to simplify signature verification by user space).
234+
* messages exchanged during an authentication or measurement sequence)
235+
* sans trailing signature (to simplify signature verification by user
236+
* space).
236237
* @combined_prefix: sysfs attribute of combined_spdm_prefix
237238
* (SPDM 1.2.0 margin no 806, needed to verify signature).
238239
* @spdm_context: sysfs attribute of spdm_context
@@ -405,9 +406,9 @@ static void spdm_shrink_log(struct spdm_state *spdm_state)
405406
* @req_nonce_off: Requester nonce offset within the transcript
406407
* @rsp_nonce_off: Responder nonce offset within the transcript
407408
*
408-
* Allocate and populate a struct spdm_log_entry upon device authentication.
409-
* Publish it in sysfs if the device has already been registered through
410-
* device_add().
409+
* Allocate and populate a struct spdm_log_entry upon device authentication or
410+
* measurement. Publish it in sysfs if the device has already been registered
411+
* through device_add().
411412
*/
412413
void spdm_create_log_entry(struct spdm_state *spdm_state,
413414
const char *spdm_context, u8 slot,
@@ -519,10 +520,11 @@ void spdm_create_log_entry(struct spdm_state *spdm_state,
519520
* @spdm_state: SPDM session state
520521
*
521522
* sysfs attributes representing received SPDM signatures are not static,
522-
* but created dynamically upon authentication. If a device was authenticated
523-
* before it became visible in sysfs, the attributes could not be created.
524-
* This function retroactively creates those attributes in sysfs after the
525-
* device has become visible through device_add().
523+
* but created dynamically upon authentication or measurement. If a device
524+
* was authenticated or measured before it became visible in sysfs, the
525+
* attributes could not be created. This function retroactively creates
526+
* those attributes in sysfs after the device has become visible through
527+
* device_add().
526528
*/
527529
void spdm_publish_log(struct spdm_state *spdm_state)
528530
{

lib/spdm/spdm.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,19 @@
103103
#define SPDM_HASH_SHA3_512 BIT(5) /* 1.0 */
104104
#define SPDM_HASH_SM3_256 BIT(6) /* 1.2 */
105105

106+
/* SPDM measurement specifications (SPDM 1.0.0 sec 4.10.1.3) */
107+
#define SPDM_MEAS_SPEC_DMTF BIT(0) /* 1.0 */
108+
109+
/* SPDM measurement hash algorithms (SPDM 1.0.0 table 14) */
110+
#define SPDM_MEAS_HASH_RAW BIT(0) /* 1.0 */
111+
#define SPDM_MEAS_HASH_SHA_256 BIT(1) /* 1.0 */
112+
#define SPDM_MEAS_HASH_SHA_384 BIT(2) /* 1.0 */
113+
#define SPDM_MEAS_HASH_SHA_512 BIT(3) /* 1.0 */
114+
#define SPDM_MEAS_HASH_SHA3_256 BIT(4) /* 1.0 */
115+
#define SPDM_MEAS_HASH_SHA3_384 BIT(5) /* 1.0 */
116+
#define SPDM_MEAS_HASH_SHA3_512 BIT(6) /* 1.0 */
117+
#define SPDM_MEAS_HASH_SM3_257 BIT(7) /* 1.2 */
118+
106119
#if IS_ENABLED(CONFIG_CRYPTO_RSA)
107120
#define SPDM_ASYM_RSA SPDM_ASYM_RSASSA_2048 | \
108121
SPDM_ASYM_RSASSA_3072 | \
@@ -433,10 +446,12 @@ struct spdm_error_rsp {
433446
* @rsp_caps: Cached capabilities of responder.
434447
* Received during GET_CAPABILITIES exchange.
435448
* @base_asym_alg: Asymmetric key algorithm for signature verification of
436-
* CHALLENGE_AUTH messages.
449+
* CHALLENGE_AUTH and MEASUREMENTS messages.
437450
* Selected by responder during NEGOTIATE_ALGORITHMS exchange.
438451
* @base_hash_alg: Hash algorithm for signature verification of
439-
* CHALLENGE_AUTH messages.
452+
* CHALLENGE_AUTH and MEASUREMENTS messages.
453+
* Selected by responder during NEGOTIATE_ALGORITHMS exchange.
454+
* @meas_hash_alg: Hash algorithm for measurement blocks.
440455
* Selected by responder during NEGOTIATE_ALGORITHMS exchange.
441456
* @supported_slots: Bitmask of responder's supported certificate slots.
442457
* Received during GET_DIGESTS exchange (from SPDM 1.3).
@@ -462,8 +477,8 @@ struct spdm_error_rsp {
462477
* responder's certificate chain.
463478
* @validate: Function to validate additional leaf certificate requirements.
464479
* @transcript: Concatenation of all SPDM messages exchanged during an
465-
* authentication sequence. Used to verify the signature, as it is
466-
* computed over the hashed transcript.
480+
* authentication or measurement sequence. Used to verify the signature,
481+
* as it is computed over the hashed transcript.
467482
* @transcript_end: Pointer into the @transcript buffer. Marks the current
468483
* end of transcript. If another message is transmitted, it is appended
469484
* at this position.
@@ -495,6 +510,7 @@ struct spdm_state {
495510
u32 rsp_caps;
496511
u32 base_asym_alg;
497512
u32 base_hash_alg;
513+
u32 meas_hash_alg;
498514
unsigned long supported_slots;
499515
unsigned long provisioned_slots;
500516

0 commit comments

Comments
 (0)