|
1 | 1 | use alloc::string::String; |
2 | | -use alloc::vec; |
3 | | -use alloc::vec::Vec; |
4 | 2 | use borsh::{BorshDeserialize, BorshSerialize}; |
5 | 3 | use serde::{Deserialize, Serialize}; |
6 | 4 | use serde_with::{Bytes, serde_as}; |
7 | 5 |
|
8 | | -use dstack_sdk_types::dstack::{EventLog, TcbInfo as DstackTcbInfo}; |
9 | | - |
10 | | -use crate::attestation::KEY_PROVIDER_EVENT; |
11 | | - |
12 | 6 | /// Required measurements for TEE attestation verification (a.k.a. RTMRs checks). These values |
13 | 7 | /// define the trusted baseline that TEE environments must match during verification. They |
14 | 8 | /// should be updated when the underlying TEE environment changes. |
@@ -45,84 +39,6 @@ pub struct ExpectedMeasurements { |
45 | 39 | pub key_provider_event_digest: [u8; 48], |
46 | 40 | } |
47 | 41 |
|
48 | | -impl ExpectedMeasurements { |
49 | | - /// Loads expected measurements from the embedded TCB info file for TEE attestation verification. |
50 | | - /// This implementation uses a cached computation to avoid runtime JSON parsing and hex decoding, |
51 | | - /// improving performance especially in smart contract environments where every cycle counts. |
52 | | - /// |
53 | | - /// The TCB info contains hex-encoded measurement values that are decoded once and cached for |
54 | | - /// all subsequent calls, ensuring consistent measurements across both production and test environments. |
55 | | - /// |
56 | | - /// TODO(#737): Define a process for updating these static RTMRs going forward, since they are already outdated. |
57 | | - /// $ git rev-parse HEAD |
58 | | - /// fbdf2e76fb6bd9142277fdd84809de87d86548ef |
59 | | - /// |
60 | | - /// See also: https://github.com/Dstack-TEE/meta-dstack?tab=readme-ov-file#reproducible-build-the-guest-image |
61 | | - /// Load all supported TCB info measurement sets (e.g., production + dev). |
62 | | - pub fn from_embedded_tcb_info( |
63 | | - tcb_info_strings: &[&str], |
64 | | - ) -> Result<Vec<Self>, MeasurementsError> { |
65 | | - // Helper closure to parse one TCB info JSON |
66 | | - let parse_tcb_info = |json_str: &str| -> Result<ExpectedMeasurements, MeasurementsError> { |
67 | | - let tcb_info: DstackTcbInfo = |
68 | | - serde_json::from_str(json_str).map_err(|_| MeasurementsError::InvalidTcbInfo)?; |
69 | | - |
70 | | - let decode_measurement = |
71 | | - |name: &str, hex_value: &str| -> Result<[u8; 48], MeasurementsError> { |
72 | | - let decoded = hex::decode(hex_value).map_err(|_| { |
73 | | - MeasurementsError::InvalidHexValue(name.into(), hex_value.into()) |
74 | | - })?; |
75 | | - let decoded_len = decoded.len(); |
76 | | - decoded |
77 | | - .try_into() |
78 | | - .map_err(|_| MeasurementsError::InvalidLength(name.into(), decoded_len)) |
79 | | - }; |
80 | | - |
81 | | - let rtmrs = Measurements { |
82 | | - rtmr0: decode_measurement("rtmr0", &tcb_info.rtmr0)?, |
83 | | - rtmr1: decode_measurement("rtmr1", &tcb_info.rtmr1)?, |
84 | | - rtmr2: decode_measurement("rtmr2", &tcb_info.rtmr2)?, |
85 | | - mrtd: decode_measurement("mrtd", &tcb_info.mrtd)?, |
86 | | - }; |
87 | | - |
88 | | - let key_provider_event_digest_encoded = |
89 | | - Self::get_key_provider_digest(&tcb_info.event_log)?; |
90 | | - let key_provider_event_digest = |
91 | | - decode_measurement(KEY_PROVIDER_EVENT, key_provider_event_digest_encoded)?; |
92 | | - |
93 | | - Ok(ExpectedMeasurements { |
94 | | - rtmrs, |
95 | | - key_provider_event_digest, |
96 | | - }) |
97 | | - }; |
98 | | - |
99 | | - let mut results = vec![]; |
100 | | - for s in tcb_info_strings { |
101 | | - results.push(parse_tcb_info(s)?); |
102 | | - } |
103 | | - |
104 | | - Ok(results) |
105 | | - } |
106 | | - |
107 | | - /// The expected SHA-384 digest for the `key-provider` event, not the event payload. |
108 | | - /// |
109 | | - /// Digest format: |
110 | | - /// digest = SHA384( event_type + ":" + "key-provider" + ":"+payload) ) |
111 | | - /// |
112 | | - /// If the key provider is `local-sgx` then: |
113 | | - /// Payload format: sha256 {"name":"local-sgx", "id": "<mr_enclave of the provider>"} |
114 | | - fn get_key_provider_digest(event_log: &[EventLog]) -> Result<&str, MeasurementsError> { |
115 | | - let key_provider_events: Vec<&EventLog> = event_log |
116 | | - .iter() |
117 | | - .filter(|e| e.event == KEY_PROVIDER_EVENT) |
118 | | - .collect(); |
119 | | - if key_provider_events.len() != 1 { |
120 | | - return Err(MeasurementsError::InvalidTcbInfo); |
121 | | - }; |
122 | | - Ok(&key_provider_events[0].digest) |
123 | | - } |
124 | | -} |
125 | | - |
126 | 42 | #[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)] |
127 | 43 | pub enum MeasurementsError { |
128 | 44 | #[error("no TD10 report")] |
|
0 commit comments