initial commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
use chacha20poly1305::aead::Buffer;
|
||||
|
||||
pub trait AeadPacker {
|
||||
fn encrypt<B: Buffer>(&mut self, data: &mut B) -> Result<(), chacha20poly1305::aead::Error>;
|
||||
fn decrypt<B: Buffer>(&mut self, data: &mut B) -> Result<(), chacha20poly1305::aead::Error>;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
use chacha20poly1305::aead::generic_array::GenericArray;
|
||||
use chacha20poly1305::aead::{Buffer, OsRng};
|
||||
use chacha20poly1305::{
|
||||
AeadCore, AeadInPlace, ChaCha20Poly1305, ChaChaPoly1305, Key, KeyInit, Nonce,
|
||||
};
|
||||
|
||||
use crate::crypto::aead::AeadPacker;
|
||||
|
||||
pub struct NonceState {
|
||||
counter: u64,
|
||||
nonce: Nonce,
|
||||
handshake: bool,
|
||||
}
|
||||
|
||||
impl NonceState {
|
||||
pub fn new() -> Self {
|
||||
let nonce = ChaCha20Poly1305::generate_nonce(&mut OsRng);
|
||||
println!("Nonce is {:?}", nonce);
|
||||
Self {
|
||||
counter: 0,
|
||||
nonce,
|
||||
handshake: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_handshake(&self) -> bool {
|
||||
return self.handshake;
|
||||
}
|
||||
|
||||
pub fn set_nonce(&mut self, nonce: Nonce) {
|
||||
self.nonce = nonce;
|
||||
self.handshake = true
|
||||
}
|
||||
|
||||
pub fn increase_counter(&mut self) {
|
||||
self.counter += 1;
|
||||
let counter_bytes = self.counter.to_be_bytes();
|
||||
self.nonce[4..12].copy_from_slice(&counter_bytes);
|
||||
println!("Current Nonce is {:?}", self.nonce);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChaChaCipher {
|
||||
key: Key,
|
||||
pub encrypt_state: NonceState,
|
||||
pub decrypt_state: NonceState,
|
||||
pub cipher: ChaCha20Poly1305,
|
||||
}
|
||||
|
||||
impl ChaChaCipher {
|
||||
pub fn new() -> Self {
|
||||
let key = GenericArray::clone_from_slice(&[0; 32]);
|
||||
let cipher = ChaCha20Poly1305::new(&key);
|
||||
Self {
|
||||
key,
|
||||
encrypt_state: NonceState::new(),
|
||||
decrypt_state: NonceState::new(),
|
||||
cipher,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_key(&mut self, key: Key) -> () {
|
||||
self.key = key;
|
||||
self.cipher = ChaChaPoly1305::new(&self.key);
|
||||
}
|
||||
}
|
||||
|
||||
impl AeadPacker for ChaChaCipher {
|
||||
fn encrypt<B: Buffer>(&mut self, data: &mut B) -> Result<(), chacha20poly1305::aead::Error> {
|
||||
self.cipher
|
||||
.encrypt_in_place(&self.encrypt_state.nonce, &[], data)?;
|
||||
self.encrypt_state.increase_counter();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn decrypt<B: Buffer>(&mut self, data: &mut B) -> Result<(), chacha20poly1305::aead::Error> {
|
||||
println!("Buffer: {:?}", data.as_mut());
|
||||
println!("nonce: {:?}", &self.decrypt_state.nonce);
|
||||
self.cipher
|
||||
.decrypt_in_place(&self.decrypt_state.nonce, &[], data)?;
|
||||
self.decrypt_state.increase_counter();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
use aead::OsRng;
|
||||
use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
pub struct ECDH {
|
||||
pub public_key: PublicKey,
|
||||
secret_key: EphemeralSecret,
|
||||
}
|
||||
|
||||
impl ECDH {
|
||||
pub fn new() -> Self {
|
||||
let secret = EphemeralSecret::random_from_rng(&mut OsRng);
|
||||
let public = PublicKey::from(&secret);
|
||||
Self {
|
||||
secret_key: secret,
|
||||
public_key: public,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_shared(self, public: &PublicKey) -> [u8; 32] {
|
||||
let shared = self.secret_key.diffie_hellman(&public);
|
||||
*shared.as_bytes()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
use hkdf::Hkdf;
|
||||
use sha2::Sha256;
|
||||
|
||||
pub struct HKDF;
|
||||
|
||||
impl HKDF {
|
||||
pub fn extract_key(salt: &[u8], ikm: &[u8]) -> Hkdf<Sha256> {
|
||||
let extracted_key = Hkdf::<Sha256>::new(Some(salt), ikm);
|
||||
extracted_key
|
||||
}
|
||||
|
||||
pub fn expand<const N: usize>(
|
||||
extracted_key: &Hkdf<Sha256>,
|
||||
mark: &[u8],
|
||||
) -> Result<[u8; N], String> {
|
||||
let mut expanded_key: [u8; N] = [0u8; N];
|
||||
extracted_key
|
||||
.expand(mark, &mut expanded_key)
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(expanded_key)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
use hmac::{Hmac, Mac};
|
||||
use sha2::Sha256;
|
||||
|
||||
type HmacSha256 = Hmac<Sha256>;
|
||||
|
||||
pub fn generate_auth_tag(secret: &[u8]) -> [u8; 16] {
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
let minute_step = (now / 60).to_be_bytes();
|
||||
|
||||
// Создаем HMAC-Sha256 с твоим секретным ключом
|
||||
let mut mac = HmacSha256::new_from_slice(secret).expect("HMAC can take key of any size");
|
||||
|
||||
// Подмешиваем туда текущую минуту
|
||||
mac.update(&minute_step);
|
||||
|
||||
let result = mac.finalize().into_bytes();
|
||||
|
||||
// Берем первые 16 байт от 32-байтного хеша SHA256
|
||||
let mut tag = [0u8; 16];
|
||||
tag.copy_from_slice(&result[..16]);
|
||||
tag
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
pub mod aead;
|
||||
pub mod chacha;
|
||||
pub mod ecdh;
|
||||
pub mod hkdf;
|
||||
pub mod hmac;
|
||||
Reference in New Issue
Block a user