Skip to content

Commit a159164

Browse files
committed
Add os_image_hash in verifier report
1 parent 846637c commit a159164

File tree

2 files changed

+45
-77
lines changed

2 files changed

+45
-77
lines changed

verifier/src/verification.rs

Lines changed: 43 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use dstack_types::VmConfig;
1111
use ra_tls::attestation::{Attestation, VerifiedAttestation};
1212
use sha2::{Digest as _, Sha256, Sha384};
1313
use tokio::{io::AsyncWriteExt, process::Command};
14-
use tracing::{debug, info};
14+
use tracing::info;
1515

1616
use crate::types::{
1717
AcpiTables, RtmrEventEntry, RtmrEventStatus, RtmrMismatch, VerificationDetails,
@@ -52,12 +52,15 @@ fn replay_event_logs(eventlog: &[EventLog]) -> Result<RtmrComputationResult> {
5252

5353
fn collect_rtmr_mismatch(
5454
rtmr_label: &str,
55-
expected_hex: &str,
56-
actual_hex: &str,
55+
expected: &[u8],
56+
actual: &[u8],
5757
expected_sequence: &RtmrLog,
5858
actual_indices: &[usize],
5959
event_log: &[EventLog],
6060
) -> RtmrMismatch {
61+
let expected_hex = hex::encode(expected);
62+
let actual_hex = hex::encode(actual);
63+
6164
let mut events = Vec::new();
6265

6366
for (&idx, expected_digest) in actual_indices.iter().zip(expected_sequence.iter()) {
@@ -200,20 +203,6 @@ impl CvmVerifier {
200203
}
201204
};
202205

203-
match verified_attestation.decode_app_info(false) {
204-
Ok(info) => {
205-
details.event_log_verified = true;
206-
details.app_info = Some(info);
207-
}
208-
Err(e) => {
209-
return Ok(VerificationResponse {
210-
is_valid: false,
211-
details,
212-
reason: Some(format!("Event log verification failed: {}", e)),
213-
});
214-
}
215-
};
216-
217206
// Step 3: Verify os-image-hash matches using dstack-mr
218207
if let Err(e) = self
219208
.verify_os_image_hash(&vm_config, &verified_attestation, &mut details)
@@ -226,6 +215,20 @@ impl CvmVerifier {
226215
});
227216
}
228217
details.os_image_hash_verified = true;
218+
match verified_attestation.decode_app_info(false) {
219+
Ok(mut info) => {
220+
info.os_image_hash = vm_config.os_image_hash;
221+
details.event_log_verified = true;
222+
details.app_info = Some(info);
223+
}
224+
Err(e) => {
225+
return Ok(VerificationResponse {
226+
is_valid: false,
227+
details,
228+
reason: Some(format!("Event log verification failed: {}", e)),
229+
});
230+
}
231+
};
229232

230233
Ok(VerificationResponse {
231234
is_valid: true,
@@ -263,31 +266,14 @@ impl CvmVerifier {
263266
.as_td10()
264267
.context("Failed to decode TD report")?;
265268

266-
let app_info = attestation.decode_app_info(false)?;
267-
268-
let boot_info = upgrade_authority::BootInfo {
269+
// Extract the verified MRs from the report
270+
let verified_mrs = Mrs {
269271
mrtd: report.mr_td.to_vec(),
270272
rtmr0: report.rt_mr0.to_vec(),
271273
rtmr1: report.rt_mr1.to_vec(),
272274
rtmr2: report.rt_mr2.to_vec(),
273-
rtmr3: report.rt_mr3.to_vec(),
274-
mr_aggregated: app_info.mr_aggregated.to_vec(),
275-
os_image_hash: vm_config.os_image_hash.clone(),
276-
mr_system: app_info.mr_system.to_vec(),
277-
app_id: app_info.app_id,
278-
compose_hash: app_info.compose_hash,
279-
instance_id: app_info.instance_id,
280-
device_id: app_info.device_id,
281-
key_provider_info: app_info.key_provider_info,
282-
event_log: String::from_utf8(attestation.raw_event_log.clone())
283-
.context("Failed to serialize event log")?,
284-
tcb_status: attestation.report.status.clone(),
285-
advisory_ids: attestation.report.advisory_ids.clone(),
286275
};
287276

288-
// Extract the verified MRs from the boot info
289-
let verified_mrs = Mrs::from(&boot_info);
290-
291277
// Get image directory
292278
let image_dir = Path::new(&self.image_cache_dir)
293279
.join("images")
@@ -349,27 +335,19 @@ impl CvmVerifier {
349335
});
350336

351337
let expected_mrs = Mrs {
352-
mrtd: hex::encode(&mrs.mrtd),
353-
rtmr0: hex::encode(&mrs.rtmr0),
354-
rtmr1: hex::encode(&mrs.rtmr1),
355-
rtmr2: hex::encode(&mrs.rtmr2),
338+
mrtd: mrs.mrtd.clone(),
339+
rtmr0: mrs.rtmr0.clone(),
340+
rtmr1: mrs.rtmr1.clone(),
341+
rtmr2: mrs.rtmr2.clone(),
356342
};
357343

358-
debug!(
359-
"Expected MRs from dstack-mr: MRTD={}, RTMR0={}, RTMR1={}, RTMR2={}",
360-
expected_mrs.mrtd, expected_mrs.rtmr0, expected_mrs.rtmr1, expected_mrs.rtmr2
361-
);
362-
debug!(
363-
"Verified MRs from attestation: MRTD={}, RTMR0={}, RTMR1={}, RTMR2={}",
364-
verified_mrs.mrtd, verified_mrs.rtmr0, verified_mrs.rtmr1, verified_mrs.rtmr2
365-
);
366344
let event_log: Vec<EventLog> = serde_json::from_slice(&attestation.raw_event_log)
367345
.context("Failed to parse event log for mismatch analysis")?;
368346

369347
let computation_result = replay_event_logs(&event_log)
370348
.context("Failed to replay event logs for mismatch analysis")?;
371349

372-
if computation_result.rtmrs[3] != *boot_info.rtmr3 {
350+
if computation_result.rtmrs[3] != report.rt_mr3 {
373351
bail!("RTMR3 mismatch");
374352
}
375353

@@ -544,57 +522,46 @@ impl CvmVerifier {
544522

545523
#[derive(Debug, Clone)]
546524
struct Mrs {
547-
mrtd: String,
548-
rtmr0: String,
549-
rtmr1: String,
550-
rtmr2: String,
525+
mrtd: Vec<u8>,
526+
rtmr0: Vec<u8>,
527+
rtmr1: Vec<u8>,
528+
rtmr2: Vec<u8>,
551529
}
552530

553531
impl Mrs {
554532
fn assert_eq(&self, other: &Self) -> Result<()> {
555533
if self.mrtd != other.mrtd {
556534
bail!(
557-
"MRTD does not match: expected={}, actual={}",
558-
self.mrtd,
559-
other.mrtd
535+
"MRTD mismatch: expected={}, actual={}",
536+
hex::encode(&self.mrtd),
537+
hex::encode(&other.mrtd)
560538
);
561539
}
562540
if self.rtmr0 != other.rtmr0 {
563541
bail!(
564-
"RTMR0 does not match: expected={}, actual={}",
565-
self.rtmr0,
566-
other.rtmr0
542+
"RTMR0 mismatch: expected={}, actual={}",
543+
hex::encode(&self.rtmr0),
544+
hex::encode(&other.rtmr0)
567545
);
568546
}
569547
if self.rtmr1 != other.rtmr1 {
570548
bail!(
571-
"RTMR1 does not match: expected={}, actual={}",
572-
self.rtmr1,
573-
other.rtmr1
549+
"RTMR1 mismatch: expected={}, actual={}",
550+
hex::encode(&self.rtmr1),
551+
hex::encode(&other.rtmr1)
574552
);
575553
}
576554
if self.rtmr2 != other.rtmr2 {
577555
bail!(
578-
"RTMR2 does not match: expected={}, actual={}",
579-
self.rtmr2,
580-
other.rtmr2
556+
"RTMR2 mismatch: expected={}, actual={}",
557+
hex::encode(&self.rtmr2),
558+
hex::encode(&other.rtmr2)
581559
);
582560
}
583561
Ok(())
584562
}
585563
}
586564

587-
impl From<&upgrade_authority::BootInfo> for Mrs {
588-
fn from(report: &upgrade_authority::BootInfo) -> Self {
589-
Self {
590-
mrtd: hex::encode(&report.mrtd),
591-
rtmr0: hex::encode(&report.rtmr0),
592-
rtmr1: hex::encode(&report.rtmr1),
593-
rtmr2: hex::encode(&report.rtmr2),
594-
}
595-
}
596-
}
597-
598565
mod upgrade_authority {
599566
use serde::{Deserialize, Serialize};
600567

verifier/test.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ fi
9999

100100
# Show app info if available
101101
APP_ID=$(echo "$RESPONSE" | jq -r '.details.app_info.app_id // "null"')
102+
OS_IMAGE_HASH=$(echo "$RESPONSE" | jq -r '.details.app_info.os_image_hash // "null"')
102103
if [ "$APP_ID" != "null" ]; then
103104
echo -e "\n${YELLOW}App Information:${NC}"
104105
echo "App ID: $APP_ID"
105-
echo "Instance ID: $(echo "$RESPONSE" | jq -r '.details.app_info.instance_id')"
106106
echo "Compose Hash: $(echo "$RESPONSE" | jq -r '.details.app_info.compose_hash')"
107+
echo "OS Image Hash: $OS_IMAGE_HASH"
107108
fi
108109

109110
# Show report data

0 commit comments

Comments
 (0)