commit
0abd878df2
@ -0,0 +1,2 @@
|
||||
/target
|
||||
*~
|
@ -0,0 +1,132 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chachaex"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"getrandom",
|
||||
"hex-literal",
|
||||
"openssl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex-literal"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "chachaex"
|
||||
version = "0.1.0"
|
||||
authors = ["Avril <flanchan@cumallover.me>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.13.0"
|
||||
getrandom = "0.2.2"
|
||||
hex-literal = "0.3.1"
|
||||
openssl = "0.10.32"
|
@ -0,0 +1,112 @@
|
||||
|
||||
use getrandom::getrandom;
|
||||
use openssl::{
|
||||
symm::{
|
||||
Cipher, Crypter, Mode,
|
||||
},
|
||||
error::ErrorStack,
|
||||
};
|
||||
|
||||
pub const KEY_SIZE: usize = 32;
|
||||
pub const IV_SIZE: usize = 12;
|
||||
|
||||
static NEW_CIPHER: fn() -> Cipher = Cipher::chacha20_poly1305;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct Key([u8; KEY_SIZE]);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct IV([u8; IV_SIZE]);
|
||||
|
||||
#[inline] pub fn decrypter(key: impl AsRef<Key>, iv: impl AsRef<IV>) -> Result<Crypter, ErrorStack>
|
||||
{
|
||||
Crypter::new(
|
||||
NEW_CIPHER(),
|
||||
Mode::Decrypt,
|
||||
key.as_ref().as_ref(),
|
||||
Some(iv.as_ref().as_ref())
|
||||
)
|
||||
}
|
||||
#[inline] pub fn encrypter(key: impl AsRef<Key>, iv: impl AsRef<IV>) -> Result<Crypter, ErrorStack>
|
||||
{
|
||||
Crypter::new(
|
||||
NEW_CIPHER(),
|
||||
Mode::Encrypt,
|
||||
key.as_ref().as_ref(),
|
||||
Some(iv.as_ref().as_ref())
|
||||
)
|
||||
}
|
||||
|
||||
impl Key
|
||||
{
|
||||
pub fn new() -> Self
|
||||
{
|
||||
let mut output = [0u8; KEY_SIZE];
|
||||
getrandom(&mut output[..]).expect("rng fatal");
|
||||
Self(output)
|
||||
}
|
||||
}
|
||||
|
||||
impl IV
|
||||
{
|
||||
pub fn new() -> Self
|
||||
{
|
||||
let mut output = [0u8; IV_SIZE];
|
||||
getrandom(&mut output[..]).expect("rng fatal");
|
||||
Self(output)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for Key
|
||||
{
|
||||
fn as_ref(&self) -> &[u8]
|
||||
{
|
||||
&self.0[..]
|
||||
}
|
||||
}
|
||||
impl AsRef<[u8]> for IV
|
||||
{
|
||||
fn as_ref(&self) -> &[u8]
|
||||
{
|
||||
&self.0[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for Key
|
||||
{
|
||||
fn as_mut(&mut self) -> &mut [u8]
|
||||
{
|
||||
&mut self.0[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for IV
|
||||
{
|
||||
fn as_mut(&mut self) -> &mut [u8]
|
||||
{
|
||||
&mut self.0[..]
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)] pub fn keygen() -> (Key, IV)
|
||||
{
|
||||
(Key::new(), IV::new())
|
||||
}
|
||||
|
||||
impl AsRef<Key> for Key
|
||||
{
|
||||
#[inline] fn as_ref(&self) -> &Key
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
impl AsRef<IV> for IV
|
||||
{
|
||||
#[inline] fn as_ref(&self) -> &IV
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
|
||||
#[macro_use] extern crate hex_literal;
|
||||
|
||||
mod cha;
|
||||
|
||||
use cha::{Key, IV};
|
||||
|
||||
fn encrypt((key, iv): &(Key, IV), input: impl Into<Vec<u8>>) -> Result<String, openssl::error::ErrorStack>
|
||||
{
|
||||
let input = input.into();//.into();
|
||||
let mut output = vec![0u8; input.len()];
|
||||
|
||||
eprintln!("(enc) Key: {:?}, IV: {:?}, Input: ({}, {:?})", key, iv, input.len(), input);
|
||||
|
||||
let mut enc = cha::encrypter(key, iv)?;
|
||||
|
||||
let n = enc.update(&input[..], &mut output[..])?;
|
||||
eprintln!("(enc) Written {} bytes", n);
|
||||
enc.finalize(&mut output[..n])?;
|
||||
|
||||
Ok(base64::encode(&output[..n]))
|
||||
}
|
||||
|
||||
fn decrypt((key, iv): &(Key, IV), input: impl Into<String>) -> Result<Vec<u8>, openssl::error::ErrorStack>
|
||||
{
|
||||
let input = base64::decode(input.into()).expect("invalid base64");
|
||||
let mut output = vec![0u8; input.len()];
|
||||
|
||||
eprintln!("(dec) Key: {:?}, IV: {:?}, Input: ({}, {:?})", key, iv, input.len(), input);
|
||||
|
||||
let mut dec = cha::decrypter(key, iv)?;
|
||||
|
||||
let n = dec.update(&input[..], &mut output[..])?;
|
||||
eprintln!("(dec) Written {} bytes", n);
|
||||
dec.finalize(&mut output[..n])?;
|
||||
|
||||
output.truncate(n);
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let key = cha::keygen();
|
||||
let enc = encrypt(&key, std::env::args().nth(1).unwrap()).expect("encrypt");
|
||||
println!("{}", enc);
|
||||
let dec = decrypt(&key, enc).expect("decrypt");
|
||||
|
||||
println!("{:?}", std::str::from_utf8(&dec[..]).unwrap());
|
||||
}
|
Loading…
Reference in new issue