1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
use ::stream::StreamCipher;
use ::auth::NonceMac;
use ::hash::GenericHash;
use super::{ AeadCipher, DecryptFail };
use std::marker::PhantomData;


/// General Authenticated Encryption.
///
/// # Example(encrypt/decrypt)
/// ```
/// # extern crate rand;
/// # extern crate sarkara;
/// # fn main() {
/// use rand::{ Rng, thread_rng };
/// use sarkara::aead::{ General, AeadCipher };
/// use sarkara::stream::HC256;
/// use sarkara::auth::HMAC;
/// use sarkara::hash::Blake2b;
///
/// type HHBB = General<HC256, HMAC<Blake2b>, Blake2b>;
///
/// let mut rng = thread_rng();
/// let mut pass = vec![0; HHBB::key_length()];
/// let mut nonce = vec![0; HHBB::nonce_length()];
/// let mut data = vec![0; 1024];
/// rng.fill_bytes(&mut pass);
/// rng.fill_bytes(&mut nonce);
/// rng.fill_bytes(&mut data);
///
/// let ciphertext = HHBB::new(&pass)
///     .with_aad(&nonce)
///     .encrypt(&nonce, &data);
/// let plaintext = HHBB::new(&pass)
///     .with_aad(&nonce)
///     .decrypt(&nonce, &ciphertext)
///     .unwrap();
/// assert_eq!(plaintext, data);
/// # }
/// ```
#[derive(Debug, Clone)]
pub struct General<C, M, H> {
    cipher: C,
    mac: M,
    aad: Vec<u8>,
    _ext: PhantomData<H>
}

impl<C, M, H> AeadCipher for General<C, M, H>
    where
        C: StreamCipher,
        M: NonceMac,
        H: GenericHash
{
    fn new(key: &[u8]) -> Self {
        let mkey = H::default()
            .with_size(M::key_length())
            .hash::<Vec<u8>>(key);
        General {
            cipher: C::new(key),
            mac: M::new(&mkey),
            aad: Vec::new(),
            _ext: PhantomData
        }
    }

    #[inline] fn key_length() -> usize { C::key_length() }
    #[inline] fn tag_length() -> usize { M::tag_length() }
    #[inline] fn nonce_length() -> usize { C::nonce_length() }

    fn with_aad(&mut self, aad: &[u8]) -> &mut Self {
        self.aad = aad.into();
        self
    }

    fn encrypt(&mut self, nonce: &[u8], data: &[u8]) -> Vec<u8> {
        let mnonce = H::default()
            .with_size(M::nonce_length())
            .hash::<Vec<u8>>(nonce);
        let mut output = self.cipher.process(nonce, data);
        let mut aad = self.aad.clone();
        aad.extend_from_slice(&output);

        let mut tag = self.mac
            .with_nonce(&mnonce)
            .result::<Vec<u8>>(&aad);
        output.append(&mut tag);
        output
    }

    fn decrypt(&mut self, nonce: &[u8], data: &[u8]) -> Result<Vec<u8>, DecryptFail> {
        if data.len() < Self::tag_length() { Err(DecryptFail::LengthError)? };

        let mnonce = H::default()
            .with_size(M::nonce_length())
            .hash::<Vec<u8>>(nonce);
        let (data, tag) = data.split_at(data.len() - Self::tag_length());
        let mut aad = self.aad.clone();
        aad.extend_from_slice(data);

        if self.mac.with_nonce(&mnonce).verify(&aad, tag) {
            Ok(self.cipher.process(nonce, data))
        } else {
            Err(DecryptFail::AuthenticationFail)
        }
    }
}