From 1a4c890f831bca62624945c6ca4e829bc050ebd1 Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Thu, 8 Feb 2024 11:53:56 -0800 Subject: [PATCH] vmm: pass host data to SevSnp guest Host data that is passed to the hypervisor. Then the firmware includes the data in the attestation report. The data might include any key or secret that the SevSnp guest might need later. Signed-off-by: Muminul Islam --- vmm/src/igvm/igvm_loader.rs | 14 ++++++++++++-- vmm/src/vm.rs | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/vmm/src/igvm/igvm_loader.rs b/vmm/src/igvm/igvm_loader.rs index 09f076af0..8d6b9adb7 100644 --- a/vmm/src/igvm/igvm_loader.rs +++ b/vmm/src/igvm/igvm_loader.rs @@ -53,6 +53,8 @@ pub enum Error { ImportIsolatedPages(#[source] hypervisor::HypervisorVmError), #[error("Error completing importing isolated pages: {0}")] CompleteIsolatedImport(#[source] hypervisor::HypervisorVmError), + #[error("Error decoding host data: {0}")] + FailedToDecodeHostData(#[source] hex::FromHexError), } #[allow(dead_code)] @@ -141,6 +143,7 @@ pub fn load_igvm( memory_manager: Arc>, cpu_manager: Arc>, cmdline: &str, + #[cfg(feature = "sev_snp")] host_data: &Option, ) -> Result, Error> { let mut loaded_info: Box = Box::default(); let command_line = CString::new(cmdline).map_err(Error::InvalidCommandLine)?; @@ -149,6 +152,14 @@ pub fn load_igvm( let mut gpas: Vec = Vec::new(); let proc_count = cpu_manager.lock().unwrap().vcpus().len() as u32; + #[cfg(feature = "sev_snp")] + let mut host_data_contents = [0; 32]; + #[cfg(feature = "sev_snp")] + if let Some(host_data_str) = host_data { + hex::decode_to_slice(host_data_str, &mut host_data_contents as &mut [u8]) + .map_err(Error::FailedToDecodeHostData)?; + } + file.seek(SeekFrom::Start(0)).map_err(Error::Igvm)?; file.read_to_end(&mut file_contents).map_err(Error::Igvm)?; @@ -470,12 +481,11 @@ pub fn load_igvm( now = Instant::now(); // Call Complete Isolated Import since we are done importing isolated pages - let host_data: [u8; 32] = [0; 32]; memory_manager .lock() .unwrap() .vm - .complete_isolated_import(loaded_info.snp_id_block, host_data, 1) + .complete_isolated_import(loaded_info.snp_id_block, host_data_contents, 1) .map_err(Error::CompleteIsolatedImport)?; info!( diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 53a6721ca..da8a627e3 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -574,7 +574,13 @@ impl Vm { // per cpuid through cpu_manager. #[cfg(feature = "igvm")] let load_payload_handle = if snapshot.is_none() { - Self::load_payload_async(&memory_manager, &config, &cpu_manager)? + Self::load_payload_async( + &memory_manager, + &config, + &cpu_manager, + #[cfg(feature = "sev_snp")] + sev_snp_enabled, + )? } else { None }; @@ -1006,9 +1012,17 @@ impl Vm { igvm: File, memory_manager: Arc>, cpu_manager: Arc>, + #[cfg(feature = "sev_snp")] host_data: &Option, ) -> Result { - let res = igvm_loader::load_igvm(&igvm, memory_manager, cpu_manager.clone(), "") - .map_err(Error::IgvmLoad)?; + let res = igvm_loader::load_igvm( + &igvm, + memory_manager, + cpu_manager.clone(), + "", + #[cfg(feature = "sev_snp")] + host_data, + ) + .map_err(Error::IgvmLoad)?; cfg_if::cfg_if! { if #[cfg(feature = "sev_snp")] { @@ -1087,12 +1101,20 @@ impl Vm { payload: &PayloadConfig, memory_manager: Arc>, #[cfg(feature = "igvm")] cpu_manager: Arc>, + #[cfg(feature = "sev_snp")] sev_snp_enabled: bool, ) -> Result { trace_scoped!("load_payload"); #[cfg(feature = "igvm")] - if let Some(_igvm_file) = &payload.igvm { - let igvm = File::open(_igvm_file).map_err(Error::IgvmFile)?; - return Self::load_igvm(igvm, memory_manager, cpu_manager); + { + if let Some(_igvm_file) = &payload.igvm { + let igvm = File::open(_igvm_file).map_err(Error::IgvmFile)?; + #[cfg(feature = "sev_snp")] + if sev_snp_enabled { + return Self::load_igvm(igvm, memory_manager, cpu_manager, &payload.host_data); + } + #[cfg(not(feature = "sev_snp"))] + return Self::load_igvm(igvm, memory_manager, cpu_manager); + } } match ( &payload.firmware, @@ -1135,6 +1157,7 @@ impl Vm { memory_manager: &Arc>, config: &Arc>, #[cfg(feature = "igvm")] cpu_manager: &Arc>, + #[cfg(feature = "sev_snp")] sev_snp_enabled: bool, ) -> Result>>> { // Kernel with TDX is loaded in a different manner #[cfg(feature = "tdx")] @@ -1161,6 +1184,8 @@ impl Vm { memory_manager, #[cfg(feature = "igvm")] cpu_manager, + #[cfg(feature = "sev_snp")] + sev_snp_enabled, ) }) .map_err(Error::KernelLoadThreadSpawn)