diff --git a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs index bf504f394b..14afb19a10 100644 --- a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs +++ b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs @@ -37,13 +37,19 @@ use kata_types::capabilities::CapabilityBits; use kata_types::config::hypervisor::Hypervisor as HypervisorConfig; use kata_types::config::hypervisor::HYPERVISOR_NAME_CH; use kata_types::config::TomlConfig; +use kata_types::initdata::{calculate_initdata_digest, ProtectedPlatform}; use oci_spec::runtime as oci; use persist::{self, sandbox_persist::Persist}; use protobuf::SpecialFields; +use resource::coco_data::initdata::{ + InitDataConfig, KATA_INIT_DATA_IMAGE, KATA_SHARED_INIT_DATA_PATH, +}; +use resource::coco_data::initdata_block; use resource::manager::ManagerArgs; use resource::network::{dan_config_path, DanNetworkConfig, NetworkConfig, NetworkWithNetNsConfig}; use resource::{ResourceConfig, ResourceManager}; use runtime_spec as spec; +use std::path::Path; use std::sync::Arc; use strum::Display; use tokio::sync::{mpsc::Sender, Mutex, RwLock}; @@ -157,6 +163,19 @@ impl VirtSandbox { resource_configs.push(vm_rootfs); } + // prepare protection device config + let _init_data = if let Some(initdata) = self + .prepare_initdata_device_config(&self.hypervisor.hypervisor_config().await) + .await + .context("failed to prepare initdata device config")? + { + resource_configs.push(ResourceConfig::InitData(initdata.0)); + + Some(initdata.1) + } else { + None + }; + // prepare protection device config if let Some(protection_dev_config) = self .prepare_protection_device_config(&self.hypervisor.hypervisor_config().await) @@ -411,6 +430,55 @@ impl VirtSandbox { } } + async fn prepare_initdata_device_config( + &self, + hypervisor_config: &HypervisorConfig, + ) -> Result> { + let initdata = hypervisor_config.security_info.initdata.clone(); + if initdata.is_empty() { + return Ok(None); + } + info!(sl!(), "Init Data Content String: {:?}", &initdata); + let available_protection = available_guest_protection()?; + info!( + sl!(), + "sandbox: available protection: {:?}", available_protection + ); + let initdata_digest = match available_protection { + GuestProtection::Tdx => calculate_initdata_digest(&initdata, ProtectedPlatform::Tdx)?, + GuestProtection::Snp(_details) => { + calculate_initdata_digest(&initdata, ProtectedPlatform::Snp)? + } + // TODO: there's more `GuestProtection` types to be supported. + _ => return Ok(None), + }; + info!( + sl!(), + "calculate initdata: {:?} with initdata digest {:?}", &initdata, &initdata_digest + ); + + // initdata within compressed rawblock + let image_path = Path::new(KATA_SHARED_INIT_DATA_PATH) + .join(&self.sid) + .join(KATA_INIT_DATA_IMAGE); + initdata_block::push_data(&image_path, &initdata)?; + info!( + sl!(), + "initdata push data into compressed block: {:?}", &image_path + ); + let block_driver = &hypervisor_config.boot_info.vm_rootfs_driver; + let block_config = BlockConfig { + path_on_host: image_path.display().to_string(), + is_readonly: true, + driver_option: block_driver.clone(), + ..Default::default() + }; + let initdata_config = InitDataConfig(block_config, initdata_digest); + info!(sl!(), "initdata config: {:?}", initdata_config.clone()); + + Ok(Some(initdata_config)) + } + fn has_prestart_hooks( &self, prestart_hooks: &[oci::Hook],