igvmfilegen/
identity_mapping.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Implements creation of JSON formatted launch measurement identity documents.
5//! This comes from Intel's TD Identity Mapping, and has been expanded
6//! for SNP and VBS.
7//! This format allows verifiers to validate a COSE Sign1 payload,
8//! and correlate that to a launch measurement and SVN.
9use serde::Serialize;
10
11/// Defined by specification.
12const CLASS_ID_GUID: &str = "7fb00ee4-a7ff-11ed-9e2f-00155d09de56";
13
14/// This field is required by TD mapping specification.
15#[derive(Serialize, Debug)]
16pub struct Environment {
17    pub class_id: String,
18}
19
20/// SNP launch measurement.
21#[derive(Serialize, Debug, Clone)]
22pub struct SnpLaunchMeasurement {
23    #[serde(
24        serialize_with = "hex::serde::serialize_upper",
25        deserialize_with = "hex::serde::deserialize"
26    )]
27    pub snp_ld: [u8; 48],
28}
29
30/// TDX MRTD.
31#[derive(Serialize, Debug, Clone)]
32pub struct TdxLaunchMeasurement {
33    #[serde(
34        serialize_with = "hex::serde::serialize_upper",
35        deserialize_with = "hex::serde::deserialize"
36    )]
37    pub tdx_mrtd: [u8; 48],
38}
39
40/// VBS Boot Digest.
41#[derive(Serialize, Debug, Clone)]
42pub struct VbsLaunchMeasurement {
43    #[serde(
44        serialize_with = "hex::serde::serialize_upper",
45        deserialize_with = "hex::serde::deserialize"
46    )]
47    pub vbs_boot_digest: [u8; 32],
48}
49
50/// Build information.
51#[derive(Serialize, Debug, Clone)]
52pub struct BuildInfo {
53    pub debug_build: bool,
54}
55
56/// SVN of this image.
57#[derive(Serialize, Debug, Clone)]
58pub struct SnpEndorsement {
59    pub snp_isvsvn: u32,
60    pub build_info: BuildInfo,
61}
62
63/// SVN of this image.
64#[derive(Serialize, Debug, Clone)]
65pub struct TdxEndorsement {
66    pub tdx_isvsvn: u32,
67    pub build_info: BuildInfo,
68}
69
70/// SVN of this image.
71#[derive(Serialize, Debug, Clone)]
72pub struct VbsEndorsement {
73    pub vbs_isvsvn: u32,
74    pub build_info: BuildInfo,
75}
76
77#[derive(Serialize, Debug, Clone)]
78pub struct MeasurementInstance<R, E> {
79    pub reference: R,
80    pub endorsement: E,
81}
82
83#[derive(Serialize, Debug)]
84pub struct BaseMeasurement<R, E> {
85    pub environment: Environment,
86    pub series: Vec<MeasurementInstance<R, E>>,
87}
88
89/// Combined measurement structure.
90#[derive(Serialize, Debug)]
91#[serde(untagged)]
92pub enum Measurement {
93    Snp(BaseMeasurement<SnpLaunchMeasurement, SnpEndorsement>),
94    Tdx(BaseMeasurement<TdxLaunchMeasurement, TdxEndorsement>),
95    Vbs(BaseMeasurement<VbsLaunchMeasurement, VbsEndorsement>),
96}
97
98pub type SnpMeasurement = BaseMeasurement<SnpLaunchMeasurement, SnpEndorsement>;
99pub type TdxMeasurement = BaseMeasurement<TdxLaunchMeasurement, TdxEndorsement>;
100pub type VbsMeasurement = BaseMeasurement<VbsLaunchMeasurement, VbsEndorsement>;
101
102impl SnpMeasurement {
103    /// SNP measurement and endorsements.
104    pub fn new(ld: [u8; 48], svn: u32, debug_enabled: bool) -> Self {
105        let info = BuildInfo {
106            debug_build: debug_enabled,
107        };
108        let measurements: MeasurementInstance<_, _> = MeasurementInstance {
109            reference: SnpLaunchMeasurement { snp_ld: ld },
110            endorsement: SnpEndorsement {
111                snp_isvsvn: svn,
112                build_info: info,
113            },
114        };
115        BaseMeasurement {
116            environment: Environment {
117                class_id: CLASS_ID_GUID.to_string(),
118            },
119            series: [measurements].to_vec(),
120        }
121    }
122}
123impl TdxMeasurement {
124    /// TDX measurement and endorsements.
125    pub fn new(mrtd: [u8; 48], svn: u32, debug_enabled: bool) -> Self {
126        let info = BuildInfo {
127            debug_build: debug_enabled,
128        };
129        let measurements: MeasurementInstance<_, _> = MeasurementInstance {
130            reference: TdxLaunchMeasurement { tdx_mrtd: mrtd },
131            endorsement: TdxEndorsement {
132                tdx_isvsvn: svn,
133                build_info: info,
134            },
135        };
136        BaseMeasurement {
137            environment: Environment {
138                class_id: CLASS_ID_GUID.to_string(),
139            },
140            series: [measurements].to_vec(),
141        }
142    }
143}
144
145impl VbsMeasurement {
146    /// VBS measurement and endorsements.
147    pub fn new(digest: [u8; 32], svn: u32, debug_enabled: bool) -> Self {
148        let info = BuildInfo {
149            debug_build: debug_enabled,
150        };
151        let measurements: MeasurementInstance<_, _> = MeasurementInstance {
152            reference: VbsLaunchMeasurement {
153                vbs_boot_digest: digest,
154            },
155            endorsement: VbsEndorsement {
156                vbs_isvsvn: svn,
157                build_info: info,
158            },
159        };
160        BaseMeasurement {
161            environment: Environment {
162                class_id: CLASS_ID_GUID.to_string(),
163            },
164            series: [measurements].to_vec(),
165        }
166    }
167}