Compare commits

...

2 Commits

Author SHA1 Message Date
Matéo Duparc f6fe3912c6
Add encrypted file layout table in README 2021-08-31 12:36:19 +02:00
Matéo Duparc 882a917971
Little code improvements 2021-08-31 11:23:15 +02:00
4 changed files with 42 additions and 9 deletions

View File

@ -154,6 +154,7 @@ let hmac = Hmac::new(
blake2b, //hash function
);
hmac.update(random_salt);
//integers are encoded in big-endian
hmac.update(argon2_time_cost);
hmac.update(argon2_memory_cost);
hmac.update(argon2_parallelism);
@ -182,6 +183,41 @@ Once the whole plaintext is encrypted, doby computes and appends the HMAC to the
output.write(hmac.digest());
```
So here is what an encrypted file layout looks like:
<table>
<tr>
<th align="left">Magic bytes</th>
<td>4 bytes</td>
</tr>
<tr>
<th align="left">Salt</th>
<td>64 bytes</td>
</tr>
<tr>
<th align="left" rowspan="3">Argon2 parameters</th>
<td>Time cost: 4 bytes</td>
</tr>
<tr>
<td>Memory cost: 4 bytes</td>
</tr>
<tr>
<td>Parallelism cost: 1 byte</td>
</tr>
<tr>
<th align="left">Encryption cipher</th>
<td>1 byte</td>
</tr>
<tr>
<th align="left">Ciphertext</th>
<td>Exact same size as the plaintext</td>
</tr>
<tr>
<th align="left">HMAC</th>
<td>64 bytes</td>
</tr>
</table>
### Decryption
doby reads the public encryption values from the input header to get all parameters needed to re-derive the `master_key` from the password with Argon2.

View File

@ -96,11 +96,11 @@ pub fn parse() -> Option<CliArgs> {
let cipher = app
.value_of("cipher")
.and_then(|s| Some(if s.to_lowercase() == "aes" {
.map(|s| if s.to_lowercase() == "aes" {
CipherAlgorithm::AesCtr
} else {
CipherAlgorithm::XChaCha20
})
}
)
.unwrap_or_else(|| if aes_ni::get() {
CipherAlgorithm::AesCtr

View File

@ -17,7 +17,7 @@ impl Password {
impl From<Option<&str>> for Password {
fn from(s: Option<&str>) -> Self {
Self(s.map(|s| String::from(s)))
Self(s.map(String::from))
}
}
@ -66,7 +66,7 @@ impl<P: AsRef<Path>> Write for LazyWriter<P> {
}
}
pub fn encrypt<R: Read, W: Write>(reader: &mut R, writer: &mut W, params: &EncryptionParams, mut cipher: DobyCipher, block_size: usize, already_read: Option<Vec<u8>>) -> io::Result<()> {
pub fn encrypt<R: Read, W: Write>(reader: &mut R, writer: &mut W, params: &EncryptionParams, mut cipher: DobyCipher, block_size: usize, already_read: Option<&[u8]>) -> io::Result<()> {
writer.write_all(MAGIC_BYTES)?;
params.write(writer)?;
let mut buff = vec![0; block_size];
@ -97,7 +97,7 @@ pub fn decrypt<R: Read, W: Write>(reader: &mut R, writer: &mut W, mut cipher: Do
if n == 0 {
break;
} else {
writer.write(&buff[..n])?;
writer.write_all(&buff[..n])?;
}
}
Ok(cipher.verify_hmac())

View File

@ -16,9 +16,6 @@ fn run() -> bool {
let mut magic_bytes = vec![0; MAGIC_BYTES.len()];
match reader.read(&mut magic_bytes) {
Ok(n) => {
if n < magic_bytes.len() {
magic_bytes.truncate(n);
}
if magic_bytes == MAGIC_BYTES && !cli_args.force_encrypt { //we probably want to decrypt
match EncryptionParams::read(&mut reader) {
Ok(params) => {
@ -55,7 +52,7 @@ fn run() -> bool {
&params,
cipher,
cli_args.block_size,
Some(magic_bytes)
Some(&magic_bytes[..n])
) {
Ok(_) => success = true,
Err(e) => eprintln!("I/O error while encrypting: {}", e)