diff --git a/app/oxide-rot-1/app-dev.toml b/app/oxide-rot-1/app-dev.toml index 21580a7d67..00e23d511b 100644 --- a/app/oxide-rot-1/app-dev.toml +++ b/app/oxide-rot-1/app-dev.toml @@ -77,7 +77,7 @@ task-slots = ["syscon_driver"] [tasks.sprot] name = "drv-lpc55-sprot-server" priority = 6 -max-sizes = {flash = 45248, ram = 32768} +max-sizes = {flash = 46100, ram = 32768} uses = ["flexcomm8", "bootrom"] features = ["spi0"] start = true diff --git a/app/oxide-rot-1/app.toml b/app/oxide-rot-1/app.toml index d6a06d2ee8..f1190d8b54 100644 --- a/app/oxide-rot-1/app.toml +++ b/app/oxide-rot-1/app.toml @@ -68,7 +68,7 @@ task-slots = ["syscon_driver"] [tasks.sprot] name = "drv-lpc55-sprot-server" priority = 6 -max-sizes = {flash = 45248, ram = 32768} +max-sizes = {flash = 46100, ram = 32768} uses = ["flexcomm8", "bootrom"] features = ["spi0"] start = true diff --git a/app/rot-carrier/app.toml b/app/rot-carrier/app.toml index 2bb8aa23a7..8365cd20fd 100644 --- a/app/rot-carrier/app.toml +++ b/app/rot-carrier/app.toml @@ -108,7 +108,7 @@ task-slots = ["syscon_driver"] [tasks.sprot] name = "drv-lpc55-sprot-server" priority = 6 -max-sizes = {flash = 45248, ram = 32768} +max-sizes = {flash = 46100, ram = 32768} uses = ["flexcomm8", "bootrom"] features = ["spi0"] start = true diff --git a/drv/lpc55-sprot-server/src/handler.rs b/drv/lpc55-sprot-server/src/handler.rs index e44da2310c..cbf33fc968 100644 --- a/drv/lpc55-sprot-server/src/handler.rs +++ b/drv/lpc55-sprot-server/src/handler.rs @@ -45,7 +45,8 @@ pub struct StartupState { /// Marker for data which should be copied after the packet is encoded pub enum TrailingData { Caboose { slot: SlotId, start: u32, size: u32 }, - Attest { index: u32, offset: u32, size: u32 }, + AttestCert { index: u32, offset: u32, size: u32 }, + AttestLog { offset: u32, size: u32 }, RotPage { page: RotPage }, } @@ -128,7 +129,7 @@ impl Handler { } } } - Some(TrailingData::Attest { + Some(TrailingData::AttestCert { index, offset, size, @@ -169,6 +170,27 @@ impl Handler { Err(e) => Response::pack(&Ok(e), tx_buf), } } + Some(TrailingData::AttestLog { offset, size }) => { + let size: usize = usize::try_from(size).unwrap_lite(); + if size > 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 + .log(offset, &mut buf[..size]) + .map_err(|e| RspBody::Attest(Err(e)))?; + Ok(size) + }) { + Ok(size) => size, + Err(e) => Response::pack(&Ok(e), tx_buf), + } + } + } _ => Response::pack(&rsp_body, tx_buf), } } @@ -289,7 +311,7 @@ impl Handler { // the work can be done elsewhere. Ok(( RspBody::Attest(Ok(AttestRsp::Cert)), - Some(TrailingData::Attest { + Some(TrailingData::AttestCert { index, offset, size, @@ -327,6 +349,17 @@ impl Handler { Some(TrailingData::RotPage { page }), )) } + ReqBody::Attest(AttestReq::Log { offset, size }) => Ok(( + RspBody::Attest(Ok(AttestRsp::Log)), + Some(TrailingData::AttestLog { offset, size }), + )), + ReqBody::Attest(AttestReq::LogLen) => { + let rsp = match self.attest.log_len() { + Ok(l) => Ok(AttestRsp::LogLen(l)), + Err(e) => Err(e), + }; + Ok((RspBody::Attest(rsp), None)) + } } } } diff --git a/drv/sprot-api/src/lib.rs b/drv/sprot-api/src/lib.rs index 58feccd055..4448a15200 100644 --- a/drv/sprot-api/src/lib.rs +++ b/drv/sprot-api/src/lib.rs @@ -389,6 +389,8 @@ pub enum AttestReq { CertLen(u32), Cert { index: u32, offset: u32, size: u32 }, Record { algorithm: HashAlgorithm }, + Log { offset: u32, size: u32 }, + LogLen, } /// A response used for RoT updates @@ -414,6 +416,8 @@ pub enum AttestRsp { CertLen(u32), Cert, Record, + Log, + LogLen(u32), } /// The body of a sprot response. diff --git a/drv/stm32h7-sprot-server/src/main.rs b/drv/stm32h7-sprot-server/src/main.rs index 9ef4ad965f..65122dbbad 100644 --- a/drv/stm32h7-sprot-server/src/main.rs +++ b/drv/stm32h7-sprot-server/src/main.rs @@ -947,6 +947,67 @@ impl idl::InOrderSpRotImpl for ServerImpl { Err(e) => Err(e.into()), } } + + fn log( + &mut self, + _msg: &userlib::RecvMessage, + offset: u32, + data: idol_runtime::Leased, + ) -> Result<(), idol_runtime::RequestError> { + let body = ReqBody::Attest(AttestReq::Log { + offset, + size: data.len() as u32, + }); + let tx_size = Request::pack(&body, &mut self.tx_buf); + let rsp = + self.do_send_recv_retries(tx_size, DUMP_TIMEOUT, DEFAULT_ATTEMPTS)?; + + match rsp.body { + Ok(RspBody::Attest(Ok(AttestRsp::Log))) => { + // Copy from the trailing data into the lease + if rsp.blob.len() < data.len() { + return Err(idol_runtime::RequestError::Fail( + idol_runtime::ClientError::BadLease, + )); + } + data.write_range(0..data.len(), &rsp.blob[..data.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 log_len( + &mut self, + _msg: &userlib::RecvMessage, + ) -> Result> { + let body = ReqBody::Attest(AttestReq::LogLen); + let tx_size = Request::pack(&body, &mut self.tx_buf); + let rsp = self.do_send_recv_retries(tx_size, TIMEOUT_QUICK, 1)?; + match rsp.body { + Ok(RspBody::Attest(Ok(AttestRsp::LogLen(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 { diff --git a/idl/sprot.idol b/idl/sprot.idol index 7c479bed21..2e2ae8f8dc 100644 --- a/idl/sprot.idol +++ b/idl/sprot.idol @@ -234,6 +234,28 @@ Interface( encoding: Hubpack, idempotent: true, ), - - } + "log": ( + doc: "Get the measurement log", + args: { + "offset" : "u32", + }, + leases: { + "dest": (type: "[u8]", write: true), + }, + reply: Result( + ok: "()", + err: Complex("AttestOrSprotError"), + ), + encoding: Hubpack, + ), + "log_len": ( + doc: "Get length of the serialized measurement log", + reply: Result( + ok: "u32", + err: Complex("AttestOrSprotError"), + ), + encoding: Hubpack, + idempotent: true, + ), + } )