Skip to content

Commit 12cbb6b

Browse files
authored
Merge pull request #2 from aidangarske/novoton-support-refactor
Fix SPDM Nuvoton session establishment and refactor
2 parents 128fe28 + 588afe9 commit 12cbb6b

8 files changed

Lines changed: 331 additions & 204 deletions

File tree

src/spdm_crypto.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ int wolfSPDM_ComputeSharedSecret(WOLFSPDM_CTX* ctx,
171171

172172
wolfSPDM_DebugPrint(ctx, "ECDH shared secret computed (%u bytes)\n",
173173
ctx->sharedSecretSz);
174-
wolfSPDM_DebugHex(ctx, "Z.x", ctx->sharedSecret, ctx->sharedSecretSz);
175174

176175
rc = 0;
177176

@@ -262,7 +261,6 @@ int wolfSPDM_SignHash(WOLFSPDM_CTX* ctx, const byte* hash, word32 hashSz,
262261
*sigSz = WOLFSPDM_ECC_POINT_SIZE; /* 96 bytes */
263262

264263
wolfSPDM_DebugPrint(ctx, "Signed hash with P-384 key (sig=%u bytes)\n", *sigSz);
265-
wolfSPDM_DebugHex(ctx, "Signature", sig, *sigSz);
266264

267265
rc = 0;
268266

src/spdm_internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ struct WOLFSPDM_CTX {
101101
byte spdmVersion; /* Negotiated SPDM version */
102102
word32 rspCaps; /* Responder capabilities */
103103
word32 reqCaps; /* Our (requester) capabilities */
104+
byte mutAuthRequested; /* MutAuthRequested from KEY_EXCHANGE_RSP (offset 6) */
105+
byte reqSlotId; /* ReqSlotIDParam from KEY_EXCHANGE_RSP (offset 7) */
104106

105107
/* Ephemeral ECDHE key (generated for KEY_EXCHANGE) */
106108
ecc_key ephemeralKey;
@@ -211,6 +213,9 @@ int wolfSPDM_SignHash(WOLFSPDM_CTX* ctx, const byte* hash, word32 hashSz,
211213
/* Derive all keys from shared secret and TH1 */
212214
int wolfSPDM_DeriveHandshakeKeys(WOLFSPDM_CTX* ctx, const byte* th1Hash);
213215

216+
/* Derive application data keys from MasterSecret and TH2_final */
217+
int wolfSPDM_DeriveAppDataKeys(WOLFSPDM_CTX* ctx);
218+
214219
/* HKDF-Expand with SPDM BinConcat format (uses version-specific prefix) */
215220
int wolfSPDM_HkdfExpandLabel(byte spdmVersion, const byte* secret, word32 secretSz,
216221
const char* label, const byte* context, word32 contextSz,

src/spdm_kdf.c

Lines changed: 89 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -128,31 +128,20 @@ int wolfSPDM_DeriveHandshakeKeys(WOLFSPDM_CTX* ctx, const byte* th1Hash)
128128
return WOLFSPDM_E_CRYPTO_FAIL;
129129
}
130130

131-
wolfSPDM_DebugHex(ctx, "HandshakeSecret", ctx->handshakeSecret,
132-
WOLFSPDM_HASH_SIZE);
133-
wolfSPDM_DebugHex(ctx, "TH1 context for key derivation", th1Hash,
134-
WOLFSPDM_HASH_SIZE);
135-
136131
/* reqHsSecret = HKDF-Expand(HS, "req hs data" || TH1, 48) */
137132
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, ctx->handshakeSecret,
138133
WOLFSPDM_HASH_SIZE, SPDM_LABEL_REQ_HS_DATA, th1Hash, WOLFSPDM_HASH_SIZE,
139134
ctx->reqHsSecret, WOLFSPDM_HASH_SIZE);
140135
if (rc != WOLFSPDM_SUCCESS) {
141136
return rc;
142137
}
143-
wolfSPDM_DebugHex(ctx, "reqHsSecret (intermediate)", ctx->reqHsSecret,
144-
WOLFSPDM_HASH_SIZE);
145-
146138
/* rspHsSecret = HKDF-Expand(HS, "rsp hs data" || TH1, 48) */
147139
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, ctx->handshakeSecret,
148140
WOLFSPDM_HASH_SIZE, SPDM_LABEL_RSP_HS_DATA, th1Hash, WOLFSPDM_HASH_SIZE,
149141
ctx->rspHsSecret, WOLFSPDM_HASH_SIZE);
150142
if (rc != WOLFSPDM_SUCCESS) {
151143
return rc;
152144
}
153-
wolfSPDM_DebugHex(ctx, "rspHsSecret (intermediate)", ctx->rspHsSecret,
154-
WOLFSPDM_HASH_SIZE);
155-
156145
/* Finished keys (used for VerifyData HMAC) */
157146
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, ctx->reqHsSecret,
158147
WOLFSPDM_HASH_SIZE, SPDM_LABEL_FINISHED, NULL, 0,
@@ -169,8 +158,6 @@ int wolfSPDM_DeriveHandshakeKeys(WOLFSPDM_CTX* ctx, const byte* th1Hash)
169158
}
170159

171160
/* Data encryption keys (AES-256-GCM) */
172-
wolfSPDM_DebugHex(ctx, "PRK for reqDataKey (reqHsSecret)", ctx->reqHsSecret,
173-
WOLFSPDM_HASH_SIZE);
174161
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, ctx->reqHsSecret,
175162
WOLFSPDM_HASH_SIZE, SPDM_LABEL_KEY, NULL, 0,
176163
ctx->reqDataKey, WOLFSPDM_AEAD_KEY_SIZE);
@@ -200,10 +187,95 @@ int wolfSPDM_DeriveHandshakeKeys(WOLFSPDM_CTX* ctx, const byte* th1Hash)
200187
return rc;
201188
}
202189

