Skip to content
Closed
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"))]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you have to disable this API for lax-parser?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It encodes hashstick, which is not supported as it requires skip_bytes.

#[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"
))]
Comment on lines +93 to +96
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would lax-parser be part of this check?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is precisely to detect the use of one of the crypto features together with lax-parser. The only purpose is to give a clear error message above the error messages that will follow due to the disabled code.

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