@@ -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