sirenia: Use serde_bytes where appropriate.

Vec<u8> is often inefficient in serde, but serde_bytes provides a way of
labeling these as byte fields so they can be handled efficiently.

Also fix a clippy error where a mutable reference to a vector could be
replaced by a slice.

BUG=b:233694042,b:239114202
TEST=cargo test --workspace --all-features

Cq-Depend: chromium:3780891
Change-Id: Ic6fa83a2420064cf52cf882c59d8fc1f807d7bbc
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/3781443
Reviewed-by: Paramjit Oberoi <psoberoi@google.com>
Tested-by: Allen Webb <allenwebb@google.com>
Commit-Queue: Allen Webb <allenwebb@google.com>
diff --git a/sirenia/Cargo.toml b/sirenia/Cargo.toml
index 4589656..0032a92 100644
--- a/sirenia/Cargo.toml
+++ b/sirenia/Cargo.toml
@@ -71,6 +71,7 @@
 libsirenia = { path = "libsirenia" } # provided by ebuild
 log = "0.4.0"
 serde = { version = "1.0.114", features = ["derive"] }
+serde_bytes = "0.10.0"
 serde_json = "1.0.64"
 stderrlog = "0.5.0"
 thiserror = "1.0.20"
diff --git a/sirenia/libsirenia/Cargo.toml b/sirenia/libsirenia/Cargo.toml
index ed5147c..ea445c2 100644
--- a/sirenia/libsirenia/Cargo.toml
+++ b/sirenia/libsirenia/Cargo.toml
@@ -25,5 +25,6 @@
 openssl = "0.10.40"
 sirenia-rpc-macros = { path = "sirenia-rpc-macros" } # provided by ebuild
 serde = { version = "1.0.114", features = ["derive"] }
+serde_bytes = "0.10.0"
 serde_json = "1.0.64"
 thiserror = "1.0.20"
diff --git a/sirenia/libsirenia/src/communication/mod.rs b/sirenia/libsirenia/src/communication/mod.rs
index 85e8cd8..1277533 100644
--- a/sirenia/libsirenia/src/communication/mod.rs
+++ b/sirenia/libsirenia/src/communication/mod.rs
@@ -26,6 +26,7 @@
 use serde::de::DeserializeOwned;
 use serde::Deserialize;
 use serde::Serialize;
+use serde_bytes::ByteBuf;
 use thiserror::Error as ThisError;
 
 use crate::sys::eagain_is_ok;
@@ -188,7 +189,8 @@
 pub const SHA256_SIZE: usize = 32;
 
 #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
-pub struct Digest([u8; SHA256_SIZE]);
+#[serde(try_from = "ByteBuf")]
+pub struct Digest(#[serde(serialize_with = "serde_bytes::serialize")] [u8; SHA256_SIZE]);
 
 impl Deref for Digest {
     type Target = [u8; SHA256_SIZE];
@@ -212,6 +214,14 @@
     }
 }
 
