feat: pedning add chacha20-poly1305
This commit is contained in:
29
Cargo.lock
generated
29
Cargo.lock
generated
@@ -264,6 +264,16 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chacha20-poly1305-stream"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3de0436856104bf1d2e4d5ea07661cb1a16268157f2a130c48253237ef09a457"
|
||||
dependencies = [
|
||||
"constant_time_eq",
|
||||
"hex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.31"
|
||||
@@ -353,6 +363,12 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.4"
|
||||
@@ -361,9 +377,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
|
||||
checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@@ -1653,18 +1669,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.49"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
|
||||
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.49"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
|
||||
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1717,6 +1733,7 @@ version = "0.4.4"
|
||||
dependencies = [
|
||||
"aes-gcm-stream",
|
||||
"base64",
|
||||
"chacha20-poly1305-stream",
|
||||
"chrono",
|
||||
"clap",
|
||||
"flate2",
|
||||
|
||||
@@ -11,6 +11,7 @@ repository = "https://git.hatter.ink/hatter/tiny-encrypt-rs"
|
||||
[dependencies]
|
||||
aes-gcm-stream = "0.2"
|
||||
base64 = "0.21"
|
||||
chacha20-poly1305-stream = "0.1.0"
|
||||
chrono = "0.4"
|
||||
clap = { version = "4.4", features = ["derive"] }
|
||||
flate2 = "1.0"
|
||||
|
||||
@@ -8,6 +8,7 @@ pub const TINY_ENC_FILE_EXT: &str = ".tinyenc";
|
||||
pub const TINY_ENC_CONFIG_FILE: &str = "~/.tinyencrypt/config-rs.json";
|
||||
|
||||
pub const TINY_ENC_AES_GCM: &str = "AES/GCM";
|
||||
pub const TINY_ENC_CHACHA20_POLY1305: &str = "CHACHA20/POLY1305";
|
||||
|
||||
// Tiny enc magic tag
|
||||
pub const TINY_ENC_MAGIC_TAG: u16 = 0x01;
|
||||
|
||||
157
src/crypto_cryptor.rs
Normal file
157
src/crypto_cryptor.rs
Normal file
@@ -0,0 +1,157 @@
|
||||
use aes_gcm_stream::{Aes256GcmStreamDecryptor, Aes256GcmStreamEncryptor};
|
||||
use chacha20_poly1305_stream::{ChaCha20Poly1305StreamDecryptor, ChaCha20Poly1305StreamEncryptor};
|
||||
use rust_util::{opt_result, simple_error, XResult};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::consts;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Cryptor {
|
||||
Aes256Gcm,
|
||||
ChaCha20Poly1305,
|
||||
}
|
||||
|
||||
impl Cryptor {
|
||||
pub fn from(algorithm: &str) -> XResult<Self> {
|
||||
match algorithm {
|
||||
"aes256-gcm" | consts::TINY_ENC_AES_GCM => Ok(Cryptor::Aes256Gcm),
|
||||
"chacha20-poly1305" | consts::TINY_ENC_CHACHA20_POLY1305 => Ok(Cryptor::ChaCha20Poly1305),
|
||||
_ => simple_error!("Unknown altorighm: {}",algorithm),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encryptor(self, key: &[u8], nonce: &[u8]) -> XResult<Box<dyn Encryptor>> {
|
||||
get_encryptor(self, key, nonce)
|
||||
}
|
||||
|
||||
pub fn decryptor(self, key: &[u8], nonce: &[u8]) -> XResult<Box<dyn Decryptor>> {
|
||||
get_decryptor(self, key, nonce)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Encryptor {
|
||||
fn update(&mut self, message: &[u8]) -> Vec<u8>;
|
||||
|
||||
fn finalize(&mut self) -> (Vec<u8>, Vec<u8>);
|
||||
|
||||
fn encrypt(&mut self, message: &[u8]) -> Vec<u8> {
|
||||
let mut cipher_text = self.update(message);
|
||||
let (last_block, tag) = self.finalize();
|
||||
cipher_text.extend_from_slice(&last_block);
|
||||
cipher_text.extend_from_slice(&tag);
|
||||
cipher_text
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Decryptor {
|
||||
fn update(&mut self, message: &[u8]) -> Vec<u8>;
|
||||
|
||||
fn finalize(&mut self) -> XResult<Vec<u8>>;
|
||||
|
||||
fn decrypt(&mut self, message: &[u8]) -> XResult<Vec<u8>> {
|
||||
let mut plaintext = self.update(message);
|
||||
let last_block = self.finalize()?;
|
||||
plaintext.extend_from_slice(&last_block);
|
||||
Ok(plaintext)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_encryptor(crypto: Cryptor, key: &[u8], nonce: &[u8]) -> XResult<Box<dyn Encryptor>> {
|
||||
match crypto {
|
||||
Cryptor::Aes256Gcm => {
|
||||
let mut key: [u8; 32] = opt_result!(key.try_into(), "Bad AES 256 key: {}");
|
||||
let aes256_gcm_stream_encryptor = Aes256GcmStreamEncryptor::new(key, nonce);
|
||||
key.zeroize();
|
||||
Ok(Box::new(Aes256GcmEncryptor {
|
||||
aes256_gcm_stream_encryptor,
|
||||
}))
|
||||
}
|
||||
Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Encryptor {
|
||||
chacha20_poly1305_stream_encryptor: ChaCha20Poly1305StreamEncryptor::new(key, nonce)?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_decryptor(crypto: Cryptor, key: &[u8], nonce: &[u8]) -> XResult<Box<dyn Decryptor>> {
|
||||
match crypto {
|
||||
Cryptor::Aes256Gcm => {
|
||||
let mut key: [u8; 32] = opt_result!(key.try_into(), "Bad AES 256 key: {}");
|
||||
let aes256_gcm_stream_decryptor = Aes256GcmStreamDecryptor::new(key, nonce);
|
||||
key.zeroize();
|
||||
Ok(Box::new(Aes256GcmDecryptor {
|
||||
aes256_gcm_stream_decryptor,
|
||||
}))
|
||||
}
|
||||
Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Decryptor {
|
||||
chacha20_poly1305_stream_decryptor: ChaCha20Poly1305StreamDecryptor::new(key, nonce)?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Aes256GcmEncryptor {
|
||||
aes256_gcm_stream_encryptor: Aes256GcmStreamEncryptor,
|
||||
}
|
||||
|
||||
impl Encryptor for Aes256GcmEncryptor {
|
||||
fn update(&mut self, message: &[u8]) -> Vec<u8> {
|
||||
self.aes256_gcm_stream_encryptor.update(message)
|
||||
}
|
||||
|
||||
fn finalize(&mut self) -> (Vec<u8>, Vec<u8>) {
|
||||
self.aes256_gcm_stream_encryptor.finalize()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChaCha20Poly1305Encryptor {
|
||||
chacha20_poly1305_stream_encryptor: ChaCha20Poly1305StreamEncryptor,
|
||||
}
|
||||
|
||||
impl Encryptor for ChaCha20Poly1305Encryptor {
|
||||
fn update(&mut self, message: &[u8]) -> Vec<u8> {
|
||||
self.chacha20_poly1305_stream_encryptor.update(message)
|
||||
}
|
||||
|
||||
fn finalize(&mut self) -> (Vec<u8>, Vec<u8>) {
|
||||
self.chacha20_poly1305_stream_encryptor.finalize()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Aes256GcmDecryptor {
|
||||
aes256_gcm_stream_decryptor: Aes256GcmStreamDecryptor,
|
||||
}
|
||||
|
||||
impl Decryptor for Aes256GcmDecryptor {
|
||||
fn update(&mut self, message: &[u8]) -> Vec<u8> {
|
||||
self.aes256_gcm_stream_decryptor.update(message)
|
||||
}
|
||||
|
||||
fn finalize(&mut self) -> XResult<Vec<u8>> {
|
||||
Ok(self.aes256_gcm_stream_decryptor.finalize()?)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChaCha20Poly1305Decryptor {
|
||||
chacha20_poly1305_stream_decryptor: ChaCha20Poly1305StreamDecryptor,
|
||||
}
|
||||
|
||||
impl Decryptor for ChaCha20Poly1305Decryptor {
|
||||
fn update(&mut self, message: &[u8]) -> Vec<u8> {
|
||||
self.chacha20_poly1305_stream_decryptor.update(message)
|
||||
}
|
||||
|
||||
fn finalize(&mut self) -> XResult<Vec<u8>> {
|
||||
Ok(self.chacha20_poly1305_stream_decryptor.finalize()?)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cryptor() {
|
||||
let key = [0u8; 32];
|
||||
let nonce = [0u8; 12];
|
||||
let ciphertext = Cryptor::Aes256Gcm.encryptor(&key, &nonce).unwrap()
|
||||
.encrypt(b"hello world");
|
||||
let plaintext = Cryptor::Aes256Gcm.decryptor(&key, &nonce).unwrap()
|
||||
.decrypt(&ciphertext).unwrap();
|
||||
|
||||
assert_eq!(b"hello world", plaintext.as_slice());
|
||||
}
|
||||
@@ -23,6 +23,7 @@ mod config;
|
||||
mod spec;
|
||||
mod crypto_aes;
|
||||
mod crypto_rsa;
|
||||
mod crypto_cryptor;
|
||||
mod wrap_key;
|
||||
mod util_envelop;
|
||||
mod util_file;
|
||||
|
||||
Reference in New Issue
Block a user