From 5bd113e625b072781f29e56e7a94820033ddf57a Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Fri, 13 Oct 2023 12:58:56 -0700 Subject: [PATCH] hypervisor: Add API to complete isolated import This is the function that needs to be called by the VMM to inform the MSHV that isolation is complete and inform PSP about this completion. Signed-off-by: Jinank Jain Signed-off-by: Muminul Islam --- Cargo.lock | 75 ++++++++++++++++++++++++++++ hypervisor/Cargo.toml | 6 ++- hypervisor/src/mshv/mod.rs | 55 ++++++++++++++++++++ hypervisor/src/mshv/snp_constants.rs | 18 +++++++ hypervisor/src/vm.rs | 16 ++++++ 5 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 hypervisor/src/mshv/snp_constants.rs diff --git a/Cargo.lock b/Cargo.lock index a2fb7d5f1..d0c92e760 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -300,6 +300,17 @@ dependencies = [ "serde", ] +[[package]] +name = "bitfield-struct" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac32db62a43cf33353ce30b4a208b08193ea2086a1c6c004acb0073c706a29d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.31", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -478,6 +489,15 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "crc64" version = "1.0.0" @@ -938,6 +958,8 @@ dependencies = [ "byteorder", "env_logger", "iced-x86", + "igvm", + "igvm_defs", "kvm-bindings", "kvm-ioctls", "libc", @@ -967,6 +989,33 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "igvm" +version = "0.1.0" +source = "git+https://github.com/microsoft/igvm?branch=main#c1b0201d8286cb23b9f30cb16ba435484666cfa3" +dependencies = [ + "bitfield-struct", + "crc32fast", + "hex", + "igvm_defs", + "open-enum", + "range_map_vec", + "thiserror", + "tracing", + "zerocopy", +] + +[[package]] +name = "igvm_defs" +version = "0.1.0" +source = "git+https://github.com/microsoft/igvm?branch=main#c1b0201d8286cb23b9f30cb16ba435484666cfa3" +dependencies = [ + "bitfield-struct", + "open-enum", + "static_assertions", + "zerocopy", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1294,6 +1343,26 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "open-enum" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9807f1199cf84ec7cc801a79e5ee9aa5178e4762c6b9c7066c30b3cabdcd911e" +dependencies = [ + "open-enum-derive", +] + +[[package]] +name = "open-enum-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "894ae443e59fecf7173ab3b963473f44193fa71b3c8953c61a5bd5f30880bb88" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "openssl-src" version = "300.1.5+3.1.3" @@ -1641,6 +1710,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "range_map_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8edc89eaa583cf6bc4c6ef16a219f0a60d342ca3bf0eae793560038ac8af1795" + [[package]] name = "rate_limiter" version = "0.1.0" diff --git a/hypervisor/Cargo.toml b/hypervisor/Cargo.toml index bdc4acd14..1149eff18 100644 --- a/hypervisor/Cargo.toml +++ b/hypervisor/Cargo.toml @@ -8,13 +8,14 @@ license = "Apache-2.0 OR BSD-3-Clause" [features] kvm = ["kvm-ioctls", "kvm-bindings", "vfio-ioctls/kvm"] mshv = ["mshv-ioctls", "mshv-bindings", "vfio-ioctls/mshv", "iced-x86"] -sev_snp = [] +sev_snp = ["igvm_parser", "igvm_defs"] tdx = [] [dependencies] anyhow = "1.0.75" byteorder = "1.4.3" -thiserror = "1.0.40" +igvm_defs = { git = "https://github.com/microsoft/igvm", branch = "main" , package = "igvm_defs", optional = true } +igvm_parser = { git = "https://github.com/microsoft/igvm", branch = "main" , package = "igvm", optional = true } libc = "0.2.147" log = "0.4.17" kvm-ioctls = { version = "0.13.0", optional = true } @@ -26,6 +27,7 @@ serde_with = { version = "3.0.0", default-features = false, features = ["macros" vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false } vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic"] } vmm-sys-util = { version = "0.11.0", features = ["with-serde"] } +thiserror = "1.0.40" [target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86] optional = true diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index c07831b43..a7c23306d 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -20,13 +20,21 @@ use std::collections::HashMap; use std::sync::{Arc, RwLock}; use vfio_ioctls::VfioDeviceFd; use vm::DataMatch; + +#[cfg(feature = "sev_snp")] +mod snp_constants; // x86_64 dependencies #[cfg(target_arch = "x86_64")] pub mod x86_64; +#[cfg(feature = "sev_snp")] +use snp_constants::*; + use crate::{ ClockData, CpuState, IoEventAddress, IrqRoutingEntry, MpState, UserMemoryRegion, USER_MEMORY_REGION_EXECUTE, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE, }; +#[cfg(feature = "sev_snp")] +use igvm_defs::IGVM_VHS_SNP_ID_BLOCK; use vmm_sys_util::eventfd::EventFd; #[cfg(target_arch = "x86_64")] pub use x86_64::VcpuMshvState; @@ -1314,4 +1322,51 @@ impl vm::Vm for MshvVm { .import_isolated_pages(&isolated_pages[0]) .map_err(|e| vm::HypervisorVmError::ImportIsolatedPages(e.into())) } + #[cfg(feature = "sev_snp")] + fn complete_isolated_import( + &self, + snp_id_block: IGVM_VHS_SNP_ID_BLOCK, + host_data: &[u8], + id_block_enabled: u8, + ) -> vm::Result<()> { + let mut auth_info = hv_snp_id_auth_info { + id_key_algorithm: snp_id_block.id_key_algorithm, + auth_key_algorithm: snp_id_block.author_key_algorithm, + ..Default::default() + }; + // Each of r/s component is 576 bits long + auth_info.id_block_signature[..SIG_R_COMPONENT_SIZE_IN_BYTES] + .copy_from_slice(snp_id_block.id_key_signature.r_comp.as_ref()); + auth_info.id_block_signature + [SIG_R_COMPONENT_SIZE_IN_BYTES..SIG_R_AND_S_COMPONENT_SIZE_IN_BYTES] + .copy_from_slice(snp_id_block.id_key_signature.s_comp.as_ref()); + auth_info.id_key[..ECDSA_CURVE_ID_SIZE_IN_BYTES] + .copy_from_slice(snp_id_block.id_public_key.curve.to_le_bytes().as_ref()); + auth_info.id_key[ECDSA_SIG_X_COMPONENT_START..ECDSA_SIG_X_COMPONENT_END] + .copy_from_slice(snp_id_block.id_public_key.qx.as_ref()); + auth_info.id_key[ECDSA_SIG_Y_COMPONENT_START..ECDSA_SIG_Y_COMPONENT_END] + .copy_from_slice(snp_id_block.id_public_key.qy.as_ref()); + + let data = mshv_complete_isolated_import { + import_data: hv_partition_complete_isolated_import_data { + psp_parameters: hv_psp_launch_finish_data { + id_block: hv_snp_id_block { + launch_digest: snp_id_block.ld, + family_id: snp_id_block.family_id, + image_id: snp_id_block.image_id, + version: snp_id_block.version, + guest_svn: snp_id_block.guest_svn, + policy: get_default_snp_guest_policy(), + }, + id_auth_info: auth_info, + host_data: host_data[0..32].try_into().unwrap(), + id_block_enabled, + author_key_enabled: 0, + }, + }, + }; + self.fd + .complete_isolated_import(&data) + .map_err(|e| vm::HypervisorVmError::CompleteIsolatedImport(e.into())) + } } diff --git a/hypervisor/src/mshv/snp_constants.rs b/hypervisor/src/mshv/snp_constants.rs new file mode 100644 index 000000000..84e240c49 --- /dev/null +++ b/hypervisor/src/mshv/snp_constants.rs @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// +// Copyright © 2020, Microsoft Corporation +// + +// Reference: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56860.pdf +// Chapter 10 +pub const SIG_R_COMPONENT_SIZE_IN_BYTES: usize = 72; +pub const SIG_R_AND_S_COMPONENT_SIZE_IN_BYTES: usize = 144; +pub const ECDSA_CURVE_ID_SIZE_IN_BYTES: usize = 4; +pub const ECDSA_SIG_X_COMPONENT_SIZE_IN_BYTES: usize = 72; +pub const ECDSA_SIG_Y_COMPONENT_SIZE_IN_BYTES: usize = 72; +pub const ECDSA_SIG_X_COMPONENT_START: usize = ECDSA_CURVE_ID_SIZE_IN_BYTES; +pub const ECDSA_SIG_X_COMPONENT_END: usize = + ECDSA_SIG_X_COMPONENT_START + ECDSA_SIG_X_COMPONENT_SIZE_IN_BYTES; +pub const ECDSA_SIG_Y_COMPONENT_START: usize = ECDSA_SIG_X_COMPONENT_END; +pub const ECDSA_SIG_Y_COMPONENT_END: usize = + ECDSA_SIG_X_COMPONENT_END + ECDSA_SIG_Y_COMPONENT_SIZE_IN_BYTES; diff --git a/hypervisor/src/vm.rs b/hypervisor/src/vm.rs index 9f54430f3..ebe504ede 100644 --- a/hypervisor/src/vm.rs +++ b/hypervisor/src/vm.rs @@ -19,6 +19,8 @@ use crate::cpu::Vcpu; use crate::ClockData; use crate::UserMemoryRegion; use crate::{IoEventAddress, IrqRoutingEntry}; +#[cfg(feature = "sev_snp")] +use igvm_defs::IGVM_VHS_SNP_ID_BLOCK; use std::any::Any; #[cfg(target_arch = "x86_64")] use std::fs::File; @@ -225,6 +227,10 @@ pub enum HypervisorVmError { /// #[error("Failed to import isolated pages: {0}")] ImportIsolatedPages(#[source] anyhow::Error), + /// Failed to complete isolated import + /// + #[error("Failed to complete isolated import: {0}")] + CompleteIsolatedImport(#[source] anyhow::Error), } /// /// Result type for returning from a function @@ -374,6 +380,16 @@ pub trait Vm: Send + Sync + Any { ) -> Result<()> { unimplemented!() } + /// Complete the isolated import + #[cfg(feature = "sev_snp")] + fn complete_isolated_import( + &self, + _snp_id_block: IGVM_VHS_SNP_ID_BLOCK, + _host_data: &[u8], + _id_block_enabled: u8, + ) -> Result<()> { + unimplemented!() + } } pub trait VmOps: Send + Sync {