+impl TryFrom<ByteBuf> for Digest {
+    type Error = TryFromSliceError;
+
+    fn try_from(value: ByteBuf) -> StdResult<Self, Self::Error> {
+        Ok(Digest(value.deref().try_into()?))
+    }
+}
+
 impl fmt::Display for Digest {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{}", self.map(|x| format!("{:02x}", x)).join(""))
diff --git a/sirenia/libsirenia/src/communication/tee_api.rs b/sirenia/libsirenia/src/communication/tee_api.rs
index 0220965..ad437d6 100644
--- a/sirenia/libsirenia/src/communication/tee_api.rs
+++ b/sirenia/libsirenia/src/communication/tee_api.rs
@@ -6,6 +6,7 @@
 
 use std::result::Result as StdResult;
 
+use serde_bytes::ByteBuf;
 use sirenia_rpc_macros::sirenia_rpc;
 
 use crate::communication::persistence;
@@ -13,7 +14,7 @@
 #[sirenia_rpc]
 pub trait TeeApi<E> {
     // Storage.
-    fn read_data(&mut self, id: String) -> StdResult<(persistence::Status, Vec<u8>), E>;
+    fn read_data(&mut self, id: String) -> StdResult<(persistence::Status, ByteBuf), E>;
     fn remove(&mut self, id: String) -> StdResult<persistence::Status, E>;
     fn write_data(&mut self, id: String, data: Vec<u8>) -> StdResult<persistence::Status, E>;
 }
diff --git a/sirenia/libsirenia/src/communication/trichechus.rs b/sirenia/libsirenia/src/communication/trichechus.rs
index bc9d89f..c635796 100644
--- a/sirenia/libsirenia/src/communication/trichechus.rs
+++ b/sirenia/libsirenia/src/communication/trichechus.rs
@@ -13,6 +13,7 @@
 use log::info;
 use serde::Deserialize;
 use serde::Serialize;
+use serde_bytes::ByteBuf;
 use sirenia_rpc_macros::sirenia_rpc;
 use thiserror::Error as ThisError;
 
@@ -83,7 +84,7 @@
     #[error()]
     fn get_apps(&mut self) -> StdResult<AppManifest, E>;
     #[error()]
-    fn get_logs(&mut self) -> StdResult<Vec<Vec<u8>>, E>;
+    fn get_logs(&mut self) -> StdResult<Vec<ByteBuf>, E>;
 
     fn prepare_manatee_memory_service_socket(&mut self, port_number: u32) -> StdResult<(), E>;
 
diff --git a/sirenia/manatee-runtime/Cargo.toml b/sirenia/manatee-runtime/Cargo.toml
index 0f44511..3c508fb 100644
--- a/sirenia/manatee-runtime/Cargo.toml
+++ b/sirenia/manatee-runtime/Cargo.toml
@@ -18,5 +18,6 @@
 log = "0.4.0"
 once_cell = "1.7.2"
 serde = { version = "1.0.114", features = ["derive"] }
+serde_bytes = "0.10.0"
 stderrlog = "0.5.0"
 sync = { path = "../../../platform/crosvm/common/sync" } # provided by ebuild
diff --git a/sirenia/manatee-runtime/src/storage/mod.rs b/sirenia/manatee-runtime/src/storage/mod.rs
index 49ba310..79fa060 100644
--- a/sirenia/manatee-runtime/src/storage/mod.rs
+++ b/sirenia/manatee-runtime/src/storage/mod.rs
@@ -56,7 +56,7 @@
     fn read_raw(&mut self, id: &str) -> Result<Vec<u8>> {
         // TODO: Log the rpc error.
         match self.rpc.lock().read_data(id.to_string()) {
-            Ok((Status::Success, res)) => Ok(res),
+            Ok((Status::Success, res)) => Ok(res.into()),
             Ok((Status::IdNotFound, _)) => Err(Error::IdNotFound(id.to_string())),
             Ok((Status::Failure, _)) | Ok((Status::CryptoFailure, _)) => Err(Error::ReadData(None)),
             Err(err) => Err(to_read_data_error(err)),
@@ -98,6 +98,7 @@
     use libsirenia::rpc::RpcDispatcher;
     use libsirenia::storage::Error as StorageError;
     use libsirenia::transport::create_transport_from_pipes;
+    use serde_bytes::ByteBuf;
 
     use super::*;
 
@@ -109,9 +110,9 @@
     }
 
     impl TeeApi<Error> for TeeApiServerImpl {
-        fn read_data(&mut self, id: String) -> Result<(Status, Vec<u8>)> {
+        fn read_data(&mut self, id: String) -> Result<(Status, ByteBuf)> {
             match self.map.borrow().get(&id) {
-                Some(val) => Ok((Status::Success, val.to_vec())),
+                Some(val) => Ok((Status::Success, val.clone().into())),
                 None => Err(anyhow!("id missing")),
             }
         }
diff --git a/sirenia/src/dugong.rs b/sirenia/src/dugong.rs
index 7071807..d21175c 100644
--- a/sirenia/src/dugong.rs
+++ b/sirenia/src/dugong.rs
@@ -14,6 +14,7 @@
 use std::io::Read;
 use std::mem::drop;
 use std::mem::replace;
+use std::ops::Deref;
 use std::ops::DerefMut;
 use std::os::unix::net::UnixDatagram;
 use std::result::Result as StdResult;
@@ -47,6 +48,7 @@
 use libsirenia::transport::DEFAULT_SERVER_PORT;
 use log::error;
 use log::info;
+use serde_bytes::ByteBuf;
 use sirenia::server::register_org_chromium_mana_teeinterface;
 use sirenia::server::OrgChromiumManaTEEInterface;
 
@@ -203,7 +205,7 @@
 fn handle_manatee_logs(dugong_state: &DugongState) -> Result<()> {
     const LOG_PATH: &str = "/dev/log";
     let mut trichechus_client = dugong_state.trichechus_client().lock().unwrap();
-    let logs: Vec<Vec<u8>> = trichechus_client
+    let logs: Vec<ByteBuf> = trichechus_client
         .get_logs()
         .context("failed to call get_logs rpc")?;
     if logs.is_empty() {
@@ -214,7 +216,7 @@
     let raw_syslog = UnixDatagram::unbound().context("failed connect to /dev/log")?;
     for entry in logs.as_slice() {
         raw_syslog
-            .send_to(entry, LOG_PATH)
+            .send_to(entry.deref(), LOG_PATH)
             .context("failed write to /dev/log")?;
     }
 
diff --git a/sirenia/src/trichechus.rs b/sirenia/src/trichechus.rs
index 7778c3f..db7445c 100644
--- a/sirenia/src/trichechus.rs
+++ b/sirenia/src/trichechus.rs
@@ -131,6 +131,7 @@
 use log::error;
 use log::info;
 use log::warn;
+use serde_bytes::ByteBuf;
 use sirenia::install_crash_handler;
 use sirenia::log_error;
 use sirenia::pstore;
@@ -241,9 +242,11 @@
 }
 
 impl TeeApi<Error> for TeeAppHandler {
-    fn read_data(&mut self, id: String) -> Result<(Status, Vec<u8>)> {
+    fn read_data(&mut self, id: String) -> Result<(Status, ByteBuf)> {
         self.conditionally_use_storage_encryption(|params, cronista| {
-            cronista.retrieve(params.scope.clone(), params.domain.to_string(), id.clone())
+            cronista
+                .retrieve(params.scope.clone(), params.domain.to_string(), id.clone())
+                .map(|r| (r.0, r.1.into()))
         })
     }
 
@@ -487,10 +490,10 @@
         Ok(self.state.borrow().app_manifest.clone())
     }
 
-    fn get_logs(&mut self) -> Result<Vec<Vec<u8>>> {
+    fn get_logs(&mut self) -> Result<Vec<ByteBuf>> {
         let mut replacement: VecDeque<Vec<u8>> = VecDeque::new();
         swap(&mut self.state.borrow_mut().log_queue, &mut replacement);
-        Ok(replacement.into())
+        Ok(replacement.into_iter().map(Into::<ByteBuf>::into).collect())
     }
 
     fn prepare_manatee_memory_service_socket(&mut self, port_number: u32) -> Result<()> {
@@ -532,7 +535,7 @@
     None
 }
 
-fn setup_pty(connections: &mut Vec<(Transport, i32)>) -> Result<[Box<dyn Mutator>; 4]> {
+fn setup_pty(connections: &mut [(Transport, i32)]) -> Result<[Box<dyn Mutator>; 4]> {
     let (stdin, stdout) =
         get_stdio_indices(connections).ok_or_else(|| anyhow!("failed to identify stdio"))?;
     let (main, client) = get_a_pty().context("failed get a pty")?;