on the way to a usable version
This commit is contained in:
+57
-42
@@ -1,54 +1,61 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
use chacha20poly1305::{
|
||||
aead::{stream, NewAead},
|
||||
ChaCha20Poly1305,
|
||||
};
|
||||
|
||||
use chacha20poly1305::{aead::stream, KeyInit, XChaCha20Poly1305};
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
|
||||
use crate::error::*;
|
||||
use crate::reader::ReadInfo;
|
||||
use crate::utils::BUFSIZE;
|
||||
use crate::utils::*;
|
||||
|
||||
const BUFSIZE: usize = 64 * 1024; // 64 KiB
|
||||
|
||||
fn new_random_nonce() -> Result<[u8; 7], FcryError> {
|
||||
let mut nonce = [0u8; 7];
|
||||
OsRng.try_fill_bytes(&mut nonce)?;
|
||||
Ok(nonce)
|
||||
}
|
||||
|
||||
pub fn encrypt<S: AsRef<str>>(
|
||||
input_file: Option<S>,
|
||||
output_file: Option<S>,
|
||||
key: [u8; 32],
|
||||
) -> Result<(), FcryError> {
|
||||
let mut f_plain = read_from_file_or_stdin(input_file);
|
||||
let mut f_plain = read_from_file_or_stdin(input_file, BUFSIZE);
|
||||
let mut f_encrypted = write_to_file_or_stdout(output_file);
|
||||
|
||||
let nonce = new_random_nonce()?;
|
||||
let mut nonce = [0u8; 19];
|
||||
OsRng.fill_bytes(&mut nonce);
|
||||
|
||||
// let key = XChaCha20Poly1305::generate_key(&mut OsRng);
|
||||
|
||||
f_encrypted.write_all(&nonce)?;
|
||||
|
||||
let aead = ChaCha20Poly1305::new(&key.into());
|
||||
let aead = XChaCha20Poly1305::new(&key.into());
|
||||
let mut stream_encryptor = stream::EncryptorBE32::from_aead(aead, &nonce.into());
|
||||
|
||||
let mut buf = vec![0; BUFSIZE];
|
||||
let mut read_bytes;
|
||||
|
||||
loop {
|
||||
read_bytes = f_plain.read(&mut buf)?;
|
||||
let read_result = f_plain.read_ahead(&mut buf)?;
|
||||
|
||||
if read_bytes < BUFSIZE {
|
||||
break;
|
||||
match read_result {
|
||||
ReadInfo::NormalChunk(n) => {
|
||||
assert_eq!(n, BUFSIZE);
|
||||
assert_eq!(buf.len(), BUFSIZE);
|
||||
println!("[encrypt]: read normal chunk");
|
||||
stream_encryptor.encrypt_next_in_place(&[], &mut buf)?;
|
||||
f_encrypted.write_all(&buf)?;
|
||||
// buf grows after encrypt_next_in_place because of tag that is added
|
||||
// we shrink it to the BUFSIZE in order to read the correct size
|
||||
buf.truncate(BUFSIZE);
|
||||
}
|
||||
ReadInfo::LastChunk(n) => {
|
||||
println!("[encrypt]: read last chunk");
|
||||
buf.truncate(n);
|
||||
stream_encryptor.encrypt_last_in_place(&[], &mut buf)?;
|
||||
f_encrypted.write_all(&buf)?;
|
||||
break;
|
||||
}
|
||||
ReadInfo::EmptyChunk => {
|
||||
println!("[encrypt]: read empty chunk");
|
||||
panic!("[ERROR] Empty Chunk while reading");
|
||||
}
|
||||
}
|
||||
|
||||
stream_encryptor.encrypt_next_in_place(&[], &mut buf)?;
|
||||
f_encrypted.write_all(&buf)?;
|
||||
buf.truncate(BUFSIZE);
|
||||
}
|
||||
|
||||
buf.truncate(read_bytes);
|
||||
stream_encryptor.encrypt_last_in_place(&[], &mut buf)?;
|
||||
f_encrypted.write_all(&buf)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -57,33 +64,41 @@ pub fn decrypt<S: AsRef<str>>(
|
||||
output_file: Option<S>,
|
||||
key: [u8; 32],
|
||||
) -> Result<(), FcryError> {
|
||||
let mut f_encrypted = read_from_file_or_stdin(input_file);
|
||||
let mut f_encrypted = read_from_file_or_stdin(input_file, BUFSIZE + 16);
|
||||
let mut f_plain = write_to_file_or_stdout(output_file);
|
||||
|
||||
let mut nonce = [0u8; 7];
|
||||
let mut nonce = [0u8; 19];
|
||||
f_encrypted.read_exact(&mut nonce)?;
|
||||
|
||||
let aead = ChaCha20Poly1305::new(&key.into());
|
||||
let aead = XChaCha20Poly1305::new(&key.into());
|
||||
let mut stream_decryptor = stream::DecryptorBE32::from_aead(aead, &nonce.into());
|
||||
|
||||
let mut buf = vec![0; BUFSIZE + 16];
|
||||
let mut read_bytes;
|
||||
|
||||
loop {
|
||||
read_bytes = f_encrypted.read(&mut buf)?;
|
||||
let read_result = f_encrypted.read_ahead(&mut buf)?;
|
||||
|
||||
if read_bytes < BUFSIZE + 16 {
|
||||
break;
|
||||
match read_result {
|
||||
ReadInfo::NormalChunk(n) => {
|
||||
assert_eq!(n, BUFSIZE + 16);
|
||||
println!("[decrypt]: read normal chunk");
|
||||
stream_decryptor.decrypt_next_in_place(&[], &mut buf)?;
|
||||
f_plain.write_all(&buf)?;
|
||||
buf.resize(BUFSIZE + 16, 0);
|
||||
}
|
||||
ReadInfo::LastChunk(n) => {
|
||||
println!("[decrypt]: read last chunk");
|
||||
buf.truncate(n);
|
||||
stream_decryptor.decrypt_last_in_place(&[], &mut buf)?;
|
||||
f_plain.write_all(&buf)?;
|
||||
break;
|
||||
}
|
||||
ReadInfo::EmptyChunk => {
|
||||
println!("[decrypt]: read empty chunk");
|
||||
panic!("Empty Chunk while reading");
|
||||
}
|
||||
}
|
||||
|
||||
stream_decryptor.decrypt_next_in_place(&[], &mut buf)?;
|
||||
f_plain.write_all(&buf)?;
|
||||
buf.resize(BUFSIZE + 16, 0);
|
||||
}
|
||||
|
||||
buf.truncate(read_bytes);
|
||||
stream_decryptor.decrypt_last_in_place(&[], &mut buf)?;
|
||||
f_plain.write_all(&buf)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user