Compare commits

...

3 Commits

Author SHA1 Message Date
Matéo Duparc d818e52d45
Add authentication integration test 2021-07-08 19:12:30 +02:00
Matéo Duparc c15985e928
Better --block-size help 2021-07-08 18:16:50 +02:00
Matéo Duparc 663933e32c
Improve Argon2 parameters tests 2021-07-08 18:10:16 +02:00
5 changed files with 63 additions and 6 deletions

View File

@ -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

View File

@ -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(

View File

@ -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()
}

51
tests/authentication.rs Normal file
View File

@ -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(), &params).unwrap();
let mut ciphertext = Vec::with_capacity(PLAINTEXT.len()+158);
encrypt(&mut &PLAINTEXT[..], &mut ciphertext, &params, 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(), &params).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(), &params).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);
}

View File

@ -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(())
}