Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attest: Add attest_len & attest ops. #1591

Merged
merged 2 commits into from
Jan 23, 2024
Merged
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
2 changes: 2 additions & 0 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions app/lpc55xpresso/app-sprot.toml
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ task-slots = ["swd"]
[tasks.sprot]
name = "drv-lpc55-sprot-server"
priority = 6
max-sizes = {flash = 46592, ram = 32768}
max-sizes = {flash = 47328, ram = 32768}
uses = ["flexcomm8", "bootrom"]
features = ["spi0"]
start = true
Expand Down Expand Up @@ -211,8 +211,8 @@ pins = [
[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 14528, ram = 16384}
stacksize = 11264
max-sizes = {flash = 33904, ram = 16384}
stacksize = 12304
start = true
extern-regions = ["dice_alias", "dice_certs"]

Expand Down
4 changes: 2 additions & 2 deletions app/lpc55xpresso/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ extern-regions = ["sram2"]
[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 14800, ram = 16384}
stacksize = 11264
max-sizes = {flash = 33904, ram = 16384}
stacksize = 12304
start = true
extern-regions = ["dice_alias", "dice_certs"]

Expand Down
6 changes: 3 additions & 3 deletions app/oxide-rot-1/app-dev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ task-slots = ["syscon_driver"]
[tasks.sprot]
name = "drv-lpc55-sprot-server"
priority = 6
max-sizes = {flash = 46592, ram = 32768}
max-sizes = {flash = 47328, ram = 32768}
uses = ["flexcomm8", "bootrom"]
features = ["spi0"]
start = true
Expand Down Expand Up @@ -158,8 +158,8 @@ binary_path = "../../target/gimlet-c/dist/default/final.bin"
[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 14800, ram = 16384}
stacksize = 11264
max-sizes = {flash = 33904, ram = 16384}
stacksize = 12304
start = true
extern-regions = ["dice_alias", "dice_certs"]

Expand Down
6 changes: 3 additions & 3 deletions app/oxide-rot-1/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ task-slots = ["syscon_driver"]
[tasks.sprot]
name = "drv-lpc55-sprot-server"
priority = 6
max-sizes = {flash = 46592, ram = 32768}
max-sizes = {flash = 47328, ram = 32768}
uses = ["flexcomm8", "bootrom"]
features = ["spi0"]
start = true
Expand Down Expand Up @@ -137,8 +137,8 @@ task-slots = ["swd"]
[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 14800, ram = 16384}
stacksize = 11264
max-sizes = {flash = 33904, ram = 16384}
flihp marked this conversation as resolved.
Show resolved Hide resolved
stacksize = 12304
start = true
extern-regions = ["dice_alias", "dice_certs"]

Expand Down
6 changes: 3 additions & 3 deletions app/rot-carrier/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ task-slots = ["syscon_driver"]
[tasks.sprot]
name = "drv-lpc55-sprot-server"
priority = 6
max-sizes = {flash = 46592, ram = 32768}
max-sizes = {flash = 47328, ram = 32768}
uses = ["flexcomm8", "bootrom"]
features = ["spi0"]
start = true
Expand Down Expand Up @@ -204,8 +204,8 @@ binary_path = "../../target/gemini-bu/dist/final.bin"
[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 14800, ram = 16384}
stacksize = 11264
max-sizes = {flash = 33904, ram = 16384}
stacksize = 12304
start = true
extern-regions = ["dice_alias", "dice_certs"]

Expand Down
46 changes: 42 additions & 4 deletions drv/lpc55-sprot-server/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ pub struct StartupState {
}

/// Marker for data which should be copied after the packet is encoded
pub enum TrailingData {
pub enum TrailingData<'a> {
Caboose { slot: SlotId, start: u32, size: u32 },
AttestCert { index: u32, offset: u32, size: u32 },
AttestLog { offset: u32, size: u32 },
Attest { nonce: &'a [u8], write_size: u32 },
RotPage { page: RotPage },
}

Expand All @@ -57,7 +58,7 @@ pub struct Handler {
attest: Attest,
}

impl Handler {
impl<'a> Handler {
pub fn new() -> Handler {
Handler {
sprocket: crate::handler::sprockets::init(),
Expand Down Expand Up @@ -198,15 +199,35 @@ impl Handler {
}
}
}
Some(TrailingData::Attest { nonce, write_size }) => {
if write_size as usize > drv_sprot_api::MAX_BLOB_SIZE {
Response::pack(
&Err(SprotError::Protocol(
SprotProtocolError::BadMessageLength,
)),
tx_buf,
)
} else {
match Response::pack_with_cb(&rsp_body, tx_buf, |buf| {
self.attest
.attest(nonce, &mut buf[..write_size as usize])
.map_err(|e| RspBody::Attest(Err(e)))?;
Ok(write_size as usize)
}) {
Ok(size) => size,
Err(e) => Response::pack(&Ok(e), tx_buf),
}
}
}
_ => Response::pack(&rsp_body, tx_buf),
}
}

pub fn handle_request(
&mut self,
req: Request<'_>,
req: Request<'a>,
stats: &mut RotIoStats,
) -> Result<(RspBody, Option<TrailingData>), SprotError> {
) -> Result<(RspBody, Option<TrailingData<'a>>), SprotError> {
match req.body {
ReqBody::Status => {
let status = RotStatus {
Expand Down Expand Up @@ -367,6 +388,23 @@ impl Handler {
};
Ok((RspBody::Attest(rsp), None))
}
ReqBody::Attest(AttestReq::Attest {
nonce_size,
write_size,
}) => Ok((
RspBody::Attest(Ok(AttestRsp::Attest)),
Some(TrailingData::Attest {
nonce: &req.blob[..nonce_size as usize],
write_size,
}),
)),
ReqBody::Attest(AttestReq::AttestLen) => {
let rsp = match self.attest.attest_len() {
Ok(l) => Ok(AttestRsp::AttestLen(l)),
Err(e) => Err(e),
};
Ok((RspBody::Attest(rsp), None))
}
}
}
}
4 changes: 4 additions & 0 deletions drv/sprot-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ pub enum AttestReq {
Record { algorithm: HashAlgorithm },
Log { offset: u32, size: u32 },
LogLen,
Attest { nonce_size: u32, write_size: u32 },
AttestLen,
}

/// A response used for RoT updates
Expand Down Expand Up @@ -414,6 +416,8 @@ pub enum AttestRsp {
Record,
Log,
LogLen(u32),
Attest,
AttestLen(u32),
}

/// The body of a sprot response.
Expand Down
85 changes: 84 additions & 1 deletion drv/stm32h7-sprot-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#![no_main]
#![deny(elided_lifetimes_in_paths)]

use attest_api::HashAlgorithm;
use attest_api::{AttestError, HashAlgorithm, NONCE_MAX_SIZE, NONCE_MIN_SIZE};
use core::convert::Into;
use drv_lpc55_update_api::{
RotBootInfo, RotPage, SlotId, SwitchDuration, UpdateTarget,
Expand Down Expand Up @@ -1010,6 +1010,89 @@ impl<S: SpiServer> idl::InOrderSpRotImpl for ServerImpl<S> {
Err(e) => Err(AttestOrSprotError::Sprot(e).into()),
}
}

fn attest(
&mut self,
_msg: &userlib::RecvMessage,
nonce: idol_runtime::LenLimit<
idol_runtime::Leased<idol_runtime::R, [u8]>,
NONCE_MAX_SIZE,
>,
dest: idol_runtime::Leased<idol_runtime::W, [u8]>,
) -> Result<(), idol_runtime::RequestError<AttestOrSprotError>>
where
AttestOrSprotError: From<idol_runtime::ServerDeath>,
{
if nonce.len() < NONCE_MIN_SIZE {
return Err(
AttestOrSprotError::Attest(AttestError::BadLease).into()
);
}

let nonce_size = u32::try_from(nonce.len()).unwrap_lite();
let write_size = u32::try_from(dest.len()).unwrap_lite();

let body = ReqBody::Attest(AttestReq::Attest {
nonce_size,
write_size,
});
let tx_size = Request::pack_with_cb(&body, self.tx_buf, |buf| {
nonce
.read_range(0..nonce.len(), buf)
.map_err(|_| SprotProtocolError::TaskRestarted)?;
Ok::<usize, idol_runtime::RequestError<AttestOrSprotError>>(
nonce.len(),
)
})?;

let rsp = self.do_send_recv_retries(tx_size, TIMEOUT_MEDIUM, 1)?;

match rsp.body {
Ok(RspBody::Attest(Ok(AttestRsp::Attest))) => {
// Copy response data into the lease
if rsp.blob.len() < dest.len() {
return Err(idol_runtime::RequestError::Fail(
idol_runtime::ClientError::BadLease,
));
}
dest.write_range(0..dest.len(), &rsp.blob[..dest.len()])
.map_err(|()| {
idol_runtime::RequestError::Fail(
idol_runtime::ClientError::WentAway,
)
})?;
Ok(())
}
Ok(RspBody::Attest(Err(e))) => {
Err(AttestOrSprotError::Attest(e).into())
}
Ok(RspBody::Attest(_)) | Ok(_) => Err(AttestOrSprotError::Sprot(
SprotError::Protocol(SprotProtocolError::UnexpectedResponse),
)
.into()),
Err(e) => Err(AttestOrSprotError::Sprot(e).into()),
}
}

fn attest_len(
&mut self,
_msg: &userlib::RecvMessage,
) -> Result<u32, idol_runtime::RequestError<AttestOrSprotError>> {
let body = ReqBody::Attest(AttestReq::AttestLen);
let tx_size = Request::pack(&body, self.tx_buf);
let rsp = self.do_send_recv_retries(tx_size, TIMEOUT_QUICK, 1)?;
match rsp.body {
Ok(RspBody::Attest(Ok(AttestRsp::AttestLen(s)))) => Ok(s),
Ok(RspBody::Attest(Err(e))) => {
Err(AttestOrSprotError::Attest(e).into())
}
Ok(RspBody::Attest(_)) | Ok(_) => Err(AttestOrSprotError::Sprot(
SprotError::Protocol(SprotProtocolError::UnexpectedResponse),
)
.into()),
Err(e) => Err(AttestOrSprotError::Sprot(e).into()),
}
}
}

