From ede47d9574f5ff30a61fb8ae667e730f09857c7a Mon Sep 17 00:00:00 2001 From: Hardcore Sushi Date: Mon, 3 May 2021 13:23:56 +0200 Subject: [PATCH] Updating crates & README --- Cargo.toml | 10 +++++----- README.md | 3 +-- src/crypto.rs | 24 ++++++++++++------------ src/identity.rs | 2 +- src/session_manager/session.rs | 18 +++++++++--------- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f8b1a88..63d8f3d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,10 @@ rusqlite = {version = "0.25.1", features = ["bundled"]} ed25519-dalek = "1" #for singing x25519-dalek = "1.1" #for shared secret sha2 = "0.9.3" -hkdf = "0.10.0" -aes-gcm = "0.8.0" -hmac = "0.10.1" +hkdf = "0.11.0" +aes-gcm = "0.9.0" #PSEC +aes-gcm-siv = "0.10.0" #Database +hmac = "0.11.0" hex = "0.4.3" strum_macros = "0.20.1" #display enums actix-web = "3" @@ -33,6 +34,5 @@ libmdns = "0.6" #mDNS advertiser multicast_dns = "0.5" #mDNS browser base64 = "0.13.0" time = "0.2.25" -aes-gcm-siv = "0.9.0" -scrypt = "0.6.3" +scrypt = "0.7.0" zeroize = "1.2.0" \ No newline at end of file diff --git a/README.md b/README.md index 04f71c4..198ffce 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # AIRA AIRA is peer-to-peer encrypted communication tool for local networks built on the [PSEC protocol](https://forge.chapril.org/hardcoresushi/PSEC). It allows to securely send text messages and files without any server or Internet access. - +![Screenshot of a conversation between Alice and Bob on AIRA](/screenshot.png) # Rationale When people want to send a file from one computer to another located only meters apart, they usually send it via mail. This mail usually goes through many servers around the world before reaching its final destination. @@ -19,7 +19,6 @@ AIRA is still under developement and is not ready for production usage yet. Not - Automatic peer discovery using mDNS - Manual peer connection - File transferts -- Notifications - Encrypted database - Contact verification - IPv4/v6 compatibility diff --git a/src/crypto.rs b/src/crypto.rs index 6a02659..d402d95 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -4,8 +4,8 @@ use sha2::Sha384; use hmac::{Hmac, Mac, NewMac}; use scrypt::{scrypt, Params}; use rand_8::{RngCore, rngs::OsRng}; -use aes_gcm::{aead::{Aead, generic_array::GenericArray}, NewAead}; -use aes_gcm_siv::{Aes256GcmSiv}; +use aes_gcm::{aead::Aead, NewAead, Nonce}; +use aes_gcm_siv::Aes256GcmSiv; use zeroize::Zeroize; use strum_macros::Display; use crate::utils::*; @@ -128,7 +128,7 @@ impl ApplicationKeys { pub fn compute_handshake_finished(local_handshake_traffic_secret: [u8; HASH_OUTPUT_LEN], handshake_hash: [u8; HASH_OUTPUT_LEN]) -> [u8; HASH_OUTPUT_LEN] { let mut finished_key = [0; HASH_OUTPUT_LEN]; hkdf_expand_label(&local_handshake_traffic_secret, "finished", None, &mut finished_key); - let mut hmac = Hmac::::new_varkey(&finished_key).unwrap(); + let mut hmac = Hmac::::new_from_slice(&finished_key).unwrap(); hmac.update(&handshake_hash); hmac.finalize().into_bytes().as_slice().try_into().unwrap() } @@ -136,7 +136,7 @@ pub fn compute_handshake_finished(local_handshake_traffic_secret: [u8; HASH_OUTP pub fn verify_handshake_finished(peer_handshake_finished: [u8; HASH_OUTPUT_LEN], peer_handshake_traffic_secret: [u8; HASH_OUTPUT_LEN], handshake_hash: [u8; HASH_OUTPUT_LEN]) -> bool { let mut peer_finished_key = [0; HASH_OUTPUT_LEN]; hkdf_expand_label(&peer_handshake_traffic_secret, "finished", None, &mut peer_finished_key); - let mut hmac = Hmac::::new_varkey(&peer_finished_key).unwrap(); + let mut hmac = Hmac::::new_from_slice(&peer_finished_key).unwrap(); hmac.update(&handshake_hash); hmac.verify(&peer_handshake_finished).is_ok() } @@ -161,11 +161,11 @@ pub fn encrypt_data(data: &[u8], master_key: &[u8]) -> Result, CryptoErr if master_key.len() != MASTER_KEY_LEN { return Err(CryptoError::InvalidLength); } - let cipher = Aes256GcmSiv::new(GenericArray::from_slice(master_key)); + let cipher = Aes256GcmSiv::new_from_slice(master_key).unwrap(); let mut iv = [0; IV_LEN]; OsRng.fill_bytes(&mut iv); //use it for IV for now let mut cipher_text = iv.to_vec(); - cipher_text.extend(cipher.encrypt(GenericArray::from_slice(&iv), data).unwrap()); + cipher_text.extend(cipher.encrypt(Nonce::from_slice(&iv), data).unwrap()); Ok(cipher_text) } @@ -179,8 +179,8 @@ pub fn decrypt_data(data: &[u8], master_key: &[u8]) -> Result, CryptoErr if data.len() <= IV_LEN || master_key.len() != MASTER_KEY_LEN { return Err(CryptoError::InvalidLength); } - let cipher = Aes256GcmSiv::new(GenericArray::from_slice(master_key)); - match cipher.decrypt(GenericArray::from_slice(&data[..IV_LEN]), &data[IV_LEN..]) { + let cipher = Aes256GcmSiv::new_from_slice(master_key).unwrap(); + match cipher.decrypt(Nonce::from_slice(&data[..IV_LEN]), &data[IV_LEN..]) { Ok(data) => { Ok(data) }, @@ -202,8 +202,8 @@ pub fn encrypt_master_key(mut master_key: [u8; MASTER_KEY_LEN], password: &[u8]) scrypt(password, &salt, &scrypt_params(), &mut password_hash).unwrap(); let mut output = [0; IV_LEN+MASTER_KEY_LEN+AES_TAG_LEN]; OsRng.fill_bytes(&mut output); //use it for IV for now - let cipher = Aes256GcmSiv::new(GenericArray::from_slice(&password_hash)); - let encrypted_master_key = cipher.encrypt(GenericArray::from_slice(&output[..IV_LEN]), master_key.as_ref()).unwrap(); + let cipher = Aes256GcmSiv::new_from_slice(&password_hash).unwrap(); + let encrypted_master_key = cipher.encrypt(Nonce::from_slice(&output[..IV_LEN]), master_key.as_ref()).unwrap(); master_key.zeroize(); password_hash.zeroize(); encrypted_master_key.into_iter().enumerate().for_each(|i|{ @@ -218,8 +218,8 @@ pub fn decrypt_master_key(encrypted_master_key: &[u8], password: &[u8], salt: &[ } let mut password_hash = [0; PASSWORD_HASH_LEN]; scrypt(password, salt, &scrypt_params(), &mut password_hash).unwrap(); - let cipher = Aes256GcmSiv::new(GenericArray::from_slice(&password_hash)); - let result = match cipher.decrypt(GenericArray::from_slice(&encrypted_master_key[..IV_LEN]), &encrypted_master_key[IV_LEN..]) { + let cipher = Aes256GcmSiv::new_from_slice(&password_hash).unwrap(); + let result = match cipher.decrypt(Nonce::from_slice(&encrypted_master_key[..IV_LEN]), &encrypted_master_key[IV_LEN..]) { Ok(master_key) => { if master_key.len() == MASTER_KEY_LEN { Ok(master_key.try_into().unwrap()) diff --git a/src/identity.rs b/src/identity.rs index e0b7975..8cca8a1 100644 --- a/src/identity.rs +++ b/src/identity.rs @@ -415,7 +415,7 @@ impl Identity { Ok(Identity { name: name.to_owned(), keypair, - master_key: master_key, + master_key, }) } diff --git a/src/session_manager/session.rs b/src/session_manager/session.rs index e3b0215..2a4888b 100644 --- a/src/session_manager/session.rs +++ b/src/session_manager/session.rs @@ -5,7 +5,7 @@ use ed25519_dalek::{ed25519::signature::Signature, Verifier, PUBLIC_KEY_LENGTH, use x25519_dalek; use rand_7::{RngCore, rngs::OsRng}; use sha2::{Sha384, Digest}; -use aes_gcm::{Aes128Gcm, aead::Aead, NewAead, aead::Payload, aead::generic_array::GenericArray}; +use aes_gcm::{Aes128Gcm, aead::Aead, NewAead, aead::Payload, Nonce}; use crate::utils::*; use crate::crypto::*; use crate::identity::Identity; @@ -112,9 +112,9 @@ impl Session { } fn on_handshake_successful(&mut self, application_keys: ApplicationKeys){ - self.local_cipher = Some(Aes128Gcm::new_varkey(&application_keys.local_key).unwrap()); + self.local_cipher = Some(Aes128Gcm::new_from_slice(&application_keys.local_key).unwrap()); self.local_iv = Some(application_keys.local_iv); - self.peer_cipher = Some(Aes128Gcm::new_varkey(&application_keys.peer_key).unwrap()); + self.peer_cipher = Some(Aes128Gcm::new_from_slice(&application_keys.peer_key).unwrap()); self.peer_iv = Some(application_keys.peer_iv); self.handshake_sent_buff.clear(); self.handshake_sent_buff.shrink_to_fit(); @@ -156,19 +156,19 @@ impl Session { auth_msg[..PUBLIC_KEY_LENGTH].copy_from_slice(&identity.get_public_key()); auth_msg[PUBLIC_KEY_LENGTH..].copy_from_slice(&identity.sign(ephemeral_public_key.as_bytes())); //encrypt auth_msg - let local_cipher = Aes128Gcm::new_varkey(&handshake_keys.local_key).unwrap(); + let local_cipher = Aes128Gcm::new_from_slice(&handshake_keys.local_key).unwrap(); let mut local_handshake_counter = 0; let nonce = iv_to_nonce(&handshake_keys.local_iv, &mut local_handshake_counter); - let encrypted_auth_msg = local_cipher.encrypt(GenericArray::from_slice(&nonce), auth_msg.as_ref()).unwrap(); + let encrypted_auth_msg = local_cipher.encrypt(Nonce::from_slice(&nonce), auth_msg.as_ref()).unwrap(); self.handshake_write(&encrypted_auth_msg).await?; let mut encrypted_peer_auth_msg = [0; PUBLIC_KEY_LENGTH+SIGNATURE_LENGTH+AES_TAG_LEN]; self.handshake_read(&mut encrypted_peer_auth_msg).await?; //decrypt peer_auth_msg - let peer_cipher = Aes128Gcm::new_varkey(&handshake_keys.peer_key).unwrap(); + let peer_cipher = Aes128Gcm::new_from_slice(&handshake_keys.peer_key).unwrap(); let mut peer_handshake_counter = 0; let peer_nonce = iv_to_nonce(&handshake_keys.peer_iv, &mut peer_handshake_counter); - match peer_cipher.decrypt(GenericArray::from_slice(&peer_nonce), encrypted_peer_auth_msg.as_ref()) { + match peer_cipher.decrypt(Nonce::from_slice(&peer_nonce), encrypted_peer_auth_msg.as_ref()) { Ok(peer_auth_msg) => { //verify ephemeral public key signature self.peer_public_key = Some(to_array_32(&peer_auth_msg[..PUBLIC_KEY_LENGTH])); @@ -222,7 +222,7 @@ impl Session { aad: &cipher_len }; let nonce = iv_to_nonce(&self.local_iv.unwrap(), &mut self.local_counter); - let cipher_text = self.local_cipher.as_ref().unwrap().encrypt(GenericArray::from_slice(&nonce), payload).unwrap(); + let cipher_text = self.local_cipher.as_ref().unwrap().encrypt(Nonce::from_slice(&nonce), payload).unwrap(); [&cipher_len, cipher_text.as_slice()].concat() } @@ -247,7 +247,7 @@ impl Session { msg: &cipher_text, aad: &message_len }; - match peer_cipher.decrypt(GenericArray::from_slice(&peer_nonce), payload) { + match peer_cipher.decrypt(Nonce::from_slice(&peer_nonce), payload) { Ok(plain_text) => Ok(Session::unpad(plain_text)), Err(_) => Err(SessionError::TransmissionCorrupted) }