203-
wolfSPDM_DebugHex(ctx, "reqDataKey", ctx->reqDataKey, WOLFSPDM_AEAD_KEY_SIZE);
204-
wolfSPDM_DebugHex(ctx, "reqDataIV", ctx->reqDataIv, WOLFSPDM_AEAD_IV_SIZE);
205-
wolfSPDM_DebugHex(ctx, "reqFinishedKey", ctx->reqFinishedKey, WOLFSPDM_HASH_SIZE);
206-
wolfSPDM_DebugHex(ctx, "rspFinishedKey", ctx->rspFinishedKey, WOLFSPDM_HASH_SIZE);
190+
return WOLFSPDM_SUCCESS;
191+
}
192+
193+
int wolfSPDM_DeriveAppDataKeys(WOLFSPDM_CTX* ctx)
194+
{
195+
byte th2Hash[WOLFSPDM_HASH_SIZE];
196+
byte salt[WOLFSPDM_HASH_SIZE];
197+
byte masterSecret[WOLFSPDM_HASH_SIZE];
198+
byte reqAppSecret[WOLFSPDM_HASH_SIZE];
199+
byte rspAppSecret[WOLFSPDM_HASH_SIZE];
200+
byte zeroIkm[WOLFSPDM_HASH_SIZE];
201+
int rc;
202+
203+
if (ctx == NULL) {
204+
return WOLFSPDM_E_INVALID_ARG;
205+
}
206+
207+
/* Compute TH2_final = Hash(full transcript including FINISH + FINISH_RSP) */
208+
rc = wolfSPDM_TranscriptHash(ctx, th2Hash);
209+
if (rc != WOLFSPDM_SUCCESS) {
210+
return rc;
211+
}
212+
/* salt = HKDF-Expand(HandshakeSecret, BinConcat("derived"), 48)
213+
* Per DSP0277: "derived" label has NO context (unlike TLS 1.3 which uses Hash(""))
214+
* libspdm confirms: bin_concat("derived", context=NULL) */
215+
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, ctx->handshakeSecret,
216+
WOLFSPDM_HASH_SIZE, "derived", NULL, 0,
217+
salt, WOLFSPDM_HASH_SIZE);
218+
if (rc != WOLFSPDM_SUCCESS) {
219+
return rc;
220+
}
221+
222+
/* MasterSecret = HKDF-Extract(salt, 0^hashSize) */
223+
XMEMSET(zeroIkm, 0, sizeof(zeroIkm));
224+
rc = wc_HKDF_Extract(WC_SHA384, salt, WOLFSPDM_HASH_SIZE,
225+
zeroIkm, WOLFSPDM_HASH_SIZE, masterSecret);
226+
if (rc != 0) {
227+
return WOLFSPDM_E_CRYPTO_FAIL;
228+
}
229+
/* reqAppSecret = HKDF-Expand(MasterSecret, "req app data" || TH2, 48) */
230+
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, masterSecret,
231+
WOLFSPDM_HASH_SIZE, SPDM_LABEL_REQ_DATA, th2Hash, WOLFSPDM_HASH_SIZE,
232+
reqAppSecret, WOLFSPDM_HASH_SIZE);
233+
if (rc != WOLFSPDM_SUCCESS) {
234+
return rc;
235+
}
236+
237+
/* rspAppSecret = HKDF-Expand(MasterSecret, "rsp app data" || TH2, 48) */
238+
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, masterSecret,
239+
WOLFSPDM_HASH_SIZE, SPDM_LABEL_RSP_DATA, th2Hash, WOLFSPDM_HASH_SIZE,
240+
rspAppSecret, WOLFSPDM_HASH_SIZE);
241+
if (rc != WOLFSPDM_SUCCESS) {
242+
return rc;
243+
}
244+
245+
/* Derive new encryption keys from app data secrets */
246+
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, reqAppSecret,
247+
WOLFSPDM_HASH_SIZE, SPDM_LABEL_KEY, NULL, 0,
248+
ctx->reqDataKey, WOLFSPDM_AEAD_KEY_SIZE);
249+
if (rc != WOLFSPDM_SUCCESS) {
250+
return rc;
251+
}
252+
253+
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, rspAppSecret,
254+
WOLFSPDM_HASH_SIZE, SPDM_LABEL_KEY, NULL, 0,
255+
ctx->rspDataKey, WOLFSPDM_AEAD_KEY_SIZE);
256+
if (rc != WOLFSPDM_SUCCESS) {
257+
return rc;
258+
}
259+
260+
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, reqAppSecret,
261+
WOLFSPDM_HASH_SIZE, SPDM_LABEL_IV, NULL, 0,
262+
ctx->reqDataIv, WOLFSPDM_AEAD_IV_SIZE);
263+
if (rc != WOLFSPDM_SUCCESS) {
264+
return rc;
265+
}
266+
267+
rc = wolfSPDM_HkdfExpandLabel(ctx->spdmVersion, rspAppSecret,
268+
WOLFSPDM_HASH_SIZE, SPDM_LABEL_IV, NULL, 0,
269+
ctx->rspDataIv, WOLFSPDM_AEAD_IV_SIZE);
270+
if (rc != WOLFSPDM_SUCCESS) {
271+
return rc;
272+
}
273+
274+
/* Reset sequence numbers for application phase */
275+
ctx->reqSeqNum = 0;
276+
ctx->rspSeqNum = 0;
277+
278+
wolfSPDM_DebugPrint(ctx, "App data keys derived, seq nums reset to 0\n");
207279

208280
return WOLFSPDM_SUCCESS;
209281
}

0 commit comments

Comments
 (0)