Compare commits
3 Commits
ed7a227080
...
d818e52d45
Author | SHA1 | Date |
---|---|---|
Matéo Duparc | d818e52d45 | |
Matéo Duparc | c15985e928 | |
Matéo Duparc | 663933e32c |
|
@ -74,11 +74,11 @@ FLAGS:
|
|||
|
||||
OPTIONS:
|
||||
-p, --password <password> Password used to derive encryption keys
|
||||
-b, --block-size <blocksize> Size of file chunk (in bytes) [default: 65536]
|
||||
-c, --cipher <cipher> Encryption cipher to use [possible values: aes, xchacha20]
|
||||
-i, --iterations <iterations> Argon2 time cost [default: 10]
|
||||
-m, --memory-cost <memory cost> Argon2 memory cost (in kilobytes) [default: 4096]
|
||||
-t, --threads <threads> Argon2 parallelism (between 1 and 255) [default: 4]
|
||||
-i, --iterations <iterations> Argon2 time cost [default: 10]
|
||||
-b, --block-size <blocksize> Size of the I/O buffer (in bytes) [default: 65536]
|
||||
-c, --cipher <cipher> Encryption cipher to use [possible values: aes, xchacha20]
|
||||
|
||||
ARGS:
|
||||
<INPUT> <PATH> | "-" or empty for stdin
|
||||
|
|
|
@ -67,7 +67,7 @@ pub fn parse() -> Option<CliArgs> {
|
|||
Arg::with_name("blocksize")
|
||||
.short("b")
|
||||
.long("block-size")
|
||||
.help("Size of file chunk (in bytes)")
|
||||
.help("Size of the I/O buffer (in bytes)")
|
||||
.default_value("65536")
|
||||
)
|
||||
.arg(
|
||||
|
|
|
@ -60,7 +60,7 @@ pub struct EncryptionParams {
|
|||
}
|
||||
|
||||
impl EncryptionParams {
|
||||
fn get_params_len(&self) -> usize {
|
||||
pub fn get_params_len(&self) -> usize {
|
||||
SALT_LEN + 4*2 + 2 + self.cipher.get_nonce_size()
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
use rand::Rng;
|
||||
use doby::{
|
||||
crypto::{
|
||||
ArgonParams,
|
||||
CipherAlgorithm,
|
||||
EncryptionParams,
|
||||
DobyCipher,
|
||||
},
|
||||
encrypt,
|
||||
decrypt,
|
||||
};
|
||||
|
||||
fn different_elements<T: Eq>(v1: &Vec<T>, v2: &Vec<T>) -> usize {
|
||||
assert_eq!(v1.len(), v2.len());
|
||||
v1.into_iter().enumerate().filter(|x| v2[x.0] != *x.1).count()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authentication() {
|
||||
const BLOCK_SIZE: usize = 65536;
|
||||
const PLAINTEXT: &[u8; 13] = b"the plaintext";
|
||||
const PASSWORD: &str = "the password";
|
||||
let params = EncryptionParams::new(ArgonParams {
|
||||
t_cost: 1,
|
||||
m_cost: 8,
|
||||
parallelism: 1,
|
||||
}, CipherAlgorithm::AesCtr);
|
||||
|
||||
let encrypter = DobyCipher::new(PASSWORD.into(), ¶ms).unwrap();
|
||||
let mut ciphertext = Vec::with_capacity(PLAINTEXT.len()+158);
|
||||
encrypt(&mut &PLAINTEXT[..], &mut ciphertext, ¶ms, encrypter, BLOCK_SIZE, None).unwrap();
|
||||
assert_eq!(ciphertext.len(), PLAINTEXT.len()+158);
|
||||
|
||||
for i in 0..ciphertext.len() {
|
||||
let mut compromised = ciphertext.clone();
|
||||
while compromised[i] == ciphertext[i] {
|
||||
compromised[i] = rand::thread_rng().gen();
|
||||
}
|
||||
assert_eq!(different_elements(&compromised, &ciphertext), 1);
|
||||
let decrypter = DobyCipher::new(PASSWORD.into(), ¶ms).unwrap();
|
||||
let mut decrypted = Vec::with_capacity(PLAINTEXT.len());
|
||||
let verified = decrypt(&mut &compromised[..], &mut decrypted, decrypter, BLOCK_SIZE).unwrap();
|
||||
assert_eq!(verified, false);
|
||||
}
|
||||
|
||||
let decrypter = DobyCipher::new(PASSWORD.into(), ¶ms).unwrap();
|
||||
let mut decrypted = Vec::with_capacity(PLAINTEXT.len());
|
||||
let verified = decrypt(&mut &ciphertext[4+params.get_params_len()..], &mut decrypted, decrypter, BLOCK_SIZE).unwrap();
|
||||
assert_eq!(decrypted, PLAINTEXT);
|
||||
assert_eq!(verified, true);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use std::{io::{self, Read, Write}, fs::{self, File, create_dir}, path::PathBuf};
|
||||
use std::{convert::TryInto, fs::{self, File, create_dir}, io::{self, Read, Write}, path::PathBuf};
|
||||
use assert_cmd::{Command, cargo::{CargoError, cargo_bin}};
|
||||
use tempfile::TempDir;
|
||||
use doby::crypto::{CipherAlgorithm, SALT_LEN, HASH_LEN};
|
||||
|
@ -133,5 +133,11 @@ fn argon2_params() -> io::Result<()> {
|
|||
Command::cargo_bin("doby").unwrap().arg("-i").arg("0").assert().failure().stderr("Invalid argon2 params: time cost is too small\n");
|
||||
Command::cargo_bin("doby").unwrap().arg("-m").arg("0").assert().failure().stderr("Invalid argon2 params: memory cost is too small\n");
|
||||
Command::cargo_bin("doby").unwrap().arg("-t").arg("0").assert().failure().stderr("Invalid argon2 params: too few lanes\n");
|
||||
|
||||
let ciphertext = doby_cmd().unwrap().arg("-i").arg("8").arg("-m").arg("2048").arg("-t").arg("8").assert().success().stderr("").get_output().stdout.clone();
|
||||
assert_eq!(u32::from_be_bytes(ciphertext[4+SALT_LEN..4+SALT_LEN+4].try_into().unwrap()), 8); //time cost
|
||||
assert_eq!(u32::from_be_bytes(ciphertext[4+SALT_LEN+4..4+SALT_LEN+8].try_into().unwrap()), 2048); //memory cost
|
||||
assert_eq!(u8::from_be_bytes([ciphertext[4+SALT_LEN+8]]), 8); //parallelism
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue