From bd41e3a5244eefd4dd3eeab38002ba18a867ba88 Mon Sep 17 00:00:00 2001 From: Marc Schoolderman Date: Fri, 19 Jul 2024 20:48:42 +0200 Subject: [PATCH] add optional mutability to crypto layer (uses an unsafe hack) Signed-off-by: Marc Schoolderman --- tsp/src/cesr/packet.rs | 40 +++++++++++++++++++++------------ tsp/src/cesr/packet/from_mut.rs | 17 ++++++++++++++ tsp/src/crypto/tsp_hpke.rs | 6 ++--- 3 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 tsp/src/cesr/packet/from_mut.rs diff --git a/tsp/src/cesr/packet.rs b/tsp/src/cesr/packet.rs index 66061a5..15d7d74 100644 --- a/tsp/src/cesr/packet.rs +++ b/tsp/src/cesr/packet.rs @@ -58,11 +58,11 @@ type Sha256Digest = crate::definitions::Digest; #[repr(u32)] #[derive(Debug)] #[cfg_attr(any(test, feature = "fuzzing"), derive(PartialEq, Eq, Clone))] -pub enum Payload<'a, Bytes: AsRef<[u8]>, Vid> { +pub enum Payload<'a, Bytes: AsRef<[u8]>, Vid, NestedBytes: AsRef<[u8]> = Bytes> { /// A TSP message which consists only of a message which will be protected using HPKE GenericMessage(Bytes), /// A payload that consists of a TSP Envelope+Message - NestedMessage(Bytes), + NestedMessage(NestedBytes), /// A routed payload; same as above but with routing information attached RoutedMessage(Vec, Bytes), /// A TSP message requesting a relationship @@ -299,13 +299,25 @@ fn decode_hops<'a, Vid: TryFrom<&'a [u8]>>(stream: &mut &'a [u8]) -> Result { - pub payload: Payload<'a, &'a [u8], &'a [u8]>, +// "NestedBytes" to support both mutable and non-mutable data +/// A decoded payload + optional ESSR data +pub struct DecodedPayload<'a, Bytes: AsRef<[u8]> = &'a mut [u8]> { + pub payload: Payload<'a, Bytes, &'a [u8]>, pub sender_identity: Option<&'a [u8]>, } +// temporary +fn fudge(x: &[u8]) -> &mut [u8] { + unsafe { std::mem::transmute(x as *const _) } +} + +mod from_mut; +use from_mut::FromMut; + /// Decode a TSP Payload -pub fn decode_payload(mut stream: &[u8]) -> Result { +pub fn decode_payload<'a, Bytes: AsRef<[u8]> + FromMut<'a, [u8]>>( + mut stream: &'a [u8], +) -> Result, DecodeError> { let sender_identity = match decode_count(TSP_PAYLOAD, &mut stream) { Some(2) => Some( decode_variable_data(TSP_DEVELOPMENT_VID, &mut stream) @@ -321,10 +333,11 @@ pub fn decode_payload(mut stream: &[u8]) -> Result msgtype::GEN_MSG => { let hop_list = decode_hops(&mut stream)?; if hop_list.is_empty() { - decode_variable_data(TSP_PLAINTEXT, &mut stream).map(Payload::GenericMessage) + decode_variable_data(TSP_PLAINTEXT, &mut stream) + .map(|msg| Payload::GenericMessage(FromMut::from_mut(fudge(msg)))) } else { decode_variable_data(TSP_PLAINTEXT, &mut stream) - .map(|msg| Payload::RoutedMessage(hop_list, msg)) + .map(|msg| Payload::RoutedMessage(hop_list, FromMut::from_mut(fudge(msg)))) } } msgtype::NEW_REL => { @@ -335,9 +348,8 @@ pub fn decode_payload(mut stream: &[u8]) -> Result hops: hop_list, }) } - msgtype::NEST_MSG => { - decode_variable_data(TSP_PLAINTEXT, &mut stream).map(Payload::NestedMessage) - } + msgtype::NEST_MSG => decode_variable_data(TSP_PLAINTEXT, &mut stream) + .map(|msg| Payload::NestedMessage(FromMut::from_mut(fudge(msg)))), msgtype::NEW_REL_REPLY => decode_fixed_data(TSP_SHA256, &mut stream) .map(|reply| Payload::DirectRelationAffirm { reply }), msgtype::NEW_NEST_REL => { @@ -933,8 +945,8 @@ mod test { assert_eq!(env.receiver, Some(&b"Bobbi"[..])); assert_eq!(env.nonconfidential_data, None); - let DecodedPayload { - payload: Payload::<_, &[u8]>::GenericMessage(data), + let DecodedPayload::<&[u8]> { + payload: Payload::GenericMessage(data), .. } = decode_payload(dummy_crypt(ciphertext.unwrap())).unwrap() else { @@ -982,8 +994,8 @@ mod test { assert_eq!(env.receiver, Some(&b"Bobbi"[..])); assert_eq!(env.nonconfidential_data, Some(&b"treasure"[..])); - let DecodedPayload { - payload: Payload::<_, &[u8]>::GenericMessage(data), + let DecodedPayload::<&[u8]> { + payload: Payload::GenericMessage(data), .. } = decode_payload(dummy_crypt(ciphertext.unwrap())).unwrap() else { diff --git a/tsp/src/cesr/packet/from_mut.rs b/tsp/src/cesr/packet/from_mut.rs new file mode 100644 index 0000000..fb1f610 --- /dev/null +++ b/tsp/src/cesr/packet/from_mut.rs @@ -0,0 +1,17 @@ +/// A little trait to support a limited form of 'mut polymorphism' + +pub trait FromMut<'a, T: ?Sized> { + fn from_mut(x: &'a mut T) -> Self; +} + +impl<'a, T: ?Sized> FromMut<'a, T> for &'a T { + fn from_mut(x: &'a mut T) -> Self { + x + } +} + +impl<'a, T: ?Sized> FromMut<'a, T> for &'a mut T { + fn from_mut(x: &'a mut T) -> Self { + x + } +} diff --git a/tsp/src/crypto/tsp_hpke.rs b/tsp/src/crypto/tsp_hpke.rs index 36987d9..baf7a9e 100644 --- a/tsp/src/crypto/tsp_hpke.rs +++ b/tsp/src/crypto/tsp_hpke.rs @@ -227,7 +227,7 @@ where } let secret_payload = match payload { - crate::cesr::Payload::GenericMessage(data) => Payload::Content(data), + crate::cesr::Payload::GenericMessage(data) => Payload::Content(data as _), crate::cesr::Payload::DirectRelationProposal { hops, .. } => Payload::RequestRelationship { route: if hops.is_empty() { None } else { Some(hops) }, }, @@ -249,8 +249,8 @@ where crate::cesr::Payload::RelationshipCancel { reply: &thread_id, .. } => Payload::CancelRelationship { thread_id }, - crate::cesr::Payload::NestedMessage(data) => todo!(), // Payload::NestedMessage(data), - crate::cesr::Payload::RoutedMessage(hops, data) => Payload::RoutedMessage(hops, data), + crate::cesr::Payload::NestedMessage(data) => Payload::NestedMessage(data), + crate::cesr::Payload::RoutedMessage(hops, data) => Payload::RoutedMessage(hops, data as _), crate::cesr::Payload::NewIdentifierProposal { thread_id: &thread_id, new_vid,