aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2026-03-28 22:35:26 +0000
committers-ol <s+removethis@s-ol.nu>2026-03-28 22:38:32 +0000
commitb4bb62b7ca0be710a0a7d5484cb9d3371f24ec2a (patch)
tree2cb6178dfa67f52f9be5bd7844969ca92e8cb4f8 /src
parentexpose more fields (diff)
downloadmeshcore-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.rs5
-rw-r--r--src/lib.rs8
-rw-r--r--src/no_std_crypto.rs279
-rw-r--r--src/packet.rs10
-rw-r--r--src/packet_content.rs6
-rw-r--r--src/text.rs9
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)
}
diff --git a/src/lib.rs b/src/lib.rs
index 5afbd16..c7d327c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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 {