// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use aes::KeySize;
use aes::KeySize::{KeySize128, KeySize192, KeySize256};
use symmetriccipher::{BlockEncryptor, BlockDecryptor};
//use util::supports_aesni;

#[derive(Copy)]
pub struct AesNiEncryptor {
    rounds: u8,
    round_keys: [u8; 240]
}

impl Clone for AesNiEncryptor { fn clone(&self) -> AesNiEncryptor { *self } }

#[derive(Copy)]
pub struct AesNiDecryptor {
    rounds: u8,
    round_keys: [u8; 240]
}

impl Clone for AesNiDecryptor { fn clone(&self) -> AesNiDecryptor { *self } }

/// The number of rounds as well as a function to setup an appropriately sized key.
type RoundSetupInfo = (u8, fn(&[u8], KeyType, &mut [u8]));

impl AesNiEncryptor {
    pub fn new(key_size: KeySize, key: &[u8]) -> AesNiEncryptor {
        //if !supports_aesni() {
        //    panic!("AES-NI not supported on this architecture. If you are \
        //        using the MSVC toolchain, this is because the AES-NI method's \
        //        have not been ported, yet");
        //}
        //println!("enter AesNiEncryptor new");
        let (rounds, setup_function): RoundSetupInfo = match key_size {
            KeySize128 => (10, setup_working_key_aesni_128),
            KeySize192 => (12, setup_working_key_aesni_192),
            KeySize256 => (14, setup_working_key_aesni_256)
        };
        let mut e = AesNiEncryptor {
            rounds: rounds,
            round_keys: [0u8; 240]
        };
        setup_function(key, KeyType::Encryption, &mut e.round_keys[0..size(e.rounds)]);
        e
    }
}

impl AesNiDecryptor {
    pub fn new(key_size: KeySize, key: &[u8]) -> AesNiDecryptor {
        //if !supports_aesni() {
        //    panic!("AES-NI not supported on this architecture. If you are \
        //        using the MSVC toolchain, this is because the AES-NI method's \
        //        have not been ported, yet");
        //}
        let (rounds, setup_function): RoundSetupInfo = match key_size {
            KeySize128 => (10, setup_working_key_aesni_128),
            KeySize192 => (12, setup_working_key_aesni_192),
            KeySize256 => (14, setup_working_key_aesni_256)
        };
        let mut d = AesNiDecryptor {
            rounds: rounds,
            round_keys: [0u8; 240]
        };
        setup_function(key, KeyType::Decryption, &mut d.round_keys[0..size(d.rounds)]);
        d
    }

}

impl BlockEncryptor for AesNiEncryptor {
    fn block_size(&self) -> usize { 16 }
    fn encrypt_block(&self, input: &[u8], output: &mut [u8]) {
        encrypt_block_aesni(self.rounds, input, &self.round_keys[0..size(self.rounds)], output);
    }
}

impl BlockDecryptor for AesNiDecryptor {
    fn block_size(&self) -> usize { 16 }
    fn decrypt_block(&self, input: &[u8], output: &mut [u8]) {
        decrypt_block_aesni(self.rounds, input, &self.round_keys[0..size(self.rounds)], output);
    }
}

enum KeyType {
    Encryption,
    Decryption
}

#[inline(always)]
fn size(rounds: u8) -> usize { 16 * ((rounds as usize) + 1) }

extern {
    fn rust_crypto_aesni_aesimc(round_keys: *mut u8);
    fn rust_crypto_aesni_setup_working_key_128(key: *const u8, round_key: *mut u8);
    fn rust_crypto_aesni_setup_working_key_192(key: *const u8, round_key: *mut u8);
    fn rust_crypto_aesni_setup_working_key_256(key: *const u8, round_key: *mut u8);
    fn rust_crypto_aesni_encrypt_block(
            rounds: u8,
            input: *const u8,
            round_keys: *const u8,
            output: *mut u8);
    fn rust_crypto_aesni_decrypt_block(
            rounds: u8,
            input: *const u8,
            round_keys: *const u8,
            output: *mut u8);
}

fn setup_working_key_aesni_128(key: &[u8], key_type: KeyType, round_key: &mut [u8]) {
    unsafe {
        rust_crypto_aesni_setup_working_key_128(key.as_ptr(), round_key.as_mut_ptr());

        match key_type {
            KeyType::Decryption => {
                // range of rounds keys from #1 to #9; skip the first and last key
                for i in 1..10 {
                    rust_crypto_aesni_aesimc(round_key.get_unchecked_mut(16 * i));
                }
            }
            KeyType::Encryption => { /* nothing more to do */ }
        }
    }
}

fn setup_working_key_aesni_192(key: &[u8], key_type: KeyType, round_key: &mut [u8]) {
    unsafe {
        rust_crypto_aesni_setup_working_key_192(key.as_ptr(), round_key.as_mut_ptr());

        match key_type {
            KeyType::Decryption => {
                // range of rounds keys from #1 to #11; skip the first and last key
                for i in 1..12 {
                    rust_crypto_aesni_aesimc(round_key.get_unchecked_mut(16 * i));
                }
            }
            KeyType::Encryption => { /* nothing more to do */ }
        }
    }
}

fn setup_working_key_aesni_256(key: &[u8], key_type: KeyType, round_key: &mut [u8]) {
    unsafe {
        rust_crypto_aesni_setup_working_key_256(key.as_ptr(), round_key.as_mut_ptr());

        match key_type {
            KeyType::Decryption => {
                // range of rounds keys from #1 to #13; skip the first and last key
                for i in 1..14 {
                    rust_crypto_aesni_aesimc(round_key.get_unchecked_mut(16 * i));
                }
            }
            KeyType::Encryption => { /* nothing more to do */ }
        }
    }
}

fn encrypt_block_aesni(rounds: u8, input: &[u8], round_keys: &[u8], output: &mut [u8]) {
    unsafe {
        rust_crypto_aesni_encrypt_block(
                rounds,
                input.as_ptr(),
                round_keys.as_ptr(),
                output.as_mut_ptr());
    }
}

fn decrypt_block_aesni(rounds: u8, input: &[u8], round_keys: &[u8], output: &mut [u8]) {
    unsafe {
        rust_crypto_aesni_decrypt_block(
                rounds as u8,
                input.as_ptr(),
                round_keys.get_unchecked(round_keys.len() - 16),
                output.as_mut_ptr());
    }
}
