diff --git a/Cargo.lock b/Cargo.lock index 0def329e..141af01d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -289,6 +289,36 @@ dependencies = [ "typenum", ] +[[package]] +name = "curl" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +dependencies = [ + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2", + "winapi", +] + +[[package]] +name = "curl-sys" +version = "0.4.70+curl-8.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0333d8849afe78a4c8102a429a446bfdd055832af071945520e835ae2d841e" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "windows-sys", +] + [[package]] name = "der" version = "0.4.5" @@ -543,6 +573,18 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linked_list_allocator" version = "0.10.5" @@ -629,6 +671,17 @@ dependencies = [ "td-uefi-pi", ] +[[package]] +name = "migtd-policy-generator" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "curl", + "serde", + "serde_json", +] + [[package]] name = "minicov" version = "0.2.4" @@ -654,6 +707,24 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parse_int" version = "0.6.0" @@ -676,6 +747,12 @@ dependencies = [ "x86", ] +[[package]] +name = "pkg-config" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" + [[package]] name = "policy" version = "0.1.0" @@ -875,6 +952,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -943,6 +1029,16 @@ dependencies = [ "digest", ] +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "spin" version = "0.5.2" @@ -1266,6 +1362,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index a25f1ee0..377fb10b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "src/policy", "tests/test-td-payload", "tools/migtd-hash", + "tools/migtd-policy-generator", "xtask", ] diff --git a/tools/migtd-policy-generator/Cargo.toml b/tools/migtd-policy-generator/Cargo.toml new file mode 100644 index 00000000..df0d93f2 --- /dev/null +++ b/tools/migtd-policy-generator/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "migtd-policy-generator" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0" +clap = { version = "4.0", features = ["derive"] } +curl = "0.4.44" +serde = { version = "1.0", features = ["derive"]} +serde_json = "1.0" \ No newline at end of file diff --git a/tools/migtd-policy-generator/readme.md b/tools/migtd-policy-generator/readme.md new file mode 100644 index 00000000..09d02814 --- /dev/null +++ b/tools/migtd-policy-generator/readme.md @@ -0,0 +1,28 @@ +## migtd-policy-generator tool + +This tool can be used to fetch the platform TCB and enclave information from backend server and generate the migtd policy based on the values. + +### How to build + +``` +pushd tools/migtd-policy-generator +cargo build +popd +``` + +### How to use + +- Help + ``` + ./target/debug/migtd-policy-generator -h + ``` + +- Generate migtd policy for production platforms: + ``` + ./target/debug/migtd-policy-generator -o config/policy_production_fmspc.json + ``` + +- Generate migtd policy for pre-production platforms: + ``` + ./target/debug/migtd-policy-generator -o config/policy_pre_production_fmspc.json --pre-production + ``` diff --git a/tools/migtd-policy-generator/src/lib.rs b/tools/migtd-policy-generator/src/lib.rs new file mode 100644 index 00000000..68c8a9b6 --- /dev/null +++ b/tools/migtd-policy-generator/src/lib.rs @@ -0,0 +1,26 @@ +// Copyright (c) 2023 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent + +use curl::easy::Easy; + +pub mod platform_tcb; +pub mod policy; +pub mod qe_identity; + +pub(crate) fn fetch_data_from_url(url: &str) -> Result<(u32, Vec), curl::Error> { + let mut handle = Easy::new(); + let mut data = Vec::new(); + + handle.url(url)?; + { + let mut transfer = handle.transfer(); + transfer.write_function(|new_data| { + data.extend_from_slice(new_data); + Ok(new_data.len()) + })?; + transfer.perform()?; + } + + Ok((handle.response_code()?, data)) +} diff --git a/tools/migtd-policy-generator/src/main.rs b/tools/migtd-policy-generator/src/main.rs new file mode 100644 index 00000000..60d38c4f --- /dev/null +++ b/tools/migtd-policy-generator/src/main.rs @@ -0,0 +1,31 @@ +// Copyright (c) 2023 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent + +use clap::Parser; +use migtd_policy_generator::policy::generate_policy; +use std::{fs, path::PathBuf, process::exit}; + +#[derive(Debug, Clone, Parser)] +struct Config { + /// Set to use pre-prodution server. Production server is used by + /// default. + #[clap(long)] + pub pre_production: bool, + /// Where to write the generated policy + #[clap(long, short)] + pub output: PathBuf, +} + +fn main() { + let config = Config::parse(); + + let policy = generate_policy(!config.pre_production).unwrap_or_else(|e| { + eprintln!("Failed to generate policy: {}", e); + exit(1); + }); + fs::write(config.output, &policy).unwrap_or_else(|e| { + eprintln!("Failed to write output file: {}", e); + exit(1); + }) +} diff --git a/tools/migtd-policy-generator/src/platform_tcb/fmspc.rs b/tools/migtd-policy-generator/src/platform_tcb/fmspc.rs new file mode 100644 index 00000000..56bca831 --- /dev/null +++ b/tools/migtd-policy-generator/src/platform_tcb/fmspc.rs @@ -0,0 +1,58 @@ +// Copyright (c) 2023 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent + +use anyhow::{anyhow, Result}; +use serde::Deserialize; + +use crate::fetch_data_from_url; + +const FMSPC_LIST_URL: &str = "https://api.trustedservices.intel.com/sgx/certification/v4/fmspcs"; +const SBX_FMSPC_LIST_URL: &str = + "https://sbx.api.trustedservices.intel.com/sgx/certification/v4/fmspcs"; + +pub fn fetch_fmspc_list(for_production: bool) -> Result> { + let fmspc_list_url = if for_production { + FMSPC_LIST_URL + } else { + SBX_FMSPC_LIST_URL + }; + + let (response_code, data) = fetch_data_from_url(fmspc_list_url)?; + match response_code { + 200 => Ok(serde_json::from_slice::>(&data)?), + _ => { + eprintln!("Error fetching fmspc list - {:?}", response_code); + Err(anyhow!("AccessException")) + } + } +} + +pub fn get_all_e5_platform(list: &Vec) -> Vec<&Fmspc> { + list.iter() + .filter(|p| p.platform.as_str() == "E5") + .collect() +} + +#[derive(Debug, Deserialize)] +pub struct Fmspc { + pub fmspc: String, + platform: String, +} + +impl Fmspc { + pub fn is_e5(&self) -> bool { + self.platform.as_str() == "E5" + } +} + +mod test { + #[test] + fn test_json_deserialize() { + use crate::platform_tcb::fmspc::Fmspc; + + let list = include_str!("../../test/fmspc_list.json"); + let result = serde_json::from_str::>(list); + assert!(result.is_ok()); + } +} diff --git a/tools/migtd-policy-generator/src/platform_tcb/mod.rs b/tools/migtd-policy-generator/src/platform_tcb/mod.rs new file mode 100644 index 00000000..19f0fd1b --- /dev/null +++ b/tools/migtd-policy-generator/src/platform_tcb/mod.rs @@ -0,0 +1,33 @@ +// Copyright (c) 2023 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent + +use anyhow::Result; + +use crate::policy::PlatformPolicy; +use fmspc::{fetch_fmspc_list, get_all_e5_platform}; +use tcb_info::fetch_platform_tcb; + +pub mod fmspc; +pub mod tcb_info; + +pub fn get_platform_info(for_production: bool) -> Result> { + match fetch_fmspc_list(for_production) { + Ok(list) => { + let mut platforms = Vec::new(); + for platform in get_all_e5_platform(&list) { + if let Ok(platform_tcb) = fetch_platform_tcb(for_production, &platform.fmspc) { + if let Some(platform_tcb) = platform_tcb { + let platform = PlatformPolicy::new(&platform_tcb); + platforms.push(platform); + } + } + } + Ok(platforms) + } + Err(err) => { + eprintln!("Error fetching fmspc list: {}", err); + Err(err.into()) + } + } +} diff --git a/tools/migtd-policy-generator/src/platform_tcb/tcb_info.rs b/tools/migtd-policy-generator/src/platform_tcb/tcb_info.rs new file mode 100644 index 00000000..3130ad49 --- /dev/null +++ b/tools/migtd-policy-generator/src/platform_tcb/tcb_info.rs @@ -0,0 +1,90 @@ +// Copyright (c) 2023 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent + +use anyhow::Result; +use serde::Deserialize; + +use crate::fetch_data_from_url; + +const TCB_INFO_URL: &str = "https://api.trustedservices.intel.com/tdx/certification/v4/tcb"; +const SBX_TCB_INFO_URL: &str = "https://sbx.api.trustedservices.intel.com/tdx/certification/v4/tcb"; + +pub fn fetch_platform_tcb(for_production: bool, fmspc: &str) -> Result> { + let tcb_info_url = if for_production { + TCB_INFO_URL + } else { + SBX_TCB_INFO_URL + }; + let url = format!("{}?fmspc={}", tcb_info_url, fmspc); + let (response_code, data) = fetch_data_from_url(&url)?; + + let result = if response_code == 200 { + println!("Got TCB info of fmspc - {}", fmspc,); + Some(serde_json::from_slice::(&data)?) + } else if response_code == 404 { + // Ignore 404 errors + None + } else { + eprintln!( + "Error fetching details for fmspc {}: {:?}", + fmspc, response_code + ); + None + }; + + Ok(result) +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PlatformTcb { + pub tcb_info: TcbInfo, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TcbInfo { + pub fmspc: String, + pub tcb_levels: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TcbLevel { + pub tcb: Tcb, + pub tcb_status: String, +} + +#[derive(Debug, Deserialize)] +pub struct Tcb { + pub sgxtcbcomponents: Vec, + pub pcesvn: u64, + pub tdxtcbcomponents: Vec, +} + +impl Tcb { + pub fn get_sgx_tcb(&self) -> Vec { + self.sgxtcbcomponents.iter().map(|svn| svn.svn).collect() + } + + pub fn get_tdx_tcb(&self) -> Vec { + self.tdxtcbcomponents.iter().map(|svn| svn.svn).collect() + } +} + +#[derive(Debug, Deserialize)] +pub struct Svn { + svn: u8, +} + +mod test { + #[test] + fn test_deserialize() { + use super::PlatformTcb; + + let example = include_str!("../../test/tcb_info.json"); + let result = serde_json::from_str::(example); + assert!(result.is_ok()); + } +} diff --git a/tools/migtd-policy-generator/src/policy.rs b/tools/migtd-policy-generator/src/policy.rs new file mode 100644 index 00000000..aa86925d --- /dev/null +++ b/tools/migtd-policy-generator/src/policy.rs @@ -0,0 +1,275 @@ +// Copyright (c) 2023 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent + +use std::collections::BTreeMap; + +use anyhow::Result; +use serde::Serialize; +use serde_json::json; + +use crate::{ + platform_tcb::{get_platform_info, tcb_info::PlatformTcb}, + qe_identity::get_qe_identity, +}; + +pub fn generate_policy(for_production: bool) -> Result> { + let platform_tcb = get_platform_info(for_production)?; + let qe_identity = get_qe_identity(for_production)?; + let migtd = MigTdInfoPolicy::default(); + let tdx_module = TdxModulePolicy::new(for_production); + + let mut policy: Vec = platform_tcb + .into_iter() + .map(|p| PolicyTypes::Platform(p)) + .collect(); + policy.push(PolicyTypes::Qe(qe_identity)); + policy.push(PolicyTypes::TdxModule(tdx_module)); + policy.push(PolicyTypes::Migtd(migtd)); + + let mut data = Vec::new(); + let formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); + let mut ser = serde_json::Serializer::with_formatter(&mut data, formatter); + let obj = json!(policy); + obj.serialize(&mut ser).unwrap(); + + Ok(data) +} + +#[derive(Debug, Serialize)] +#[serde(untagged)] +pub enum PolicyTypes { + Platform(PlatformPolicy), + Qe(QePolicy), + TdxModule(TdxModulePolicy), + Migtd(MigTdInfoPolicy), +} + +#[derive(Debug, Serialize)] +pub struct PlatformPolicy { + pub(crate) fmspc: String, + #[serde(rename = "Platform")] + pub(crate) platform: Platform, +} + +impl PlatformPolicy { + pub fn new(platform_tcb: &PlatformTcb) -> Self { + PlatformPolicy { + fmspc: platform_tcb.tcb_info.fmspc.clone(), + platform: Platform { + tcb_info: TcbInfo { + sgxtcbcomponents: Property { + operation: "array-greater-or-equal".to_string(), + reference: Reference::Array( + platform_tcb.tcb_info.tcb_levels[0] + .tcb + .get_sgx_tcb() + .clone(), + ), + }, + pcesvn: Property { + operation: "greater-or-equal".to_string(), + reference: Reference::Integer( + platform_tcb.tcb_info.tcb_levels[0].tcb.pcesvn, + ), + }, + tdxtcbcomponents: Property { + operation: "array-greater-or-equal".to_string(), + reference: Reference::Array( + platform_tcb.tcb_info.tcb_levels[0] + .tcb + .get_tdx_tcb() + .clone(), + ), + }, + }, + }, + } + } +} + +#[derive(Debug, Serialize)] +pub struct Platform { + #[serde(rename = "TcbInfo")] + pub tcb_info: TcbInfo, +} + +#[derive(Debug, Serialize)] +pub struct TcbInfo { + sgxtcbcomponents: Property, + pcesvn: Property, + tdxtcbcomponents: Property, +} + +#[derive(Debug, Serialize)] +pub struct QePolicy { + #[serde(rename = "QE")] + qe_info: QeInfo, +} + +#[derive(Debug, Serialize)] +pub struct QeInfo { + #[serde(rename = "QeIdentity")] + qe_identity: QeIdentity, +} + +impl QePolicy { + pub fn new( + miscselect: String, + attributes: String, + mrsigner: String, + isvprodid: u64, + isvsvn: u64, + ) -> Self { + Self { + qe_info: QeInfo { + qe_identity: QeIdentity { + miscselect: Property { + operation: "equal".to_string(), + reference: Reference::Str(miscselect), + }, + attributes: Property { + operation: "equal".to_string(), + reference: Reference::Str(attributes), + }, + mrsigner: Property { + operation: "equal".to_string(), + reference: Reference::Str(mrsigner), + }, + isvprodid: Property { + operation: "equal".to_string(), + reference: Reference::Integer(isvprodid), + }, + isvsvn: Property { + operation: "equal".to_string(), + reference: Reference::Integer(isvsvn), + }, + }, + }, + } + } +} + +#[derive(Debug, Serialize)] +pub struct QeIdentity { + #[serde(rename = "MISCSELECT")] + miscselect: Property, + #[serde(rename = "ATTRIBUTES")] + attributes: Property, + #[serde(rename = "MRSIGNER")] + mrsigner: Property, + #[serde(rename = "ISVPRODID")] + isvprodid: Property, + #[serde(rename = "ISVSVN")] + isvsvn: Property, +} + +#[derive(Debug, Default, Serialize)] +pub struct MigTdInfoPolicy { + #[serde(rename = "MIGTD")] + migtd: TdInfo, +} + +#[derive(Debug, Serialize)] +pub(crate) struct TdInfo { + #[serde(rename = "TDINFO")] + td_info: BTreeMap, + #[serde(rename = "EventLog")] + event_log: BTreeMap, +} + +impl Default for TdInfo { + fn default() -> Self { + let mut td_info = BTreeMap::new(); + td_info.insert("ATTRIBUTES".to_string(), Property::default()); + td_info.insert("XFAM".to_string(), Property::default()); + td_info.insert("MRTD".to_string(), Property::default()); + td_info.insert("MRCONFIGID".to_string(), Property::default()); + td_info.insert("MROWNER".to_string(), Property::default()); + td_info.insert("MROWNERCONFIG".to_string(), Property::default()); + td_info.insert("RTMR0".to_string(), Property::default()); + td_info.insert("RTMR1".to_string(), Property::default()); + td_info.insert("RTMR2".to_string(), Property::default()); + td_info.insert("RTMR3".to_string(), Property::default()); + + let mut event_log = BTreeMap::new(); + event_log.insert("Digest.MigTdPolicy".to_string(), Property::default()); + event_log.insert("Digest.MigTdSgxRootKey".to_string(), Property::default()); + + Self { td_info, event_log } + } +} + +#[derive(Debug, Serialize)] +pub struct TdxModulePolicy { + #[serde(rename = "TDXModule")] + tdx_module: TdxModuleInfo, +} + +#[derive(Debug, Serialize)] +pub(crate) struct TdxModuleInfo { + #[serde(rename = "TDXModule_Identity")] + tdx_module_identity: TdxModuleIdentityPolicy, +} + +#[derive(Debug, Serialize)] +pub struct TdxModuleIdentityPolicy { + #[serde(rename = "TDXModuleMajorVersion")] + tdx_module_major_version: Property, + #[serde(rename = "TDXModuleSVN")] + tdx_module_svn: Property, + #[serde(rename = "MRSIGNERSEAM")] + mrsigner_seam: Property, + #[serde(rename = "ATTRIBUTES")] + attributes: Property, +} + +impl TdxModulePolicy { + fn new(for_production: bool) -> Self { + Self { + tdx_module: TdxModuleInfo { + tdx_module_identity: TdxModuleIdentityPolicy { + tdx_module_major_version: Property { + operation: "equal".to_string(), + reference: Reference::Integer(1), + }, + tdx_module_svn: Property { + operation: "equal".to_string(), + reference: Reference::Integer(if for_production { 2 } else { 0 }), + }, + mrsigner_seam: Property { + operation: "equal".to_string(), + reference: Reference::Str("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".to_string()), + }, + attributes: Property { + operation: "equal".to_string(), + reference: Reference::Str("0000000000000000".to_string()), + }, + }, + }, + } + } +} + +#[derive(Debug, Serialize)] +struct Property { + operation: String, + reference: Reference, +} + +impl Default for Property { + fn default() -> Self { + Property { + operation: "equal".to_string(), + reference: Reference::Str("self".to_string()), + } + } +} + +#[derive(Debug, Serialize)] +#[serde(untagged)] +enum Reference { + Array(Vec), + Integer(u64), + Str(String), +} diff --git a/tools/migtd-policy-generator/src/qe_identity.rs b/tools/migtd-policy-generator/src/qe_identity.rs new file mode 100644 index 00000000..89dca307 --- /dev/null +++ b/tools/migtd-policy-generator/src/qe_identity.rs @@ -0,0 +1,85 @@ +// Copyright (c) 2023 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent + +use anyhow::{anyhow, Result}; +use serde::Deserialize; + +use crate::{fetch_data_from_url, policy::QePolicy}; + +const QE_IDENTITY_URL: &str = + "https://api.trustedservices.intel.com/tdx/certification/v4/qe/identity?update="; +const SBX_QE_IDENTITY_URL: &str = + "https://sbx.api.trustedservices.intel.com/tdx/certification/v4/qe/identity?update="; + +pub fn get_qe_identity(for_production: bool) -> Result { + let qe_info = fetch_qe_identity(for_production)?; + Ok(QePolicy::new( + qe_info.enclave_identity.miscselect, + qe_info.enclave_identity.attributes, + qe_info.enclave_identity.mrsigner, + qe_info.enclave_identity.isvprodid, + qe_info.enclave_identity.tcb_levels[0].tcb.isvsvn, + )) +} + +fn fetch_qe_identity(for_production: bool) -> Result { + let url = if for_production { + QE_IDENTITY_URL + } else { + SBX_QE_IDENTITY_URL + }; + + let (response_code, data) = fetch_data_from_url(&url)?; + match response_code { + 200 => { + println!("Got enclave identity"); + Ok(serde_json::from_slice::(&data)?) + } + _ => { + eprintln!("Error fetching enclave identity - {:?}", response_code); + Err(anyhow!("AccessException")) + } + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct QeInfo { + pub enclave_identity: EnalaveIdentity, + pub signature: String, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct EnalaveIdentity { + pub miscselect: String, + pub attributes: String, + pub mrsigner: String, + pub isvprodid: u64, + pub tcb_levels: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TcbLevel { + pub tcb: Tcb, + pub tcb_status: String, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Tcb { + pub isvsvn: u64, +} + +mod test { + #[test] + fn test_json_deserialize() { + use crate::qe_identity::QeInfo; + + let list = include_str!("../test/qe_identity.json"); + let result = serde_json::from_str::(list); + assert!(result.is_ok()) + } +} diff --git a/tools/migtd-policy-generator/test/fmspc_list.json b/tools/migtd-policy-generator/test/fmspc_list.json new file mode 100644 index 00000000..1278e30e --- /dev/null +++ b/tools/migtd-policy-generator/test/fmspc_list.json @@ -0,0 +1 @@ +[{"fmspc":"10C06F000000","platform":"E5"},{"fmspc":"00906EA50000","platform":"client"},{"fmspc":"20606C040000","platform":"E5"},{"fmspc":"50806F000000","platform":"E5"},{"fmspc":"00A067110000","platform":"E3"},{"fmspc":"00606C040000","platform":"E5"},{"fmspc":"00706E470000","platform":"client"},{"fmspc":"00806EA60000","platform":"client"},{"fmspc":"00706A800000","platform":"client"},{"fmspc":"00706A100000","platform":"client"},{"fmspc":"F0806F000000","platform":"E5"},{"fmspc":"00806EB70000","platform":"client"},{"fmspc":"20806F040000","platform":"E5"},{"fmspc":"00906EC50000","platform":"client"},{"fmspc":"90806F000000","platform":"E5"},{"fmspc":"10A06F010000","platform":"E5"},{"fmspc":"00906EC10000","platform":"client"},{"fmspc":"B0C06F000000","platform":"E5"},{"fmspc":"A0806F000000","platform":"E5"},{"fmspc":"20A06F000000","platform":"E5"},{"fmspc":"00906ED50000","platform":"E3"},{"fmspc":"D0806F000000","platform":"E5"},{"fmspc":"30606A000000","platform":"E5"},{"fmspc":"20806EB70000","platform":"client"},{"fmspc":"00906EA10000","platform":"E3"},{"fmspc":"80806F000000","platform":"E5"},{"fmspc":"30806F040000","platform":"E5"},{"fmspc":"C0806F000000","platform":"E5"},{"fmspc":"30A06D050000","platform":"E5"},{"fmspc":"60C06F000000","platform":"E5"},{"fmspc":"00806F040000","platform":"E5"},{"fmspc":"E0806F000000","platform":"E5"},{"fmspc":"00806F050000","platform":"E5"},{"fmspc":"20906EC10000","platform":"client"},{"fmspc":"90C06F000000","platform":"E5"},{"fmspc":"80C06F000000","platform":"E5"},{"fmspc":"00806F000000","platform":"E5"},{"fmspc":"00906EB10000","platform":"client"},{"fmspc":"00606A000000","platform":"E5"}] \ No newline at end of file diff --git a/tools/migtd-policy-generator/test/qe_identity.json b/tools/migtd-policy-generator/test/qe_identity.json new file mode 100644 index 00000000..c38de85b --- /dev/null +++ b/tools/migtd-policy-generator/test/qe_identity.json @@ -0,0 +1,25 @@ +{ + "enclaveIdentity": { + "id": "TD_QE", + "version": 2, + "issueDate": "2023-12-26T05:52:10Z", + "nextUpdate": "2024-01-25T05:52:10Z", + "tcbEvaluationDataNumber": 5, + "miscselect": "00000000", + "miscselectMask": "FFFFFFFF", + "attributes": "11000000000000000000000000000000", + "attributesMask": "FBFFFFFFFFFFFFFF0000000000000000", + "mrsigner": "DC9E2A7C6F948F17474E34A7FC43ED030F7C1563F1BABDDF6340C82E0E54A8C5", + "isvprodid": 2, + "tcbLevels": [ + { + "tcb": { + "isvsvn": 0 + }, + "tcbDate": "2022-11-09T00:00:00Z", + "tcbStatus": "UpToDate" + } + ] + }, + "signature": "e4e884765ca3d6149b5d26904b7f93b400fc2c54263ffa72967d8c5067c85b691e8bc268df684094d4f6fb0da953ecd7cd5d066054edf12f347c09023c4e52f5" +} \ No newline at end of file diff --git a/tools/migtd-policy-generator/test/tcb_info.json b/tools/migtd-policy-generator/test/tcb_info.json new file mode 100644 index 00000000..566a248e --- /dev/null +++ b/tools/migtd-policy-generator/test/tcb_info.json @@ -0,0 +1 @@ +{"tcbInfo":{"id":"TDX","version":3,"issueDate":"2023-12-20T11:32:54Z","nextUpdate":"2024-01-19T11:32:54Z","fmspc":"50806F000000","pceId":"0000","tcbType":0,"tcbEvaluationDataNumber":16,"tdxModule":{"mrsigner":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","attributes":"0000000000000000","attributesMask":"FFFFFFFFFFFFFFFF"},"tdxModuleIdentities":[{"id":"TDX_01","mrsigner":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","attributes":"0000000000000000","attributesMask":"FFFFFFFFFFFFFFFF","tcbLevels":[{"tcb":{"isvsvn":2},"tcbDate":"2023-08-09T00:00:00Z","tcbStatus":"UpToDate"}]}],"tcbLevels":[{"tcb":{"sgxtcbcomponents":[{"svn":6,"category":"BIOS","type":"Early Microcode Update"},{"svn":6,"category":"OS/VMM","type":"SGX Late Microcode Update"},{"svn":2,"category":"OS/VMM","type":"TXT SINIT"},{"svn":2,"category":"BIOS"},{"svn":3,"category":"BIOS"},{"svn":1,"category":"BIOS"},{"svn":0},{"svn":3,"category":"OS/VMM","type":"SEAMLDR ACM"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":11,"tdxtcbcomponents":[{"svn":3,"category":"OS/VMM","type":"TDX Module"},{"svn":0,"category":"OS/VMM","type":"TDX Module"},{"svn":6,"category":"OS/VMM","type":"TDX Late Microcode Update"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}]},"tcbDate":"2023-08-09T00:00:00Z","tcbStatus":"UpToDate"},{"tcb":{"sgxtcbcomponents":[{"svn":5,"category":"BIOS","type":"Early Microcode Update"},{"svn":5,"category":"OS/VMM","type":"SGX Late Microcode Update"},{"svn":2,"category":"OS/VMM","type":"TXT SINIT"},{"svn":2,"category":"BIOS"},{"svn":3,"category":"BIOS"},{"svn":1,"category":"BIOS"},{"svn":0},{"svn":3,"category":"OS/VMM","type":"SEAMLDR ACM"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":11,"tdxtcbcomponents":[{"svn":3,"category":"OS/VMM","type":"TDX Module"},{"svn":0,"category":"OS/VMM","type":"TDX Module"},{"svn":5,"category":"OS/VMM","type":"TDX Late Microcode Update"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}]},"tcbDate":"2023-02-15T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00837"]},{"tcb":{"sgxtcbcomponents":[{"svn":5,"category":"BIOS","type":"Early Microcode Update"},{"svn":5,"category":"OS/VMM","type":"SGX Late Microcode Update"},{"svn":2,"category":"OS/VMM","type":"TXT SINIT"},{"svn":2,"category":"BIOS"},{"svn":3,"category":"BIOS"},{"svn":1,"category":"BIOS"},{"svn":0},{"svn":3,"category":"OS/VMM","type":"SEAMLDR ACM"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":5,"tdxtcbcomponents":[{"svn":3,"category":"OS/VMM","type":"TDX Module"},{"svn":0,"category":"OS/VMM","type":"TDX Module"},{"svn":5,"category":"OS/VMM","type":"TDX Late Microcode Update"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}]},"tcbDate":"2018-01-04T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00106","INTEL-SA-00115","INTEL-SA-00135","INTEL-SA-00203","INTEL-SA-00220","INTEL-SA-00233","INTEL-SA-00270","INTEL-SA-00293","INTEL-SA-00320","INTEL-SA-00329","INTEL-SA-00381","INTEL-SA-00389","INTEL-SA-00477","INTEL-SA-00837"]}]},"signature":"3884ffc7ccb9ca4654c2980120ff3bd69a7226dd4e541f0bf68f4428eab5ba27e75b725061b070bb0a810c2f0e186d1ef84417133f07d36a5d6fa6d73bc58051"} \ No newline at end of file