noise-rust-crypto-0.6.2/.cargo_vcs_info.json0000644000000001570000000000100144720ustar { "git": { "sha1": "36bc85bd05db04b0d469843275ccafd848cddb99" }, "path_in_vcs": "noise-rust-crypto" }noise-rust-crypto-0.6.2/Cargo.toml0000644000000034150000000000100124700ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" name = "noise-rust-crypto" version = "0.6.2" authors = ["Guanhao Yin "] description = "Wrappers of dalek and RustCrypto crates for noise-protocol" readme = "README.md" license = "Unlicense" repository = "https://github.com/sopium/noise-rust" [dependencies.aes-gcm] version = "0.10.3" features = ["aes"] optional = true default-features = false [dependencies.blake2] version = "0.10.6" optional = true [dependencies.chacha20poly1305] version = "0.10.1" optional = true default-features = false [dependencies.noise-protocol] version = "0.2.0" default-features = false [dependencies.sha2] version = "0.10.8" optional = true default-features = false [dependencies.x25519-dalek] version = "2.0.0" optional = true default-features = false [dependencies.zeroize] version = "1" default-features = false [dev-dependencies.hex] version = "0.4.3" [features] default = [ "use-x25519", "use-chacha20poly1305", "use-aes-256-gcm", "use-blake2", "use-sha2", ] use-aes-256-gcm = ["aes-gcm"] use-blake2 = ["blake2"] use-chacha20poly1305 = ["chacha20poly1305"] use-sha2 = ["sha2"] use-x25519 = [ "x25519", "x25519-dalek/precomputed-tables", "x25519-dalek/zeroize", "x25519-dalek/getrandom", ] x25519 = [ "x25519-dalek", "x25519-dalek/static_secrets", ] noise-rust-crypto-0.6.2/Cargo.toml.orig000064400000000000000000000023671046102023000161560ustar 00000000000000[package] edition = "2021" authors = ["Guanhao Yin "] license = "Unlicense" name = "noise-rust-crypto" readme = "README.md" repository = "https://github.com/sopium/noise-rust" version = "0.6.2" description = "Wrappers of dalek and RustCrypto crates for noise-protocol" [features] default = ["use-x25519", "use-chacha20poly1305", "use-aes-256-gcm", "use-blake2", "use-sha2"] x25519 = ["x25519-dalek", "x25519-dalek/static_secrets"] use-x25519 = ["x25519", "x25519-dalek/precomputed-tables", "x25519-dalek/zeroize", "x25519-dalek/getrandom"] use-chacha20poly1305 = ["chacha20poly1305"] use-aes-256-gcm = ["aes-gcm"] use-blake2 = ["blake2"] use-sha2 = ["sha2"] [dependencies] x25519-dalek = { version = "2.0.0", optional = true, default-features = false } aes-gcm = { version = "0.10.3", features = ["aes"], default-features = false, optional = true } chacha20poly1305 = { version = "0.10.1", default-features = false, optional = true } blake2 = { version = "0.10.6", optional = true } sha2 = { version = "0.10.8", optional = true, default-features = false } zeroize = { version = "1", default-features = false } [dependencies.noise-protocol] path = "../noise-protocol" version = "0.2.0" default-features = false [dev-dependencies] hex = "0.4.3" noise-rust-crypto-0.6.2/README.md000064400000000000000000000006331046102023000145400ustar 00000000000000This crate provides wrappers around pure rust implementations of the crypto primitives used in `noise-protocol`. The underlying implementations are: * [`x25519-dalek`](https://crates.io/crates/x25519-dalek) * [`chacha20poly1305`](https://crates.io/crates/chacha20poly1305) * [`aes-gcm`](https://crates.io/crates/aes-gcm) * [`sha2`](https://crates.io/crates/sha2) * [`blake2`](https://crates.io/crates/blake2) noise-rust-crypto-0.6.2/src/lib.rs000064400000000000000000000223101046102023000151600ustar 00000000000000//! This crate provides wrappers around pure rust implementations of the crypto //! primitives used in `noise-protocol`. // //! The underlying implementations are: // //! * [`x25519-dalek`](https://crates.io/crates/x25519-dalek) //! * [`chacha20poly1305`](https://crates.io/crates/chacha20poly1305) //! * [`aes-gcm`](https://crates.io/crates/aes-gcm) //! * [`sha2`](https://crates.io/crates/sha2) //! * [`blake2`](https://crates.io/crates/blake2) #![no_std] pub mod sensitive; use sensitive::Sensitive; use noise_protocol::*; #[cfg(feature = "x25519")] use x25519_dalek::{PublicKey, StaticSecret}; #[cfg(feature = "x25519")] pub enum X25519 {} #[cfg(feature = "x25519")] impl DH for X25519 { type Key = Sensitive<[u8; 32]>; type Pubkey = [u8; 32]; type Output = Sensitive<[u8; 32]>; fn name() -> &'static str { "25519" } fn genkey() -> Self::Key { Self::Key::from_slice(StaticSecret::random().as_bytes()) } fn pubkey(k: &Self::Key) -> Self::Pubkey { let static_secret = StaticSecret::from(**k); *PublicKey::from(&static_secret).as_bytes() } fn dh(k: &Self::Key, pk: &Self::Pubkey) -> Result { let k = StaticSecret::from(**k); let pk = PublicKey::from(*pk); Ok(Self::Output::from_slice(k.diffie_hellman(&pk).as_bytes())) } } #[cfg(feature = "use-chacha20poly1305")] pub enum ChaCha20Poly1305 {} #[cfg(feature = "use-chacha20poly1305")] impl Cipher for ChaCha20Poly1305 { fn name() -> &'static str { "ChaChaPoly" } type Key = Sensitive<[u8; 32]>; fn encrypt(k: &Self::Key, nonce: u64, ad: &[u8], plaintext: &[u8], out: &mut [u8]) { assert!(plaintext.len().checked_add(16) == Some(out.len())); let mut full_nonce = [0u8; 12]; full_nonce[4..].copy_from_slice(&nonce.to_le_bytes()); let (in_out, tag_out) = out.split_at_mut(plaintext.len()); in_out.copy_from_slice(plaintext); use chacha20poly1305::{AeadInPlace, KeyInit}; let tag = chacha20poly1305::ChaCha20Poly1305::new(&(**k).into()) .encrypt_in_place_detached(&full_nonce.into(), ad, in_out) .unwrap(); tag_out.copy_from_slice(tag.as_ref()) } fn encrypt_in_place( k: &Self::Key, nonce: u64, ad: &[u8], in_out: &mut [u8], plaintext_len: usize, ) -> usize { assert!(plaintext_len .checked_add(16) .map_or(false, |l| l <= in_out.len())); let mut full_nonce = [0u8; 12]; full_nonce[4..].copy_from_slice(&nonce.to_le_bytes()); let (in_out, tag_out) = in_out[..plaintext_len + 16].split_at_mut(plaintext_len); use chacha20poly1305::{AeadInPlace, KeyInit}; let tag = chacha20poly1305::ChaCha20Poly1305::new(&(**k).into()) .encrypt_in_place_detached(&full_nonce.into(), ad, in_out) .unwrap(); tag_out.copy_from_slice(tag.as_ref()); plaintext_len + 16 } fn decrypt( k: &Self::Key, nonce: u64, ad: &[u8], ciphertext: &[u8], out: &mut [u8], ) -> Result<(), ()> { assert!(ciphertext.len().checked_sub(16) == Some(out.len())); let mut full_nonce = [0u8; 12]; full_nonce[4..].copy_from_slice(&nonce.to_le_bytes()); out.copy_from_slice(&ciphertext[..out.len()]); let tag = &ciphertext[out.len()..]; use chacha20poly1305::{AeadInPlace, KeyInit}; chacha20poly1305::ChaCha20Poly1305::new(&(**k).into()) .decrypt_in_place_detached(&full_nonce.into(), ad, out, tag.into()) .map_err(|_| ()) } fn decrypt_in_place( k: &Self::Key, nonce: u64, ad: &[u8], in_out: &mut [u8], ciphertext_len: usize, ) -> Result { assert!(ciphertext_len <= in_out.len()); assert!(ciphertext_len >= 16); let mut full_nonce = [0u8; 12]; full_nonce[4..].copy_from_slice(&nonce.to_le_bytes()); let (in_out, tag) = in_out[..ciphertext_len].split_at_mut(ciphertext_len - 16); use chacha20poly1305::{AeadInPlace, KeyInit}; chacha20poly1305::ChaCha20Poly1305::new(&(**k).into()) .decrypt_in_place_detached(&full_nonce.into(), ad, in_out, tag.as_ref().into()) .map_err(|_| ())?; Ok(in_out.len()) } } #[cfg(feature = "use-aes-256-gcm")] pub enum Aes256Gcm {} #[cfg(feature = "use-aes-256-gcm")] impl Cipher for Aes256Gcm { fn name() -> &'static str { "AESGCM" } type Key = Sensitive<[u8; 32]>; fn encrypt(k: &Self::Key, nonce: u64, ad: &[u8], plaintext: &[u8], out: &mut [u8]) { assert!(plaintext.len().checked_add(16) == Some(out.len())); let mut full_nonce = [0u8; 12]; full_nonce[4..].copy_from_slice(&nonce.to_be_bytes()); let (in_out, tag_out) = out.split_at_mut(plaintext.len()); in_out.copy_from_slice(plaintext); use aes_gcm::{AeadInPlace, KeyInit}; let tag = aes_gcm::Aes256Gcm::new(&(**k).into()) .encrypt_in_place_detached(&full_nonce.into(), ad, in_out) .unwrap(); tag_out.copy_from_slice(tag.as_ref()) } fn encrypt_in_place( k: &Self::Key, nonce: u64, ad: &[u8], in_out: &mut [u8], plaintext_len: usize, ) -> usize { assert!(plaintext_len .checked_add(16) .map_or(false, |l| l <= in_out.len())); let mut full_nonce = [0u8; 12]; full_nonce[4..].copy_from_slice(&nonce.to_be_bytes()); let (in_out, tag_out) = in_out[..plaintext_len + 16].split_at_mut(plaintext_len); use aes_gcm::{AeadInPlace, KeyInit}; let tag = aes_gcm::Aes256Gcm::new(&(**k).into()) .encrypt_in_place_detached(&full_nonce.into(), ad, in_out) .unwrap(); tag_out.copy_from_slice(tag.as_ref()); plaintext_len + 16 } fn decrypt( k: &Self::Key, nonce: u64, ad: &[u8], ciphertext: &[u8], out: &mut [u8], ) -> Result<(), ()> { assert!(ciphertext.len().checked_sub(16) == Some(out.len())); let mut full_nonce = [0u8; 12]; full_nonce[4..].copy_from_slice(&nonce.to_be_bytes()); out.copy_from_slice(&ciphertext[..out.len()]); let tag = &ciphertext[out.len()..]; use aes_gcm::{AeadInPlace, KeyInit}; aes_gcm::Aes256Gcm::new(&(**k).into()) .decrypt_in_place_detached(&full_nonce.into(), ad, out, tag.into()) .map_err(|_| ()) } fn decrypt_in_place( k: &Self::Key, nonce: u64, ad: &[u8], in_out: &mut [u8], ciphertext_len: usize, ) -> Result { assert!(ciphertext_len <= in_out.len()); assert!(ciphertext_len >= 16); let mut full_nonce = [0u8; 12]; full_nonce[4..].copy_from_slice(&nonce.to_be_bytes()); let (in_out, tag) = in_out[..ciphertext_len].split_at_mut(ciphertext_len - 16); use aes_gcm::{AeadInPlace, KeyInit}; aes_gcm::Aes256Gcm::new(&(**k).into()) .decrypt_in_place_detached(&full_nonce.into(), ad, in_out, tag.as_ref().into()) .map_err(|_| ())?; Ok(in_out.len()) } } #[cfg(feature = "use-sha2")] #[derive(Default, Clone)] pub struct Sha256(sha2::Sha256); #[cfg(feature = "use-sha2")] impl Hash for Sha256 { fn name() -> &'static str { "SHA256" } type Block = [u8; 64]; type Output = Sensitive<[u8; 32]>; fn input(&mut self, data: &[u8]) { use sha2::Digest; self.0.update(data); } fn result(&mut self) -> Self::Output { use sha2::Digest; Self::Output::from_slice(self.0.finalize_reset().as_ref()) } } #[cfg(feature = "use-sha2")] #[derive(Default, Clone)] pub struct Sha512(sha2::Sha512); #[cfg(feature = "use-sha2")] impl Hash for Sha512 { fn name() -> &'static str { "SHA512" } type Block = [u8; 128]; type Output = Sensitive<[u8; 64]>; fn input(&mut self, data: &[u8]) { use sha2::Digest; self.0.update(data); } fn result(&mut self) -> Self::Output { use sha2::Digest; Self::Output::from_slice(self.0.finalize_reset().as_ref()) } } #[cfg(feature = "use-blake2")] #[derive(Default, Clone)] pub struct Blake2s(blake2::Blake2s256); #[cfg(feature = "use-blake2")] impl Hash for Blake2s { fn name() -> &'static str { "BLAKE2s" } type Block = [u8; 64]; type Output = Sensitive<[u8; 32]>; fn input(&mut self, data: &[u8]) { use blake2::Digest; self.0.update(data); } fn result(&mut self) -> Self::Output { use blake2::Digest; Self::Output::from_slice(self.0.finalize_reset().as_ref()) } } #[cfg(feature = "use-blake2")] #[derive(Default, Clone)] pub struct Blake2b(blake2::Blake2b512); #[cfg(feature = "use-blake2")] impl Hash for Blake2b { fn name() -> &'static str { "BLAKE2b" } type Block = [u8; 128]; type Output = Sensitive<[u8; 64]>; fn input(&mut self, data: &[u8]) { use blake2::Digest; self.0.update(data); } fn result(&mut self) -> Self::Output { use blake2::Digest; Self::Output::from_slice(self.0.finalize_reset().as_ref()) } } noise-rust-crypto-0.6.2/src/sensitive.rs000064400000000000000000000021441046102023000164260ustar 00000000000000use noise_protocol::U8Array; use zeroize::{Zeroize, Zeroizing}; /// Struct holding a value that is safely zeroed on drop. pub struct Sensitive(Zeroizing); impl Sensitive { pub fn from(a: Zeroizing) -> Self { Sensitive(a) } } impl core::ops::Deref for Sensitive { type Target = A; fn deref(&self) -> &Self::Target { &self.0 } } impl core::ops::DerefMut for Sensitive { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl U8Array for Sensitive where A: Zeroize + U8Array, { fn new() -> Self { Sensitive::from(Zeroizing::new(A::new())) } fn new_with(v: u8) -> Self { Sensitive::from(Zeroizing::new(A::new_with(v))) } fn from_slice(s: &[u8]) -> Self { Sensitive::from(Zeroizing::new(A::from_slice(s))) } fn len() -> usize { A::len() } fn as_slice(&self) -> &[u8] { self.0.as_slice() } fn as_mut(&mut self) -> &mut [u8] { self.0.as_mut() } }