Skip to content

Commit 319b24f

Browse files
rjzakharaldh
authored andcommitted
Adding additional SNP field validations
Co-authored-by: Harald Hoyer <[email protected]> Signed-off-by: Richard Zak <[email protected]>
1 parent 772803f commit 319b24f

File tree

1 file changed

+111
-8
lines changed

1 file changed

+111
-8
lines changed

src/ext/snp/mod.rs

+111-8
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct Evidence<'a> {
2626
}
2727

2828
flags! {
29-
pub enum Flags: u8 {
29+
pub enum PolicyFlags: u8 {
3030
/// Indicates if only one socket is permitted
3131
SingleSocket = 1 << 4,
3232
/// Indicates if debugging is permitted
@@ -38,6 +38,11 @@ flags! {
3838
/// Indicates if SMT is permitted
3939
SMT = 1 << 0,
4040
}
41+
42+
pub enum PlatformInfoFlags: u8 {
43+
TSME = 1 << 1,
44+
SMT = 1 << 0,
45+
}
4146
}
4247

4348
#[repr(C, packed)]
@@ -48,17 +53,26 @@ pub struct Policy {
4853
/// Minimum ABI major version required for the guest to run
4954
pub abi_major: u8,
5055
/// Bit fields indicating enabled features
51-
pub flags: FlagSet<Flags>,
56+
pub flags: FlagSet<PolicyFlags>,
5257
/// Reserved, must be zero
5358
rsvd: [u8; 5],
5459
}
5560

61+
#[repr(C, packed)]
62+
#[derive(Copy, Clone, Debug)]
63+
pub struct PlatformInfo {
64+
/// Bit fields indicating enabled features
65+
pub flags: FlagSet<PlatformInfoFlags>,
66+
/// Reserved
67+
rsvd: [u8; 7],
68+
}
69+
5670
#[repr(C, packed)]
5771
#[derive(Copy, Clone, Debug)]
5872
struct Body {
5973
/// The version of the attestation report, currently 2
6074
pub version: u32,
61-
/// Guest SVN
75+
/// Guest Security Version Number (SVN)
6276
pub guest_svn: u32,
6377
/// The guest policy
6478
/// This indicates the required version of the firmware, and if debugging is enabled.
@@ -67,14 +81,14 @@ struct Body {
6781
pub family_id: [u8; 16],
6882
/// The image ID provided at launch
6983
pub image_id: [u8; 16],
70-
/// The guest VMPL for the attestation report
84+
/// The guest Virtual Machine Privilege Level (VMPL) for the attestation report
7185
pub vmpl: u32,
7286
/// The signature algorithm used to sign this report
7387
pub sig_algo: u32,
7488
/// Current TCB
7589
pub plat_version: u64,
7690
/// Platform information
77-
pub plat_info: u64,
91+
pub plat_info: PlatformInfo,
7892
/// Indicates (zero or one) that the digest of the author key is in `author_key_digest`
7993
/// The other bits are reserved and must be zero.
8094
pub author_key_en: u32,
@@ -100,8 +114,28 @@ struct Body {
100114
rsvd2: [u8; 24],
101115
/// The identifier unique to the chip, optionally masked and set to zero
102116
pub chip_id: [u8; 64],
117+
/// Committed TCB
118+
pub committed_tcb: u64,
119+
/// The build number of the Current Version
120+
pub current_build: u8,
121+
/// The minor number of the Current Version
122+
pub current_minor: u8,
123+
/// The major number of the Current Version
124+
pub current_major: u8,
125+
/// Reserved, must be zero
126+
rsvd3: u8,
127+
/// The build number of the Committed Version
128+
pub committed_build: u8,
129+
/// The minor number of the Committed Version
130+
pub committed_minor: u8,
131+
/// The major number of the Committed Version
132+
pub committed_major: u8,
103133
/// Reserved, must be zero
104-
rsvd3: [u8; 192],
134+
rsvd4: u8,
135+
/// The Current TCB at the time the guest was launched or imported
136+
pub launch_tcb: u64,
137+
/// Reserved, must be zero
138+
rsvd5: [u8; 168],
105139
}
106140

107141
impl AsRef<[u8; size_of::<Self>()]> for Body {
@@ -254,22 +288,91 @@ impl ExtVerifier for Snp {
254288

255289
// TODO: additional field validations.
256290

291+
// Should only be version 2
257292
if report.body.version != 2 {
258293
return Err(anyhow!("snp report is an unknown version"));
259294
}
260295

261-
if !report.body.policy.flags.contains(Flags::Reserved) {
296+
// Check policy
297+
if !report.body.policy.flags.contains(PolicyFlags::Reserved) {
262298
return Err(anyhow!("snp guest policy mandatory reserved flag not set"));
263299
}
264300

301+
if report.body.policy.flags.contains(PolicyFlags::MigrateMA) {
302+
return Err(anyhow!("snp guest policy migration flag was set"));
303+
}
304+
305+
// Check reserved fields
306+
if report.body.rsvd1 != 0 || report.body.rsvd3 != 0 || report.body.rsvd4 != 0 {
307+
return Err(anyhow!("snp report reserved fields were set"));
308+
}
309+
310+
for value in report.body.rsvd2 {
311+
if value != 0 {
312+
return Err(anyhow!("snp report reserved fields were set"));
313+
}
314+
}
315+
316+
for value in report.body.rsvd5 {
317+
if value != 0 {
318+
return Err(anyhow!("snp report reserved fields were set"));
319+
}
320+
}
321+
322+
for value in report.body.policy.rsvd {
323+
if value != 0 {
324+
return Err(anyhow!("snp report policy reserved fields were set"));
325+
}
326+
}
327+
328+
for value in report.body.plat_info.rsvd {
329+
if value != 0 {
330+
return Err(anyhow!("snp report platform_info reserved fields were set"));
331+
}
332+
}
333+
334+
// Check fields not set by Enarx
335+
for value in report.body.author_key_digest {
336+
if value != 0 {
337+
return Err(anyhow!("snp report author_key_digest field not set by Enarx"));
338+
}
339+
}
340+
341+
for value in report.body.host_data {
342+
if value != 0 {
343+
return Err(anyhow!("snp report host_data field not set by Enarx"));
344+
}
345+
}
346+
347+
for value in report.body.id_key_digest {
348+
if value != 0 {
349+
return Err(anyhow!("snp report id_key_digest field not set by Enarx"));
350+
}
351+
}
352+
353+
if report.body.vmpl != 0 {
354+
return Err(anyhow!("snp report vmpl field not set by Enarx"));
355+
}
356+
357+
if report.body.guest_svn != 0 {
358+
return Err(anyhow!("snp report guest_svn field not set by Enarx"));
359+
}
360+
361+
// Check field set by Enarx
362+
for value in report.body.report_id_ma {
363+
if value != 255 {
364+
return Err(anyhow!("snp report report_id_ma field not the value set by Enarx"));
365+
}
366+
}
367+
265368
if !dbg {
266369
// Validate that the certification request came from an SNP VM.
267370
let hash = sha2::Sha384::digest(&cri.public_key.to_vec()?);
268371
if hash.as_slice() != &report.body.report_data[..hash.as_slice().len()] {
269372
return Err(anyhow!("snp report.report_data is invalid"));
270373
}
271374

272-
if report.body.policy.flags.contains(Flags::Debug) {
375+
if report.body.policy.flags.contains(PolicyFlags::Debug) {
273376
return Err(anyhow!("snp guest policy permits debugging"));
274377
}
275378
}

0 commit comments

Comments
 (0)