4545#include <wolfssl/wolfcrypt/kdf.h>
4646#include <wolfssl/wolfcrypt/aes.h>
4747#include <wolfssl/wolfcrypt/memory.h>
48+ #include <wolfssl/wolfcrypt/asn_public.h>
4849
4950#ifdef __cplusplus
5051extern "C" {
@@ -64,6 +65,23 @@ extern "C" {
6465#define WOLFSPDM_STATE_FINISH 7 /* FINISH complete */
6566#define WOLFSPDM_STATE_CONNECTED 8 /* Session established */
6667#define WOLFSPDM_STATE_ERROR 9 /* Error state */
68+ #ifndef NO_WOLFSPDM_MEAS
69+ #define WOLFSPDM_STATE_MEASURED 10 /* Measurements retrieved */
70+ #endif
71+
72+ /* ==========================================================================
73+ * Measurement Block Structure
74+ * ========================================================================== */
75+
76+ #ifndef NO_WOLFSPDM_MEAS
77+ typedef struct WOLFSPDM_MEAS_BLOCK {
78+ byte index ; /* SPDM measurement index (1-based) */
79+ byte measurementSpec ; /* Measurement specification (1=DMTF) */
80+ byte dmtfType ; /* DMTFSpecMeasurementValueType */
81+ word16 valueSize ; /* Actual value size in bytes */
82+ byte value [WOLFSPDM_MAX_MEAS_VALUE_SIZE ]; /* Measurement value (digest/raw) */
83+ } WOLFSPDM_MEAS_BLOCK ;
84+ #endif /* !NO_WOLFSPDM_MEAS */
6785
6886/* ==========================================================================
6987 * Internal Context Structure
@@ -117,6 +135,7 @@ struct WOLFSPDM_CTX {
117135 /* Transcript hash for TH1/TH2 computation */
118136 byte transcript [WOLFSPDM_MAX_TRANSCRIPT ];
119137 word32 transcriptLen ;
138+ word32 vcaLen ; /* VCA transcript size (after ALGORITHMS, used by measurement sig) */
120139
121140 /* Certificate chain buffer for Ct computation */
122141 byte certChain [WOLFSPDM_MAX_CERT_CHAIN ];
@@ -164,6 +183,52 @@ struct WOLFSPDM_CTX {
164183 /* Message buffers */
165184 byte sendBuf [WOLFSPDM_MAX_MSG_SIZE + WOLFSPDM_AEAD_TAG_SIZE ];
166185 byte recvBuf [WOLFSPDM_MAX_MSG_SIZE + WOLFSPDM_AEAD_TAG_SIZE ];
186+
187+ #ifndef NO_WOLFSPDM_MEAS
188+ /* Measurement data */
189+ WOLFSPDM_MEAS_BLOCK measBlocks [WOLFSPDM_MAX_MEAS_BLOCKS ];
190+ word32 measBlockCount ;
191+ byte measNonce [32 ]; /* Nonce for signed measurements */
192+ byte measSummaryHash [WOLFSPDM_HASH_SIZE ]; /* Summary hash from response */
193+ byte measSignature [WOLFSPDM_ECC_SIG_SIZE ]; /* Captured signature (96 bytes P-384) */
194+ word32 measSignatureSize ; /* 0 if unsigned, 96 if signed */
195+ int hasMeasurements ;
196+
197+ #ifndef NO_WOLFSPDM_MEAS_VERIFY
198+ /* Saved GET_MEASUREMENTS request for L1/L2 transcript */
199+ byte measReqMsg [48 ]; /* Saved request (max 37 bytes) */
200+ word32 measReqMsgSz ;
201+ #endif /* !NO_WOLFSPDM_MEAS_VERIFY */
202+ #endif /* !NO_WOLFSPDM_MEAS */
203+
204+ /* Responder identity for signature verification (measurements + challenge) */
205+ ecc_key responderPubKey ; /* Extracted from cert chain leaf */
206+ int hasResponderPubKey ; /* 1 if key extracted successfully */
207+
208+ /* Certificate chain validation */
209+ byte trustedCAs [WOLFSPDM_MAX_CERT_CHAIN ]; /* DER-encoded root CAs */
210+ word32 trustedCAsSz ;
211+ int hasTrustedCAs ; /* 1 if CAs loaded */
212+
213+ #ifndef NO_WOLFSPDM_CHALLENGE
214+ /* Challenge authentication */
215+ byte challengeNonce [32 ]; /* Saved nonce from CHALLENGE request */
216+ byte challengeMeasHashType ; /* MeasurementSummaryHashType from req */
217+
218+ /* Running M1/M2 hash for CHALLENGE_AUTH signature verification.
219+ * Per DSP0274, M1/M2 = A || B || C where:
220+ * A = VCA (GET_VERSION..ALGORITHMS)
221+ * B = GET_DIGESTS + DIGESTS + GET_CERTIFICATE + CERTIFICATE (all chunks)
222+ * C = CHALLENGE + CHALLENGE_AUTH (before sig)
223+ * This hash accumulates A+B during NegAlgo/GetDigests/GetCertificate,
224+ * then C is added in VerifyChallengeAuthSig. */
225+ wc_Sha384 m1m2Hash ;
226+ int m1m2HashInit ; /* 1 if m1m2Hash is initialized */
227+ #endif
228+
229+ /* Key update state — app secrets for re-derivation */
230+ byte reqAppSecret [WOLFSPDM_HASH_SIZE ]; /* 48 bytes */
231+ byte rspAppSecret [WOLFSPDM_HASH_SIZE ]; /* 48 bytes */
167232};
168233
169234/* ==========================================================================
@@ -315,6 +380,81 @@ void wolfSPDM_DebugPrint(WOLFSPDM_CTX* ctx, const char* fmt, ...);
315380void wolfSPDM_DebugHex (WOLFSPDM_CTX * ctx , const char * label ,
316381 const byte * data , word32 len );
317382
383+ /* ==========================================================================
384+ * Internal Function Declarations - Measurements
385+ * ========================================================================== */
386+
387+ #ifndef NO_WOLFSPDM_MEAS
388+ /* Build GET_MEASUREMENTS request */
389+ int wolfSPDM_BuildGetMeasurements (WOLFSPDM_CTX * ctx , byte * buf , word32 * bufSz ,
390+ byte operation , byte requestSig );
391+
392+ /* Parse MEASUREMENTS response */
393+ int wolfSPDM_ParseMeasurements (WOLFSPDM_CTX * ctx , const byte * buf , word32 bufSz );
394+
395+ #ifndef NO_WOLFSPDM_MEAS_VERIFY
396+ /* Verify measurement signature (L1/L2 transcript) */
397+ int wolfSPDM_VerifyMeasurementSig (WOLFSPDM_CTX * ctx ,
398+ const byte * rspBuf , word32 rspBufSz ,
399+ const byte * reqMsg , word32 reqMsgSz );
400+ #endif /* !NO_WOLFSPDM_MEAS_VERIFY */
401+ #endif /* !NO_WOLFSPDM_MEAS */
402+
403+ /* ==========================================================================
404+ * Internal Function Declarations - Certificate Chain Validation
405+ * ========================================================================== */
406+
407+ /* Extract responder's public key from certificate chain leaf cert */
408+ int wolfSPDM_ExtractResponderPubKey (WOLFSPDM_CTX * ctx );
409+
410+ /* Validate certificate chain using trusted CAs and extract public key */
411+ int wolfSPDM_ValidateCertChain (WOLFSPDM_CTX * ctx );
412+
413+ /* ==========================================================================
414+ * Internal Function Declarations - Challenge
415+ * ========================================================================== */
416+
417+ #ifndef NO_WOLFSPDM_CHALLENGE
418+ /* Build CHALLENGE request */
419+ int wolfSPDM_BuildChallenge (WOLFSPDM_CTX * ctx , byte * buf , word32 * bufSz ,
420+ int slotId , byte measHashType );
421+
422+ /* Parse CHALLENGE_AUTH response */
423+ int wolfSPDM_ParseChallengeAuth (WOLFSPDM_CTX * ctx , const byte * buf ,
424+ word32 bufSz , word32 * sigOffset );
425+
426+ /* Verify CHALLENGE_AUTH signature */
427+ int wolfSPDM_VerifyChallengeAuthSig (WOLFSPDM_CTX * ctx ,
428+ const byte * rspBuf , word32 rspBufSz ,
429+ const byte * reqMsg , word32 reqMsgSz , word32 sigOffset );
430+ #endif /* !NO_WOLFSPDM_CHALLENGE */
431+
432+ /* ==========================================================================
433+ * Internal Function Declarations - Heartbeat
434+ * ========================================================================== */
435+
436+ /* Build HEARTBEAT request */
437+ int wolfSPDM_BuildHeartbeat (WOLFSPDM_CTX * ctx , byte * buf , word32 * bufSz );
438+
439+ /* Parse HEARTBEAT_ACK response */
440+ int wolfSPDM_ParseHeartbeatAck (WOLFSPDM_CTX * ctx , const byte * buf ,
441+ word32 bufSz );
442+
443+ /* ==========================================================================
444+ * Internal Function Declarations - Key Update
445+ * ========================================================================== */
446+
447+ /* Build KEY_UPDATE request */
448+ int wolfSPDM_BuildKeyUpdate (WOLFSPDM_CTX * ctx , byte * buf , word32 * bufSz ,
449+ byte operation , byte * tag );
450+
451+ /* Parse KEY_UPDATE_ACK response */
452+ int wolfSPDM_ParseKeyUpdateAck (WOLFSPDM_CTX * ctx , const byte * buf ,
453+ word32 bufSz , byte operation , byte tag );
454+
455+ /* Derive updated keys from saved app secrets */
456+ int wolfSPDM_DeriveUpdatedKeys (WOLFSPDM_CTX * ctx , int updateAll );
457+
318458#ifdef __cplusplus
319459}
320460#endif
0 commit comments