openhcl_attestation_protocol/
vmgs.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Include modules that define the data structures of VMGS entries.
5
6use zerocopy::FromBytes;
7use zerocopy::Immutable;
8use zerocopy::IntoBytes;
9use zerocopy::KnownLayout;
10
11/// Number of the key protector entries.
12/// One for ingress, and one for egress
13pub const NUMBER_KP: usize = 2;
14
15/// DEK buffer size
16pub const DEK_BUFFER_SIZE: usize = 512;
17
18/// GSP buffer size
19pub const GSP_BUFFER_SIZE: usize = 512;
20
21/// Size of the `FileId::KEY_PROTECTOR` VMGS file entry.
22pub const KEY_PROTECTOR_SIZE: usize = size_of::<KeyProtector>();
23
24/// DEK key protector entry.
25#[repr(C)]
26#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
27pub struct DekKp {
28    /// DEK buffer
29    pub dek_buffer: [u8; DEK_BUFFER_SIZE],
30}
31
32/// GSP key protector entry.
33#[repr(C)]
34#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
35pub struct GspKp {
36    /// GSP data size
37    pub gsp_length: u32,
38    /// GSP buffer
39    pub gsp_buffer: [u8; GSP_BUFFER_SIZE],
40}
41
42/// The data format of the `FileId::KEY_PROTECTOR` entry in the VMGS file.
43#[repr(C)]
44#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
45pub struct KeyProtector {
46    /// Array of DEK entries
47    pub dek: [DekKp; NUMBER_KP],
48    /// Array of GSP entries
49    pub gsp: [GspKp; NUMBER_KP],
50    /// Index of the activate entry
51    pub active_kp: u32,
52}
53
54/// The data format of the host/fabric-provided key protector.
55#[repr(C)]
56#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
57pub struct KeyProtectorById {
58    /// Id
59    pub id_guid: guid::Guid,
60    /// Ported (boolean)
61    pub ported: u8,
62    /// Padding
63    pub pad: [u8; 3],
64}
65
66/// Maximum size of the `agent_data`.
67pub const AGENT_DATA_MAX_SIZE: usize = 2048;
68
69/// The data format of the `FileId::ATTEST` entry in the VMGS file.
70#[repr(C)]
71#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
72pub struct SecurityProfile {
73    /// the agent data used during attestation requests
74    pub agent_data: [u8; AGENT_DATA_MAX_SIZE],
75}
76
77/// The header, IV, and last 256 bits of HMAC are fixed for this version.
78/// The ciphertext is allowed to grow, though secrets should stay
79/// in the same position to allow downlevel versions to continue to understand
80/// that portion of the data.
81pub const HW_KEY_VERSION: u32 = 1; // using AES-CBC-HMAC-SHA256
82
83/// The size of the `FileId::HW_KEY_PROTECTOR` entry in the VMGS file.
84pub const HW_KEY_PROTECTOR_SIZE: usize = size_of::<HardwareKeyProtector>();
85
86/// AES-GCM key size
87pub const AES_GCM_KEY_LENGTH: usize = 32;
88
89/// AES-CBC key size
90pub const AES_CBC_KEY_LENGTH: usize = AES_GCM_KEY_LENGTH;
91
92/// AES-CVC IV size
93pub const AES_CBC_IV_LENGTH: usize = 16;
94
95/// HACK-SHA-256 key size
96pub const HMAC_SHA_256_KEY_LENGTH: usize = 32;
97
98/// The header of [`HardwareKeyProtector`].
99#[repr(C)]
100#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
101pub struct HardwareKeyProtectorHeader {
102    /// Version of the format
103    pub version: u32,
104    /// Size of the [`HardwareKeyProtector`] data blob
105    pub length: u32,
106    /// TCB version obtained from the hardware
107    pub tcb_version: u64,
108    /// Reserved
109    pub _reserved: [u8; 8],
110}
111
112impl HardwareKeyProtectorHeader {
113    /// Create a `HardwareKeyProtectorHeader` instance.
114    pub fn new(version: u32, length: u32, tcb_version: u64) -> Self {
115        Self {
116            version,
117            length,
118            tcb_version,
119            _reserved: [0u8; 8],
120        }
121    }
122}
123
124/// The data format of the `FileId::HW_KEY_PROTECTOR` entry in the VMGS file.
125#[repr(C)]
126#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
127pub struct HardwareKeyProtector {
128    /// Header
129    pub header: HardwareKeyProtectorHeader,
130    /// Random IV for AES-CBC
131    pub iv: [u8; AES_CBC_IV_LENGTH],
132    /// Encrypted key
133    pub ciphertext: [u8; AES_GCM_KEY_LENGTH],
134    /// HMAC-SHA-256 of [`header`, `iv`, `ciphertext`]
135    pub hmac: [u8; HMAC_SHA_256_KEY_LENGTH],
136}
137
138/// Maximum size of the `guest_secret_key`.
139pub const GUEST_SECRET_KEY_MAX_SIZE: usize = 2048;
140
141/// The data format of the `FileId::GUEST_SECRET_KEY` entry in the VMGS file.
142#[repr(C)]
143#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
144pub struct GuestSecretKey {
145    /// the guest secret key to be provisioned to vTPM
146    pub guest_secret_key: [u8; GUEST_SECRET_KEY_MAX_SIZE],
147}