Secure symmetric encryption from the command line.
doby started as a fork of [aef](https://github.com/wyhaya/aef) by [wyhaya](https://github.com/wyhaya). It aims to replace the [ccrypt](http://ccrypt.sourceforge.net) tool which is a bit old and not very secure.
* Fast: written in [rust](https://www.rust-lang.org), encrypts with [AES-256-CTR](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_(CTR)) or [XChaCha20](https://en.wikipedia.org/wiki/Salsa20#XChaCha)
doby is provided "as is", without any warranty of any kind. I'm not a professional cryptographer. This program didn't receive any security audit and therefore __shouldn't be considered fully secure__.
doby first derives your password with Argon2 (version 19) in Argon2id mode with a 64 bytes long random salt. A `master_key` of 32 bytes is thus generated.
```rust
let master_key: [u8; 32] = argon2id(
password,
random_password_salt,
argon2_time_cost,
argon2_memory_cost,
argon2_parallelism,
);
```
Then, doby uses [HKDF](https://en.wikipedia.org/wiki/HKDF) with a new random salt to compute the `encryption_key`and the `authentication_key`.
```rust
let hkdf = Hkdf::new(
random_hkdf_salt,
master_key, //ikm
blake3, //hash function
);
let encryption_key: [u8; 32] = hkdf.expand(b"doby_encryption_key");
let authentication_key: [u8; 32] = hkdf.expand(b"doby_authentication_key");
```
Next, doby initializes a [BLAKE3](https://en.wikipedia.org/wiki/BLAKE_%28hash_function%29#BLAKE3) HMAC with `authentication_key` and add all public encryption parameters to it.
Now, doby initializes a symmetric cipher with `encryption_key` and `random_nonce` (either AES-CTR or XChaCha20, based on the `--cipher` option) and starts the actual encryption. It reads chunks from the plaintext (according to the `--block-size` parameter), encrypts them with the cipher and updates the HMAC with the ciphertext.
Once the whole plaintext is encrypted, doby computes and appends the HMAC to the ciphertext.
```rust
output.write(hmac.digest());
```
### 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.
```rust
let master_key: [u8; 32] = argon2id(
password,
password_salt_read_from_input,
argon2_time_cost_read_from_input,
argon2_memory_cost_read_from_input,
argon2_parallelism_read_from_input,
);
```
`encryption_key`and `authentication_key` are computed from `master_key` and the HKDF salt in the same way as during encryption. The HMAC is also initialized and updated with the values read from the header.