Skip to content

Commit

Permalink
attest: Add 'log' and 'log_len' to Attest idl & implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
flihp committed Sep 13, 2023
1 parent 8d87e5b commit 40c9d7e
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 27 deletions.
81 changes: 70 additions & 11 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion app/lpc55xpresso/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ extern-regions = ["sram2"]
[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 13600, ram = 16384}
max-sizes = {flash = 14800, ram = 16384}
stacksize = 9304
start = true
extern-regions = ["dice_alias", "dice_certs"]
Expand Down
2 changes: 1 addition & 1 deletion app/oxide-rot-1/app-dev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ binary_path = "../../target/gimlet-c/dist/default/final.bin"
[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 13600, ram = 16384}
max-sizes = {flash = 14800, ram = 16384}
stacksize = 9304
start = true
extern-regions = ["dice_alias", "dice_certs"]
Expand Down
2 changes: 1 addition & 1 deletion app/oxide-rot-1/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ task-slots = ["swd"]
[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 13600, ram = 16384}
max-sizes = {flash = 14800, ram = 16384}
stacksize = 9304
start = true
extern-regions = ["dice_alias", "dice_certs"]
Expand Down
4 changes: 2 additions & 2 deletions app/rot-carrier/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ binary_path = "../../target/gemini-bu/dist/final.bin"
[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 13600, ram = 16384}
stacksize = 9304
max-sizes = {flash = 14800, ram = 16384}
stacksize = 9952
start = true
extern-regions = ["dice_alias", "dice_certs"]

Expand Down
23 changes: 23 additions & 0 deletions idl/attest.idol
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,28 @@ Interface(
),
encoding: Hubpack,
),
"log": (
doc: "Get the measurement log",
args: {
"offset" : "u32",
},
leases: {
"dest": (type: "[u8]", write: true),
},
reply: Result(
ok: "()",
err: Complex("AttestError"),
),
encoding: Hubpack,
),
"log_len": (
doc: "Get length of the serialized measurement log",
reply: Result(
ok: "u32",
err: Complex("AttestError"),
),
encoding: Hubpack,
idempotent: true,
),
}
)
4 changes: 3 additions & 1 deletion task/attest-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ pub enum AttestError {
InvalidCertIndex,
NoCerts,
OutOfRange,
MeasurementLogFull,
LogFull,
LogTooBig,
TaskRestarted,
BadLease,
UnsupportedAlgorithm,
SerializeLog,
}

