| 26 | }; |
| 27 | |
| 28 | fn collect_rtmr_mismatch( |
| 29 | rtmr_label: &str, |
| 30 | expected: &[u8], |
| 31 | actual: &[u8], |
| 32 | expected_sequence: &RtmrLog, |
| 33 | actual_indices: &[usize], |
| 34 | event_log: &[TdxEvent], |
| 35 | ) -> RtmrMismatch { |
| 36 | let expected_hex = hex::encode(expected); |
| 37 | let actual_hex = hex::encode(actual); |
| 38 | |
| 39 | let mut events = Vec::new(); |
| 40 | |
| 41 | for (&idx, expected_digest) in actual_indices.iter().zip(expected_sequence.iter()) { |
| 42 | match event_log.get(idx) { |
| 43 | Some(event) => { |
| 44 | let event_name = if event.event.is_empty() { |
| 45 | "(unnamed)".to_string() |
| 46 | } else { |
| 47 | event.event.clone() |
| 48 | }; |
| 49 | let status = if event.digest() == expected_digest.as_slice() { |
| 50 | RtmrEventStatus::Match |
| 51 | } else { |
| 52 | RtmrEventStatus::Mismatch |
| 53 | }; |
| 54 | events.push(RtmrEventEntry { |
| 55 | index: idx, |
| 56 | event_type: event.event_type, |
| 57 | event_name, |
| 58 | actual_digest: hex::encode(event.digest()), |
| 59 | expected_digest: Some(hex::encode(expected_digest)), |
| 60 | payload_len: event.event_payload.len(), |
| 61 | status, |
| 62 | }); |
| 63 | } |
| 64 | None => { |
| 65 | events.push(RtmrEventEntry { |
| 66 | index: idx, |
| 67 | event_type: 0, |
| 68 | event_name: "(missing)".to_string(), |
| 69 | actual_digest: String::new(), |
| 70 | expected_digest: Some(hex::encode(expected_digest)), |
| 71 | payload_len: 0, |
| 72 | status: RtmrEventStatus::Missing, |
| 73 | }); |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | for &idx in actual_indices.iter().skip(expected_sequence.len()) { |
| 79 | let (event_type, event_name, actual_digest, payload_len) = match event_log.get(idx) { |
| 80 | Some(event) => ( |
| 81 | event.event_type, |
| 82 | if event.event.is_empty() { |
| 83 | "(unnamed)".to_string() |
| 84 | } else { |
| 85 | event.event.clone() |