Skip to content

Commit

Permalink
testing sealed
Browse files Browse the repository at this point in the history
  • Loading branch information
DGonzalezVillal committed Jan 30, 2025
1 parent 0e42d14 commit dbf6351
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 6 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ path = "src/lib.rs"
doc = false

[features]
default = ["sev", "snp"]
default = ["sev", "snp", "openssl"]
openssl = ["dep:openssl", "dep:rdrand"]
hw_tests = []
dangerous_hw_tests = ["hw_tests", "dep:reqwest", "dep:tokio"]
Expand All @@ -50,6 +50,7 @@ iocuddle = "0.1"
[dependencies]
openssl = { version = "0.10", optional = true }
serde = { version = "1.0", features = ["derive"] }
serde_repr = "0.1.19"
serde_bytes = "0.11"
bitflags = "1.2"
codicon = "3.0"
Expand Down
1 change: 1 addition & 0 deletions src/firmware/guest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! one or more guest confidential virtual-machines (VM) or containers which
//! may be deployed in a Platform Owner's environment..
///CHANGEME
mod types;

pub use types::*;
Expand Down
150 changes: 145 additions & 5 deletions src/firmware/guest/types/snp.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// SPDX-License-Identifier: Apache-2.0

use crate::error::AttestationReportError;
use crate::{certs::snp::ecdsa::Signature, firmware::host::TcbVersion, util::hexdump};
use crate::{
certs::snp::ecdsa::Signature,
firmware::host::TcbVersion,
util::{hexdump, sealed},
};
use bitfield::bitfield;
use serde::{Deserialize, Serialize};
use serde::de::{self, SeqAccess, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_big_array::BigArray;
use std::convert::{TryFrom, TryInto};
use std::fmt::Display;
Expand Down Expand Up @@ -101,7 +106,7 @@ bitfield! {

/// Trait shared between attestation reports to be able to verify them against the VEK.
#[cfg(any(feature = "openssl", feature = "crypto_nossl"))]
pub(crate) trait Attestable: Serialize {
pub trait Attestable: Serialize + sealed::Sealed {
/// Serialize the provided Attestation Report and get the measurable bytes from it
fn measurable_bytes(&self) -> io::Result<Vec<u8>> {
let measurable_bytes: &[u8] = &bincode::serialize(self).map_err(|e| {
Expand All @@ -116,6 +121,9 @@ pub(crate) trait Attestable: Serialize {
fn signature(&self) -> &Signature;
}

// impl sealed::Sealed for Attestable{}
/// Sealed trait
/// The guest can request that the firmware construct an attestation report. External entities can use an
/// attestation report to assure the identity and security configuration of the guest.
///
Expand All @@ -139,20 +147,22 @@ pub(crate) trait Attestable: Serialize {
///
/// Since the release of the 1.56 ABI, the Attestation Report was bumped from version 2 to 3.
/// Due to content differences, both versions are kept separately in order to provide backwards compatibility and most reliable security.
#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
#[derive(Debug, Clone, Copy)]
pub enum AttestationReport {
/// Version 2 of the Attestation Report
V2(AttestationReportV2),
/// Version 3 of the Attestation Report
V3(AttestationReportV3),
}

impl sealed::Sealed for AttestationReport {}

impl TryFrom<&[u8]> for AttestationReport {
type Error = AttestationReportError;

fn try_from(raw_report: &[u8]) -> Result<Self, Self::Error> {
let version =
u32::from_le_bytes([raw_report[0], raw_report[1], raw_report[2], raw_report[3]]);
u32::from_le_bytes([0, raw_report[2], raw_report[1], raw_report[0]]);
// Return the appropriate report version
match version {
2 => {
Expand All @@ -168,6 +178,132 @@ impl TryFrom<&[u8]> for AttestationReport {
}
}

// Implement custom serialization for AttestationReport
impl Serialize for AttestationReport {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
AttestationReport::V2(report) => {
println!("Serializing V2 report with version: {}", report.version);
report.serialize(serializer)
}
AttestationReport::V3(report) => {
println!("Serializing V3 report with version: {}", report.version);
report.serialize(serializer)
}
}
}
}

impl<'de> Deserialize<'de> for AttestationReport {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct AttestationReportVisitor;

impl<'de> Visitor<'de> for AttestationReportVisitor {
type Value = AttestationReport;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a byte buffer representing an attestation report")
}

fn visit_byte_buf<E>(self, value: Vec<u8>) -> Result<Self::Value, E>
where
E: de::Error,
{
println!("Byte Buf: {:?}", value);
AttestationReport::try_from(value.as_slice()).map_err(de::Error::custom)
}
}

deserializer.deserialize_byte_buf(AttestationReportVisitor)

// println!("Version Bytes: {:?}", raw_bytes);

// if raw_bytes.len() < 4 {
// return Err(de::Error::custom("Attestation report is too small"));
// }

// // Extract version number (assuming little-endian encoding)
// let version = u32::from_le_bytes([raw_bytes[0], raw_bytes[1], raw_bytes[2], raw_bytes[3]]);
// println!("Extracted Version: {}", version);

// match version {
// 2 => {
// let report_v2 = bincode::deserialize::<AttestationReportV2>(&raw_bytes)
// .map_err(de::Error::custom)?;

// Ok(AttestationReport::V2(report_v2))
// }
// 3 => {
// let report_v3 = bincode::deserialize::<AttestationReportV3>(&raw_bytes)
// .map_err(de::Error::custom)?;
// Ok(AttestationReport::V3(report_v3))
// }
// _ => Err(de::Error::custom(format!(
// "Unsupported attestation report version: {}",
// version
// ))),
// }
}
}

// struct AttestationReportVisitor;
// impl<'de> Visitor<'de> for AttestationReportVisitor {
// type Value = AttestationReport;
// fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
// formatter.write_str("An attestation report based upon a given version number.")
// }
// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
// where
// A: SeqAccess<'de>,
// {
// // let Some(version_bytes) = seq.next_element::<[u8;4]>()? else {
// // return Err(de::Error::custom("missing version bytes"));
// // };

// // Ensure we correctly read the first 4 bytes as the version
// let version_bytes: [u8; 4] = seq
// .next_element()?
// .ok_or_else(|| de::Error::custom("Missing version bytes"))?;

// println!("Version Bytes: {:?}", version_bytes);

// let version = u32::from_be_bytes(version_bytes); // .ok_or_else(|| de::Error::custom("missing version"))?;
// println!("Deserialized report version: {}", version);
// match version {
// 2 => {
// let report: AttestationReportV2 = seq
// .next_element()?
// .ok_or_else(|| de::Error::custom("missing V2 report data"))?;
// Ok(AttestationReport::V2(report))
// }
// 3 => {
// let report: AttestationReportV3 = seq
// .next_element()?
// .ok_or_else(|| de::Error::custom("missing V3 report data"))?;
// Ok(AttestationReport::V3(report))
// }
// _ => Err(de::Error::custom(format!(
// "unsupported attestation report version: {}",
// version
// ))),
// }
// }
// }
// impl<'de> Deserialize<'de> for AttestationReport {
// fn deserialize<D>(deserializer: D) -> Result<AttestationReport, D::Error>
// where
// D: Deserializer<'de>,
// {
// deserializer.deserialize_byte_buf(AttestationReportVisitor)
// }
// }

#[cfg(any(feature = "openssl", feature = "crypto_nossl"))]
impl Attestable for AttestationReport {
fn measurable_bytes(&self) -> io::Result<Vec<u8>> {
Expand Down Expand Up @@ -594,6 +730,8 @@ Launch TCB:
}
}

impl sealed::Sealed for AttestationReportV2 {}

#[cfg(any(feature = "openssl", feature = "crypto_nossl"))]
impl Attestable for AttestationReportV2 {
fn signature(&self) -> &Signature {
Expand Down Expand Up @@ -816,6 +954,8 @@ Launch TCB:
}
}

impl sealed::Sealed for AttestationReportV3 {}

#[cfg(any(feature = "openssl", feature = "crypto_nossl"))]
impl Attestable for AttestationReportV3 {
fn signature(&self) -> &Signature {
Expand Down
1 change: 1 addition & 0 deletions src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
pub mod cached_chain;
mod impl_const_id;
pub mod large_array;
pub(crate) mod sealed;

use std::{
io::{Read, Result, Write},
Expand Down
1 change: 1 addition & 0 deletions src/util/sealed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub trait Sealed {}

0 comments on commit dbf6351

Please sign in to comment.