impl From<idol_runtime::ServerDeath> for AttestError {
Expand Down
2 changes: 2 additions & 0 deletions task/attest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ crypto-common = { workspace = true }
lib-dice = { path = "../../lib/dice" }
hubpack = { workspace = true }
idol-runtime = { workspace = true }
mutable-statics = { path = "../../lib/mutable-statics" }
num-traits = { workspace = true }
ringbuf = { path = "../../lib/ringbuf" }
serde = { workspace = true }
serde_with = { version = "3.3.0", default-features = false, features = ["macros"] }
stage0-handoff = { path = "../../lib/stage0-handoff" }
attest-api = { path = "../attest-api" }
sha3 = { workspace = true }
Expand Down
64 changes: 54 additions & 10 deletions task/attest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ use crypto_common::{typenum::Unsigned, OutputSizeUser};
use hubpack::SerializedSize;
use idol_runtime::{ClientError, Leased, RequestError, W};
use lib_dice::{AliasData, CertData};
use mutable_statics::mutable_statics;
use ringbuf::{ringbuf, ringbuf_entry};
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use sha3::Sha3_256Core;
use stage0_handoff::{HandoffData, HandoffDataLoadError};
use zerocopy::AsBytes;
Expand All @@ -46,6 +48,8 @@ enum Trace {
Startup,
Record(HashAlgorithm),
BadLease(usize),
LogLen(u32),
Log,
None,
}

Expand Down Expand Up @@ -84,8 +88,9 @@ const SHA3_256_DIGEST_SIZE: usize =
const CAPACITY: usize = 16;

// Digest is a fixed length array of bytes
#[derive(Clone, Copy, Debug, PartialEq)]
struct Digest<const N: usize>([u8; N]);
#[serde_as]
#[derive(Clone, Copy, Debug, PartialEq, Serialize, SerializedSize)]
struct Digest<const N: usize>(#[serde_as(as = "[_; N]")] [u8; N]);

impl<const N: usize> Default for Digest<N> {
fn default() -> Self {
Expand All @@ -96,7 +101,7 @@ impl<const N: usize> Default for Digest<N> {
type Sha3_256Digest = Digest<SHA3_256_DIGEST_SIZE>;

// Measurement is an enum that can hold any of the supported hash algorithms
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Serialize, SerializedSize)]
enum Measurement {
Sha3_256(Sha3_256Digest),
}
Expand Down Expand Up @@ -129,16 +134,19 @@ impl Default for Measurement {
}
}

// Would have been nice to use ArrayVec but it's particularly difficult to
// use with hubpack.
// ArrayVec has everything we need but isn't compatible with hubpack. We only
// need a small subset of its functionality so this saves us some flash.
#[serde_as]
#[derive(Serialize, SerializedSize)]
struct Log<const N: usize> {
index: usize,
index: u32,
#[serde_as(as = "[_; N]")]
measurements: [Measurement; N],
}

impl<const N: usize> Log<N> {
fn is_full(&self) -> bool {
if self.index == N {
if self.index as usize == N {
true
} else {
false
Expand All @@ -147,7 +155,7 @@ impl<const N: usize> Log<N> {

fn push(&mut self, measurement: Measurement) -> bool {
if !self.is_full() {
self.measurements[self.index] = measurement;
self.measurements[self.index as usize] = measurement;
self.index += 1;
true
} else {
Expand All @@ -167,14 +175,19 @@ impl<const N: usize> Default for Log<N> {

struct AttestServer {
alias_data: Option<AliasData>,
buf: &'static mut [u8; Log::<CAPACITY>::MAX_SIZE],
cert_data: Option<CertData>,
measurements: Log<CAPACITY>,
}

impl Default for AttestServer {
fn default() -> Self {
let buf = mutable_statics! {
static mut LOG_BUF: [u8; Log::<CAPACITY>::MAX_SIZE] = [|| 0; _];
};
Self {
alias_data: load_data_from_region(&ALIAS_DATA),
buf,
cert_data: load_data_from_region(&CERT_DATA),
measurements: Log::<CAPACITY>::default(),
}
Expand Down Expand Up @@ -293,13 +306,44 @@ impl idl::InOrderAttestImpl for AttestServer {
ringbuf_entry!(Trace::Record(algorithm));

if self.measurements.is_full() {
return Err(AttestError::MeasurementLogFull.into());
return Err(AttestError::LogFull.into());
}

self.measurements.push(Measurement::new(algorithm, data)?);

Ok(())
}

fn log(
&mut self,
_: &userlib::RecvMessage,
offset: u32,
dest: Leased<W, [u8]>,
) -> Result<(), RequestError<AttestError>> {
ringbuf_entry!(Trace::Log);

hubpack::serialize(self.buf, &self.measurements)
.map_err(|_| AttestError::SerializeLog)?;

let offset = offset as usize;
dest.write_range(0..dest.len(), &self.buf[offset..offset + dest.len()])
.map_err(|_| RequestError::Fail(ClientError::WentAway))?;

Ok(())
}

fn log_len(
&mut self,
_: &userlib::RecvMessage,
) -> Result<u32, RequestError<AttestError>> {
let len = hubpack::serialize(self.buf, &self.measurements)
.map_err(|_| AttestError::SerializeLog)?;
let len = u32::try_from(len).map_err(|_| AttestError::LogTooBig)?;

ringbuf_entry!(Trace::LogLen(len));

Ok(len)
}
}

#[export_name = "main"]
Expand Down

0 comments on commit 40c9d7e

Please sign in to comment.