From 7657a086090c7e53fa9fc99f90e60ecc1dcb3cf1 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 9 Dec 2025 10:37:10 -0800 Subject: [PATCH] chore: allow validating SNP measurement hashes in non-linux OS Signed-off-by: Matias Fontanini --- src/launch/mod.rs | 33 +++++++++++++++++++++++++++++---- src/launch/snp.rs | 27 +-------------------------- src/lib.rs | 7 +------ src/measurement/gctx.rs | 7 ++----- src/measurement/mod.rs | 2 +- src/measurement/snp.rs | 2 +- tests/snp_launch.rs | 2 +- 7 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/launch/mod.rs b/src/launch/mod.rs index 0ab5ffc9..5fae35d4 100644 --- a/src/launch/mod.rs +++ b/src/launch/mod.rs @@ -6,12 +6,37 @@ //! AMD Secure Processor for purposes of attestation as well as abstractions //! for navigating the AMD SEV launch process for a virtual machine. -#[cfg(target_os = "linux")] -#[cfg(any(feature = "sev", feature = "snp"))] +#[cfg(all(any(feature = "sev", feature = "snp"), target_os = "linux"))] mod linux; -#[cfg(feature = "sev")] +#[cfg(all(feature = "sev", target_os = "linux"))] pub mod sev; -#[cfg(feature = "snp")] +#[cfg(all(feature = "snp", target_os = "linux"))] pub mod snp; + +/// Encoded page types for a launch update. See Table 58 of the SNP Firmware +/// specification for further details. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(C)] +#[non_exhaustive] +pub enum PageType { + /// A normal data page. + Normal = 0x1, + + /// A VMSA page. + Vmsa = 0x2, + + /// A page full of zeroes. + Zero = 0x3, + + /// A page that is encrypted but not measured + Unmeasured = 0x4, + + /// A page for the firmware to store secrets for the guest. + Secrets = 0x5, + + /// A page for the hypervisor to provide CPUID function values. + Cpuid = 0x6, +} diff --git a/src/launch/snp.rs b/src/launch/snp.rs index b2ba09ef..5b112eeb 100644 --- a/src/launch/snp.rs +++ b/src/launch/snp.rs @@ -4,6 +4,7 @@ //! This ensures (at compile time) that the right steps are called in the //! right order. +use crate::launch::PageType; #[cfg(target_os = "linux")] use crate::{ error::FirmwareError, @@ -173,32 +174,6 @@ impl Start { } } -/// Encoded page types for a launch update. See Table 58 of the SNP Firmware -/// specification for further details. -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[repr(C)] -#[non_exhaustive] -pub enum PageType { - /// A normal data page. - Normal = 0x1, - - /// A VMSA page. - Vmsa = 0x2, - - /// A page full of zeroes. - Zero = 0x3, - - /// A page that is encrypted but not measured - Unmeasured = 0x4, - - /// A page for the firmware to store secrets for the guest. - Secrets = 0x5, - - /// A page for the hypervisor to provide CPUID function values. - Cpuid = 0x6, -} - /// Encapsulates the various data needed to begin the update process. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/src/lib.rs b/src/lib.rs index 15f8fc96..d97cd811 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,13 +94,8 @@ compile_error!( pub mod certs; pub mod firmware; -#[cfg(target_os = "linux")] pub mod launch; -#[cfg(all( - any(feature = "sev", feature = "snp"), - feature = "openssl", - target_os = "linux" -))] +#[cfg(all(any(feature = "sev", feature = "snp"), feature = "openssl"))] pub mod measurement; #[cfg(all(target_os = "linux", feature = "openssl", feature = "sev"))] pub mod session; diff --git a/src/measurement/gctx.rs b/src/measurement/gctx.rs index ecbca8c9..5d69488c 100644 --- a/src/measurement/gctx.rs +++ b/src/measurement/gctx.rs @@ -4,11 +4,9 @@ use std::convert::TryInto; use openssl::sha::sha384; -use crate::error::*; - -#[cfg(target_os = "linux")] use crate::{ - launch::snp::PageType, + error::*, + launch::PageType, measurement::snp::{SnpLaunchDigest, LD_BYTES}, }; @@ -93,7 +91,6 @@ impl Gctx { /// Update Lanunch digest type according to page type and guest physical address. /// Some Page types don't require data. Some page types just require size of the page. - #[cfg(target_os = "linux")] pub fn update_page( &mut self, page_type: PageType, diff --git a/src/measurement/mod.rs b/src/measurement/mod.rs index 99cf46ec..9bf9fb55 100644 --- a/src/measurement/mod.rs +++ b/src/measurement/mod.rs @@ -3,7 +3,7 @@ //! Everything one needs to calculate a launch measurement for a SEV encrypted confidential guest. //! This includes, GCTX, SEV-HASHES, VMSA and OVMF pages. -#[cfg(all(target_os = "linux", feature = "snp", feature = "openssl"))] +#[cfg(all(feature = "snp", feature = "openssl"))] pub mod gctx; #[cfg(any(feature = "sev", feature = "snp"))] diff --git a/src/measurement/snp.rs b/src/measurement/snp.rs index 51629b5b..206c5224 100644 --- a/src/measurement/snp.rs +++ b/src/measurement/snp.rs @@ -3,7 +3,7 @@ //! Operations to calculate guest measurement for different SEV modes use crate::{ error::*, - launch::snp::PageType, + launch::PageType, measurement::{ gctx::{Gctx, Updating, VMSA_GPA}, ovmf::{OvmfSevMetadataSectionDesc, SectionType, OVMF}, diff --git a/tests/snp_launch.rs b/tests/snp_launch.rs index 47284555..cabfd54b 100644 --- a/tests/snp_launch.rs +++ b/tests/snp_launch.rs @@ -5,7 +5,7 @@ use kvm_bindings::{kvm_create_guest_memfd, kvm_userspace_memory_region2, KVM_MEM_GUEST_MEMFD}; use kvm_ioctls::{Kvm, VcpuExit}; use sev::firmware::{guest::GuestPolicy, host::Firmware}; -use sev::launch::snp::*; +use sev::launch::{snp::*, PageType}; use std::os::fd::RawFd; use std::slice::from_raw_parts_mut;