vbs_defs/
lib.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4// Virtualization Based Security (VBS) platform definitions defined by Hyper-V
5
6#![expect(missing_docs)]
7#![forbid(unsafe_code)]
8#![allow(non_camel_case_types)]
9
10use bitfield_struct::bitfield;
11use igvm_defs::PAGE_SIZE_4K;
12use open_enum::open_enum;
13use static_assertions::const_assert;
14use zerocopy::Immutable;
15use zerocopy::IntoBytes;
16use zerocopy::KnownLayout;
17
18pub const VBS_VP_CHUNK_SIZE_BYTES: usize = PAGE_SIZE_4K as usize + size_of::<VpGpaPageChunk>();
19
20/// Structure containing the completed VBS boot measurement of the IGVM file.
21/// The signature of the hash of this struct is the signature for [`igvm_defs::IGVM_VHS_VBS_MEASUREMENT`]
22#[repr(C)]
23#[derive(IntoBytes, Immutable, KnownLayout, Debug)]
24pub struct VBS_VM_BOOT_MEASUREMENT_SIGNED_DATA {
25    /// The version of the signature structure
26    pub version: u32,
27    /// The user supplied product id
28    pub product_id: u32,
29    /// The uesr supplied module id
30    pub module_id: u32,
31    /// The user supplied svn
32    pub security_version: u32,
33    /// Security policy for the guest
34    pub security_policy: VBS_POLICY_FLAGS,
35    /// Algorithm that created the boot digest hash
36    pub boot_digest_algo: u32,
37    /// Algorithm that produces the signature
38    pub signing_algo: u32,
39    /// VBS Boot digest
40    pub boot_measurement_digest: [u8; 32],
41}
42
43/// Chunk that is measured to generate digest. These consist of a 16 byte header followed by data.
44/// This needs c style alignment to generate a consistent measurement.
45/// Defined by the following struct in C:
46/// ``` ignore
47/// typedef struct _VBS_VM_BOOT_MEASUREMENT_CHUNK
48/// {
49///     UINT32 ByteCount;
50///     VBS_VM_BOOT_MEASUREMENT_CHUNK_TYPE Type;
51///     UINT64 Reserved;
52///
53///     union
54///     {
55///         VBS_VM_BOOT_MEASUREMENT_CHUNK_VP_REGISTER VpRegister;
56///         VBS_VM_BOOT_MEASUREMENT_CHUNK_VP_VTL_ENABLED VpVtlEnabled;
57///         VBS_VM_BOOT_MEASUREMENT_CHUNK_GPA_PAGE GpaPage;
58///     } u;
59/// } VBS_VM_BOOT_MEASUREMENT_CHUNK, *PVBS_VM_BOOT_MEASUREMENT_CHUNK;
60/// ```
61///
62/// Structure describing the chunk to be measured
63#[repr(C)]
64#[derive(IntoBytes, Immutable, KnownLayout)]
65pub struct VbsChunkHeader {
66    /// The full size to be measured
67    pub byte_count: u32,
68    pub chunk_type: BootMeasurementType,
69    pub reserved: u64,
70}
71
72/// Structure describing the register being measured. Will be padded to [`VBS_VP_CHUNK_SIZE_BYTES`] when hashed to generate digest
73#[repr(C)]
74#[derive(IntoBytes, Immutable, KnownLayout)]
75pub struct VbsRegisterChunk {
76    pub header: VbsChunkHeader,
77    pub reserved: u32,
78    pub vtl: u8,
79    pub reserved2: u8,
80    pub reserved3: u16,
81    pub reserved4: u32,
82    pub name: u32,
83    pub value: [u8; 16],
84}
85const_assert!(size_of::<VbsRegisterChunk>() <= VBS_VP_CHUNK_SIZE_BYTES);
86
87/// Structure describing the page to be measured.
88/// Page data is hashed after struct to generate digest, if not a full page, measurable data will be padded to [`VBS_VP_CHUNK_SIZE_BYTES`]
89#[repr(C)]
90#[derive(IntoBytes, Immutable, KnownLayout)]
91pub struct VpGpaPageChunk {
92    pub header: VbsChunkHeader,
93    pub metadata: u64,
94    pub page_number: u64,
95}
96
97open_enum! {
98#[derive(IntoBytes, Immutable, KnownLayout)]
99pub enum BootMeasurementType: u32 {
100    VP_REGISTER = 0,
101    VP_VTL_ENABLED = 1,
102    VP_GPA_PAGE = 2,
103}
104}
105
106/// Flags indicating read and write acceptance of a GPA Page and whether it is
107/// to be measured in the digest
108#[bitfield(u64)]
109pub struct VBS_VM_GPA_PAGE_BOOT_METADATA {
110    #[bits(2)]
111    pub acceptance: u64,
112    #[bits(1)]
113    pub data_unmeasured: bool,
114    #[bits(61)]
115    reserved: u64,
116}
117
118/// Flags defining the security policy for the guest
119#[bitfield(u32)]
120#[derive(IntoBytes, Immutable, KnownLayout)]
121pub struct VBS_POLICY_FLAGS {
122    /// Guest supports debugging
123    #[bits(1)]
124    pub debug: bool,
125    #[bits(31)]
126    reserved: u32,
127}
128pub const VM_GPA_PAGE_READABLE: u64 = 0x1;
129pub const VM_GPA_PAGE_WRITABLE: u64 = 0x2;