diff options
| author | s-ol <s+removethis@s-ol.nu> | 2026-03-28 22:35:26 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2026-03-28 22:38:32 +0000 |
| commit | b4bb62b7ca0be710a0a7d5484cb9d3371f24ec2a (patch) | |
| tree | 2cb6178dfa67f52f9be5bd7844969ca92e8cb4f8 /src | |
| parent | expose more fields (diff) | |
| download | meshcore-rs-dumb-no-std.tar.gz meshcore-rs-dumb-no-std.zip | |
no-std compatible cryptodumb-no-std
Diffstat (limited to 'src')
| -rw-r--r-- | src/crypto.rs | 5 | ||||
| -rw-r--r-- | src/lib.rs | 8 | ||||
| -rw-r--r-- | src/no_std_crypto.rs | 279 | ||||
| -rw-r--r-- | src/packet.rs | 10 | ||||
| -rw-r--r-- | src/packet_content.rs | 6 | ||||
| -rw-r--r-- | src/text.rs | 9 |
6 files changed, 15 insertions, 302 deletions
diff --git a/src/crypto.rs b/src/crypto.rs index acbb464..034e9cc 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -6,7 +6,7 @@ use aes::Aes128; use aes::cipher::{BlockDecrypt, BlockEncrypt, generic_array::GenericArray}; use bytes::{Buf, BufMut, Bytes, BytesMut}; use curve25519_dalek::MontgomeryPoint; -use ed25519_dalek::{VerifyingKey, hazmat::ExpandedSecretKey}; +use ed25519_dalek::{SigningKey, VerifyingKey, hazmat::ExpandedSecretKey}; use hmac::{Hmac, Mac}; use sha2::Sha256; @@ -82,6 +82,7 @@ impl Clone for PrivateKey { impl Default for PrivateKey { fn default() -> Self { + /* // To make a key whole-cloth, we need to start with a SigningKey made // using a good RNG. Then we can use that to make an ExpandedSecretKey. use ed25519_dalek::SigningKey; @@ -95,6 +96,8 @@ impl Default for PrivateKey { // Then, there are only a few constructors for making an ExpandedSecretKey. // Meshcore uses this kind of key, so it's what we need in this application, // but it's an uncommon formulation. + */ + let signing_key = SigningKey::from_bytes(&[0u8; 32]); let esk = ExpandedSecretKey::from(&signing_key.to_bytes()); Self(esk) } @@ -1,13 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(feature = "std")] pub mod crypto; -#[cfg(not(feature = "std"))] -pub mod no_std_crypto; -#[cfg(not(feature = "std"))] -pub use no_std_crypto as crypto; - pub mod string_helper; #[derive(Debug, PartialEq)] @@ -24,7 +18,7 @@ pub mod std_identity; // This version of identity is no-std #[cfg(not(feature = "std"))] -pub(crate) mod no_std_identity; +pub mod no_std_identity; pub mod ack; pub mod advert; diff --git a/src/no_std_crypto.rs b/src/no_std_crypto.rs deleted file mode 100644 index 31f4626..0000000 --- a/src/no_std_crypto.rs +++ /dev/null @@ -1,279 +0,0 @@ -use bytes::{Buf, BufMut, Bytes, BytesMut}; -use serde::{Deserialize, Serialize}; - -use crate::string_helper::NameString; - -pub trait Keystore { - fn decrypt_and_id_p2p( - &self, - source: u8, - _dest: u8, - mac: u16, - data: &Bytes, - ) -> Option<(Bytes, u32, u32)>; - - fn decrypt_and_id_group( - &self, - group_hash_prefix: u8, - mac: u16, - data: &Bytes, - ) -> Option<(Bytes, Option<NameString>)>; - - fn decrypt_anon( - &self, - dest: u8, - pub_key: &PublicKey, - mac: u16, - data: &Bytes, - ) -> Option<(Bytes, u32)>; -} - -#[derive(Debug, PartialEq)] -pub enum MeshcoreCryptoError { - KeyLengthError, - TryFromSliceError, - HexDecodeError, - KeyCreationError, -} - -impl core::error::Error for MeshcoreCryptoError {} - -impl core::fmt::Display for MeshcoreCryptoError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - MeshcoreCryptoError::KeyLengthError => f.write_str("Key Length Error"), - MeshcoreCryptoError::TryFromSliceError => f.write_str("Try From Slice Error"), - MeshcoreCryptoError::HexDecodeError => f.write_str("Hex Decode Error"), - MeshcoreCryptoError::KeyCreationError => f.write_str("Key Creation Error"), - } - } -} - -#[derive(Serialize, Deserialize, Clone, PartialEq)] -pub struct PrivateKey(pub [u8; 32]); - -impl core::fmt::Debug for PrivateKey { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_tuple("PublicKey") - .field(&hex::encode(self.0)) - .finish() - } -} - -impl Default for PrivateKey { - fn default() -> Self { - Self([0; 32]) - } -} - -impl PrivateKey { - pub fn hash_prefix(&self) -> u32 { - // The has prefix is the beginning of the public key of the secret - let public_key = PublicKey::from(self); - public_key.hash_prefix() - } -} - -#[derive(Eq, Hash, Serialize, Deserialize, PartialEq, Clone)] -pub struct PublicKey(pub [u8; 32]); - -impl core::fmt::Debug for PublicKey { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_tuple("PublicKey") - .field(&hex::encode(self.0)) - .finish() - } -} - -impl PublicKey { - pub fn hash_prefix(&self) -> u32 { - let mut bytes = Bytes::copy_from_slice(&self.0); - bytes.get_u32() - } -} - -#[derive(Clone, Eq, Hash, PartialEq)] -pub struct SharedSecret([u8; 32]); - -impl core::fmt::Debug for SharedSecret { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_tuple("SharedSecret") - .field(&hex::encode(self.0)) - .finish() - } -} - -impl core::str::FromStr for SharedSecret { - type Err = MeshcoreCryptoError; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - let mut array = [0_u8; 32]; - - // The provided group secrets are only 16 bytes, - // but they're zero-paded to be 32. So, we're - // going to get the hex from the string and copy it in. - if hex::decode_to_slice(s, &mut array[0..16]).is_err() { - return Err(MeshcoreCryptoError::TryFromSliceError); - } else { - Ok(SharedSecret(array)) - } - } -} - -impl TryFrom<Bytes> for SharedSecret { - type Error = MeshcoreCryptoError; - - fn try_from(value: Bytes) -> Result<Self, Self::Error> { - if let Some(arr) = value.first_chunk::<32>() { - // value.as_array::<32>() { - Ok(Self(*arr)) - } else { - Err(MeshcoreCryptoError::KeyLengthError) - } - } -} - -// This is kinda meaningless because a shared secret only works -// when it's connected to a key pair, but it needs to exist for -// Arrayvec. -impl Default for SharedSecret { - fn default() -> Self { - Self(Default::default()) - } -} - -impl SharedSecret { - fn get_key(&self) -> &[u8; 16] { - // Safety: The size of the slice ensures that this will never be wrong. - (&self.0[0..16]).try_into().unwrap() - } - - pub fn new_from_group_secret(bytes: Bytes) -> Self { - // The group secret is 16-bytes of key with the last 16-bytes set to zero. - let mut group_secret = BytesMut::from(bytes); - group_secret.reserve(16); - group_secret.put(&[0_u8; 16][..]); - - // group_secret.as_array::<32>(); - let slice = group_secret.first_chunk::<32>().unwrap(); - SharedSecret(slice.clone()) - } - - pub fn get_hmac(&self, _ciphertext: &Bytes) -> u16 { - // @TODO - 10 - } - - pub fn decrypt(&self, ciphertext: &Bytes) -> Bytes { - // @TODO - ciphertext.clone() - } - - pub fn encrypt(&self, plaintext: Bytes) -> Bytes { - // @TODO - plaintext - } - - pub fn hash_prefix(&self) -> u8 { - self.0[0] - } -} - -// This is just for creating placeholders -impl Default for PublicKey { - fn default() -> Self { - PublicKey(Default::default()) - } -} - -impl TryFrom<&[u8; 32]> for PublicKey { - type Error = MeshcoreCryptoError; - - fn try_from(value: &[u8; 32]) -> Result<Self, Self::Error> { - Ok(PublicKey(*value)) - } -} - -impl TryFrom<&[u8]> for PublicKey { - type Error = MeshcoreCryptoError; - - fn try_from(value: &[u8]) -> Result<Self, Self::Error> { - let bytes = Bytes::copy_from_slice(value); - Self::try_from(bytes) - } -} - -impl TryFrom<Bytes> for PublicKey { - type Error = MeshcoreCryptoError; - - fn try_from(value: Bytes) -> Result<Self, Self::Error> { - if let Some(arr) = value.first_chunk::<32>() { - Self::try_from(arr) - } else { - Err(MeshcoreCryptoError::KeyLengthError) - } - } -} - -impl core::str::FromStr for PublicKey { - type Err = MeshcoreCryptoError; - - fn from_str(hex_str: &str) -> Result<Self, Self::Err> { - if let Ok(hex) = hex::decode(hex_str) { - if let Ok(slice) = <[u8; 32]>::try_from(hex) { - Self::try_from(&slice) - } else { - Err(MeshcoreCryptoError::KeyLengthError) - } - } else { - Err(MeshcoreCryptoError::HexDecodeError) - } - } -} - -impl core::str::FromStr for PrivateKey { - type Err = MeshcoreCryptoError; - - fn from_str(hex_str: &str) -> Result<Self, Self::Err> { - if let Ok(hex) = hex::decode(hex_str) { - if let Ok(bytes) = <[u8; 32]>::try_from(hex) { - Ok(PrivateKey(bytes)) - } else { - Err(MeshcoreCryptoError::TryFromSliceError) - } - } else { - Err(MeshcoreCryptoError::HexDecodeError) - } - } -} - -impl From<&PrivateKey> for PublicKey { - fn from(key: &PrivateKey) -> Self { - Self(key.0.clone()) - } -} - -impl PrivateKey { - pub fn create_secret(&self, _other: &PublicKey) -> SharedSecret { - SharedSecret(self.0) - } -} - -impl SharedSecret { - pub fn mac_then_decrypt(&self, mac: u16, data: &Bytes) -> Option<Bytes> { - // Get the MAC of the message and key to check vailidity - let our_mac = self.get_hmac(&data); - if our_mac != mac { - return None; - } - - // Attempt to decrypt the packet itself - Some(self.decrypt(&data)) - } - - pub fn encrypt_then_mac(&self, data: Bytes) -> (u16, Bytes) { - let ciphertext = self.encrypt(data); - let mac = self.get_hmac(&ciphertext); - (mac, ciphertext) - } -} diff --git a/src/packet.rs b/src/packet.rs index 86537a7..b1be782 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -1,12 +1,11 @@ -#[cfg(feature = "std")] -use crate::std_identity::Keystore; - +extern crate alloc; +use alloc::borrow::ToOwned; use bytes::{Buf, Bytes}; use tinyvec::ArrayVec; +use crate::crypto::Keystore; use crate::packet_content::PacketContent; -#[cfg(feature = "std")] use crate::{ anon_req::ClearAnonRequest, request::ClearRequest, response::ClearResponse, text::ClearText, }; @@ -201,8 +200,7 @@ impl core::fmt::Display for Packet { } impl Packet { - #[cfg(feature = "std")] - pub fn try_decrypt(&mut self, keystore: &Keystore) -> bool { + pub fn try_decrypt<T: Keystore>(&mut self, keystore: &T) -> bool { match self.content { // Encrypted packet types PacketContent::Path(ref mut path) => path.cipher.try_decrypt(keystore), diff --git a/src/packet_content.rs b/src/packet_content.rs index a6fa914..5b762d7 100644 --- a/src/packet_content.rs +++ b/src/packet_content.rs @@ -11,8 +11,7 @@ use crate::{ }; use bytes::{Buf, Bytes}; -#[cfg(feature = "std")] -use crate::std_identity::Keystore; +use crate::crypto::Keystore; #[derive(PartialEq, Clone, core::fmt::Debug)] pub enum PacketContent { @@ -152,8 +151,7 @@ impl From<Bytes> for PeerToPeerCipher { } impl PeerToPeerCipher { - #[cfg(feature = "std")] - pub fn try_decrypt(&mut self, keystore: &Keystore) -> bool { + pub fn try_decrypt<T: Keystore>(&mut self, keystore: &T) -> bool { let decrypt = keystore.decrypt_and_id_p2p(self.source, self.destination, self.mac, &self.ciphertext); diff --git a/src/text.rs b/src/text.rs index 60d8869..e9efc2e 100644 --- a/src/text.rs +++ b/src/text.rs @@ -6,8 +6,7 @@ use crate::string_helper::{ MessageString, NameString, message_string_from_slice, name_string_from_slice, }; -#[cfg(feature = "std")] -use crate::std_identity::Keystore; +use crate::crypto::Keystore; #[derive(PartialEq, Debug, Clone)] pub struct Text { @@ -173,13 +172,13 @@ impl From<Bytes> for GroupText { } impl GroupText { - #[cfg(feature = "std")] - pub fn try_decrypt(&mut self, keysore: &Keystore) -> bool { + pub fn try_decrypt<T: Keystore>(&mut self, keysore: &T) -> bool { let decrypt_result = keysore.decrypt_and_id_group(self.hash, self.mac, &self.ciphertext); if let Some((cleartext, group)) = decrypt_result { let mut cleartext = ClearText::from(cleartext); - cleartext.crypto_recipient = group; + // @TODO: what? + // cleartext.crypto_recipient = group; self.cleartext = Some(cleartext); true } else { |
