This commit is contained in:
Karolin Varner
2025-11-01 20:35:10 +01:00
parent 9580961dd9
commit 8f276f70a6
24 changed files with 203 additions and 150 deletions

18
Cargo.lock generated
View File

@@ -1965,7 +1965,7 @@ checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [ dependencies = [
"rand_chacha 0.9.0", "rand_chacha 0.9.0",
"rand_core 0.9.3", "rand_core 0.9.3",
"zerocopy 0.8.24", "zerocopy 0.8.27",
] ]
[[package]] [[package]]
@@ -2115,7 +2115,7 @@ dependencies = [
"thiserror 1.0.69", "thiserror 1.0.69",
"toml", "toml",
"uds", "uds",
"zerocopy 0.7.35", "zerocopy 0.8.27",
"zeroize", "zeroize",
] ]
@@ -2273,7 +2273,7 @@ dependencies = [
"tokio", "tokio",
"typenum", "typenum",
"uds", "uds",
"zerocopy 0.7.35", "zerocopy 0.8.27",
"zeroize", "zeroize",
] ]
@@ -2298,7 +2298,7 @@ dependencies = [
"thiserror 1.0.69", "thiserror 1.0.69",
"tokio", "tokio",
"wireguard-uapi", "wireguard-uapi",
"zerocopy 0.7.35", "zerocopy 0.8.27",
] ]
[[package]] [[package]]
@@ -3315,11 +3315,11 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.8.24" version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
dependencies = [ dependencies = [
"zerocopy-derive 0.8.24", "zerocopy-derive 0.8.27",
] ]
[[package]] [[package]]
@@ -3335,9 +3335,9 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.8.24" version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@@ -66,7 +66,7 @@ chacha20poly1305 = { version = "0.10.1", default-features = false, features = [
"std", "std",
"heapless", "heapless",
] } ] }
zerocopy = { version = "0.7.35", features = ["derive"] } zerocopy = { version = "0.8.27", features = ["derive"] }
home = "=0.5.9" # 5.11 requires rustc 1.81 home = "=0.5.9" # 5.11 requires rustc 1.81
derive_builder = "0.20.1" derive_builder = "0.20.1"
tokio = { version = "1.46", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.46", features = ["macros", "rt-multi-thread"] }

View File

@@ -97,6 +97,7 @@ rustix = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
[features] [features]
default = ["experiment_api"]
experiment_cookie_dos_mitigation = [] experiment_cookie_dos_mitigation = []
experiment_memfd_secret = ["rosenpass-wireguard-broker/experiment_memfd_secret"] experiment_memfd_secret = ["rosenpass-wireguard-broker/experiment_memfd_secret"]
experiment_libcrux_all = ["rosenpass-ciphers/experiment_libcrux_all"] experiment_libcrux_all = ["rosenpass-ciphers/experiment_libcrux_all"]

View File

@@ -316,7 +316,7 @@ where
use crate::app_server::BrokerStorePtr; use crate::app_server::BrokerStorePtr;
// //
use rosenpass_secret_memory::Public; use rosenpass_secret_memory::Public;
use zerocopy::AsBytes; use zerocopy::IntoBytes;
(self.app_server().brokers.store.len() - 1) (self.app_server().brokers.store.len() - 1)
.apply(|x| x as u64) .apply(|x| x as u64)
.apply(|x| Public::from_slice(x.as_bytes())) .apply(|x| Public::from_slice(x.as_bytes()))

View File

@@ -1,4 +1,4 @@
use zerocopy::{ByteSlice, Ref}; use zerocopy::{ByteSlice, Ref, SplitByteSlice};
use rosenpass_util::zerocopy::{RefMaker, ZerocopySliceExt}; use rosenpass_util::zerocopy::{RefMaker, ZerocopySliceExt};
@@ -7,7 +7,7 @@ use super::{
ResponseMsgType, ResponseRef, SupplyKeypairRequest, SupplyKeypairResponse, ResponseMsgType, ResponseRef, SupplyKeypairRequest, SupplyKeypairResponse,
}; };
pub trait ByteSliceRefExt: ByteSlice { pub trait ByteSliceRefExt: SplitByteSlice {
/// Shorthand for the typed use of [ZerocopySliceExt::zk_ref_maker]. /// Shorthand for the typed use of [ZerocopySliceExt::zk_ref_maker].
fn msg_type_maker(self) -> RefMaker<Self, RawMsgType> { fn msg_type_maker(self) -> RefMaker<Self, RawMsgType> {
self.zk_ref_maker() self.zk_ref_maker()
@@ -259,4 +259,4 @@ pub trait ByteSliceRefExt: ByteSlice {
} }
} }
impl<B: ByteSlice> ByteSliceRefExt for B {} impl<B: SplitByteSlice> ByteSliceRefExt for B {}

View File

@@ -1,4 +1,4 @@
use zerocopy::{ByteSliceMut, Ref}; use zerocopy::{Ref, SplitByteSliceMut};
use rosenpass_util::zerocopy::RefMaker; use rosenpass_util::zerocopy::RefMaker;
@@ -35,7 +35,7 @@ pub trait Message {
/// # Examples /// # Examples
/// ///
/// See [crate::api::PingRequest::setup] /// See [crate::api::PingRequest::setup]
fn setup<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>>; fn setup<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>>;
} }
/// Additional convenience functions for working with [rosenpass_util::zerocopy::RefMaker] /// Additional convenience functions for working with [rosenpass_util::zerocopy::RefMaker]
@@ -45,7 +45,7 @@ pub trait ZerocopyResponseMakerSetupMessageExt<B, T> {
impl<B, T> ZerocopyResponseMakerSetupMessageExt<B, T> for RefMaker<B, T> impl<B, T> ZerocopyResponseMakerSetupMessageExt<B, T> for RefMaker<B, T>
where where
B: ByteSliceMut, B: SplitByteSliceMut,
T: Message, T: Message,
{ {
/// Initialize the message using [Message::setup]. /// Initialize the message using [Message::setup].

View File

@@ -1,6 +1,6 @@
use hex_literal::hex; use hex_literal::hex;
use rosenpass_util::zerocopy::RefMaker; use rosenpass_util::zerocopy::RefMaker;
use zerocopy::ByteSlice; use zerocopy::{SplitByteSlice};
use crate::RosenpassError::{self, InvalidApiMessageType}; use crate::RosenpassError::{self, InvalidApiMessageType};
@@ -169,12 +169,12 @@ pub trait RefMakerRawMsgTypeExt {
fn parse_response_msg_type(self) -> anyhow::Result<ResponseMsgType>; fn parse_response_msg_type(self) -> anyhow::Result<ResponseMsgType>;
} }
impl<B: ByteSlice> RefMakerRawMsgTypeExt for RefMaker<B, RawMsgType> { impl<B: SplitByteSlice> RefMakerRawMsgTypeExt for RefMaker<B, RawMsgType> {
fn parse_request_msg_type(self) -> anyhow::Result<RequestMsgType> { fn parse_request_msg_type(self) -> anyhow::Result<RequestMsgType> {
Ok(self.parse()?.read().try_into()?) Ok(zerocopy::Ref::read(&self.parse()?).try_into()?)
} }
fn parse_response_msg_type(self) -> anyhow::Result<ResponseMsgType> { fn parse_response_msg_type(self) -> anyhow::Result<ResponseMsgType> {
Ok(self.parse()?.read().try_into()?) Ok(zerocopy::Ref::<B, u128>::read(&self.parse()?).try_into()?)
} }
} }

View File

@@ -1,5 +1,5 @@
use rosenpass_util::zerocopy::ZerocopyMutSliceExt; use rosenpass_util::zerocopy::ZerocopyMutSliceExt;
use zerocopy::{AsBytes, ByteSliceMut, FromBytes, FromZeroes, Ref}; use zerocopy::{SplitByteSliceMut, FromBytes, Immutable, IntoBytes, KnownLayout, Ref};
use super::{Message, RawMsgType, RequestMsgType, ResponseMsgType}; use super::{Message, RawMsgType, RequestMsgType, ResponseMsgType};
@@ -12,8 +12,8 @@ pub const MAX_REQUEST_FDS: usize = 2;
/// Message envelope for API messages /// Message envelope for API messages
#[repr(packed)] #[repr(packed)]
#[derive(Debug, Copy, Clone, Hash, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] #[derive(Debug, Copy, Clone, Hash, IntoBytes, FromBytes, PartialEq, Eq, Immutable, KnownLayout)]
pub struct Envelope<M: AsBytes + FromBytes> { pub struct Envelope<M: IntoBytes + FromBytes + Immutable + KnownLayout> {
/// Which message this is /// Which message this is
pub msg_type: RawMsgType, pub msg_type: RawMsgType,
/// The actual Paylod /// The actual Paylod
@@ -27,7 +27,7 @@ pub type ResponseEnvelope<M> = Envelope<M>;
#[allow(missing_docs)] #[allow(missing_docs)]
#[repr(packed)] #[repr(packed)]
#[derive(Debug, Copy, Clone, Hash, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] #[derive(Debug, Copy, Clone, Hash, IntoBytes, FromBytes, PartialEq, Eq, Immutable, KnownLayout)]
pub struct PingRequestPayload { pub struct PingRequestPayload {
/// Randomly generated connection id /// Randomly generated connection id
pub echo: [u8; 256], pub echo: [u8; 256],
@@ -55,7 +55,7 @@ impl Message for PingRequest {
} }
} }
fn setup<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> { fn setup<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> {
let mut r: Ref<B, Self> = buf.zk_zeroized()?; let mut r: Ref<B, Self> = buf.zk_zeroized()?;
r.init(); r.init();
Ok(r) Ok(r)
@@ -68,7 +68,7 @@ impl Message for PingRequest {
#[allow(missing_docs)] #[allow(missing_docs)]
#[repr(packed)] #[repr(packed)]
#[derive(Debug, Copy, Clone, Hash, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] #[derive(Debug, Copy, Clone, Hash, IntoBytes, FromBytes, PartialEq, Eq, Immutable, KnownLayout)]
pub struct PingResponsePayload { pub struct PingResponsePayload {
/// Randomly generated connection id /// Randomly generated connection id
pub echo: [u8; 256], pub echo: [u8; 256],
@@ -96,7 +96,7 @@ impl Message for PingResponse {
} }
} }
fn setup<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> { fn setup<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> {
let mut r: Ref<B, Self> = buf.zk_zeroized()?; let mut r: Ref<B, Self> = buf.zk_zeroized()?;
r.init(); r.init();
Ok(r) Ok(r)
@@ -109,7 +109,7 @@ impl Message for PingResponse {
#[allow(missing_docs)] #[allow(missing_docs)]
#[repr(packed)] #[repr(packed)]
#[derive(Debug, Copy, Clone, Hash, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] #[derive(Debug, Copy, Clone, Hash, IntoBytes, FromBytes, PartialEq, Eq, Immutable, KnownLayout)]
pub struct SupplyKeypairRequestPayload {} pub struct SupplyKeypairRequestPayload {}
#[allow(missing_docs)] #[allow(missing_docs)]
@@ -140,7 +140,7 @@ impl Message for SupplyKeypairRequest {
} }
} }
fn setup<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> { fn setup<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> {
let mut r: Ref<B, Self> = buf.zk_zeroized()?; let mut r: Ref<B, Self> = buf.zk_zeroized()?;
r.init(); r.init();
Ok(r) Ok(r)
@@ -169,7 +169,7 @@ pub mod supply_keypair_response_status {
#[allow(missing_docs)] #[allow(missing_docs)]
#[repr(packed)] #[repr(packed)]
#[derive(Debug, Copy, Clone, Hash, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] #[derive(Debug, Copy, Clone, Hash, IntoBytes, FromBytes, PartialEq, Eq, Immutable, KnownLayout)]
pub struct SupplyKeypairResponsePayload { pub struct SupplyKeypairResponsePayload {
#[allow(missing_docs)] #[allow(missing_docs)]
pub status: u128, pub status: u128,
@@ -197,7 +197,7 @@ impl Message for SupplyKeypairResponse {
} }
} }
fn setup<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> { fn setup<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> {
let mut r: Ref<B, Self> = buf.zk_zeroized()?; let mut r: Ref<B, Self> = buf.zk_zeroized()?;
r.init(); r.init();
Ok(r) Ok(r)
@@ -210,7 +210,7 @@ impl Message for SupplyKeypairResponse {
#[allow(missing_docs)] #[allow(missing_docs)]
#[repr(packed)] #[repr(packed)]
#[derive(Debug, Copy, Clone, Hash, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] #[derive(Debug, Copy, Clone, Hash, IntoBytes, FromBytes, PartialEq, Eq, Immutable, KnownLayout)]
pub struct AddListenSocketRequestPayload {} pub struct AddListenSocketRequestPayload {}
#[allow(missing_docs)] #[allow(missing_docs)]
@@ -241,7 +241,7 @@ impl Message for AddListenSocketRequest {
} }
} }
fn setup<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> { fn setup<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> {
let mut r: Ref<B, Self> = buf.zk_zeroized()?; let mut r: Ref<B, Self> = buf.zk_zeroized()?;
r.init(); r.init();
Ok(r) Ok(r)
@@ -264,7 +264,7 @@ pub mod add_listen_socket_response_status {
#[allow(missing_docs)] #[allow(missing_docs)]
#[repr(packed)] #[repr(packed)]
#[derive(Debug, Copy, Clone, Hash, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] #[derive(Debug, Copy, Clone, Hash, IntoBytes, FromBytes, PartialEq, Eq, Immutable, KnownLayout)]
pub struct AddListenSocketResponsePayload { pub struct AddListenSocketResponsePayload {
pub status: u128, pub status: u128,
} }
@@ -291,7 +291,7 @@ impl Message for AddListenSocketResponse {
} }
} }
fn setup<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> { fn setup<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> {
let mut r: Ref<B, Self> = buf.zk_zeroized()?; let mut r: Ref<B, Self> = buf.zk_zeroized()?;
r.init(); r.init();
Ok(r) Ok(r)
@@ -304,7 +304,7 @@ impl Message for AddListenSocketResponse {
#[allow(missing_docs)] #[allow(missing_docs)]
#[repr(packed)] #[repr(packed)]
#[derive(Debug, Copy, Clone, Hash, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] #[derive(Debug, Copy, Clone, Hash, IntoBytes, FromBytes, PartialEq, Eq, Immutable, KnownLayout)]
pub struct AddPskBrokerRequestPayload {} pub struct AddPskBrokerRequestPayload {}
#[allow(missing_docs)] #[allow(missing_docs)]
@@ -336,7 +336,7 @@ impl Message for AddPskBrokerRequest {
} }
} }
fn setup<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> { fn setup<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> {
let mut r: Ref<B, Self> = buf.zk_zeroized()?; let mut r: Ref<B, Self> = buf.zk_zeroized()?;
r.init(); r.init();
Ok(r) Ok(r)
@@ -359,7 +359,7 @@ pub mod add_psk_broker_response_status {
#[allow(missing_docs)] #[allow(missing_docs)]
#[repr(packed)] #[repr(packed)]
#[derive(Debug, Copy, Clone, Hash, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] #[derive(Debug, Copy, Clone, Hash, IntoBytes, FromBytes, PartialEq, Eq, Immutable, KnownLayout)]
pub struct AddPskBrokerResponsePayload { pub struct AddPskBrokerResponsePayload {
pub status: u128, pub status: u128,
} }
@@ -386,7 +386,7 @@ impl Message for AddPskBrokerResponse {
} }
} }
fn setup<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> { fn setup<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self>> {
let mut r: Ref<B, Self> = buf.zk_zeroized()?; let mut r: Ref<B, Self> = buf.zk_zeroized()?;
r.init(); r.init();
Ok(r) Ok(r)

View File

@@ -1,6 +1,6 @@
use anyhow::ensure; use anyhow::{anyhow, ensure};
use zerocopy::{ByteSlice, ByteSliceMut, Ref}; use zerocopy::{IntoBytes, Ref, SplitByteSlice, SplitByteSliceMut};
use super::{ByteSliceRefExt, MessageAttributes, PingRequest, RequestMsgType}; use super::{ByteSliceRefExt, MessageAttributes, PingRequest, RequestMsgType};
@@ -13,7 +13,7 @@ struct RequestRefMaker<B> {
msg_type: RequestMsgType, msg_type: RequestMsgType,
} }
impl<B: ByteSlice> RequestRef<B> { impl<B: SplitByteSlice> RequestRef<B> {
/// Produce a [RequestRef] from a raw message buffer, /// Produce a [RequestRef] from a raw message buffer,
/// reading the type from the buffer /// reading the type from the buffer
/// ///
@@ -95,7 +95,7 @@ impl<B> From<Ref<B, super::AddPskBrokerRequest>> for RequestRef<B> {
} }
} }
impl<B: ByteSlice> RequestRefMaker<B> { impl<B: SplitByteSlice> RequestRefMaker<B> {
fn new(buf: B) -> anyhow::Result<Self> { fn new(buf: B) -> anyhow::Result<Self> {
let msg_type = buf.deref().request_msg_type_from_prefix()?; let msg_type = buf.deref().request_msg_type_from_prefix()?;
Ok(Self { buf, msg_type }) Ok(Self { buf, msg_type })
@@ -125,7 +125,8 @@ impl<B: ByteSlice> RequestRefMaker<B> {
self.ensure_fit()?; self.ensure_fit()?;
let point = self.target_size(); let point = self.target_size();
let Self { buf, msg_type } = self; let Self { buf, msg_type } = self;
let (buf, _) = buf.split_at(point); let (buf, _) = buf.split_at(point)
.map_err(|_| anyhow!("Failed to split buffer"))?;
Ok(Self { buf, msg_type }) Ok(Self { buf, msg_type })
} }
@@ -134,7 +135,8 @@ impl<B: ByteSlice> RequestRefMaker<B> {
self.ensure_fit()?; self.ensure_fit()?;
let point = self.buf.len() - self.target_size(); let point = self.buf.len() - self.target_size();
let Self { buf, msg_type } = self; let Self { buf, msg_type } = self;
let (buf, _) = buf.split_at(point); let (buf, _) = buf.split_at(point)
.map_err(|_| anyhow!("Failed to split buffer"))?;
Ok(Self { buf, msg_type }) Ok(Self { buf, msg_type })
} }
@@ -159,7 +161,7 @@ pub enum RequestRef<B> {
impl<B> RequestRef<B> impl<B> RequestRef<B>
where where
B: ByteSlice, B: SplitByteSlice,
{ {
/// Access the byte data of this reference /// Access the byte data of this reference
/// ///
@@ -168,25 +170,25 @@ where
/// See [Self::parse]. /// See [Self::parse].
pub fn bytes(&self) -> &[u8] { pub fn bytes(&self) -> &[u8] {
match self { match self {
Self::Ping(r) => r.bytes(), Self::Ping(r) => r.as_bytes(),
Self::SupplyKeypair(r) => r.bytes(), Self::SupplyKeypair(r) => r.as_bytes(),
Self::AddListenSocket(r) => r.bytes(), Self::AddListenSocket(r) => r.as_bytes(),
Self::AddPskBroker(r) => r.bytes(), Self::AddPskBroker(r) => r.as_bytes(),
} }
} }
} }
impl<B> RequestRef<B> impl<B> RequestRef<B>
where where
B: ByteSliceMut, B: SplitByteSliceMut,
{ {
/// Access the byte data of this reference; mutably /// Access the byte data of this reference; mutably
pub fn bytes_mut(&mut self) -> &[u8] { pub fn bytes_mut(&mut self) -> &[u8] {
match self { match self {
Self::Ping(r) => r.bytes_mut(), Self::Ping(r) => r.as_mut_bytes(),
Self::SupplyKeypair(r) => r.bytes_mut(), Self::SupplyKeypair(r) => r.as_mut_bytes(),
Self::AddListenSocket(r) => r.bytes_mut(), Self::AddListenSocket(r) => r.as_mut_bytes(),
Self::AddPskBroker(r) => r.bytes_mut(), Self::AddPskBroker(r) => r.as_mut_bytes(),
} }
} }
} }

View File

@@ -1,7 +1,7 @@
use rosenpass_util::zerocopy::{ use rosenpass_util::zerocopy::{
RefMaker, ZerocopyEmancipateExt, ZerocopyEmancipateMutExt, ZerocopySliceExt, RefMaker, ZerocopyEmancipateExt, ZerocopyEmancipateMutExt, ZerocopySliceExt,
}; };
use zerocopy::{ByteSlice, ByteSliceMut, Ref}; use zerocopy::{Immutable, KnownLayout, Ref, SplitByteSlice, SplitByteSliceMut};
use super::{Message, PingRequest, PingResponse}; use super::{Message, PingRequest, PingResponse};
use super::{RequestRef, ResponseRef, ZerocopyResponseMakerSetupMessageExt}; use super::{RequestRef, ResponseRef, ZerocopyResponseMakerSetupMessageExt};
@@ -9,27 +9,27 @@ use super::{RequestRef, ResponseRef, ZerocopyResponseMakerSetupMessageExt};
/// Extension trait for [Message]s that are requests messages /// Extension trait for [Message]s that are requests messages
pub trait RequestMsg: Sized + Message { pub trait RequestMsg: Sized + Message {
/// The response message belonging to this request message /// The response message belonging to this request message
type ResponseMsg: ResponseMsg; type ResponseMsg: ResponseMsg + Immutable + KnownLayout;
/// Construct a response make for this particular message /// Construct a response make for this particular message
fn zk_response_maker<B: ByteSlice>(buf: B) -> RefMaker<B, Self::ResponseMsg> { fn zk_response_maker<B: SplitByteSlice>(buf: B) -> RefMaker<B, Self::ResponseMsg> {
buf.zk_ref_maker() buf.zk_ref_maker()
} }
/// Setup a response maker (through [Message::setup]) for this request message type /// Setup a response maker (through [Message::setup]) for this request message type
fn setup_response<B: ByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self::ResponseMsg>> { fn setup_response<B: SplitByteSliceMut>(buf: B) -> anyhow::Result<Ref<B, Self::ResponseMsg>> {
Self::zk_response_maker(buf).setup_msg() Self::zk_response_maker(buf).setup_msg()
} }
/// Setup a response maker from a buffer prefix (through [Message::setup]) for this request message type /// Setup a response maker from a buffer prefix (through [Message::setup]) for this request message type
fn setup_response_from_prefix<B: ByteSliceMut>( fn setup_response_from_prefix<B: SplitByteSliceMut>(
buf: B, buf: B,
) -> anyhow::Result<Ref<B, Self::ResponseMsg>> { ) -> anyhow::Result<Ref<B, Self::ResponseMsg>> {
Self::zk_response_maker(buf).from_prefix()?.setup_msg() Self::zk_response_maker(buf).from_prefix()?.setup_msg()
} }
/// Setup a response maker from a buffer suffix (through [Message::setup]) for this request message type /// Setup a response maker from a buffer suffix (through [Message::setup]) for this request message type
fn setup_response_from_suffix<B: ByteSliceMut>( fn setup_response_from_suffix<B: SplitByteSliceMut>(
buf: B, buf: B,
) -> anyhow::Result<Ref<B, Self::ResponseMsg>> { ) -> anyhow::Result<Ref<B, Self::ResponseMsg>> {
Self::zk_response_maker(buf).from_prefix()?.setup_msg() Self::zk_response_maker(buf).from_prefix()?.setup_msg()
@@ -125,8 +125,8 @@ impl<B1, B2> From<AddPskBrokerPair<B1, B2>> for RequestResponsePair<B1, B2> {
impl<B1, B2> RequestResponsePair<B1, B2> impl<B1, B2> RequestResponsePair<B1, B2>
where where
B1: ByteSlice, B1: SplitByteSlice,
B2: ByteSlice, B2: SplitByteSlice,
{ {
/// Returns a tuple to both the request and the response message /// Returns a tuple to both the request and the response message
pub fn both(&self) -> (RequestRef<&[u8]>, ResponseRef<&[u8]>) { pub fn both(&self) -> (RequestRef<&[u8]>, ResponseRef<&[u8]>) {
@@ -167,8 +167,8 @@ where
impl<B1, B2> RequestResponsePair<B1, B2> impl<B1, B2> RequestResponsePair<B1, B2>
where where
B1: ByteSliceMut, B1: SplitByteSliceMut,
B2: ByteSliceMut, B2: SplitByteSliceMut,
{ {
/// Returns a mutable tuple to both the request and the response message /// Returns a mutable tuple to both the request and the response message
pub fn both_mut(&mut self) -> (RequestRef<&mut [u8]>, ResponseRef<&mut [u8]>) { pub fn both_mut(&mut self) -> (RequestRef<&mut [u8]>, ResponseRef<&mut [u8]>) {

View File

@@ -1,7 +1,7 @@
// TODO: This is copied verbatim from ResponseRef…not pretty // TODO: This is copied verbatim from ResponseRef…not pretty
use anyhow::ensure; use anyhow::{anyhow, ensure};
use zerocopy::{ByteSlice, ByteSliceMut, Ref}; use zerocopy::{IntoBytes, Ref, SplitByteSlice, SplitByteSliceMut};
use super::{ByteSliceRefExt, MessageAttributes, PingResponse, ResponseMsgType}; use super::{ByteSliceRefExt, MessageAttributes, PingResponse, ResponseMsgType};
@@ -16,7 +16,7 @@ struct ResponseRefMaker<B> {
msg_type: ResponseMsgType, msg_type: ResponseMsgType,
} }
impl<B: ByteSlice> ResponseRef<B> { impl<B: SplitByteSlice> ResponseRef<B> {
/// Produce a [ResponseRef] from a raw message buffer, /// Produce a [ResponseRef] from a raw message buffer,
/// reading the type from the buffer /// reading the type from the buffer
/// ///
@@ -99,7 +99,7 @@ impl<B> From<Ref<B, super::AddPskBrokerResponse>> for ResponseRef<B> {
} }
} }
impl<B: ByteSlice> ResponseRefMaker<B> { impl<B: SplitByteSlice> ResponseRefMaker<B> {
fn new(buf: B) -> anyhow::Result<Self> { fn new(buf: B) -> anyhow::Result<Self> {
let msg_type = buf.deref().response_msg_type_from_prefix()?; let msg_type = buf.deref().response_msg_type_from_prefix()?;
Ok(Self { buf, msg_type }) Ok(Self { buf, msg_type })
@@ -129,7 +129,8 @@ impl<B: ByteSlice> ResponseRefMaker<B> {
self.ensure_fit()?; self.ensure_fit()?;
let point = self.target_size(); let point = self.target_size();
let Self { buf, msg_type } = self; let Self { buf, msg_type } = self;
let (buf, _) = buf.split_at(point); let (buf, _) = buf.split_at(point)
.map_err(|_| anyhow!("Failed to split buffer!"))?;
Ok(Self { buf, msg_type }) Ok(Self { buf, msg_type })
} }
@@ -138,7 +139,8 @@ impl<B: ByteSlice> ResponseRefMaker<B> {
self.ensure_fit()?; self.ensure_fit()?;
let point = self.buf.len() - self.target_size(); let point = self.buf.len() - self.target_size();
let Self { buf, msg_type } = self; let Self { buf, msg_type } = self;
let (buf, _) = buf.split_at(point); let (buf, _) = buf.split_at(point)
.map_err(|_| anyhow!("Failed to split buffer!"))?;
Ok(Self { buf, msg_type }) Ok(Self { buf, msg_type })
} }
@@ -163,7 +165,7 @@ pub enum ResponseRef<B> {
impl<B> ResponseRef<B> impl<B> ResponseRef<B>
where where
B: ByteSlice, B: SplitByteSlice,
{ {
/// Access the byte data of this reference /// Access the byte data of this reference
/// ///
@@ -172,25 +174,25 @@ where
/// See [Self::parse]. /// See [Self::parse].
pub fn bytes(&self) -> &[u8] { pub fn bytes(&self) -> &[u8] {
match self { match self {
Self::Ping(r) => r.bytes(), Self::Ping(r) => r.as_bytes(),
Self::SupplyKeypair(r) => r.bytes(), Self::SupplyKeypair(r) => r.as_bytes(),
Self::AddListenSocket(r) => r.bytes(), Self::AddListenSocket(r) => r.as_bytes(),
Self::AddPskBroker(r) => r.bytes(), Self::AddPskBroker(r) => r.as_bytes(),
} }
} }
} }
impl<B> ResponseRef<B> impl<B> ResponseRef<B>
where where
B: ByteSliceMut, B: SplitByteSliceMut,
{ {
/// Access the byte data of this reference; mutably /// Access the byte data of this reference; mutably
pub fn bytes_mut(&mut self) -> &[u8] { pub fn bytes_mut(&mut self) -> &[u8] {
match self { match self {
Self::Ping(r) => r.bytes_mut(), Self::Ping(r) => r.as_mut_bytes(),
Self::SupplyKeypair(r) => r.bytes_mut(), Self::SupplyKeypair(r) => r.as_mut_bytes(),
Self::AddListenSocket(r) => r.bytes_mut(), Self::AddListenSocket(r) => r.as_mut_bytes(),
Self::AddPskBroker(r) => r.bytes_mut(), Self::AddPskBroker(r) => r.as_mut_bytes(),
} }
} }
} }

View File

@@ -1,6 +1,6 @@
use super::{ByteSliceRefExt, Message, PingRequest, PingResponse, RequestRef, RequestResponsePair}; use super::{ByteSliceRefExt, Message, PingRequest, PingResponse, RequestRef, RequestResponsePair};
use std::{collections::VecDeque, os::fd::OwnedFd}; use std::{collections::VecDeque, os::fd::OwnedFd};
use zerocopy::{ByteSlice, ByteSliceMut}; use zerocopy::{SplitByteSlice, SplitByteSliceMut};
/// The rosenpass API implementation functions. /// The rosenpass API implementation functions.
/// ///
@@ -152,8 +152,8 @@ pub trait Server {
req_fds: &mut VecDeque<OwnedFd>, req_fds: &mut VecDeque<OwnedFd>,
) -> anyhow::Result<()> ) -> anyhow::Result<()>
where where
ReqBuf: ByteSlice, ReqBuf: SplitByteSlice,
ResBuf: ByteSliceMut, ResBuf: SplitByteSliceMut,
{ {
match p { match p {
RequestResponsePair::Ping((req, res)) => self.ping(req, req_fds, res), RequestResponsePair::Ping((req, res)) => self.ping(req, req_fds, res),
@@ -182,8 +182,8 @@ pub trait Server {
res: ResBuf, res: ResBuf,
) -> anyhow::Result<usize> ) -> anyhow::Result<usize>
where where
ReqBuf: ByteSlice, ReqBuf: SplitByteSlice,
ResBuf: ByteSliceMut, ResBuf: SplitByteSliceMut,
{ {
let req = req.parse_request_from_prefix()?; let req = req.parse_request_from_prefix()?;
// TODO: This is not pretty; This match should be moved into RequestRef // TODO: This is not pretty; This match should be moved into RequestRef

View File

@@ -13,7 +13,7 @@ use signal_hook_mio::v1_0 as signal_hook_mio;
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use derive_builder::Builder; use derive_builder::Builder;
use log::{error, info, warn}; use log::{error, info, warn};
use zerocopy::AsBytes; use zerocopy::IntoBytes;
use rosenpass_util::attempt; use rosenpass_util::attempt;
use rosenpass_util::fmt::debug::NullDebug; use rosenpass_util::fmt::debug::NullDebug;

View File

@@ -9,7 +9,7 @@
//! To achieve this we utilize the zerocopy library. //! To achieve this we utilize the zerocopy library.
//! //!
use std::mem::size_of; use std::mem::size_of;
use zerocopy::{AsBytes, FromBytes, FromZeroes}; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::RosenpassError; use super::RosenpassError;
use rosenpass_cipher_traits::primitives::{Aead as _, Kem}; use rosenpass_cipher_traits::primitives::{Aead as _, Kem};
@@ -51,7 +51,7 @@ pub type MsgEnvelopeCookie = [u8; COOKIE_SIZE];
/// ///
/// ``` /// ```
/// use rosenpass::msgs::{Envelope, InitHello}; /// use rosenpass::msgs::{Envelope, InitHello};
/// use zerocopy::{AsBytes, FromBytes, Ref, FromZeroes}; /// use zerocopy::{IntoBytes, FromBytes, Ref};
/// use memoffset::offset_of; /// use memoffset::offset_of;
/// ///
/// // Zero-initialization /// // Zero-initialization
@@ -76,8 +76,8 @@ pub type MsgEnvelopeCookie = [u8; COOKIE_SIZE];
/// assert_eq!(ih3.msg_type, 42); /// assert_eq!(ih3.msg_type, 42);
/// ``` /// ```
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes, Clone)] #[derive(IntoBytes, FromBytes, Clone, Immutable, KnownLayout)]
pub struct Envelope<M: AsBytes + FromBytes> { pub struct Envelope<M: IntoBytes + FromBytes> {
/// [MsgType] of this message /// [MsgType] of this message
pub msg_type: u8, pub msg_type: u8,
/// Reserved for future use /// Reserved for future use
@@ -106,7 +106,7 @@ pub struct Envelope<M: AsBytes + FromBytes> {
/// ///
/// ``` /// ```
/// use rosenpass::msgs::{Envelope, InitHello}; /// use rosenpass::msgs::{Envelope, InitHello};
/// use zerocopy::{AsBytes, FromBytes, Ref, FromZeroes}; /// use zerocopy::{IntoBytes, FromBytes, Ref};
/// use memoffset::span_of; /// use memoffset::span_of;
/// ///
/// // Zero initialization /// // Zero initialization
@@ -126,7 +126,7 @@ pub struct Envelope<M: AsBytes + FromBytes> {
/// assert_eq!(ih.payload.sidi, [1,2,3,4]); /// assert_eq!(ih.payload.sidi, [1,2,3,4]);
/// ``` /// ```
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes)] #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
pub struct InitHello { pub struct InitHello {
/// Randomly generated connection id /// Randomly generated connection id
pub sidi: [u8; 4], pub sidi: [u8; 4],
@@ -155,7 +155,7 @@ pub struct InitHello {
/// ///
/// ``` /// ```
/// use rosenpass::msgs::{Envelope, RespHello}; /// use rosenpass::msgs::{Envelope, RespHello};
/// use zerocopy::{AsBytes, FromBytes, Ref, FromZeroes}; /// use zerocopy::{IntoBytes, FromBytes, Ref};
/// use memoffset::span_of; /// use memoffset::span_of;
/// ///
/// // Zero initialization /// // Zero initialization
@@ -175,7 +175,7 @@ pub struct InitHello {
/// assert_eq!(ih.payload.sidi, [1,2,3,4]); /// assert_eq!(ih.payload.sidi, [1,2,3,4]);
/// ``` /// ```
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes)] #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
pub struct RespHello { pub struct RespHello {
/// Randomly generated connection id /// Randomly generated connection id
pub sidr: [u8; 4], pub sidr: [u8; 4],
@@ -206,7 +206,7 @@ pub struct RespHello {
/// ///
/// ``` /// ```
/// use rosenpass::msgs::{Envelope, InitConf}; /// use rosenpass::msgs::{Envelope, InitConf};
/// use zerocopy::{AsBytes, FromBytes, Ref, FromZeroes}; /// use zerocopy::{IntoBytes, FromBytes, Ref};
/// use memoffset::span_of; /// use memoffset::span_of;
/// ///
/// // Zero initialization /// // Zero initialization
@@ -226,7 +226,7 @@ pub struct RespHello {
/// assert_eq!(ih.payload.sidi, [1,2,3,4]); /// assert_eq!(ih.payload.sidi, [1,2,3,4]);
/// ``` /// ```
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes, Debug)] #[derive(IntoBytes, FromBytes, Debug, Immutable, KnownLayout)]
pub struct InitConf { pub struct InitConf {
/// Copied from InitHello /// Copied from InitHello
pub sidi: [u8; 4], pub sidi: [u8; 4],
@@ -264,7 +264,7 @@ pub struct InitConf {
/// ///
/// ``` /// ```
/// use rosenpass::msgs::{Envelope, EmptyData}; /// use rosenpass::msgs::{Envelope, EmptyData};
/// use zerocopy::{AsBytes, FromBytes, Ref, FromZeroes}; /// use zerocopy::{IntoBytes, FromBytes, Ref};
/// use memoffset::span_of; /// use memoffset::span_of;
/// ///
/// // Zero initialization /// // Zero initialization
@@ -284,7 +284,7 @@ pub struct InitConf {
/// assert_eq!(ih.payload.sid, [1,2,3,4]); /// assert_eq!(ih.payload.sid, [1,2,3,4]);
/// ``` /// ```
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes, Clone, Copy)] #[derive(IntoBytes, FromBytes, Clone, Copy, Immutable, KnownLayout)]
pub struct EmptyData { pub struct EmptyData {
/// Copied from RespHello /// Copied from RespHello
pub sid: [u8; 4], pub sid: [u8; 4],
@@ -311,7 +311,7 @@ pub struct EmptyData {
/// ///
/// [Envelope] and [InitHello] contain some extra examples on how to use structures from the [::zerocopy] crate. /// [Envelope] and [InitHello] contain some extra examples on how to use structures from the [::zerocopy] crate.
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes)] #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
pub struct Biscuit { pub struct Biscuit {
/// H(spki) Ident ifies the initiator /// H(spki) Ident ifies the initiator
pub pidi: [u8; KEY_LEN], pub pidi: [u8; KEY_LEN],
@@ -336,7 +336,7 @@ pub struct Biscuit {
/// ///
/// [Envelope] and [InitHello] contain some extra examples on how to use structures from the [::zerocopy] crate. /// [Envelope] and [InitHello] contain some extra examples on how to use structures from the [::zerocopy] crate.
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes)] #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
pub struct CookieReplyInner { pub struct CookieReplyInner {
/// [MsgType] of this message /// [MsgType] of this message
pub msg_type: u8, pub msg_type: u8,
@@ -363,7 +363,7 @@ pub struct CookieReplyInner {
/// ///
/// [Envelope] and [InitHello] contain some extra examples on how to use structures from the [::zerocopy] crate. /// [Envelope] and [InitHello] contain some extra examples on how to use structures from the [::zerocopy] crate.
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes)] #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
pub struct CookieReply { pub struct CookieReply {
pub inner: CookieReplyInner, pub inner: CookieReplyInner,
pub padding: [u8; size_of::<Envelope<InitHello>>() - size_of::<CookieReplyInner>()], pub padding: [u8; size_of::<Envelope<InitHello>>() - size_of::<CookieReplyInner>()],

View File

@@ -17,7 +17,7 @@ use std::{
use anyhow::{bail, ensure, Context, Result}; use anyhow::{bail, ensure, Context, Result};
use assert_tv::{TestVector, TestVectorNOP}; use assert_tv::{TestVector, TestVectorNOP};
use memoffset::span_of; use memoffset::span_of;
use zerocopy::{AsBytes, FromBytes, Ref}; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref};
use rosenpass_cipher_traits::primitives::{ use rosenpass_cipher_traits::primitives::{
Aead as _, AeadWithNonceInCiphertext, Kem, KeyedHashInstance, Aead as _, AeadWithNonceInCiphertext, Kem, KeyedHashInstance,
@@ -413,7 +413,7 @@ pub struct InitiatorHandshake {
/// ///
/// Used as [KnownInitConfResponse] for now cache [EmptyData] (responder confirmation) /// Used as [KnownInitConfResponse] for now cache [EmptyData] (responder confirmation)
/// responses to [InitConf] /// responses to [InitConf]
pub struct KnownResponse<ResponseType: AsBytes + FromBytes> { pub struct KnownResponse<ResponseType: IntoBytes + FromBytes> {
/// When the response was initially computed /// When the response was initially computed
pub received_at: Timing, pub received_at: Timing,
/// Hash of the message that triggered the response; created using /// Hash of the message that triggered the response; created using
@@ -423,7 +423,7 @@ pub struct KnownResponse<ResponseType: AsBytes + FromBytes> {
pub response: Envelope<ResponseType>, pub response: Envelope<ResponseType>,
} }
impl<ResponseType: AsBytes + FromBytes> Debug for KnownResponse<ResponseType> { impl<ResponseType: IntoBytes + FromBytes> Debug for KnownResponse<ResponseType> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("KnownResponse") f.debug_struct("KnownResponse")
.field("received_at", &self.received_at) .field("received_at", &self.received_at)
@@ -435,7 +435,7 @@ impl<ResponseType: AsBytes + FromBytes> Debug for KnownResponse<ResponseType> {
#[test] #[test]
fn known_response_format() { fn known_response_format() {
use zerocopy::FromZeroes; use zerocopy::FromZeros;
let v = KnownResponse::<[u8; 32]> { let v = KnownResponse::<[u8; 32]> {
received_at: 42.0, received_at: 42.0,
@@ -508,7 +508,7 @@ impl KnownResponseHasher {
/// # Panic & Safety /// # Panic & Safety
/// ///
/// Panics in case of a problem with this underlying hash function /// Panics in case of a problem with this underlying hash function
pub fn hash<Msg: AsBytes + FromBytes>(&self, msg: &Envelope<Msg>) -> KnownResponseHash { pub fn hash<Msg: IntoBytes + FromBytes + Immutable>(&self, msg: &Envelope<Msg>) -> KnownResponseHash {
let data = &msg.as_bytes()[span_of!(Envelope<Msg>, msg_type..cookie)]; let data = &msg.as_bytes()[span_of!(Envelope<Msg>, msg_type..cookie)];
// This function is only used internally and results are not propagated // This function is only used internally and results are not propagated
// to outside the peer. Thus, it uses SHAKE256 exclusively. // to outside the peer. Thus, it uses SHAKE256 exclusively.
@@ -2354,8 +2354,8 @@ impl CryptoServer {
/// ///
/// To save some code, the function returns the size of the message, /// To save some code, the function returns the size of the message,
/// but the same could be easily achieved by calling [size_of] with the /// but the same could be easily achieved by calling [size_of] with the
/// message type or by calling [AsBytes::as_bytes] on the message reference. /// message type or by calling [IntoBytes::as_bytes] on the message reference.
pub fn seal_and_commit_msg<M: AsBytes + FromBytes>( pub fn seal_and_commit_msg<M: IntoBytes + FromBytes + Immutable + KnownLayout>(
&mut self, &mut self,
peer: PeerPtr, peer: PeerPtr,
msg_type: MsgType, msg_type: MsgType,
@@ -3078,7 +3078,7 @@ impl IniHsPtr {
impl<M> Envelope<M> impl<M> Envelope<M>
where where
M: AsBytes + FromBytes, M: IntoBytes + FromBytes + Immutable + KnownLayout,
{ {
/// Internal business logic: Calculate the message authentication code (`mac`) and also append cookie value /// Internal business logic: Calculate the message authentication code (`mac`) and also append cookie value
pub fn seal(&mut self, peer: PeerPtr, srv: &CryptoServer) -> Result<()> { pub fn seal(&mut self, peer: PeerPtr, srv: &CryptoServer) -> Result<()> {
@@ -3107,7 +3107,7 @@ where
impl<M> Envelope<M> impl<M> Envelope<M>
where where
M: AsBytes + FromBytes, M: IntoBytes + FromBytes + Immutable + KnownLayout,
{ {
/// Internal business logic: Check the message authentication code produced by [Self::seal] /// Internal business logic: Check the message authentication code produced by [Self::seal]
pub fn check_seal(&self, srv: &CryptoServer, shake_or_blake: KeyedHash) -> Result<bool> { pub fn check_seal(&self, srv: &CryptoServer, shake_or_blake: KeyedHash) -> Result<bool> {

View File

@@ -2,19 +2,19 @@
use std::mem::size_of; use std::mem::size_of;
use zerocopy::{FromBytes, Ref}; use zerocopy::{FromBytes, Immutable, KnownLayout, Ref};
use crate::RosenpassError; use crate::RosenpassError;
/// Used to parse a network message using [zerocopy] /// Used to parse a network message using [zerocopy]
pub fn truncating_cast_into<T: FromBytes>( pub fn truncating_cast_into<T: FromBytes + KnownLayout + Immutable>(
buf: &mut [u8], buf: &mut [u8],
) -> Result<Ref<&mut [u8], T>, RosenpassError> { ) -> Result<Ref<&mut [u8], T>, RosenpassError> {
Ref::new(&mut buf[..size_of::<T>()]).ok_or(RosenpassError::BufferSizeMismatch) Ref::new(&mut buf[..size_of::<T>()]).ok_or(RosenpassError::BufferSizeMismatch)
} }
/// Used to parse a network message using [zerocopy], mutably /// Used to parse a network message using [zerocopy], mutably
pub fn truncating_cast_into_nomut<T: FromBytes>( pub fn truncating_cast_into_nomut<T: FromBytes + KnownLayout + Immutable>(
buf: &[u8], buf: &[u8],
) -> Result<Ref<&[u8], T>, RosenpassError> { ) -> Result<Ref<&[u8], T>, RosenpassError> {
Ref::new(&buf[..size_of::<T>()]).ok_or(RosenpassError::BufferSizeMismatch) Ref::new(&buf[..size_of::<T>()]).ok_or(RosenpassError::BufferSizeMismatch)

View File

@@ -2,6 +2,8 @@
use std::{borrow::Borrow, sync::atomic::AtomicU64}; use std::{borrow::Borrow, sync::atomic::AtomicU64};
use zerocopy::{FromBytes, IntoBytes};
use crate::{ use crate::{
ipc::shm::SharedMemorySegment, ipc::shm::SharedMemorySegment,
ringbuf::concurrent::framework::{ ringbuf::concurrent::framework::{
@@ -13,7 +15,8 @@ use crate::{
/// ///
/// These values must be shared between the reader/writer in such a way that access to the inner /// These values must be shared between the reader/writer in such a way that access to the inner
/// variables is synchronized and atomic between the two parties. /// variables is synchronized and atomic between the two parties.
#[derive(Debug, Default)] #[repr(C)]
#[derive(Debug, Default, IntoBytes, FromBytes)]
pub struct ShmPipeVariables { pub struct ShmPipeVariables {
/// See [crate::ringbuf::sched::RingBufferScheduler::items_read()] /// See [crate::ringbuf::sched::RingBufferScheduler::items_read()]
pub items_read: AtomicU64, pub items_read: AtomicU64,

View File

@@ -1,9 +1,9 @@
//! A module providing the [`RefMaker`] type and its associated methods for constructing //! A module providing the [`RefMaker`] type and its associated methods for constructing
//! [`zerocopy::Ref`] references from byte buffers. //! [`zerocopy::Ref`] references from byte buffers.
use anyhow::{ensure, Context}; use anyhow::ensure;
use std::marker::PhantomData; use std::marker::PhantomData;
use zerocopy::{ByteSlice, ByteSliceMut, Ref}; use zerocopy::{Immutable, KnownLayout, Ref, SplitByteSlice, SplitByteSliceMut};
use zeroize::Zeroize; use zeroize::Zeroize;
use crate::zeroize::ZeroizedExt; use crate::zeroize::ZeroizedExt;
@@ -82,7 +82,10 @@ impl<B, T> RefMaker<B, T> {
} }
} }
impl<B: ByteSlice, T> RefMaker<B, T> { impl<B: SplitByteSlice, T> RefMaker<B, T>
where
T: KnownLayout + Immutable,
{
/// Parses the buffer into a [`zerocopy::Ref<B, T>`]. /// Parses the buffer into a [`zerocopy::Ref<B, T>`].
/// ///
/// This will fail if the buffer is smaller than `size_of::<T>`. /// This will fail if the buffer is smaller than `size_of::<T>`.
@@ -120,7 +123,7 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
/// ``` /// ```
pub fn parse(self) -> anyhow::Result<Ref<B, T>> { pub fn parse(self) -> anyhow::Result<Ref<B, T>> {
self.ensure_fit()?; self.ensure_fit()?;
Ref::<B, T>::new(self.buf).context("Parser error!") Ref::<B, T>::from_bytes(self.buf).map_err(|e| anyhow::anyhow!("Parser error: {e:?}"))
} }
/// Splits the internal buffer into a `RefMaker` containing a buffer with /// Splits the internal buffer into a `RefMaker` containing a buffer with
@@ -142,7 +145,10 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
/// ``` /// ```
pub fn from_prefix_with_tail(self) -> anyhow::Result<(Self, B)> { pub fn from_prefix_with_tail(self) -> anyhow::Result<(Self, B)> {
self.ensure_fit()?; self.ensure_fit()?;
let (head, tail) = self.buf.split_at(Self::target_size()); let (head, tail) = self
.buf
.split_at(Self::target_size())
.map_err(|_| anyhow::anyhow!("Failed to split buffer!"))?;
Ok((Self::new(head), tail)) Ok((Self::new(head), tail))
} }
@@ -165,7 +171,10 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
/// ``` /// ```
pub fn split_prefix(self) -> anyhow::Result<(Self, Self)> { pub fn split_prefix(self) -> anyhow::Result<(Self, Self)> {
self.ensure_fit()?; self.ensure_fit()?;
let (head, tail) = self.buf.split_at(Self::target_size()); let (head, tail) = self
.buf
.split_at(Self::target_size())
.map_err(|_| anyhow::anyhow!("Failed to split buffer!"))?;
Ok((Self::new(head), Self::new(tail))) Ok((Self::new(head), Self::new(tail)))
} }
@@ -204,7 +213,10 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
pub fn from_suffix_with_head(self) -> anyhow::Result<(Self, B)> { pub fn from_suffix_with_head(self) -> anyhow::Result<(Self, B)> {
self.ensure_fit()?; self.ensure_fit()?;
let point = self.bytes().len() - Self::target_size(); let point = self.bytes().len() - Self::target_size();
let (head, tail) = self.buf.split_at(point); let (head, tail) = self
.buf
.split_at(point)
.map_err(|_| anyhow::anyhow!("Failed to split buffer!"))?;
Ok((Self::new(tail), head)) Ok((Self::new(tail), head))
} }
@@ -227,7 +239,10 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
pub fn split_suffix(self) -> anyhow::Result<(Self, Self)> { pub fn split_suffix(self) -> anyhow::Result<(Self, Self)> {
self.ensure_fit()?; self.ensure_fit()?;
let point = self.bytes().len() - Self::target_size(); let point = self.bytes().len() - Self::target_size();
let (head, tail) = self.buf.split_at(point); let (head, tail) = self
.buf
.split_at(point)
.map_err(|_| anyhow::anyhow!("Failed to split buffer!"))?;
Ok((Self::new(head), Self::new(tail))) Ok((Self::new(head), Self::new(tail)))
} }
@@ -282,7 +297,10 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
} }
} }
impl<B: ByteSliceMut, T> RefMaker<B, T> { impl<B: SplitByteSliceMut, T> RefMaker<B, T>
where
T: KnownLayout + Immutable,
{
/// Creates a zeroized reference of type `T` from the buffer. /// Creates a zeroized reference of type `T` from the buffer.
/// ///
/// # Errors /// # Errors
@@ -312,7 +330,10 @@ impl<B: ByteSliceMut, T> RefMaker<B, T> {
} }
} }
impl<B: ByteSliceMut, T> Zeroize for RefMaker<B, T> { impl<B: SplitByteSliceMut, T> Zeroize for RefMaker<B, T>
where
T: KnownLayout + Immutable,
{
fn zeroize(&mut self) { fn zeroize(&mut self) {
self.bytes_mut().zeroize() self.bytes_mut().zeroize()
} }

View File

@@ -1,7 +1,7 @@
//! Extension traits for converting `Ref<B, T>` into references backed by //! Extension traits for converting `Ref<B, T>` into references backed by
//! standard slices. //! standard slices.
use zerocopy::{ByteSlice, ByteSliceMut, Ref}; use zerocopy::{SplitByteSlice, SplitByteSliceMut, Immutable, KnownLayout, Ref};
/// A trait for converting a `Ref<B, T>` into a `Ref<&[u8], T>`. /// A trait for converting a `Ref<B, T>` into a `Ref<&[u8], T>`.
/// ///
@@ -16,7 +16,7 @@ pub trait ZerocopyEmancipateExt<B, T> {
/// ///
/// ``` /// ```
/// # use std::ops::Deref; /// # use std::ops::Deref;
/// # use zerocopy::{AsBytes, ByteSlice, FromBytes, FromZeroes, Ref}; /// # use zerocopy::{AsBytes, SplitByteSlice, FromBytes, FromZeroes, Ref};
/// # use rosenpass_util::zerocopy::ZerocopyEmancipateExt; /// # use rosenpass_util::zerocopy::ZerocopyEmancipateExt;
/// #[derive(FromBytes, FromZeroes, AsBytes)] /// #[derive(FromBytes, FromZeroes, AsBytes)]
/// #[repr(C)] /// #[repr(C)]
@@ -64,18 +64,20 @@ pub trait ZerocopyEmancipateMutExt<B, T> {
impl<B, T> ZerocopyEmancipateExt<B, T> for Ref<B, T> impl<B, T> ZerocopyEmancipateExt<B, T> for Ref<B, T>
where where
B: ByteSlice, B: SplitByteSlice,
T: KnownLayout + Immutable,
{ {
fn emancipate(&self) -> Ref<&[u8], T> { fn emancipate(&self) -> Ref<&[u8], T> {
Ref::new(self.bytes()).unwrap() Ref::new(zerocopy::Ref::<B, T>::bytes(&self)).unwrap()
} }
} }
impl<B, T> ZerocopyEmancipateMutExt<B, T> for Ref<B, T> impl<B, T> ZerocopyEmancipateMutExt<B, T> for Ref<B, T>
where where
B: ByteSliceMut, B: SplitByteSliceMut,
T: KnownLayout + Immutable,
{ {
fn emancipate_mut(&mut self) -> Ref<&mut [u8], T> { fn emancipate_mut(&mut self) -> Ref<&mut [u8], T> {
Ref::new(self.bytes_mut()).unwrap() Ref::new(zerocopy::Ref::<B, T>::bytes_mut(self)).unwrap()
} }
} }

View File

@@ -1,7 +1,7 @@
//! Extension traits for parsing slices into [`zerocopy::Ref`] values using the //! Extension traits for parsing slices into [`zerocopy::Ref`] values using the
//! [`RefMaker`] abstraction. //! [`RefMaker`] abstraction.
use zerocopy::{ByteSlice, ByteSliceMut, Ref}; use zerocopy::{Immutable, KnownLayout, Ref, SplitByteSlice, SplitByteSliceMut};
use super::RefMaker; use super::RefMaker;
@@ -9,7 +9,7 @@ use super::RefMaker;
/// ///
/// This trait adds methods for creating [`Ref`] references from /// This trait adds methods for creating [`Ref`] references from
/// slices by using the [`RefMaker`] type internally. /// slices by using the [`RefMaker`] type internally.
pub trait ZerocopySliceExt: Sized + ByteSlice { pub trait ZerocopySliceExt: Sized + SplitByteSlice {
/// Creates a new `RefMaker` for the given slice. /// Creates a new `RefMaker` for the given slice.
/// ///
/// # Example /// # Example
@@ -52,7 +52,10 @@ pub trait ZerocopySliceExt: Sized + ByteSlice {
/// assert_eq!(data_ref.0, 0x0201); /// assert_eq!(data_ref.0, 0x0201);
/// assert_eq!(data_ref.1, 0x0403); /// assert_eq!(data_ref.1, 0x0403);
/// ``` /// ```
fn zk_parse<T>(self) -> anyhow::Result<Ref<Self, T>> { fn zk_parse<T>(self) -> anyhow::Result<Ref<Self, T>>
where
T: Immutable + KnownLayout,
{
self.zk_ref_maker().parse() self.zk_ref_maker().parse()
} }
@@ -80,7 +83,10 @@ pub trait ZerocopySliceExt: Sized + ByteSlice {
/// let header_ref = bytes.0.zk_parse_prefix::<Header>().unwrap(); /// let header_ref = bytes.0.zk_parse_prefix::<Header>().unwrap();
/// assert_eq!(header_ref.0, 0xDDCCBBAA); /// assert_eq!(header_ref.0, 0xDDCCBBAA);
/// ``` /// ```
fn zk_parse_prefix<T>(self) -> anyhow::Result<Ref<Self, T>> { fn zk_parse_prefix<T>(self) -> anyhow::Result<Ref<Self, T>>
where
T: Immutable + KnownLayout,
{
self.zk_ref_maker().from_prefix()?.parse() self.zk_ref_maker().from_prefix()?.parse()
} }
@@ -108,18 +114,21 @@ pub trait ZerocopySliceExt: Sized + ByteSlice {
/// let header_ref = bytes.0.zk_parse_suffix::<Header>().unwrap(); /// let header_ref = bytes.0.zk_parse_suffix::<Header>().unwrap();
/// assert_eq!(header_ref.0, 0x30201000); /// assert_eq!(header_ref.0, 0x30201000);
/// ``` /// ```
fn zk_parse_suffix<T>(self) -> anyhow::Result<Ref<Self, T>> { fn zk_parse_suffix<T>(self) -> anyhow::Result<Ref<Self, T>>
where
T: Immutable + KnownLayout,
{
self.zk_ref_maker().from_suffix()?.parse() self.zk_ref_maker().from_suffix()?.parse()
} }
} }
impl<B: ByteSlice> ZerocopySliceExt for B {} impl<B: SplitByteSlice> ZerocopySliceExt for B {}
/// Extension trait for zero-copy parsing of mutable slices with zeroization /// Extension trait for zero-copy parsing of mutable slices with zeroization
/// capabilities. /// capabilities.
/// ///
/// Provides convenience methods to create zero-initialized references. /// Provides convenience methods to create zero-initialized references.
pub trait ZerocopyMutSliceExt: ZerocopySliceExt + Sized + ByteSliceMut { pub trait ZerocopyMutSliceExt: ZerocopySliceExt + Sized + SplitByteSliceMut {
/// Creates a new zeroized reference from the entire slice. /// Creates a new zeroized reference from the entire slice.
/// ///
/// This zeroizes the slice first, then provides a `Ref`. /// This zeroizes the slice first, then provides a `Ref`.
@@ -143,7 +152,10 @@ pub trait ZerocopyMutSliceExt: ZerocopySliceExt + Sized + ByteSliceMut {
/// assert_eq!(data_ref.0, [0,0,0,0]); /// assert_eq!(data_ref.0, [0,0,0,0]);
/// assert_eq!(bytes.0, [0, 0, 0, 0]); /// assert_eq!(bytes.0, [0, 0, 0, 0]);
/// ``` /// ```
fn zk_zeroized<T>(self) -> anyhow::Result<Ref<Self, T>> { fn zk_zeroized<T>(self) -> anyhow::Result<Ref<Self, T>>
where
T: Immutable + KnownLayout,
{
self.zk_ref_maker().make_zeroized() self.zk_ref_maker().make_zeroized()
} }
@@ -171,7 +183,10 @@ pub trait ZerocopyMutSliceExt: ZerocopySliceExt + Sized + ByteSliceMut {
/// assert_eq!(data_ref.0, [0,0,0,0]); /// assert_eq!(data_ref.0, [0,0,0,0]);
/// assert_eq!(bytes.0, [0, 0, 0, 0, 0xFF, 0xFF]); /// assert_eq!(bytes.0, [0, 0, 0, 0, 0xFF, 0xFF]);
/// ``` /// ```
fn zk_zeroized_from_prefix<T>(self) -> anyhow::Result<Ref<Self, T>> { fn zk_zeroized_from_prefix<T>(self) -> anyhow::Result<Ref<Self, T>>
where
T: Immutable + KnownLayout,
{
self.zk_ref_maker().from_prefix()?.make_zeroized() self.zk_ref_maker().from_prefix()?.make_zeroized()
} }
@@ -199,9 +214,12 @@ pub trait ZerocopyMutSliceExt: ZerocopySliceExt + Sized + ByteSliceMut {
/// assert_eq!(data_ref.0, [0,0,0,0]); /// assert_eq!(data_ref.0, [0,0,0,0]);
/// assert_eq!(bytes.0, [0xFF, 0xFF, 0, 0, 0, 0]); /// assert_eq!(bytes.0, [0xFF, 0xFF, 0, 0, 0, 0]);
/// ``` /// ```
fn zk_zeroized_from_suffix<T>(self) -> anyhow::Result<Ref<Self, T>> { fn zk_zeroized_from_suffix<T>(self) -> anyhow::Result<Ref<Self, T>>
where
T: Immutable + KnownLayout,
{
self.zk_ref_maker().from_suffix()?.make_zeroized() self.zk_ref_maker().from_suffix()?.make_zeroized()
} }
} }
impl<B: ByteSliceMut> ZerocopyMutSliceExt for B {} impl<B: SplitByteSliceMut> ZerocopyMutSliceExt for B {}

View File

@@ -41,6 +41,7 @@ rand = { workspace = true }
procspawn = { workspace = true } procspawn = { workspace = true }
[features] [features]
default = ["experiment_api"]
experiment_api = ["rustix", "libc"] experiment_api = ["rustix", "libc"]
experiment_memfd_secret = [] experiment_memfd_secret = []

View File

@@ -38,6 +38,8 @@
use std::{borrow::BorrowMut, fmt::Debug}; use std::{borrow::BorrowMut, fmt::Debug};
use zerocopy::IntoBytes;
use crate::{ use crate::{
api::{ api::{
config::NetworkBrokerConfig, config::NetworkBrokerConfig,
@@ -219,7 +221,7 @@ where
// Send message // Send message
self.io self.io
.borrow_mut() .borrow_mut()
.send_msg(req.bytes()) .send_msg(req.as_bytes())
.map_err(IoError)?; .map_err(IoError)?;
Ok(()) Ok(())

View File

@@ -3,7 +3,7 @@
use std::str::{from_utf8, Utf8Error}; use std::str::{from_utf8, Utf8Error};
use zerocopy::{AsBytes, FromBytes, FromZeroes}; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
/// The number of bytes reserved for overhead when packaging data. /// The number of bytes reserved for overhead when packaging data.
pub const ENVELOPE_OVERHEAD: usize = 1 + 3; pub const ENVELOPE_OVERHEAD: usize = 1 + 3;
@@ -15,8 +15,8 @@ pub const RESPONSE_MSG_BUFFER_SIZE: usize = ENVELOPE_OVERHEAD + 1;
/// Envelope for messages being passed around. /// Envelope for messages being passed around.
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes)] #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
pub struct Envelope<M: AsBytes + FromBytes> { pub struct Envelope<M: IntoBytes + FromBytes> {
/// [MsgType] of this message /// [MsgType] of this message
pub msg_type: u8, pub msg_type: u8,
/// Reserved for future use /// Reserved for future use
@@ -29,7 +29,7 @@ pub struct Envelope<M: AsBytes + FromBytes> {
/// # Example /// # Example
/// ///
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes)] #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
pub struct SetPskRequest { pub struct SetPskRequest {
/// The pre-shared key. /// The pre-shared key.
pub psk: [u8; 32], pub psk: [u8; 32],
@@ -85,7 +85,7 @@ impl SetPskRequest {
/// Message format for response to the set pre-shared key operation. /// Message format for response to the set pre-shared key operation.
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes, FromBytes, FromZeroes)] #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
pub struct SetPskResponse { pub struct SetPskResponse {
pub return_code: u8, pub return_code: u8,
} }

View File

@@ -8,6 +8,7 @@
use std::borrow::BorrowMut; use std::borrow::BorrowMut;
use rosenpass_secret_memory::{Public, Secret}; use rosenpass_secret_memory::{Public, Secret};
use zerocopy::IntoBytes;
use crate::api::msgs::{self, Envelope, SetPskRequest, SetPskResponse}; use crate::api::msgs::{self, Envelope, SetPskRequest, SetPskResponse};
use crate::WireGuardBroker; use crate::WireGuardBroker;
@@ -85,7 +86,7 @@ where
res.msg_type = msgs::MsgType::SetPsk as u8; res.msg_type = msgs::MsgType::SetPsk as u8;
self.handle_set_psk(&req.payload, &mut res.payload)?; self.handle_set_psk(&req.payload, &mut res.payload)?;
Ok(res.bytes().len()) Ok(res.as_bytes().len())
} }
/// Sets the pre-shared key for the interface identified in `req` to the pre-shared key /// Sets the pre-shared key for the interface identified in `req` to the pre-shared key