mod idl {
Expand Down
21 changes: 21 additions & 0 deletions idl/attest.idol
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,26 @@ Interface(
encoding: Hubpack,
idempotent: true,
),
"attest": (
doc: "Get an attestation",
leases: {
"nonce": (type: "[u8]", read: true, max_len: Some(128)),
"dest": (type: "[u8]", write: true),
},
reply: Result(
ok: "()",
err: Complex("AttestError"),
),
encoding: Hubpack,
),
"attest_len": (
doc: "Get the length of an attestation",
reply: Result(
ok: "u32",
err: Complex("AttestError"),
),
encoding: Hubpack,
idempotent: true,
),
}
)
22 changes: 22 additions & 0 deletions idl/sprot.idol
Original file line number Diff line number Diff line change
Expand Up @@ -257,5 +257,27 @@ Interface(
encoding: Hubpack,
idempotent: true,
),
"attest": (
doc: "Get an attestation",
args: {},
leases: {
"nonce": (type: "[u8]", read: true, max_len: Some(128)),
"dest": (type: "[u8]", write: true),
},
reply: Result(
ok: "()",
err: Complex("AttestOrSprotError"),
),
encoding: Hubpack,
),
"attest_len": (
doc: "Get length of a serialized attestation",
reply: Result(
ok: "u32",
err: Complex("AttestOrSprotError"),
),
encoding: Hubpack,
idempotent: true,
),
}
)
5 changes: 5 additions & 0 deletions task/attest-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub enum AttestError {
BadLease,
UnsupportedAlgorithm,
SerializeLog,
SerializeSignature,
SignatureTooBig,
}

impl From<idol_runtime::ServerDeath> for AttestError {
Expand All @@ -39,4 +41,7 @@ pub enum HashAlgorithm {
Sha3_256,
}

pub const NONCE_MIN_SIZE: usize = 32;
pub const NONCE_MAX_SIZE: usize = 128;

include!(concat!(env!("OUT_DIR"), "/client_stub.rs"));
2 changes: 2 additions & 0 deletions task/attest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ idol-runtime = { workspace = true }
mutable-statics = { path = "../../lib/mutable-statics" }
num-traits = { workspace = true }
ringbuf = { path = "../../lib/ringbuf" }
salty.workspace = true
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" }
attest-data.workspace = true
sha3.workspace = true
unwrap-lite = { path = "../../lib/unwrap-lite" }
userlib = { path = "../../sys/userlib", features = ["panic-messages"] }
zerocopy = { workspace = true }
Expand Down
Loading