Skip to content

Commit

Permalink
report: Reformat to remove --random
Browse files Browse the repository at this point in the history
Removing the --random flag greatly simplifies the report command.
Instead of allowing some random bytes to be generated and written.
Require a user to submit a 64-byte file containing the data they would
like to include in the report. For Hyper-V, this data is already
generated beforehand, so this data to the file provided instead.

Signed-off-by: Tyler Fanelli <tfanelli@redhat.com>
  • Loading branch information
tylerfanelli committed Jul 27, 2023
1 parent c7ad0fe commit 0c80f34
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 115 deletions.
5 changes: 1 addition & 4 deletions src/certs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,9 @@ pub struct CertificatesArgs {
pub fn get_ext_certs(args: CertificatesArgs) -> Result<()> {
let mut sev_fw: Firmware = Firmware::open().context("failed to open SEV firmware device.")?;

// Generate random request data
let request_data = report::create_random_request();

// Request extended attestation report
let (_, certificates) = sev_fw
.get_ext_report(None, Some(request_data), None)
.get_ext_report(None, None, None)
.context("Failed to get extended report.")?;

// Check if the returned table is empty
Expand Down
2 changes: 1 addition & 1 deletion src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod report_display {

// Print attestation report in console
pub fn display_attestation_report(args: Args, quiet: bool) -> Result<()> {
let att_report = report::read_report(args.att_report_path)
let att_report = report::report_read(&args.att_report_path)
.context("Could not open attestation report")?;

if !quiet {
Expand Down
2 changes: 1 addition & 1 deletion src/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ mod vcek {
let att_report = if !att_report_path.exists() {
return Err(anyhow::anyhow!("No attestation report in provided path."));
} else {
report::read_report(att_report_path).context("Could not open attestation report")?
report::report_read(&att_report_path).context("Could not open attestation report")?
};

// Use attestation report to get data for URL
Expand Down
1 change: 0 additions & 1 deletion src/hyperv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ pub fn present() -> bool {
pub mod report {
use super::*;

use anyhow::{anyhow, Context};
use serde::{Deserialize, Serialize};
use sev::firmware::guest::AttestationReport;
use tss_esapi::{
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use fetch::FetchCmd;
use report::ReportArgs;
use verify::VerifyCmd;

use anyhow::{Context, Result};
use anyhow::{anyhow, Context, Result};
use structopt::StructOpt;

const VERSION: &str = env!("CARGO_PKG_VERSION");
Expand Down
153 changes: 47 additions & 106 deletions src/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,129 +3,70 @@
use super::*;

use std::{
fs,
fs::File,
io::{BufWriter, Read, Write},
fs::{File, OpenOptions},
io::{Read, Write},
path::PathBuf,
};

use rand::{thread_rng, RngCore};

use sev::firmware::guest::{AttestationReport, Firmware};

// Read a bin-formatted attestation report.
pub fn read_report(att_report_path: PathBuf) -> Result<AttestationReport, anyhow::Error> {
let attestation_file = fs::File::open(att_report_path)?;

let attestation_report = bincode::deserialize_from(attestation_file)
.context("Could not parse attestation report.")?;

Ok(attestation_report)
}

// Create 64 random bytes of data for attestation report request
pub fn create_random_request() -> [u8; 64] {
let mut data = [0u8; 64];
thread_rng().fill_bytes(&mut data);
data
}

// Write data into given file. Split it into 16 byte lines.
pub fn write_hex<W: Write>(file: &mut BufWriter<W>, data: &[u8]) -> Result<()> {
let mut line_counter = 0;
for val in data {
// Make it blocks for easier read
if line_counter.eq(&16) {
writeln!(file).context("Failed to write data to file")?;
line_counter = 0;
}
// Write byte into file
write!(file, "{:02x}", val).context("Failed to write data to file")?;
line_counter += 1;
}
Ok(())
}

#[derive(StructOpt)]
pub struct ReportArgs {
#[structopt(help = "File to write the attestation report to.")]
pub att_report_path: PathBuf,

#[structopt(
long = "random",
short,
help = "Use random data for attestation report request. Writes data to ./random-request-file.txt by default, use --request to specify where to write data."
)]
pub random: bool,

#[structopt(
long = "vmpl",
short,
help = "Specify VMPL level the Guest is running on. Defaults to 1."
)]
#[structopt(help = "File to write the attestation report to")]
pub path: PathBuf,

#[structopt(long, help = "VMPL level the Guest is running on (defaults to 0)")]
pub vmpl: Option<u32>,

#[structopt(
help = "Provide file with data for attestation-report request. If provided with random flag, then the random data will be written in the provided path."
)]
#[structopt(help = "File containing 64-byte report_data to include in report")]
pub request_file: PathBuf,
}

// Request attestation report and write it into a file
pub fn get_report(args: ReportArgs, hv: bool) -> Result<()> {
let request_data = match args.random {
true => {
let request_buf = create_random_request();

// Overwrite data if file already exists
let request_file = if args.request_file.exists() {
std::fs::OpenOptions::new()
.write(true)
.truncate(true)
.open(args.request_file)
.context("Unable to overwrite request file contents")?
} else {
fs::File::create(args.request_file).context("Unable to create request file.")?
};
write_hex(&mut BufWriter::new(request_file), &request_buf)
.context("Failed to write request data in request file")?;
request_buf
}
false => {
let mut request_file =
File::open(args.request_file).context("Could not open the report request file.")?;
let mut request_buf: [u8; 64] = [0; 64];
request_file
.read(&mut request_buf)
.context("Could not read report request file.")?;
request_buf
}
};
let vmpl = args.vmpl.unwrap_or(0);

// Get attestation report
let att_report = if hv {
hyperv::report::get(args.vmpl.unwrap_or(0))?
} else {
let mut sev_fw: Firmware =
Firmware::open().context("failed to open SEV firmware device.")?;
sev_fw
.get_report(None, Some(request_data), args.vmpl)
.context("Failed to get report.")?
};
let report = if hv {
let r = hyperv::report::get(vmpl)?;
write!(file_w(&args.request_file)?, "{:02x?}", r.report_data)?;

// Write attestation report into desired file
let mut attestation_file = if args.att_report_path.exists() {
std::fs::OpenOptions::new()
.write(true)
.truncate(true)
.open(args.att_report_path)
.context("Unable to overwrite attestation report file contents")?
r
} else {
fs::File::create(args.att_report_path)
.context("Unable to create attestation report file contents")?
Firmware::open()
.context("unable to open /dev/sev")?
.get_report(None, Some(report_data_read(args.request_file)?), Some(vmpl))
.context("unable to fetch attestation report from /dev/sev")?
};
bincode::serialize_into(&mut attestation_file, &att_report)
.context("Could not serialize attestation report into file.")?;

let mut f = file_w(&args.path)?;
bincode::serialize_into(&mut f, &report).context(format!(
"error serializing report to {}",
args.path.display()
))?;

Ok(())
}

fn report_data_read(path: PathBuf) -> Result<[u8; 64]> {
let mut f = File::open(&path).context(format!("unable to open {}", path.display()))?;

let mut buf: [u8; 64] = [0; 64];
f.read(&mut buf)
.context(format!("error reading {}", path.display()))?;

Ok(buf)
}

fn file_w(path: &PathBuf) -> Result<File> {
OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.open(&path)
.context(format!("unable to open {}", path.display()))
}

pub fn report_read(path: &PathBuf) -> Result<AttestationReport> {
let f = File::open(&path)?;

bincode::deserialize_from(f).context(format!("unable to read report from {}", path.display()))
}
2 changes: 1 addition & 1 deletion src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ mod attestation {
let att_report = if !args.att_report_path.exists() {
return Err(anyhow::anyhow!("No attestation report was found. Provide an attestation report to request VCEK from the KDS."));
} else {
report::read_report(args.att_report_path)
report::report_read(&args.att_report_path)
.context("Could not open attestation report")?
};

Expand Down

0 comments on commit 0c80f34

Please sign in to comment.