From 0e781eb8cbe03bd76e0f2f3147fbffa8ab62bceb Mon Sep 17 00:00:00 2001 From: Larry Dewey Date: Fri, 26 Jul 2024 09:27:20 -0500 Subject: [PATCH] verifier: Use the VirTEE CA Chain This introduces changes into the code to utilize the cert chain provided by the VirTEE sev crate, pushing resposibility for upkeep and maintainership back to the library itself. This also reduces duplication of code and expands functionality for future changes. Signed-off-by: Larry Dewey --- Cargo.lock | 76 ++++++--------------------- Cargo.toml | 18 +++++-- attestation-service/Makefile | 1 - deps/verifier/Cargo.toml | 45 ++++++++++------ deps/verifier/src/az_snp_vtpm/mod.rs | 23 ++++----- deps/verifier/src/lib.rs | 4 +- deps/verifier/src/snp/mod.rs | 77 ++++++++++++++-------------- deps/verifier/src/tdx/eventlog.rs | 1 + 8 files changed, 111 insertions(+), 134 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca9cf35d28..9f9bcbfc4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,7 +40,7 @@ dependencies = [ "encoding_rs", "flate2", "futures-core", - "h2 0.3.26", + "h2", "http 0.2.12", "httparse", "httpdate", @@ -490,12 +490,6 @@ dependencies = [ "syn 2.0.60", ] -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "attestation-agent" version = "0.1.0" @@ -573,7 +567,7 @@ dependencies = [ "csv-rs", "hex", "hyper 0.14.28", - "hyper-tls 0.5.0", + "hyper-tls", "kbs-types", "log", "nix", @@ -894,6 +888,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" +[[package]] +name = "bitfield" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c821a6e124197eb56d907ccc2188eab1038fb919c914f47976e64dd8dbc855d1" + [[package]] name = "bitflags" version = "1.3.2" @@ -1417,7 +1417,7 @@ dependencies = [ "codicon", "dirs", "hyper 0.14.28", - "hyper-tls 0.5.0", + "hyper-tls", "iocuddle", "libc", "openssl", @@ -2077,25 +2077,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "h2" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.1.0", - "indexmap 2.2.6", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "2.4.1" @@ -2295,7 +2276,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", + "h2", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -2318,7 +2299,6 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.5", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -2385,22 +2365,6 @@ dependencies = [ "tokio-native-tls", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.3.1", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.5" @@ -4168,12 +4132,12 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.26", + "h2", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", "hyper-rustls 0.24.2", - "hyper-tls 0.5.0", + "hyper-tls", "ipnet", "js-sys", "log", @@ -4211,22 +4175,18 @@ dependencies = [ "bytes", "cookie 0.17.0", "cookie_store", - "encoding_rs", "futures-core", "futures-util", - "h2 0.4.5", "http 1.1.0", "http-body 1.0.0", "http-body-util", "hyper 1.3.1", "hyper-rustls 0.26.0", - "hyper-tls 0.6.0", "hyper-util", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -4237,9 +4197,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", - "tokio-native-tls", "tokio-rustls 0.25.0", "tower-service", "url", @@ -4869,12 +4827,10 @@ dependencies = [ [[package]] name = "sev" version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2890179f8ef689340f441ba05f0b268bc14f672ae4b36d629cc2266d0d747ab" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bincode", - "bitfield 0.13.2", + "bitfield 0.15.0", "bitflags 1.3.2", "byteorder", "codicon", @@ -5511,7 +5467,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "h2 0.3.26", + "h2", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", @@ -5538,7 +5494,7 @@ dependencies = [ "axum", "base64 0.21.7", "bytes", - "h2 0.3.26", + "h2", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", diff --git a/Cargo.toml b/Cargo.toml index 3d7bd6bbc9..592cf11172 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,9 +34,13 @@ kbs-types = "0.6.0" kms = { git = "https://github.com/confidential-containers/guest-components.git", rev="9bd6f06a9704e01808e91abde130dffb20e632a5", default-features = false } jsonwebtoken = { version = "9", default-features = false } log = "0.4.17" -prost = "0.12" -regorus = { version = "0.1.5", default-features = false, features = ["regex", "base64", "time"] } -reqwest = "0.12" +prost = "0.12.0" +regorus = { version = "0.1.5", default-features = false, features = [ + "regex", + "base64", + "time", +] } +reqwest = { version = "0.12", default-features = false } rstest = "0.18.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.89" @@ -46,7 +50,11 @@ sha2 = "0.10" shadow-rs = "0.19.0" strum = { version = "0.25", features = ["derive"] } thiserror = "1.0" -tokio = { version = "1", features = ["full"] } +tokio = { version = "1", features = ["full"], default-features = false } tempfile = "3.4.0" tonic = "0.11" -tonic-build = "0.11" \ No newline at end of file +tonic-build = "0.11" + +# Will be removed after updates are pulled in upstream +[patch.crates-io] +sev = { version = "3.1.1", path = "/home/larry/git/larrydewey/virtee-sev" } diff --git a/attestation-service/Makefile b/attestation-service/Makefile index 60e285b12f..e5714a44e7 100644 --- a/attestation-service/Makefile +++ b/attestation-service/Makefile @@ -23,7 +23,6 @@ grpc-as: restful-as: cargo build --bin restful-as $(release) --features restful-bin - install: for bin_name in $(BIN_NAMES); do \ install -D -m0755 $(TARGET_DIR)/$$bin_name $(DESTDIR); \ diff --git a/deps/verifier/Cargo.toml b/deps/verifier/Cargo.toml index 8f78b6ff45..84be06b5ba 100644 --- a/deps/verifier/Cargo.toml +++ b/deps/verifier/Cargo.toml @@ -4,31 +4,44 @@ version = "0.1.0" edition = "2021" [features] -default = [ "all-verifier" ] -all-verifier = [ "tdx-verifier", "sgx-verifier", "snp-verifier", "az-snp-vtpm-verifier", "az-tdx-vtpm-verifier", "csv-verifier", "cca-verifier", "se-verifier" ] -tdx-verifier = [ "eventlog-rs", "scroll", "intel-tee-quote-verification-rs" ] -sgx-verifier = [ "scroll", "intel-tee-quote-verification-rs" ] -az-snp-vtpm-verifier = [ "az-snp-vtpm", "sev", "snp-verifier" ] -az-tdx-vtpm-verifier = [ "az-tdx-vtpm", "openssl", "tdx-verifier" ] -snp-verifier = [ "asn1-rs", "openssl", "sev", "x509-parser" ] -csv-verifier = [ "openssl", "csv-rs", "codicon" ] -cca-verifier = [ "ear", "jsonwebtoken", "veraison-apiclient" ] -se-verifier = [ "openssl", "pv", "serde_with", "tokio/sync" ] +default = ["all-verifier"] +all-verifier = [ + "tdx-verifier", + "sgx-verifier", + "snp-verifier", + "az-snp-vtpm-verifier", + "az-tdx-vtpm-verifier", + "csv-verifier", + "cca-verifier", + "se-verifier", +] +tdx-verifier = ["eventlog-rs", "scroll", "intel-tee-quote-verification-rs"] +sgx-verifier = ["scroll", "intel-tee-quote-verification-rs"] +az-snp-vtpm-verifier = ["az-snp-vtpm", "sev", "snp-verifier"] +az-tdx-vtpm-verifier = ["az-tdx-vtpm", "openssl", "tdx-verifier"] +snp-verifier = ["asn1-rs", "openssl", "sev", "x509-parser"] +csv-verifier = ["openssl", "csv-rs", "codicon"] +cca-verifier = ["ear", "jsonwebtoken", "veraison-apiclient"] +se-verifier = ["openssl", "pv", "serde_with", "tokio/sync"] [dependencies] anyhow.workspace = true thiserror.workspace = true asn1-rs = { version = "0.5.1", optional = true } async-trait.workspace = true -az-snp-vtpm = { version = "0.5.3", default-features = false, features = ["verifier"], optional = true } -az-tdx-vtpm = { version = "0.5.3", default-features = false, features = ["verifier"], optional = true } +az-snp-vtpm = { version = "0.5.3", default-features = false, features = [ + "verifier", +], optional = true } +az-tdx-vtpm = { version = "0.5.3", default-features = false, features = [ + "verifier", +], optional = true } base64 = "0.21" bincode = "1.3.3" byteorder = "1" cfg-if = "1.0.0" codicon = { version = "3.0", optional = true } # TODO: change it to "0.1", once released. -csv-rs = { git = "https://github.com/openanolis/csv-rs", rev = "b74aa8c", optional = true } +csv-rs = { version = "=0.1.0", git = "https://github.com/openanolis/csv-rs", rev = "b74aa8c", optional = true } eventlog-rs = { version = "0.1.3", optional = true } hex.workspace = true jsonwebkey = "0.3.5" @@ -37,13 +50,15 @@ kbs-types.workspace = true log.workspace = true openssl = { version = "0.10.55", optional = true } pv = { version = "0.10.0", package = "s390_pv", optional = true } -scroll = { version = "0.11.0", default-features = false, features = ["derive"], optional = true } +scroll = { version = "0.11.0", default-features = false, features = [ + "derive", +], optional = true } serde.workspace = true serde_json.workspace = true serde_with = { workspace = true, optional = true } sev = { version = "3.1.1", features = ["openssl", "snp"], optional = true } sha2.workspace = true -tokio = { workspace = true, optional = true, default-features = false } +tokio = { workspace = true, optional = true } intel-tee-quote-verification-rs = { git = "https://github.com/intel/SGXDataCenterAttestationPrimitives", tag = "DCAP_1.21", optional = true } strum.workspace = true veraison-apiclient = { git = "https://github.com/chendave/rust-apiclient", branch = "token", optional = true } diff --git a/deps/verifier/src/az_snp_vtpm/mod.rs b/deps/verifier/src/az_snp_vtpm/mod.rs index a1cced4cda..52557b7ce5 100644 --- a/deps/verifier/src/az_snp_vtpm/mod.rs +++ b/deps/verifier/src/az_snp_vtpm/mod.rs @@ -4,9 +4,7 @@ // use super::{TeeEvidenceParsedClaim, Verifier}; -use crate::snp::{ - load_milan_cert_chain, parse_tee_evidence, verify_report_signature, VendorCertificates, -}; +use crate::snp::{load_milan_cert_chain, parse_tee_evidence, verify_report_signature}; use crate::{InitDataHash, ReportData}; use anyhow::{bail, Context, Result}; use async_trait::async_trait; @@ -19,6 +17,7 @@ use log::{debug, warn}; use openssl::pkey::PKey; use serde::{Deserialize, Serialize}; use serde_json::Value; +use sev::certs::snp::Chain; use sev::firmware::host::{CertTableEntry, CertType}; use thiserror::Error; @@ -32,7 +31,7 @@ struct Evidence { } pub struct AzSnpVtpm { - vendor_certs: VendorCertificates, + vendor_certs: Chain, } #[derive(Error, Debug)] @@ -54,12 +53,10 @@ pub enum CertError { } impl AzSnpVtpm { - pub fn new() -> Result { - let Result::Ok(vendor_certs) = load_milan_cert_chain() else { - return Err(CertError::LoadMilanCert); - }; - let vendor_certs = vendor_certs.clone(); - Ok(Self { vendor_certs }) + pub fn new() -> Self { + Self { + vendor_certs: load_milan_cert_chain().clone(), + } } } @@ -171,7 +168,7 @@ fn verify_report_data( fn verify_snp_report( snp_report: &AttestationReport, vcek: &Vcek, - vendor_certs: &VendorCertificates, + vendor_certs: &Chain, ) -> Result<(), CertError> { let vcek_data = vcek.0.to_der().context("Failed to get raw VCEK data")?; let cert_chain = [CertTableEntry::new(CertType::VCEK, vcek_data)]; @@ -199,7 +196,7 @@ mod tests { let hcl_report = HclReport::new(REPORT.to_vec()).unwrap(); let snp_report = hcl_report.try_into().unwrap(); let vcek = Vcek::from_pem(include_str!("../../test_data/az-snp-vtpm/vcek.pem")).unwrap(); - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_snp_report(&snp_report, &vcek, vendor_certs).unwrap(); } @@ -211,7 +208,7 @@ mod tests { let hcl_report = HclReport::new(wrong_report.to_vec()).unwrap(); let snp_report = hcl_report.try_into().unwrap(); let vcek = Vcek::from_pem(include_str!("../../test_data/az-snp-vtpm/vcek.pem")).unwrap(); - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); assert_eq!( verify_snp_report(&snp_report, &vcek, vendor_certs) .unwrap_err() diff --git a/deps/verifier/src/lib.rs b/deps/verifier/src/lib.rs index 40c09d345a..85a4a08496 100644 --- a/deps/verifier/src/lib.rs +++ b/deps/verifier/src/lib.rs @@ -39,7 +39,7 @@ pub fn to_verifier(tee: &Tee) -> Result> { Tee::AzSnpVtpm => { cfg_if::cfg_if! { if #[cfg(feature = "az-snp-vtpm-verifier")] { - let verifier = az_snp_vtpm::AzSnpVtpm::new()?; + let verifier = az_snp_vtpm::AzSnpVtpm::new(); Ok(Box::new(verifier) as Box) } else { bail!("feature `az-snp-vtpm-verifier` is not enabled for `verifier` crate.") @@ -67,7 +67,7 @@ pub fn to_verifier(tee: &Tee) -> Result> { Tee::Snp => { cfg_if::cfg_if! { if #[cfg(feature = "snp-verifier")] { - let verifier = snp::Snp::new()?; + let verifier = snp::Snp::new(); Ok(Box::new(verifier) as Box) } else { bail!("feature `snp-verifier` is not enabled for `verifier` crate.") diff --git a/deps/verifier/src/snp/mod.rs b/deps/verifier/src/snp/mod.rs index b5e4276b71..eff06868c2 100644 --- a/deps/verifier/src/snp/mod.rs +++ b/deps/verifier/src/snp/mod.rs @@ -15,6 +15,7 @@ use openssl::{ x509::{self, X509}, }; use serde_json::json; +use sev::certs::snp::{ca::Chain as CaChain, Certificate, Chain}; use sev::firmware::guest::AttestationReport; use sev::firmware::host::{CertTableEntry, CertType}; use std::sync::OnceLock; @@ -34,43 +35,43 @@ const LOADER_SPL_OID: Oid<'static> = oid!(1.3.6 .1 .4 .1 .3704 .1 .3 .1); #[derive(Debug)] pub struct Snp { - vendor_certs: VendorCertificates, + vendor_certs: Chain, } -pub(crate) fn load_milan_cert_chain() -> &'static Result { - static MILAN_CERT_CHAIN: OnceLock> = OnceLock::new(); - MILAN_CERT_CHAIN.get_or_init(|| { - let certs = X509::stack_from_pem(include_bytes!("milan_ask_ark_asvk.pem"))?; - if certs.len() != 3 { - bail!("Malformed Milan ASK/ARK/ASVK"); +fn read_certs_from_file() -> Vec { + match X509::stack_from_pem(include_bytes!("milan_ask_ark_asvk.pem")) { + Result::Ok(certs) => { + if certs.len() != 3 { + panic!("Malformed Milan ASK/ARK/ASVK"); + } + return certs; } + Result::Err(err) => panic!("Error reading certificates file: {err}"), + } +} - let vendor_certs = VendorCertificates { - ask: certs[0].clone(), - ark: certs[1].clone(), - asvk: certs[2].clone(), - }; - Ok(vendor_certs) +pub(crate) fn load_milan_cert_chain() -> &'static Chain { + static MILAN_CERT_CHAIN: OnceLock = OnceLock::new(); + MILAN_CERT_CHAIN.get_or_init(|| { + let certs = read_certs_from_file(); + Chain { + ca: CaChain { + ark: Certificate::from(certs[1].clone()), + ask: Certificate::from(certs[0].clone()), + }, + vek: Certificate::from(certs[2].clone()), + } }) } impl Snp { - pub fn new() -> Result { - let Result::Ok(vendor_certs) = load_milan_cert_chain() else { - bail!("Failed to load Milan cert chain"); - }; - let vendor_certs = vendor_certs.clone(); - Ok(Self { vendor_certs }) + pub fn new() -> Self { + Self { + vendor_certs: load_milan_cert_chain().clone(), + } } } -#[derive(Clone, Debug)] -pub(crate) struct VendorCertificates { - ask: X509, - ark: X509, - asvk: X509, -} - #[async_trait] impl Verifier for Snp { async fn evaluate( @@ -165,10 +166,10 @@ fn get_oid_int(cert: &x509_parser::certificate::TbsCertificate, oid: Oid) -> Res pub(crate) fn verify_report_signature( report: &AttestationReport, cert_chain: &[CertTableEntry], - vendor_certs: &VendorCertificates, + vendor_certs: &Chain, ) -> Result<()> { // check cert chain - let VendorCertificates { ask, ark, asvk } = vendor_certs; + let (ask, ark, asvk): (&X509, &X509, &X509) = vendor_certs.into(); // verify VCEK or VLEK cert chain // the key can be either VCEK or VLEK @@ -322,7 +323,7 @@ mod tests { #[test] fn check_milan_certificates() { - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); assert_eq!(get_common_name(ark).unwrap(), "ARK-Milan"); assert_eq!(get_common_name(ask).unwrap(), "SEV-Milan"); assert_eq!(get_common_name(asvk).unwrap(), "SEV-VLEK-Milan"); @@ -393,7 +394,7 @@ mod tests { #[test] fn check_vcek_signature_verification() { let cert_table = vec![CertTableEntry::new(CertType::VCEK, VCEK.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); verify_cert_chain(&cert_table, ask, ark, asvk).unwrap(); } @@ -406,14 +407,14 @@ mod tests { X509::from_der(&vcek).expect("failed to parse der"); let cert_table = vec![CertTableEntry::new(CertType::VCEK, vcek.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); verify_cert_chain(&cert_table, ask, ark, asvk).unwrap_err(); } #[test] fn check_vlek_signature_verification() { let cert_table = vec![CertTableEntry::new(CertType::VLEK, VLEK.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); verify_cert_chain(&cert_table, ask, ark, asvk).unwrap(); } @@ -426,14 +427,14 @@ mod tests { X509::from_der(&vlek).expect("failed to parse der"); let cert_table = vec![CertTableEntry::new(CertType::VLEK, vlek.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); verify_cert_chain(&cert_table, ask, ark, asvk).unwrap_err(); } #[test] fn check_milan_chain_signature_failure() { let cert_table = vec![CertTableEntry::new(CertType::VCEK, VCEK.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); // toggle ark <=> ask verify_cert_chain(&cert_table, ark, ask, asvk).unwrap_err(); @@ -444,7 +445,7 @@ mod tests { let attestation_report = bincode::deserialize::(VCEK_REPORT.as_slice()).unwrap(); let cert_chain = vec![CertTableEntry::new(CertType::VCEK, VCEK.to_vec())]; - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_report_signature(&attestation_report, &cert_chain, vendor_certs).unwrap(); } @@ -453,7 +454,7 @@ mod tests { let attestation_report = bincode::deserialize::(VLEK_REPORT.as_slice()).unwrap(); let cert_chain = vec![CertTableEntry::new(CertType::VLEK, VLEK.to_vec())]; - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_report_signature(&attestation_report, &cert_chain, vendor_certs).unwrap(); } @@ -466,7 +467,7 @@ mod tests { let attestation_report = bincode::deserialize::(&bytes).unwrap(); let cert_chain = vec![CertTableEntry::new(CertType::VCEK, VCEK.to_vec())]; - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_report_signature(&attestation_report, &cert_chain, vendor_certs).unwrap_err(); } @@ -479,7 +480,7 @@ mod tests { let attestation_report = bincode::deserialize::(&bytes).unwrap(); let cert_chain = vec![CertTableEntry::new(CertType::VLEK, VLEK.to_vec())]; - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_report_signature(&attestation_report, &cert_chain, vendor_certs).unwrap_err(); } } diff --git a/deps/verifier/src/tdx/eventlog.rs b/deps/verifier/src/tdx/eventlog.rs index 3278c9e71a..bef0436d27 100644 --- a/deps/verifier/src/tdx/eventlog.rs +++ b/deps/verifier/src/tdx/eventlog.rs @@ -124,6 +124,7 @@ impl CcEventLog { /// Defined in TCG PC Client Platform Firmware Profile Specification section /// 'UEFI_PLATFORM_FIRMWARE_BLOB Structure Definition' +#[allow(dead_code)] pub struct ParsedUefiPlatformFirmwareBlob2 { pub desc_len: u8, pub desc: Vec,