Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/measurement/sev_hashes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ use uuid::{uuid, Uuid};
use crate::error::*;
use crate::BINCODE_CFG;

type Sha256Hash = [u8; 32];
/// Alias for a 256-bit hash represented as a fixed-size array of 32 bytes.
pub type Sha256Hash = [u8; 32];

/// GUID stored as little endian
#[derive(Debug, Clone, Copy, Serialize, Default, Encode)]
Expand Down Expand Up @@ -182,6 +183,15 @@ impl SevHashes {
})
}

/// Generate hashes from the user provided kernel, initrd, and cmdline hashes.
pub fn new_raw(kernel_hash: Sha256Hash, initrd_hash: Sha256Hash, cmdline_hash: Sha256Hash) -> Self {
Self {
kernel_hash,
initrd_hash,
cmdline_hash,
}
}

/// Generate the SEV hashes area - this must be *identical* to the way QEMU
/// generates this info in order for the measurement to match.
pub fn construct_table(&self) -> Result<Vec<u8>, MeasurementError> {
Expand Down
74 changes: 73 additions & 1 deletion src/measurement/snp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
measurement::{
gctx::{Gctx, Updating, VMSA_GPA},
ovmf::{OvmfSevMetadataSectionDesc, SectionType, OVMF},
sev_hashes::SevHashes,
sev_hashes::{SevHashes, Sha256Hash},
vcpu_types::CpuType,
vmsa::{GuestFeatures, VMMType, VMSA},
},
Expand Down Expand Up @@ -237,3 +237,75 @@ pub fn snp_calc_launch_digest(

Ok(gctx.ld())
}

/// Arguments required to calculate the SNP measurement
pub struct SnpMeasurementWithHashesArgs<'a> {
/// Number of vcpus
pub vcpus: u32,
/// vcpu type
pub vcpu_type: CpuType,
/// Path to OVMF file
pub ovmf_file: PathBuf,
/// Active kernel guest features
pub guest_features: GuestFeatures,
/// Kernel hash
pub kernel_hash: Sha256Hash,
/// Initrd hash
pub initrd_hash: Sha256Hash,
/// Append arguments hash for kernel
pub append_hash: Sha256Hash,
/// Already calculated OVMF hash
pub ovmf_hash_str: Option<&'a str>,
/// vmm type
pub vmm_type: Option<VMMType>,
}

/// Calulate an SEV-SNP launch digest
pub fn snp_calc_launch_digest_with_hashes(
snp_measurement: SnpMeasurementWithHashesArgs,
) -> Result<SnpLaunchDigest, MeasurementError> {
let ovmf = OVMF::new(snp_measurement.ovmf_file)?;

let mut gctx: Gctx<Updating> = match snp_measurement.ovmf_hash_str {
Some(hash) => {
let ovmf_hash = Vec::from_hex(hash)?;
Gctx::new(ovmf_hash.as_slice())?
}
None => {
let mut gctx = Gctx::default();

gctx.update_page(PageType::Normal, ovmf.gpa(), Some(ovmf.data()), None)?;

gctx
}
};

let sev_hashes = SevHashes::new_raw(
snp_measurement.kernel_hash,
snp_measurement.initrd_hash,
snp_measurement.append_hash
);

let official_vmm_type = match snp_measurement.vmm_type {
Some(vmm) => vmm,
None => VMMType::QEMU,
};

snp_update_metadata_pages(&mut gctx, &ovmf, Some(&sev_hashes), official_vmm_type)?;

let vmsa = VMSA::new(
ovmf.sev_es_reset_eip()?.into(),
snp_measurement.vcpu_type,
official_vmm_type,
Some(snp_measurement.vcpus as u64),
snp_measurement.guest_features,
);

for vmsa_page in vmsa.pages(snp_measurement.vcpus as usize)?.iter() {
gctx.update_page(PageType::Vmsa, VMSA_GPA, Some(vmsa_page.as_slice()), None)?
}

let gctx = gctx.finished();

Ok(gctx.ld())
}
Loading