From c56609b6f6003ca0aca5a11aa089fcb537b88282 Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Tue, 20 Jun 2023 13:18:54 +0000 Subject: [PATCH] attester: az_snp_vtpm: Check cpuid bits in detect_platform() It took a while to realize that we can check cpuid registers exposed by Hyper-V to determine whether we are in an SNP VM that can use the az-snp-vtpm attester. Rework detect_platform() to perform these checks. Signed-off-by: Jeremi Piotrowski --- attestation-agent/attester/Cargo.toml | 3 +- .../attester/src/az_snp_vtpm/mod.rs | 34 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/attestation-agent/attester/Cargo.toml b/attestation-agent/attester/Cargo.toml index 9c85bd144..db485277d 100644 --- a/attestation-agent/attester/Cargo.toml +++ b/attestation-agent/attester/Cargo.toml @@ -11,6 +11,7 @@ az-snp-vtpm = { git = "https://github.com/kinvolk/azure-cvm-tooling", rev = "2c2 base64.workspace = true log.workspace = true occlum_dcap = { git = "https://github.com/occlum/occlum", rev = "dbe404f", optional = true } +raw-cpuid = { version = "11", optional = true } serde.workspace = true serde_json.workspace = true sev = { git = "https://github.com/virtee/sev", rev = "3dca05d2c93388cb00534ad18f5928fd812e99cc", optional = true } @@ -23,5 +24,5 @@ all-attesters = ["tdx-attester", "occlum-attester", "az-snp-vtpm-attester", "snp tdx-attester = ["tdx-attest-rs"] occlum-attester = ["occlum_dcap"] -az-snp-vtpm-attester = ["az-snp-vtpm"] +az-snp-vtpm-attester = ["az-snp-vtpm", "dep:raw-cpuid"] snp-attester = ["sev"] diff --git a/attestation-agent/attester/src/az_snp_vtpm/mod.rs b/attestation-agent/attester/src/az_snp_vtpm/mod.rs index 49cbcb79b..0e7def9e0 100644 --- a/attestation-agent/attester/src/az_snp_vtpm/mod.rs +++ b/attestation-agent/attester/src/az_snp_vtpm/mod.rs @@ -7,11 +7,41 @@ use super::Attester; use anyhow::*; use az_snp_vtpm::{imds, vtpm}; use log::debug; +use raw_cpuid::{cpuid, CpuId, Hypervisor}; use serde::{Deserialize, Serialize}; +use std::path::Path; pub fn detect_platform() -> bool { - if let Err(err) = vtpm::get_report() { - debug!("Failed to retrieve Azure HCL data from vTPM: {err}"); + if !Path::new("/dev/tpm0").exists() { + debug!("vTPM device not found"); + return false; + } + + let cpuid = CpuId::new(); + let Some(hyper_info) = cpuid.get_hypervisor_info() else { + debug!("Not a VM"); + return false; + }; + let hypervisor = hyper_info.identify(); + debug!("Hypervisor: {:?}", hypervisor); + if hypervisor != Hypervisor::HyperV { + return false; + } + + const HYPERV_CPUID_FEATURES: u32 = 0x40000003; + const HV_ISOLATION: u32 = 1 << 22; + let hv_features = cpuid!(HYPERV_CPUID_FEATURES); + if hv_features.ebx & HV_ISOLATION == 0 { + debug!("VM is not an isolation VM"); + return false; + } + + const HYPERV_CPUID_ISOLATION_CONFIG: u32 = 0x4000000C; + const HV_ISOLATION_TYPE: u32 = 0xF; + const HV_ISOLATION_TYPE_SNP: u32 = 2; + let hv_isol_config = cpuid!(HYPERV_CPUID_ISOLATION_CONFIG); + if hv_isol_config.ebx & HV_ISOLATION_TYPE != HV_ISOLATION_TYPE_SNP { + debug!("VM is not an SNP VM"); return false; } true