/src/spdm-rs/spdmlib/src/responder/finish_rsp.rs
Line | Count | Source |
1 | | // Copyright (c) 2020 Intel Corporation |
2 | | // |
3 | | // SPDX-License-Identifier: Apache-2.0 or MIT |
4 | | |
5 | | use crate::common::session::SpdmSession; |
6 | | use crate::common::{ManagedBuffer12Sign, SpdmCodec, SpdmOpaqueStruct, MAX_SPDM_OPAQUE_SIZE}; |
7 | | use crate::crypto; |
8 | | use crate::error::*; |
9 | | use crate::message::*; |
10 | | use crate::protocol::*; |
11 | | use crate::responder::*; |
12 | | extern crate alloc; |
13 | | use alloc::boxed::Box; |
14 | | |
15 | | impl ResponderContext { |
16 | 0 | pub fn handle_spdm_finish<'a>( |
17 | 0 | &mut self, |
18 | 0 | session_id: u32, |
19 | 0 | bytes: &[u8], |
20 | 0 | writer: &'a mut Writer, |
21 | 0 | ) -> (SpdmResult, Option<&'a [u8]>) { |
22 | | #[cfg(feature = "mandatory-mut-auth")] |
23 | | if !self.common.mut_auth_done { |
24 | | if let Some(session) = self.common.get_session_via_id(session_id) { |
25 | | session.teardown(); |
26 | | } |
27 | | return (Ok(()), None); |
28 | | } |
29 | | |
30 | 0 | let (result, rsp_slice) = self.write_spdm_finish_response(session_id, bytes, writer); |
31 | 0 | if result.is_err() { |
32 | 0 | if let Some(session) = self.common.get_session_via_id(session_id) { |
33 | 0 | session.teardown(); |
34 | 0 | } |
35 | 0 | } |
36 | | |
37 | 0 | (result, rsp_slice) |
38 | 0 | } |
39 | | |
40 | | // Return true on success, false otherwise. |
41 | 0 | pub fn write_spdm_finish_response<'a>( |
42 | 0 | &mut self, |
43 | 0 | session_id: u32, |
44 | 0 | bytes: &[u8], |
45 | 0 | writer: &'a mut Writer, |
46 | 0 | ) -> (SpdmResult, Option<&'a [u8]>) { |
47 | 0 | let mut reader = Reader::init(bytes); |
48 | 0 | let message_header = SpdmMessageHeader::read(&mut reader); |
49 | 0 | if let Some(message_header) = message_header { |
50 | 0 | if message_header.version != self.common.negotiate_info.spdm_version_sel { |
51 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorVersionMismatch, 0, writer); |
52 | 0 | return ( |
53 | 0 | Err(SPDM_STATUS_INVALID_MSG_FIELD), |
54 | 0 | Some(writer.used_slice()), |
55 | 0 | ); |
56 | 0 | } |
57 | | } else { |
58 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorInvalidRequest, 0, writer); |
59 | 0 | return ( |
60 | 0 | Err(SPDM_STATUS_INVALID_MSG_FIELD), |
61 | 0 | Some(writer.used_slice()), |
62 | 0 | ); |
63 | | } |
64 | | |
65 | 0 | self.common.reset_buffer_via_request_code( |
66 | 0 | SpdmRequestResponseCode::SpdmRequestFinish, |
67 | 0 | Some(session_id), |
68 | | ); |
69 | | |
70 | 0 | let finish_req = SpdmFinishRequestPayload::spdm_read(&mut self.common, &mut reader); |
71 | 0 | if let Some(finish_req) = &finish_req { |
72 | 0 | debug!("!!! finish req : {:02x?}\n", finish_req); |
73 | | } else { |
74 | 0 | error!("!!! finish req : fail !!!\n"); |
75 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorInvalidRequest, 0, writer); |
76 | 0 | return ( |
77 | 0 | Err(SPDM_STATUS_INVALID_MSG_FIELD), |
78 | 0 | Some(writer.used_slice()), |
79 | 0 | ); |
80 | | } |
81 | 0 | let finish_req = finish_req.unwrap(); |
82 | | |
83 | 0 | let opaque_total_size = |
84 | 0 | if self.common.negotiate_info.spdm_version_sel >= SpdmVersion::SpdmVersion14 { |
85 | 0 | 2 + finish_req.opaque.data_size as usize |
86 | | } else { |
87 | 0 | 0usize |
88 | | }; |
89 | | |
90 | 0 | if self |
91 | 0 | .common |
92 | 0 | .append_message_f(false, session_id, &bytes[..4 + opaque_total_size]) |
93 | 0 | .is_err() |
94 | | { |
95 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
96 | 0 | return ( |
97 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
98 | 0 | Some(writer.used_slice()), |
99 | 0 | ); |
100 | 0 | } |
101 | | |
102 | 0 | let mut_auth_attributes = |
103 | 0 | if let Some(session) = self.common.get_immutable_session_via_id(session_id) { |
104 | 0 | session.get_mut_auth_requested() |
105 | | } else { |
106 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
107 | 0 | return ( |
108 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
109 | 0 | Some(writer.used_slice()), |
110 | 0 | ); |
111 | | }; |
112 | | |
113 | 0 | let finish_request_attributes = finish_req.finish_request_attributes; |
114 | | |
115 | 0 | if (!mut_auth_attributes.is_empty() |
116 | 0 | && !finish_request_attributes.contains(SpdmFinishRequestAttributes::SIGNATURE_INCLUDED)) |
117 | 0 | || (mut_auth_attributes.is_empty() |
118 | 0 | && finish_request_attributes |
119 | 0 | .contains(SpdmFinishRequestAttributes::SIGNATURE_INCLUDED)) |
120 | | { |
121 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorInvalidRequest, 0, writer); |
122 | 0 | return ( |
123 | 0 | Err(SPDM_STATUS_INVALID_MSG_FIELD), |
124 | 0 | Some(writer.used_slice()), |
125 | 0 | ); |
126 | 0 | } |
127 | | |
128 | 0 | let is_mut_auth = !mut_auth_attributes.is_empty(); |
129 | 0 | if is_mut_auth { |
130 | 0 | let session = |
131 | 0 | if let Some(session) = self.common.get_immutable_session_via_id(session_id) { |
132 | 0 | session |
133 | | } else { |
134 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
135 | 0 | return ( |
136 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
137 | 0 | Some(writer.used_slice()), |
138 | 0 | ); |
139 | | }; |
140 | | |
141 | 0 | if self |
142 | 0 | .verify_finish_req_signature(&finish_req.signature, session) |
143 | 0 | .is_err() |
144 | | { |
145 | 0 | error!("verify finish request signature error"); |
146 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorDecryptError, 0, writer); |
147 | 0 | return (Err(SPDM_STATUS_CRYPTO_ERROR), Some(writer.used_slice())); |
148 | 0 | } |
149 | 0 | info!("verify_finish_req_signature pass"); |
150 | | |
151 | 0 | if self |
152 | 0 | .common |
153 | 0 | .append_message_f(false, session_id, finish_req.signature.as_ref()) |
154 | 0 | .is_err() |
155 | | { |
156 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
157 | 0 | return ( |
158 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
159 | 0 | Some(writer.used_slice()), |
160 | 0 | ); |
161 | 0 | } |
162 | 0 | } |
163 | | |
164 | | // verify HMAC with finished_key |
165 | 0 | let base_hash_size = self.common.get_hash_size() as usize; |
166 | | |
167 | | { |
168 | 0 | let session = if let Some(session) = self.common.get_session_via_id(session_id) { |
169 | 0 | session |
170 | | } else { |
171 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
172 | 0 | return ( |
173 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
174 | 0 | Some(writer.used_slice()), |
175 | 0 | ); |
176 | | }; |
177 | | |
178 | 0 | if session.get_use_psk() { |
179 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorInvalidRequest, 0, writer); |
180 | 0 | return ( |
181 | 0 | Err(SPDM_STATUS_INVALID_MSG_FIELD), |
182 | 0 | Some(writer.used_slice()), |
183 | 0 | ); |
184 | 0 | } |
185 | | |
186 | 0 | let session = |
187 | 0 | if let Some(session) = self.common.get_immutable_session_via_id(session_id) { |
188 | 0 | session |
189 | | } else { |
190 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
191 | 0 | return ( |
192 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
193 | 0 | Some(writer.used_slice()), |
194 | 0 | ); |
195 | | }; |
196 | | |
197 | 0 | let transcript_hash = self |
198 | 0 | .common |
199 | 0 | .calc_rsp_transcript_hash(false, is_mut_auth, session); |
200 | 0 | if transcript_hash.is_err() { |
201 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
202 | 0 | return (Err(SPDM_STATUS_CRYPTO_ERROR), Some(writer.used_slice())); |
203 | 0 | } |
204 | 0 | let transcript_hash = transcript_hash.as_ref().unwrap(); |
205 | | |
206 | 0 | if session |
207 | 0 | .verify_hmac_with_request_finished_key( |
208 | 0 | transcript_hash.as_ref(), |
209 | 0 | &finish_req.verify_data, |
210 | 0 | ) |
211 | 0 | .is_err() |
212 | | { |
213 | 0 | error!("verify_hmac_with_request_finished_key fail"); |
214 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorDecryptError, 0, writer); |
215 | 0 | return (Err(SPDM_STATUS_CRYPTO_ERROR), Some(writer.used_slice())); |
216 | | } else { |
217 | 0 | info!("verify_hmac_with_request_finished_key pass"); |
218 | | } |
219 | | |
220 | 0 | if self |
221 | 0 | .common |
222 | 0 | .append_message_f(false, session_id, finish_req.verify_data.as_ref()) |
223 | 0 | .is_err() |
224 | | { |
225 | 0 | error!("message_f add the message error"); |
226 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
227 | 0 | return ( |
228 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
229 | 0 | Some(writer.used_slice()), |
230 | 0 | ); |
231 | 0 | } |
232 | | } |
233 | | |
234 | 0 | let in_clear_text = self |
235 | 0 | .common |
236 | 0 | .negotiate_info |
237 | 0 | .req_capabilities_sel |
238 | 0 | .contains(SpdmRequestCapabilityFlags::HANDSHAKE_IN_THE_CLEAR_CAP) |
239 | 0 | && self |
240 | 0 | .common |
241 | 0 | .negotiate_info |
242 | 0 | .rsp_capabilities_sel |
243 | 0 | .contains(SpdmResponseCapabilityFlags::HANDSHAKE_IN_THE_CLEAR_CAP); |
244 | | |
245 | 0 | info!("send spdm finish rsp\n"); |
246 | | |
247 | 0 | let response = SpdmMessage { |
248 | 0 | header: SpdmMessageHeader { |
249 | 0 | version: self.common.negotiate_info.spdm_version_sel, |
250 | 0 | request_response_code: SpdmRequestResponseCode::SpdmResponseFinishRsp, |
251 | 0 | }, |
252 | 0 | payload: SpdmMessagePayload::SpdmFinishResponse(SpdmFinishResponsePayload { |
253 | 0 | verify_data: SpdmDigestStruct { |
254 | 0 | data_size: (self as &ResponderContext).common.get_hash_size(), |
255 | 0 | data: Box::new([0xcc; SPDM_MAX_HASH_SIZE]), |
256 | 0 | }, |
257 | 0 | opaque: SpdmOpaqueStruct { |
258 | 0 | data_size: 0, |
259 | 0 | data: [0u8; MAX_SPDM_OPAQUE_SIZE], |
260 | 0 | }, |
261 | 0 | }), |
262 | 0 | }; |
263 | | |
264 | 0 | let res = response.spdm_encode(&mut self.common, writer); |
265 | 0 | if res.is_err() { |
266 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
267 | 0 | return ( |
268 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
269 | 0 | Some(writer.used_slice()), |
270 | 0 | ); |
271 | 0 | } |
272 | 0 | let used = writer.used(); |
273 | | |
274 | 0 | if in_clear_text { |
275 | | // generate HMAC with finished_key |
276 | 0 | let temp_used = used - base_hash_size; |
277 | | |
278 | 0 | if self |
279 | 0 | .common |
280 | 0 | .append_message_f(false, session_id, &writer.used_slice()[..temp_used]) |
281 | 0 | .is_err() |
282 | | { |
283 | 0 | error!("message_f add the message error"); |
284 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
285 | 0 | return ( |
286 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
287 | 0 | Some(writer.used_slice()), |
288 | 0 | ); |
289 | 0 | } |
290 | | |
291 | 0 | let session = |
292 | 0 | if let Some(session) = self.common.get_immutable_session_via_id(session_id) { |
293 | 0 | session |
294 | | } else { |
295 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
296 | 0 | return ( |
297 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
298 | 0 | Some(writer.used_slice()), |
299 | 0 | ); |
300 | | }; |
301 | | |
302 | 0 | let transcript_hash = self |
303 | 0 | .common |
304 | 0 | .calc_rsp_transcript_hash(false, is_mut_auth, session); |
305 | 0 | if transcript_hash.is_err() { |
306 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
307 | 0 | return (Err(SPDM_STATUS_CRYPTO_ERROR), Some(writer.used_slice())); |
308 | 0 | } |
309 | 0 | let transcript_hash = transcript_hash.unwrap(); |
310 | | |
311 | 0 | let hmac = session.generate_hmac_with_response_finished_key(transcript_hash.as_ref()); |
312 | 0 | if hmac.is_err() { |
313 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
314 | 0 | return (Err(SPDM_STATUS_CRYPTO_ERROR), Some(writer.used_slice())); |
315 | 0 | } |
316 | 0 | let hmac = hmac.unwrap(); |
317 | | |
318 | 0 | if self |
319 | 0 | .common |
320 | 0 | .append_message_f(false, session_id, hmac.as_ref()) |
321 | 0 | .is_err() |
322 | | { |
323 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
324 | 0 | return ( |
325 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
326 | 0 | Some(writer.used_slice()), |
327 | 0 | ); |
328 | 0 | } |
329 | | |
330 | | // patch the message before send |
331 | 0 | writer.mut_used_slice()[(used - base_hash_size)..used].copy_from_slice(hmac.as_ref()); |
332 | 0 | } else if self |
333 | 0 | .common |
334 | 0 | .append_message_f(false, session_id, &writer.used_slice()[..used]) |
335 | 0 | .is_err() |
336 | | { |
337 | 0 | error!("message_f add the message error"); |
338 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
339 | 0 | return ( |
340 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
341 | 0 | Some(writer.used_slice()), |
342 | 0 | ); |
343 | 0 | } |
344 | | |
345 | | // generate the data secret |
346 | 0 | let session = if let Some(session) = self.common.get_immutable_session_via_id(session_id) { |
347 | 0 | session |
348 | | } else { |
349 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
350 | 0 | return ( |
351 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
352 | 0 | Some(writer.used_slice()), |
353 | 0 | ); |
354 | | }; |
355 | | |
356 | 0 | let th2 = self |
357 | 0 | .common |
358 | 0 | .calc_rsp_transcript_hash(false, is_mut_auth, session); |
359 | | |
360 | 0 | if th2.is_err() { |
361 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
362 | 0 | return (Err(SPDM_STATUS_CRYPTO_ERROR), Some(writer.used_slice())); |
363 | 0 | } |
364 | 0 | let th2 = th2.unwrap(); |
365 | 0 | debug!("!!! th2 : {:02x?}\n", th2.as_ref()); |
366 | 0 | let spdm_version_sel = self.common.negotiate_info.spdm_version_sel; |
367 | 0 | let session = if let Some(session) = self.common.get_session_via_id(session_id) { |
368 | 0 | session |
369 | | } else { |
370 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
371 | 0 | return ( |
372 | 0 | Err(SPDM_STATUS_INVALID_STATE_LOCAL), |
373 | 0 | Some(writer.used_slice()), |
374 | 0 | ); |
375 | | }; |
376 | 0 | session.set_th2(th2.clone()); |
377 | 0 | if let Err(e) = session.generate_data_secret(spdm_version_sel, &th2) { |
378 | 0 | self.write_spdm_error(SpdmErrorCode::SpdmErrorUnspecified, 0, writer); |
379 | 0 | (Err(e), Some(writer.used_slice())) |
380 | | } else { |
381 | 0 | (Ok(()), Some(writer.used_slice())) |
382 | | } |
383 | 0 | } |
384 | | |
385 | | #[cfg(not(feature = "hashed-transcript-data"))] |
386 | | fn verify_finish_req_signature( |
387 | | &self, |
388 | | signature: &SpdmSignatureStruct, |
389 | | session: &SpdmSession, |
390 | | ) -> SpdmResult { |
391 | | let transcript_data_hash = self.common.calc_rsp_transcript_hash(false, true, session)?; |
392 | | |
393 | | let peer_slot_id = self.common.runtime_info.get_peer_used_cert_chain_slot_id(); |
394 | | let peer_cert = if peer_slot_id == SPDM_PUB_KEY_SLOT_ID_KEY_EXCHANGE_RSP { |
395 | | let peer_pub_key = self |
396 | | .common |
397 | | .provision_info |
398 | | .peer_pub_key |
399 | | .as_ref() |
400 | | .ok_or(SPDM_STATUS_INVALID_PARAMETER)?; |
401 | | &peer_pub_key.data[..peer_pub_key.data_size as usize] |
402 | | } else { |
403 | | &self.common.peer_info.peer_cert_chain[peer_slot_id as usize] |
404 | | .as_ref() |
405 | | .ok_or(SPDM_STATUS_INVALID_PARAMETER)? |
406 | | .data[(4usize + self.common.get_hash_size() as usize) |
407 | | ..(self.common.peer_info.peer_cert_chain[peer_slot_id as usize] |
408 | | .as_ref() |
409 | | .ok_or(SPDM_STATUS_INVALID_PARAMETER)? |
410 | | .data_size as usize)] |
411 | | }; |
412 | | let mut transcript_sign = ManagedBuffer12Sign::default(); |
413 | | if self.common.negotiate_info.spdm_version_sel >= SpdmVersion::SpdmVersion12 { |
414 | | transcript_sign.reset_message(); |
415 | | transcript_sign |
416 | | .append_message(&self.common.get_signing_prefix_context()) |
417 | | .ok_or(SPDM_STATUS_BUFFER_FULL)?; |
418 | | transcript_sign |
419 | | .append_message(&SPDM_VERSION_SIGNING_CONTEXT_ZEROPAD_12) |
420 | | .ok_or(SPDM_STATUS_BUFFER_FULL)?; |
421 | | transcript_sign |
422 | | .append_message(&SPDM_FINISH_SIGN_CONTEXT) |
423 | | .ok_or(SPDM_STATUS_BUFFER_FULL)?; |
424 | | transcript_sign |
425 | | .append_message(transcript_data_hash.as_ref()) |
426 | | .ok_or(SPDM_STATUS_BUFFER_FULL)?; |
427 | | } |
428 | | |
429 | | let peer_cert_der = if peer_slot_id == SPDM_PUB_KEY_SLOT_ID_KEY_EXCHANGE_RSP { |
430 | | SpdmDer::SpdmDerPubKeyRfc7250(peer_cert) |
431 | | } else { |
432 | | SpdmDer::SpdmDerCertChain(peer_cert) |
433 | | }; |
434 | | |
435 | | crypto::spdm_asym_verify( |
436 | | self.common.negotiate_info.base_hash_sel, |
437 | | self.common.negotiate_info.req_asym_sel.to_base(), |
438 | | self.common.negotiate_info.pqc_req_asym_sel.to_base(), |
439 | | peer_cert_der, |
440 | | transcript_sign.as_ref(), |
441 | | signature, |
442 | | ) |
443 | | } |
444 | | |
445 | | #[cfg(feature = "hashed-transcript-data")] |
446 | 0 | fn verify_finish_req_signature( |
447 | 0 | &self, |
448 | 0 | signature: &SpdmSignatureStruct, |
449 | 0 | session: &SpdmSession, |
450 | 0 | ) -> SpdmResult { |
451 | 0 | let transcript_hash = self.common.calc_rsp_transcript_hash(false, true, session)?; |
452 | | |
453 | 0 | let peer_slot_id = self.common.runtime_info.get_peer_used_cert_chain_slot_id(); |
454 | 0 | let peer_cert = if peer_slot_id == SPDM_PUB_KEY_SLOT_ID_KEY_EXCHANGE_RSP { |
455 | 0 | let peer_pub_key = self |
456 | 0 | .common |
457 | 0 | .provision_info |
458 | 0 | .peer_pub_key |
459 | 0 | .as_ref() |
460 | 0 | .ok_or(SPDM_STATUS_INVALID_PARAMETER)?; |
461 | 0 | &peer_pub_key.data[..peer_pub_key.data_size as usize] |
462 | | } else { |
463 | 0 | &self.common.peer_info.peer_cert_chain[peer_slot_id as usize] |
464 | 0 | .as_ref() |
465 | 0 | .ok_or(SPDM_STATUS_INVALID_PARAMETER)? |
466 | 0 | .data[(4usize + self.common.get_hash_size() as usize) |
467 | 0 | ..(self.common.peer_info.peer_cert_chain[peer_slot_id as usize] |
468 | 0 | .as_ref() |
469 | 0 | .ok_or(SPDM_STATUS_INVALID_PARAMETER)? |
470 | | .data_size as usize)] |
471 | | }; |
472 | 0 | let mut transcript_hash_sign = ManagedBuffer12Sign::default(); |
473 | 0 | if self.common.negotiate_info.spdm_version_sel >= SpdmVersion::SpdmVersion12 { |
474 | 0 | transcript_hash_sign.reset_message(); |
475 | 0 | transcript_hash_sign |
476 | 0 | .append_message(&self.common.get_signing_prefix_context()) |
477 | 0 | .ok_or(SPDM_STATUS_BUFFER_FULL)?; |
478 | 0 | transcript_hash_sign |
479 | 0 | .append_message(&SPDM_VERSION_SIGNING_CONTEXT_ZEROPAD_12) |
480 | 0 | .ok_or(SPDM_STATUS_BUFFER_FULL)?; |
481 | 0 | transcript_hash_sign |
482 | 0 | .append_message(&SPDM_FINISH_SIGN_CONTEXT) |
483 | 0 | .ok_or(SPDM_STATUS_BUFFER_FULL)?; |
484 | 0 | transcript_hash_sign |
485 | 0 | .append_message(transcript_hash.as_ref()) |
486 | 0 | .ok_or(SPDM_STATUS_BUFFER_FULL)?; |
487 | | } else { |
488 | 0 | error!("hashed-transcript-data is unsupported in SPDM 1.0/1.1 signing!\n"); |
489 | 0 | return Err(SPDM_STATUS_INVALID_STATE_LOCAL); |
490 | | } |
491 | | |
492 | 0 | let peer_cert_der = if peer_slot_id == SPDM_PUB_KEY_SLOT_ID_KEY_EXCHANGE_RSP { |
493 | 0 | SpdmDer::SpdmDerPubKeyRfc7250(peer_cert) |
494 | | } else { |
495 | 0 | SpdmDer::SpdmDerCertChain(peer_cert) |
496 | | }; |
497 | | |
498 | 0 | let res = crypto::spdm_asym_verify( |
499 | 0 | self.common.negotiate_info.base_hash_sel, |
500 | 0 | self.common.negotiate_info.req_asym_sel.to_base(), |
501 | 0 | self.common.negotiate_info.pqc_req_asym_sel.to_base(), |
502 | 0 | peer_cert_der, |
503 | 0 | transcript_hash_sign.as_ref(), |
504 | 0 | signature, |
505 | | ); |
506 | | |
507 | 0 | res |
508 | 0 | } |
509 | | } |