use std::cmp;
use std::fmt;
use std::io;
use nettle::{aead, cipher};
use buffered_reader::BufferedReader;
use crate::constants::{
AEADAlgorithm,
SymmetricAlgorithm,
};
use crate::conversions::{
write_be_u64,
};
use crate::Error;
use crate::Result;
use crate::crypto::SessionKey;
use crate::crypto::mem::secure_cmp;
use crate::parse::Cookie;
impl AEADAlgorithm {
/// Returns the digest size of the AEAD algorithm.
pub fn digest_size(&self) -> Result<usize> {
use self::AEADAlgorithm::*;
match self {
&EAX =>
// Digest size is independent of the cipher.
Ok(aead::Eax::<cipher::Aes128>::DIGEST_SIZE),
&OCB =>
// According to RFC4880bis, Section 5.16.2.
Ok(16),
_ => Err(Error::UnsupportedAEADAlgorithm(self.clone()).into()),
}
}
/// Returns the initialization vector size of the AEAD algorithm.
pub fn iv_size(&self) -> Result<usize> {
use self::AEADAlgorithm::*;
match self {
&EAX =>
Ok(16), // According to RFC4880bis, Section 5.16.1.
&OCB =>
// According to RFC4880bis, Section 5.16.2, the IV is "at
// least 15 octets long". GnuPG hardcodes 15 in
// openpgp_aead_algo_info.
Ok(15),
_ => Err(Error::UnsupportedAEADAlgorithm(self.clone()).into()),
}
}
/// Creates a nettle context.
pub fn context(&self, sym_algo: SymmetricAlgorithm, key: &[u8], nonce: &[u8])
-> Result<Box<dyn aead::Aead>> {
match self {
AEADAlgorithm::EAX => match sym_algo {
SymmetricAlgorithm::AES128 =>
Ok(Box::new(aead::Eax::<cipher::Aes128>
::with_key_and_nonce(key, nonce)?)),
SymmetricAlgorithm::AES192 =>
Ok(Box::new(aead::Eax::<cipher::Aes192>
::with_key_and_nonce(key, nonce)?)),
SymmetricAlgorithm::AES256 =>
Ok(Box::new(aead::Eax::<cipher::Aes256>
::with_key_and_nonce(key, nonce)?)),
SymmetricAlgorithm::Twofish =>
Ok(Box::new(aead::Eax::<cipher::Twofish>
::with_key_and_nonce(key, nonce)?)),
SymmetricAlgorithm::Camellia128 =>
Ok(Box::new(aead::Eax::<cipher::Camellia128>
::with_key_and_nonce(key, nonce)?)),
SymmetricAlgorithm::Camellia192 =>
Ok(Box::new(aead::Eax::<cipher::Camellia192>
::with_key_and_nonce(key, nonce)?)),
SymmetricAlgorithm::Camellia256 =>
Ok(Box::new(aead::Eax::<cipher::Camellia256>
::with_key_and_nonce(key, nonce)?)),
_ =>
Err(Error::UnsupportedSymmetricAlgorithm(sym_algo).into()),
},
_ =>
Err(Error::UnsupportedAEADAlgorithm(self.clone()).into()),
}
}
}
const AD_PREFIX_LEN: usize = 5;
/// A `Read`er for decrypting AEAD-encrypted data.
pub struct Decryptor<'a> {
// The encrypted data.
source: Box<BufferedReader<Cookie> + 'a>,
sym_algo: SymmetricAlgorithm,
aead: AEADAlgorithm