Skip to content
Open
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
25 changes: 25 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,28 @@ jobs:
flag: --release
features:
- crypto_nossl

sw-lax-parser:
name: sw lax-parser ${{ matrix.runner }} ${{ matrix.toolchain }} ${{ matrix.profile.name }} ${{ matrix.features }}
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.toolchain }}
- run: cargo test ${{ matrix.profile.flag }} --features=lax-parser

strategy:
fail-fast: false
matrix:
runner:
- ubuntu-latest
- macos-15-intel
- windows-latest
toolchain:
- 1.85.0
- stable
profile:
- name: debug
- name: release
flag: --release
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ sev = ["dep:rdrand"]
snp = []
crypto_nossl = ["dep:p384", "dep:rsa", "dep:sha2", "dep:x509-cert"]
serde = ["dep:serde", "dep:serde-big-array", "dep:serde_bytes"]
lax-parser = []

[target.'cfg(target_os = "linux")'.dependencies]
iocuddle = "^0.1"
Expand Down
2 changes: 2 additions & 0 deletions src/certs/snp/ecdsa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl Decoder<()> for Signature {
}
}

#[cfg(not(feature = "lax-parser"))]
impl Encoder<()> for Signature {
fn encode(&self, writer: &mut impl Write, _: ()) -> Result<()> {
writer.write_bytes(self.r, ())?;
Expand Down Expand Up @@ -314,6 +315,7 @@ mod tests {
}
}

#[cfg(not(feature = "lax-parser"))]
#[test]
fn test_signature_serialization() {
let sig: Signature = Default::default();
Expand Down
45 changes: 37 additions & 8 deletions src/firmware/guest/types/snp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ impl Default for AttestationReport {
}
}

#[cfg(not(feature = "lax-parser"))]
impl Encoder<()> for AttestationReport {
fn encode(&self, writer: &mut impl Write, _: ()) -> Result<(), std::io::Error> {
// Determine the variant based on version and CPUID step
Expand Down Expand Up @@ -1688,6 +1689,14 @@ Signature:
assert_eq!(<Version as Default>::default(), Version::new(0, 0, 0));
}

const VCEK: [u8; 64] = [
0xD4, 0x95, 0x54, 0xEC, 0x71, 0x7F, 0x4E, 0x5B, 0x0F, 0xE6, 0xB1, 0x43, 0xBC, 0xF0, 0x40,
0x5B, 0xD7, 0xAE, 0x30, 0x47, 0x27, 0xED, 0xF4, 0x66, 0x03, 0xF2, 0xA7, 0x6A, 0xEF, 0x6A,
0x3A, 0xBC, 0x15, 0xD7, 0xAF, 0x38, 0xDB, 0x75, 0x70, 0x39, 0x02, 0x9F, 0x0E, 0xFA, 0xCF,
0xD0, 0x8E, 0x24, 0x43, 0x24, 0x88, 0x47, 0x38, 0xC7, 0x2B, 0x08, 0x2E, 0x2F, 0x87, 0xA4,
0x4D, 0x54, 0x1E, 0xB6,
];

#[test]
fn test_attestation_report_from_bytes() {
// Create a valid attestation report bytes minus one byte.
Expand All @@ -1696,15 +1705,32 @@ Signature:
// Push the version byte at the beginning.
bytes.insert(0, 2);

let vcek = [
0xD4, 0x95, 0x54, 0xEC, 0x71, 0x7F, 0x4E, 0x5B, 0x0F, 0xE6, 0xB1, 0x43, 0xBC, 0xF0,
0x40, 0x5B, 0xD7, 0xAE, 0x30, 0x47, 0x27, 0xED, 0xF4, 0x66, 0x03, 0xF2, 0xA7, 0x6A,
0xEF, 0x6A, 0x3A, 0xBC, 0x15, 0xD7, 0xAF, 0x38, 0xDB, 0x75, 0x70, 0x39, 0x02, 0x9F,
0x0E, 0xFA, 0xCF, 0xD0, 0x8E, 0x24, 0x43, 0x24, 0x88, 0x47, 0x38, 0xC7, 0x2B, 0x08,
0x2E, 0x2F, 0x87, 0xA4, 0x4D, 0x54, 0x1E, 0xB6,
];
bytes[0x1A8..0x1E0].copy_from_slice(&VCEK[..(0x1E0 - 0x1A8)]);

// Test valid input
let result = AttestationReport::from_bytes(bytes.as_slice());
assert!(result.is_ok());
}

#[cfg(feature = "lax-parser")]
#[test]
fn test_future_attestation_report_from_bytes() {
// Create a valid attestation report bytes minus one byte.
let mut bytes: Vec<u8> = vec![0; 1183];

// Push the version byte at the beginning.
bytes.insert(0, 9);

// Set CPUID_FAM_ID
bytes[0x188] = 0x1A;

// Set CPUID_MOD_ID
bytes[0x189] = 0x2;

// Write into a reserved area; the standard parser would expect 0.
bytes[0x19F] = 1;

bytes[0x1A8..0x1E0].copy_from_slice(&vcek[..(0x1E0 - 0x1A8)]);
bytes[0x1A8..0x1E0].copy_from_slice(&VCEK[..(0x1E0 - 0x1A8)]);

// Test valid input
let result = AttestationReport::from_bytes(bytes.as_slice());
Expand All @@ -1724,6 +1750,7 @@ Signature:
AttestationReport::from_bytes(bytes[..100].try_into().unwrap()).unwrap();
}

#[cfg(not(feature = "lax-parser"))]
#[test]
fn test_attestation_report_parse_and_write_bytes() {
let report = AttestationReport {
Expand Down Expand Up @@ -1801,6 +1828,7 @@ Signature:
assert_eq!(original.to_bytes().unwrap(), cloned.to_bytes().unwrap());
}

#[cfg(not(feature = "lax-parser"))]
#[test]
fn test_attestation_report_complex_write() {
let report = AttestationReport {
Expand Down Expand Up @@ -1830,6 +1858,7 @@ Signature:
assert_eq!(read_back.image_id, [0xBB; 16]);
}

#[cfg(not(feature = "lax-parser"))]
#[test]
fn test_write_with_limited_writer() {
let report = AttestationReport {
Expand Down
1 change: 1 addition & 0 deletions src/firmware/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ impl Firmware {
Ok(())
}

#[cfg(not(feature = "lax-parser"))]
#[cfg(feature = "snp")]
/// Insert a Version Loaded Endorsement Key Hashstick into the AMD Secure Processor.
///
Expand Down
2 changes: 2 additions & 0 deletions src/firmware/host/types/snp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,7 @@ impl Default for WrappedVlekHashstick {
}
}

#[cfg(not(feature = "lax-parser"))]
impl Encoder<Generation> for WrappedVlekHashstick {
fn encode(
&self,
Expand Down Expand Up @@ -1867,6 +1868,7 @@ mod tests {
);
}

#[cfg(not(feature = "lax-parser"))]
#[test]
fn test_wrapped_vlek_hashstick_to_bytes() {
// Create a test hashstick
Expand Down
8 changes: 8 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ compile_error!(
"feature \"openssl\" and feature \"crypto_nossl\" cannot be enabled at the same time"
);

#[cfg(all(
any(feature = "openssl", feature = "crypto_nossl"),
feature = "lax-parser"
))]
compile_error!(
r#"feature "openssl" and feature "crypto_nossl" cannot be used together with "lax-parser""#
);

/// SEV and SEV-SNP certificates interface.
pub mod certs;

Expand Down
2 changes: 2 additions & 0 deletions src/util/parser_helper/read_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub trait ReadExt: Read {
while remaining > 0 {
let n = remaining.min(CHUNK);
self.read_exact(&mut buf[..n])?;
#[cfg(not(feature = "lax-parser"))]
if buf[..n].iter().any(|&b| b != 0) {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
Expand Down Expand Up @@ -98,6 +99,7 @@ mod read_ext_tests {
}

// Test case 3: Skip, Invalid Data
#[cfg(not(feature = "lax-parser"))]
#[test]
fn test_skip_invalid_data() {
let data = vec![0, 0, 1, 0, 0x12, 0x34, 0x56, 0x78];
Expand Down
2 changes: 2 additions & 0 deletions src/util/parser_helper/write_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub trait WriteExt: Write {
value.encode(self, params)
}

#[cfg(not(feature = "lax-parser"))]
fn skip_bytes<const SKIP: usize>(&mut self) -> Result<&mut Self, std::io::Error>
where
Self: Sized,
Expand Down Expand Up @@ -56,6 +57,7 @@ mod write_ext_tests {
Ok(())
}

#[cfg(not(feature = "lax-parser"))]
#[test]
fn test_write_bytes_with_skip() -> Result<(), std::io::Error> {
let mut writer = MockWriter::default();
Expand Down