// 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.

// TODO - Optimize the XORs
// TODO - Maybe use macros to specialize BlockEngine for encryption or decryption?
// TODO - I think padding could be done better. Maybe macros for BlockEngine would help this too.

use std::prelude::v1::*;
use std::cmp;
use std::iter::repeat;

use buffer::{ReadBuffer, WriteBuffer, OwnedReadBuffer, OwnedWriteBuffer, BufferResult,
    RefReadBuffer, RefWriteBuffer};
use buffer::BufferResult::{BufferUnderflow, BufferOverflow};
use cryptoutil::{self, symm_enc_or_dec};
use symmetriccipher::{BlockEncryptor, BlockEncryptorX8, Encryptor, BlockDecryptor, Decryptor,
    SynchronousStreamCipher, SymmetricCipherError};
use symmetriccipher::SymmetricCipherError::{InvalidPadding, InvalidLength};

/// The BlockProcessor trait is used to implement modes that require processing complete blocks of
/// data. The methods of this trait are called by the BlockEngine which is in charge of properly
/// buffering input data.
trait BlockProcessor {
    /// Process a block of data. The in_hist and out_hist parameters represent the input and output
    /// when the last block was processed. These values are necessary for certain modes.
    fn process_block(&mut self, in_hist: &[u8], out_hist: &[u8], input: &[u8], output: &mut [u8]);
}

/// A PaddingProcessor handles adding or removing padding
pub trait PaddingProcessor {
    /// Add padding to the last block of input data
    /// If the mode can't handle a non-full block, it signals that error by simply leaving the block
    /// as it is which will be detected as an InvalidLength error.
    fn pad_input<W: WriteBuffer>(&mut self, input_buffer: &mut W);

    /// Remove padding from the last block of output data
    /// If false is returned, the processing fails
    fn strip_output<R: ReadBuffer>(&mut self, output_buffer: &mut R) -> bool;
}

/// The BlockEngine is implemented as a state machine with the following states. See comments in the
/// BlockEngine code for more information on the states.
#[derive(Clone, Copy)]
enum BlockEngineState {
    FastMode,
    NeedInput,
    NeedOutput,
    LastInput,
    LastInput2,
    Finished,
    Error(SymmetricCipherError)
}

/// BlockEngine buffers input and output data and handles sending complete block of data to the
/// Processor object. Additionally, BlockEngine handles logic necessary to add or remove padding by
/// calling the appropriate methods on the Processor object.
struct BlockEngine<P, X> {
    /// The block sized expected by the Processor
    block_size: usize,

    /// in_hist and out_hist keep track of data that was input to and output from the last
    /// invocation of the process_block() method of the Processor. Depending on the mode, these may
    /// be empty vectors if history is not needed.
    in_hist: Vec<u8>,
    out_hist: Vec<u8>,

    /// If some input data is supplied, but not a complete blocks worth, it is stored in this buffer
    /// until enough arrives that it can be passed to the process_block() method of the Processor.
    in_scratch: OwnedWriteBuffer,

    /// If input data is processed but there isn't enough space in the output buffer to store it,
    /// it is written into out_write_scratch. OwnedWriteBuffer's may be converted into
    /// OwnedReaderBuffers without re-allocating, so, after being written, out_write_scratch is
    /// turned into out_read_scratch. After that, if is written to the output as more output becomes
    /// available. The main point is - only out_write_scratch or out_read_scratch contains a value
    /// at any given time; never both.
    out_write_scratch: Option<OwnedWriteBuffer>,
    out_read_scratch: Option<OwnedReadBuffer>,

    /// The processor that implements the particular block mode.
    processor: P,

    /// The padding processor
    padding: X,

    /// The current state of the operation.
    state: BlockEngineState
}

fn update_history(in_hist: &mut [u8], out_hist: &mut [u8], last_in: &[u8], last_out: &[u8]) {
    let in_hist_len = in_hist.len();
    if in_hist_len > 0 {
        cryptoutil::copy_memory(
            &last_in[last_in.len() - in_hist_len..],
            in_hist);
    }
    let out_hist_len = out_hist.len();
    if out_hist_len > 0 {
        cryptoutil::copy_memory(
            &last_out[last_out.len() - out_hist_len..],
            out_hist);
    }
}

impl <P: BlockProcessor, X: PaddingProcessor> BlockEngine<P, X> {
    /// Create a new BlockProcessor instance with the given processor and block_size. No history
    /// will be saved.
    fn new(processor: P, padding: X, block_size: usize) -> BlockEngine<P, X> {
        BlockEngine {
            block_size: block_size,
            in_hist: Vec::new(),
            out_hist: Vec::new(),
            in_scratch: OwnedWriteBuffer::new(repeat(0).take(block_size).collect()),
            out_write_scratch: Some(OwnedWriteBuffer::new(repeat(0).take(block_size).collect())),
            out_read_scratch: None,
            processor: processor,
            padding: padding,
            state: BlockEngineState::FastMode
        }
    }

    /// Create a new BlockProcessor instance with the given processor, block_size, and initial input
    /// and output history.
    fn new_with_history(
            processor: P,
            padding: X,
            block_size: usize,
            in_hist: Vec<u8>,
            out_hist: Vec<u8>) -> BlockEngine<P, X> {
        BlockEngine {
            in_hist: in_hist,
            out_hist: out_hist,
            ..BlockEngine::new(processor, padding, block_size)
        }
    }

    /// This implements the FastMode state. Ideally, the encryption or decryption operation should
    /// do the bulk of its work in FastMode. Significantly, FastMode avoids doing copies as much as
    /// possible. The FastMode state does not handle the final block of data.
    fn fast_mode<R: ReadBuffer, W: WriteBuffer>(
            &mut self,
            input: &mut R,
            output: &mut W) -> BlockEngineState {
        fn has_next<R: ReadBuffer, W: WriteBuffer>(
                input: &mut R,
                output: &mut W,
                block_size: usize) -> bool {
            // Not the greater than - very important since this method must never process the last
            // block.
            let enough_input = input.remaining() > block_size;
            let enough_output = output.remaining() >= block_size;
            enough_input && enough_output
        };
        fn split_at<'a>(vec: &'a [u8], at: usize) -> (&'a [u8], &'a [u8]) {
            (&vec[..at], &vec[at..])
        }

        // First block processing. We have to retrieve the history information from self.in_hist and
        // self.out_hist.
        if !has_next(input, output, self.block_size) {
            if input.is_empty() {
                return BlockEngineState::FastMode;
            } else {
                return BlockEngineState::NeedInput;
            }
        } else {
            let next_in = input.take_next(self.block_size);
            let next_out = output.take_next(self.block_size);
            self.processor.process_block(
                &self.in_hist[..],
                &self.out_hist[..],
                next_in,
                next_out);
        }

        // Process all remaing blocks. We can pull the history out of the buffers without having to
        // do any copies
        let next_in_size = self.in_hist.len() + self.block_size;
        let next_out_size = self.out_hist.len() + self.block_size;
        while has_next(input, output, self.block_size) {
            input.rewind(self.in_hist.len());
            let (in_hist, next_in) = split_at(input.take_next(next_in_size), self.in_hist.len());
            output.rewind(self.out_hist.len());
            let (out_hist, next_out) = output.take_next(next_out_size).split_at_mut(
                self.out_hist.len());
            self.processor.process_block(
                in_hist,
                out_hist,
                next_in,
                next_out);
        }

        // Save the history and then transition to the next state
        {
            input.rewind(self.in_hist.len());
            let last_in = input.take_next(self.in_hist.len());
            output.rewind(self.out_hist.len());
            let last_out = output.take_next(self.out_hist.len());
            update_history(
                &mut self.in_hist,
                &mut self.out_hist,
                last_in,
                last_out);
        }
        if input.is_empty() {
            BlockEngineState::FastMode
        } else {
            BlockEngineState::NeedInput
        }
    }

    /// This method implements the BlockEngine state machine.
    fn process<R: ReadBuffer, W: WriteBuffer>(
            &mut self,
            input: &mut R,
            output: &mut W,
            eof: bool) -> Result<BufferResult, SymmetricCipherError> {
        // Process a block of data from in_scratch and write the result to out_write_scratch.
        // Finally, convert out_write_scratch into out_read_scratch.
        fn process_scratch<P: BlockProcessor, X: PaddingProcessor>(me: &mut BlockEngine<P, X>) {
            let mut rin = me.in_scratch.take_read_buffer();
            let mut wout = me.out_write_scratch.take().unwrap();

            {
                let next_in = rin.take_remaining();
                let next_out = wout.take_remaining();
                me.processor.process_block(
                    &me.in_hist[..],
                    &me.out_hist[..],
                    next_in,
                    next_out);
                update_history(
                    &mut me.in_hist,
                    &mut me.out_hist,
                    next_in,
                    next_out);
            }

            let rb = wout.into_read_buffer();
            me.out_read_scratch = Some(rb);
        };

        loop {
            match self.state {
                // FastMode tries to process as much data as possible while minimizing copies.
                // FastMode doesn't make use of the scratch buffers and only updates the history
                // just before exiting.
                BlockEngineState::FastMode => {
                    self.state = self.fast_mode(input, output);
                    match self.state {
                        BlockEngineState::FastMode => {
                            // If FastMode completes but stays in the FastMode state, it means that
                            // we've run out of input data.
                            return Ok(BufferUnderflow);
                        }
                        _ => {}
                    }
                }

                // The NeedInput mode is entered when there isn't enough data to run in FastMode
                // anymore. Input data is buffered in in_scratch until there is a full block or eof
                // occurs. IF eof doesn't occur, the data is processed and then we go to the
                // NeedOutput state. Otherwise, we go to the LastInput state. This state always
                // writes all available data into in_scratch before transitioning to the next state.
                BlockEngineState::NeedInput => {
                    input.push_to(&mut self.in_scratch);
                    if !input.is_empty() {
                        // !is_empty() guarantees two things - in_scratch is full and its not the
                        // last block. This state must never process the last block.
                        process_scratch(self);
                        self.state = BlockEngineState::NeedOutput;
                    } else {
                        if eof {
                            self.state = BlockEngineState::LastInput;
                        } else {
                            return Ok(BufferUnderflow);
                        }
                    }
                }

                // The NeedOutput state just writes buffered processed data to the output stream
                // until all of it has been written.
                BlockEngineState::NeedOutput => {
                    let mut rout = self.out_read_scratch.take().unwrap();
                    rout.push_to(output);
                    if rout.is_empty() {
                        self.out_write_scratch = Some(rout.into_write_buffer());
                        self.state = BlockEngineState::FastMode;
                    } else {
                        self.out_read_scratch = Some(rout);
                        return Ok(BufferOverflow);
                    }
                }

                // None of the other states are allowed to process the last block of data since
                // last block handling is a little tricky due to modes have special needs regarding
                // padding. When the last block of data is detected, this state is transitioned to
                // for handling.
                BlockEngineState::LastInput => {
                    // We we arrive in this state, we know that all input data that is going to be
                    // supplied has been suplied and that that data has been written to in_scratch
                    // by the NeedInput state. Furthermore, we know that one of three things must be
                    // true about in_scratch:
                    // 1) It is empty. This only occurs if the input is zero length. We can do last
                    //    block processing by executing the pad_input() method of the processor
                    //    which may either pad out to a full block or leave it empty, process the
                    //    data if it was padded out to a full block, and then pass it to
                    //    strip_output().
                    // 2) It is partially filled. This will occur if the input data was not a
                    //    multiple of the block size. Processing proceeds identically to case #1.
                    // 3) It is full. This case occurs when the input data was a multiple of the
                    //    block size. This case is a little trickier, since, depending on the mode,
                    //    we might actually have 2 blocks worth of data to process - the last user
                    //    supplied block (currently in in_scratch) and then another block that could
                    //    be added as padding. Processing proceeds by first processing the data in
                    //    in_scratch and writing it to out_scratch. Then, the now-empty in_scratch
                    //    buffer is passed to pad_input() which may leave it empty or write a block
                    //    of padding to it. If no padding is added, processing proceeds as in cases
                    //    #1 and #2. However, if padding is added, now have data in in_scratch and
                    //    also in out_scratch meaning that we can't immediately process the padding
                    //    data since we have nowhere to put it. So, we transition to the LastInput2
                    //    state which will first write out the last non-padding block, then process
                    //    the padding block (in in_scratch) and write it to the now-empty
                    //    out_scratch.
                    if !self.in_scratch.is_full() {
                        self.padding.pad_input(&mut self.in_scratch);
                        if self.in_scratch.is_full() {
                            process_scratch(self);
                            if self.padding.strip_output(self.out_read_scratch.as_mut().unwrap()) {
                                self.state = BlockEngineState::Finished;
                            } else {
                                self.state = BlockEngineState::Error(InvalidPadding);
                            }
                        } else if self.in_scratch.is_empty() {
                            self.state = BlockEngineState::Finished;
                        } else {
                            self.state = BlockEngineState::Error(InvalidLength);
                        }
                    } else {
                        process_scratch(self);
                        self.padding.pad_input(&mut self.in_scratch);
                        if self.in_scratch.is_full() {
                            self.state = BlockEngineState::LastInput2;
                        } else if self.in_scratch.is_empty() {
                            if self.padding.strip_output(self.out_read_scratch.as_mut().unwrap()) {
                                self.state = BlockEngineState::Finished;
                            } else {
                                self.state = BlockEngineState::Error(InvalidPadding);
                            }
                        } else {
                            self.state = BlockEngineState::Error(InvalidLength);
                        }
                    }
                }

                // See the comments on LastInput for more details. This state handles final blocks
                // of data in the case that the input was a multiple of the block size and the mode
                // decided to add a full extra block of padding.
                BlockEngineState::LastInput2 => {
                    let mut rout = self.out_read_scratch.take().unwrap();
                    rout.push_to(output);
                    if rout.is_empty() {
                        self.out_write_scratch = Some(rout.into_write_buffer());
                        process_scratch(self);
                        if self.padding.strip_output(self.out_read_scratch.as_mut().unwrap()) {
                            self.state = BlockEngineState::Finished;
                        } else {
                            self.state = BlockEngineState::Error(InvalidPadding);
                        }
                    } else {
                        self.out_read_scratch = Some(rout);
                        return Ok(BufferOverflow);
                    }
                }

                // The Finished mode just writes the data in out_scratch to the output until there
                // is no more data left.
                BlockEngineState::Finished => {
                    match self.out_read_scratch {
                        Some(ref mut rout) => {
                            rout.push_to(output);
                            if rout.is_empty() {
                                return Ok(BufferUnderflow);
                            } else {
                                return Ok(BufferOverflow);
                            }
                        }
                        None => { return Ok(BufferUnderflow); }
                    }
                }

                // The Error state is used to store error information.
                BlockEngineState::Error(err) => {
                    return Err(err);
                }
            }
        }
    }
    fn reset(&mut self) {
        self.state = BlockEngineState::FastMode;
        self.in_scratch.reset();
        if self.out_read_scratch.is_some() {
            let ors = self.out_read_scratch.take().unwrap();
            let ows = ors.into_write_buffer();
            self.out_write_scratch = Some(ows);
        } else {
            self.out_write_scratch.as_mut().unwrap().reset();
        }
    }
    fn reset_with_history(&mut self, in_hist: &[u8], out_hist: &[u8]) {
        self.reset();
        cryptoutil::copy_memory(in_hist, &mut self.in_hist);
        cryptoutil::copy_memory(out_hist, &mut self.out_hist);
    }
}

/// No padding mode for ECB and CBC encryption
#[derive(Clone, Copy)]
pub struct NoPadding;

impl PaddingProcessor for NoPadding {
    fn pad_input<W: WriteBuffer>(&mut self, _: &mut W) { }
    fn strip_output<R: ReadBuffer>(&mut self, _: &mut R) -> bool { true }
}

/// PKCS padding mode for ECB and CBC encryption
#[derive(Clone, Copy)]
pub struct PkcsPadding;

// This class implements both encryption padding, where padding is added, and decryption padding,
// where padding is stripped. Since BlockEngine doesn't know if its an Encryption or Decryption
// operation, it will call both methods if given a chance. So, this class can't be passed directly
// to BlockEngine. Instead, it must be wrapped with EncPadding or DecPadding which will ensure that
// only the propper methods are called. The client of the library, however, doesn't have to
// distinguish encryption padding handling from decryption padding handline, which is the whole
// point.
impl PaddingProcessor for PkcsPadding {
    fn pad_input<W: WriteBuffer>(&mut self, input_buffer: &mut W) {
        let rem = input_buffer.remaining();
        assert!(rem != 0 && rem <= 255);
        for v in input_buffer.take_remaining().iter_mut() {
            *v = rem as u8;
        }
    }
    fn strip_output<R: ReadBuffer>(&mut self, output_buffer: &mut R) -> bool {
        let last_byte: u8;
        {
            let data = output_buffer.peek_remaining();
            last_byte = *data.last().unwrap();
            for &x in data.iter().rev().take(last_byte as usize) {
                if x != last_byte {
                    return false;
                }
            }
        }
        output_buffer.truncate(last_byte as usize);
        true
    }
}

/// Wraps a PaddingProcessor so that only pad_input() will actually be called.
pub struct EncPadding<X> {
    padding: X
}

impl <X: PaddingProcessor> EncPadding<X> {
    fn wrap(p: X) -> EncPadding<X> { EncPadding { padding: p } }
}

impl <X: PaddingProcessor> PaddingProcessor for EncPadding<X> {
    fn pad_input<W: WriteBuffer>(&mut self, a: &mut W) { self.padding.pad_input(a); }
    fn strip_output<R: ReadBuffer>(&mut self, _: &mut R) -> bool { true }
}

/// Wraps a PaddingProcessor so that only strip_output() will actually be called.
pub struct DecPadding<X> {
    padding: X
}

impl <X: PaddingProcessor> DecPadding<X> {
    fn wrap(p: X) -> DecPadding<X> { DecPadding { padding: p } }
}

impl <X: PaddingProcessor> PaddingProcessor for DecPadding<X> {
    fn pad_input<W: WriteBuffer>(&mut self, _: &mut W) { }
    fn strip_output<R: ReadBuffer>(&mut self, a: &mut R) -> bool { self.padding.strip_output(a) }
}

struct EcbEncryptorProcessor<T> {
    algo: T
}

impl <T: BlockEncryptor> BlockProcessor for EcbEncryptorProcessor<T> {
    fn process_block(&mut self, _: &[u8], _: &[u8], input: &[u8], output: &mut [u8]) {
        self.algo.encrypt_block(input, output);
    }
}

/// ECB Encryption mode
pub struct EcbEncryptor<T, X> {
    block_engine: BlockEngine<EcbEncryptorProcessor<T>, X>
}

impl <T: BlockEncryptor, X: PaddingProcessor> EcbEncryptor<T, X> {
    /// Create a new ECB encryption mode object
    pub fn new(algo: T, padding: X) -> EcbEncryptor<T, EncPadding<X>> {
        let block_size = algo.block_size();
        let processor = EcbEncryptorProcessor {
            algo: algo
        };
        EcbEncryptor {
            block_engine: BlockEngine::new(processor, EncPadding::wrap(padding), block_size)
        }
    }
    pub fn reset(&mut self) {
        self.block_engine.reset();
    }
}

impl <T: BlockEncryptor, X: PaddingProcessor> Encryptor for EcbEncryptor<T, X> {
    fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, eof: bool)
            -> Result<BufferResult, SymmetricCipherError> {
        self.block_engine.process(input, output, eof)
    }
}

struct EcbDecryptorProcessor<T> {
    algo: T
}

impl <T: BlockDecryptor> BlockProcessor for EcbDecryptorProcessor<T> {
    fn process_block(&mut self, _: &[u8], _: &[u8], input: &[u8], output: &mut [u8]) {
        self.algo.decrypt_block(input, output);
    }
}

/// ECB Decryption mode
pub struct EcbDecryptor<T, X> {
    block_engine: BlockEngine<EcbDecryptorProcessor<T>, X>
}

impl <T: BlockDecryptor, X: PaddingProcessor> EcbDecryptor<T, X> {
    /// Create a new ECB decryption mode object
    pub fn new(algo: T, padding: X) -> EcbDecryptor<T, DecPadding<X>> {
        let block_size = algo.block_size();
        let processor = EcbDecryptorProcessor {
            algo: algo
        };
        EcbDecryptor {
            block_engine: BlockEngine::new(processor, DecPadding::wrap(padding), block_size)
        }
    }
    pub fn reset(&mut self) {
        self.block_engine.reset();
    }
}

impl <T: BlockDecryptor, X: PaddingProcessor> Decryptor for EcbDecryptor<T, X> {
    fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, eof: bool)
            -> Result<BufferResult, SymmetricCipherError> {
        self.block_engine.process(input, output, eof)
    }
}

struct CbcEncryptorProcessor<T> {
    algo: T,
    temp: Vec<u8>
}

impl <T: BlockEncryptor> BlockProcessor for CbcEncryptorProcessor<T> {
    fn process_block(&mut self, _: &[u8], out_hist: &[u8], input: &[u8], output: &mut [u8]) {
        for ((&x, &y), o) in input.iter().zip(out_hist.iter()).zip(self.temp.iter_mut()) {
            *o = x ^ y;
        }
        self.algo.encrypt_block(&self.temp[..], output);
    }
}

/// CBC encryption mode
pub struct CbcEncryptor<T, X> {
    block_engine: BlockEngine<CbcEncryptorProcessor<T>, X>
}

impl <T: BlockEncryptor, X: PaddingProcessor> CbcEncryptor<T, X> {
    /// Create a new CBC encryption mode object
    pub fn new(algo: T, padding: X, iv: Vec<u8>) -> CbcEncryptor<T, EncPadding<X>> {
        let block_size = algo.block_size();
        let processor = CbcEncryptorProcessor {
            algo: algo,
            temp: repeat(0).take(block_size).collect()
        };
        CbcEncryptor {
            block_engine: BlockEngine::new_with_history(
                processor,
                EncPadding::wrap(padding),
                block_size,
                Vec::new(),
                iv)
        }
    }
    pub fn reset(&mut self, iv: &[u8]) {
        self.block_engine.reset_with_history(&[], iv);
    }
}

impl <T: BlockEncryptor, X: PaddingProcessor> Encryptor for CbcEncryptor<T, X> {
    fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, eof: bool)
            -> Result<BufferResult, SymmetricCipherError> {
        self.block_engine.process(input, output, eof)
    }
}

struct CbcDecryptorProcessor<T> {
    algo: T,
    temp: Vec<u8>
}

impl <T: BlockDecryptor> BlockProcessor for CbcDecryptorProcessor<T> {
    fn process_block(&mut self, in_hist: &[u8], _: &[u8], input: &[u8], output: &mut [u8]) {
        self.algo.decrypt_block(input, &mut self.temp);
        for ((&x, &y), o) in self.temp.iter().zip(in_hist.iter()).zip(output.iter_mut()) {
            *o = x ^ y;
        }
    }
}

/// CBC decryption mode
pub struct CbcDecryptor<T, X> {
    block_engine: BlockEngine<CbcDecryptorProcessor<T>, X>
}

impl <T: BlockDecryptor, X: PaddingProcessor> CbcDecryptor<T, X> {
    /// Create a new CBC decryption mode object
    pub fn new(algo: T, padding: X, iv: Vec<u8>) -> CbcDecryptor<T, DecPadding<X>> {
        let block_size = algo.block_size();
        let processor = CbcDecryptorProcessor {
            algo: algo,
            temp: repeat(0).take(block_size).collect()
        };
        CbcDecryptor {
            block_engine: BlockEngine::new_with_history(
                processor,
                DecPadding::wrap(padding),
                block_size,
                iv,
                Vec::new())
        }
    }
    pub fn reset(&mut self, iv: &[u8]) {
        self.block_engine.reset_with_history(iv, &[]);
    }
}

impl <T: BlockDecryptor, X: PaddingProcessor> Decryptor for CbcDecryptor<T, X> {
    fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, eof: bool)
            -> Result<BufferResult, SymmetricCipherError> {
        self.block_engine.process(input, output, eof)
    }
}

fn add_ctr(ctr: &mut [u8], mut ammount: u8) {
    for i in ctr.iter_mut().rev() {
        let prev = *i;
        *i = i.wrapping_add(ammount);
        if *i >= prev {
            break;
        }
        ammount = 1;
    }
}

/// CTR Mode
pub struct CtrMode<A> {
    algo: A,
    ctr: Vec<u8>,
    bytes: OwnedReadBuffer
}

impl <A: BlockEncryptor> CtrMode<A> {
    /// Create a new CTR object
    pub fn new(algo: A, ctr: Vec<u8>) -> CtrMode<A> {
        let block_size = algo.block_size();
        CtrMode {
            algo: algo,
            ctr: ctr,
            bytes: OwnedReadBuffer::new_with_len(repeat(0).take(block_size).collect(), 0)
        }
    }
    pub fn reset(&mut self, ctr: &[u8]) {
        cryptoutil::copy_memory(ctr, &mut self.ctr);
        self.bytes.reset();
    }
    fn process(&mut self, input: &[u8], output: &mut [u8]) {
        assert!(input.len() == output.len());
        let len = input.len();
        let mut i = 0;
        while i < len {
            if self.bytes.is_empty() {
                let mut wb = self.bytes.borrow_write_buffer();
                self.algo.encrypt_block(&self.ctr[..], wb.take_remaining());
                add_ctr(&mut self.ctr, 1);
            }
            let count = cmp::min(self.bytes.remaining(), len - i);
            let bytes_it = self.bytes.take_next(count).iter();
            let in_it = input[i..].iter();
            let out_it = output[i..].iter_mut();
            for ((&x, &y), o) in bytes_it.zip(in_it).zip(out_it) {
                *o = x ^ y;
            }
            i += count;
        }
    }
}

impl <A: BlockEncryptor> SynchronousStreamCipher for CtrMode<A> {
    fn process(&mut self, input: &[u8], output: &mut [u8]) {
        self.process(input, output);
    }
}

impl <A: BlockEncryptor> Encryptor for CtrMode<A> {
    fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
            -> Result<BufferResult, SymmetricCipherError> {
        symm_enc_or_dec(self, input, output)
    }
}

impl <A: BlockEncryptor> Decryptor for CtrMode<A> {
    fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
            -> Result<BufferResult, SymmetricCipherError> {
        symm_enc_or_dec(self, input, output)
    }
}

/// CTR Mode that operates on 8 blocks at a time
pub struct CtrModeX8<A> {
    algo: A,
    ctr_x8: Vec<u8>,
    bytes: OwnedReadBuffer
}

fn construct_ctr_x8(in_ctr: &[u8], out_ctr_x8: &mut [u8]) {
    for (i, ctr_i) in out_ctr_x8.chunks_mut(in_ctr.len()).enumerate() {
        cryptoutil::copy_memory(in_ctr, ctr_i);
        add_ctr(ctr_i, i as u8);
    }
}

impl <A: BlockEncryptorX8> CtrModeX8<A> {
    /// Create a new CTR object that operates on 8 blocks at a time
    pub fn new(algo: A, ctr: &[u8]) -> CtrModeX8<A> {
        let block_size = algo.block_size();
        let mut ctr_x8: Vec<u8> = repeat(0).take(block_size * 8).collect();
        construct_ctr_x8(ctr, &mut ctr_x8);
        CtrModeX8 {
            algo: algo,
            ctr_x8: ctr_x8,
            bytes: OwnedReadBuffer::new_with_len(repeat(0).take(block_size * 8).collect(), 0)
        }
    }
    pub fn reset(&mut self, ctr: &[u8]) {
        construct_ctr_x8(ctr, &mut self.ctr_x8);
        self.bytes.reset();
    }
    fn process(&mut self, input: &[u8], output: &mut [u8]) {
        // TODO - Can some of this be combined with regular CtrMode?
        assert!(input.len() == output.len());
        let len = input.len();
        let mut i = 0;
        while i < len {
            if self.bytes.is_empty() {
                let mut wb = self.bytes.borrow_write_buffer();
                self.algo.encrypt_block_x8(&self.ctr_x8[..], wb.take_remaining());
                for ctr_i in &mut self.ctr_x8.chunks_mut(self.algo.block_size()) {
                    add_ctr(ctr_i, 8);
                }
            }
            let count = cmp::min(self.bytes.remaining(), len - i);
            let bytes_it = self.bytes.take_next(count).iter();
            let in_it = input[i..].iter();
            let out_it = &mut output[i..];
            for ((&x, &y), o) in bytes_it.zip(in_it).zip(out_it.iter_mut()) {
                *o = x ^ y;
            }
            i += count;
        }
    }
}

impl <A: BlockEncryptorX8> SynchronousStreamCipher for CtrModeX8<A> {
    fn process(&mut self, input: &[u8], output: &mut [u8]) {
        self.process(input, output);
    }
}

impl <A: BlockEncryptorX8> Encryptor for CtrModeX8<A> {
    fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
            -> Result<BufferResult, SymmetricCipherError> {
        symm_enc_or_dec(self, input, output)
    }
}

impl <A: BlockEncryptorX8> Decryptor for CtrModeX8<A> {
    fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
            -> Result<BufferResult, SymmetricCipherError> {
        symm_enc_or_dec(self, input, output)
    }
}

#[cfg(test)]
mod test {
    use std::iter::repeat;

    use aessafe;
    use blockmodes::{EcbEncryptor, EcbDecryptor, CbcEncryptor, CbcDecryptor, CtrMode, CtrModeX8,
        NoPadding, PkcsPadding};
    use buffer::{ReadBuffer, WriteBuffer, RefReadBuffer, RefWriteBuffer, BufferResult};
    use buffer::BufferResult::{BufferUnderflow, BufferOverflow};
    use symmetriccipher::{Encryptor, Decryptor};
    use symmetriccipher::SymmetricCipherError::{self, InvalidLength, InvalidPadding};

    use std::cmp;

    trait CipherTest {
        fn get_plain<'a>(&'a self) -> &'a [u8];
        fn get_cipher<'a>(&'a self) -> &'a [u8];
    }

    struct EcbTest {
        key: Vec<u8>,
        plain: Vec<u8>,
        cipher: Vec<u8>
    }

    impl CipherTest for EcbTest {
        fn get_plain<'a>(&'a self) -> &'a [u8] {
            &self.plain[..]
        }
        fn get_cipher<'a>(&'a self) -> &'a [u8] {
            &self.cipher[..]
        }
    }

    struct CbcTest {
        key: Vec<u8>,
        iv: Vec<u8>,
        plain: Vec<u8>,
        cipher: Vec<u8>
    }

    impl CipherTest for CbcTest {
        fn get_plain<'a>(&'a self) -> &'a [u8] {
            &self.plain[..]
        }
        fn get_cipher<'a>(&'a self) -> &'a [u8] {
            &self.cipher[..]
        }
    }

    struct CtrTest {
        key: Vec<u8>,
        ctr: Vec<u8>,
        plain: Vec<u8>,
        cipher: Vec<u8>
    }

    impl CipherTest for CtrTest {
        fn get_plain<'a>(&'a self) -> &'a [u8] {
            &self.plain[..]
        }
        fn get_cipher<'a>(&'a self) -> &'a [u8] {
            &self.cipher[..]
        }
    }

    fn aes_ecb_no_padding_tests() -> Vec<EcbTest> {
        vec![
            EcbTest {
                key: repeat(0).take(16).collect(),
                plain: repeat(0).take(32).collect(),
                cipher: vec![
                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e ]
            }
        ]
    }

    fn aes_ecb_pkcs_padding_tests() -> Vec<EcbTest> {
        vec![
            EcbTest {
                key: repeat(0).take(16).collect(),
                plain: repeat(0).take(32).collect(),
                cipher: vec![
                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
                    0x01, 0x43, 0xdb, 0x63, 0xee, 0x66, 0xb0, 0xcd,
                    0xff, 0x9f, 0x69, 0x91, 0x76, 0x80, 0x15, 0x1e ]
            },
            EcbTest {
                key: repeat(0).take(16).collect(),
                plain: repeat(0).take(33).collect(),
                cipher: vec![
                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
                    0x7a, 0xdc, 0x99, 0xb2, 0x9e, 0x82, 0xb1, 0xb2,
                    0xb0, 0xa6, 0x5a, 0x38, 0xbc, 0x57, 0x8a, 0x01 ]
            }
        ]
    }

    fn aes_cbc_no_padding_tests() -> Vec<CbcTest> {
        vec![
            CbcTest {
                key: repeat(1).take(16).collect(),
                iv: repeat(3).take(16).collect(),
                plain: repeat(2).take(32).collect(),
                cipher: vec![
                    0x5e, 0x77, 0xe5, 0x9f, 0x8f, 0x85, 0x94, 0x34,
                    0x89, 0xa2, 0x41, 0x49, 0xc7, 0x5f, 0x4e, 0xc9,
                    0xe0, 0x9a, 0x77, 0x36, 0xfb, 0xc8, 0xb2, 0xdc,
                    0xb3, 0xfb, 0x9f, 0xc0, 0x31, 0x4c, 0xb0, 0xb1 ]
            }
        ]
    }

    fn aes_cbc_pkcs_padding_tests() -> Vec<CbcTest> {
        vec![
            CbcTest {
                key: repeat(1).take(16).collect(),
                iv: repeat(3).take(16).collect(),
                plain: repeat(2).take(32).collect(),
                cipher: vec![
                    0x5e, 0x77, 0xe5, 0x9f, 0x8f, 0x85, 0x94, 0x34,
                    0x89, 0xa2, 0x41, 0x49, 0xc7, 0x5f, 0x4e, 0xc9,
                    0xe0, 0x9a, 0x77, 0x36, 0xfb, 0xc8, 0xb2, 0xdc,
                    0xb3, 0xfb, 0x9f, 0xc0, 0x31, 0x4c, 0xb0, 0xb1,
                    0xa4, 0xc2, 0xe4, 0x62, 0xef, 0x7a, 0xe3, 0x7e,
                    0xef, 0x88, 0xf3, 0x27, 0xbd, 0x9c, 0xc8, 0x4d ]
            },
            CbcTest {
                key: repeat(1).take(16).collect(),
                iv: repeat(3).take(16).collect(),
                plain: repeat(2).take(33).collect(),
                cipher: vec![
                    0x5e, 0x77, 0xe5, 0x9f, 0x8f, 0x85, 0x94, 0x34,
                    0x89, 0xa2, 0x41, 0x49, 0xc7, 0x5f, 0x4e, 0xc9,
                    0xe0, 0x9a, 0x77, 0x36, 0xfb, 0xc8, 0xb2, 0xdc,
                    0xb3, 0xfb, 0x9f, 0xc0, 0x31, 0x4c, 0xb0, 0xb1,
                    0x6c, 0x47, 0xcd, 0xec, 0xae, 0xbb, 0x1a, 0x65,
                    0x04, 0xd2, 0x32, 0x23, 0xa6, 0x8d, 0x4a, 0x65 ]
            }
        ]
    }

    fn aes_ctr_tests() -> Vec<CtrTest> {
        vec![
            CtrTest {
                key: repeat(1).take(16).collect(),
                ctr: repeat(3).take(16).collect(),
                plain: repeat(2).take(33).collect(),
                cipher: vec![
                    0x64, 0x3e, 0x05, 0x19, 0x79, 0x78, 0xd7, 0x45,
                    0xa9, 0x10, 0x5f, 0xd8, 0x4c, 0xd7, 0xe6, 0xb1,
                    0x5f, 0x66, 0xc6, 0x17, 0x4b, 0x25, 0xea, 0x24,
                    0xe6, 0xf9, 0x19, 0x09, 0xb7, 0xdd, 0x84, 0xfb,
                    0x86 ]
            }
        ]
    }

    // Test the mode by encrypting all of the data at once
    fn run_full_test<T: CipherTest, E: Encryptor, D: Decryptor>(
            test: &T,
            enc: &mut E,
            dec: &mut D) {
        let mut cipher_out: Vec<u8> = repeat(0).take(test.get_cipher().len()).collect();
        {
            let mut buff_in = RefReadBuffer::new(test.get_plain());
            let mut buff_out = RefWriteBuffer::new(&mut cipher_out);
            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
                Ok(BufferUnderflow) => {}
                Ok(BufferOverflow) => panic!("Encryption not completed"),
                Err(_) => panic!("Error"),
            }
        }
        assert!(test.get_cipher() == &cipher_out[..]);

        let mut plain_out: Vec<u8> = repeat(0).take(test.get_plain().len()).collect();
        {
            let mut buff_in = RefReadBuffer::new(test.get_cipher());
            let mut buff_out = RefWriteBuffer::new(&mut plain_out);
            match dec.decrypt(&mut buff_in, &mut buff_out, true) {
                Ok(BufferUnderflow) => {}
                Ok(BufferOverflow) => panic!("Decryption not completed"),
                Err(_) => panic!("Error"),
            }
        }
        assert!(test.get_plain() == &plain_out[..]);
    }

    /// Run and encryption or decryption operation, passing in variable sized input and output
    /// buffers.
    ///
    /// # Arguments
    /// * input - The complete input vector
    /// * output - The complete output vector
    /// * op - A closure that runs either an encryption or decryption operation
    /// * next_in_len - A closure that returns the length to use for the next input buffer; If the
    ///                 returned value is not in a valid range, it will be fixed up by this
    ///                 function.
    /// * next_out_len - A closure that returns the length to use for the next output buffer; If the
    ///                  returned value is not in a valid range, it will be fixed up by this
    ///                  function.
    /// * immediate_eof - Whether eof should be set immediately upon running out of input or if eof
    ///                   should be passed only after all input has been consumed.
    fn run_inc<OpFunc, NextInFunc, NextOutFunc>(
            input: &[u8],
            output: &mut [u8],
            mut op: OpFunc,
            mut next_in_len: NextInFunc,
            mut next_out_len: NextOutFunc,
            immediate_eof: bool)
            where
                OpFunc: FnMut(&mut RefReadBuffer, &mut RefWriteBuffer, bool) ->
                    Result<BufferResult, SymmetricCipherError>,
                NextInFunc: FnMut() -> usize,
                NextOutFunc: FnMut() -> usize {
        use std::cell::Cell;

        let in_len = input.len();
        let out_len = output.len();

        let mut state: Result<BufferResult, SymmetricCipherError> = Ok(BufferUnderflow);
        let mut in_pos: usize = 0;
        let mut out_pos: usize = 0;
        let eof = Cell::new(false);

        let mut in_end = |in_pos: usize, primary: bool| {
            if eof.get() {
                return in_len;
            }
            let x = next_in_len();
            if x >= in_len && immediate_eof {
                eof.set(true);
            }
            cmp::min(in_len, in_pos + cmp::max(x, if primary { 1 } else { 0 }))
        };

        let mut out_end = |out_pos: usize| {
            let x = next_out_len();
            cmp::min(out_len, out_pos + cmp::max(x, 1))
        };

        loop {
            match state {
                Ok(BufferUnderflow) => {
                    if in_pos == input.len() {
                        break;
                    }
                    let mut tmp_in = RefReadBuffer::new(&input[in_pos..in_end(in_pos, true)]);
                    let out_end = out_end(out_pos);
                    let mut tmp_out = RefWriteBuffer::new(&mut output[out_pos..out_end]);
                    state = op(&mut tmp_in, &mut tmp_out, eof.get());
                    match state {
                        Ok(BufferUnderflow) => assert!(tmp_in.is_empty()),
                        _ => {}
                    }
                    in_pos += tmp_in.position();
                    out_pos += tmp_out.position();
                }
                Ok(BufferOverflow) => {
                    let mut tmp_in = RefReadBuffer::new(&input[in_pos..in_end(in_pos, false)]);
                    let out_end = out_end(out_pos);
                    let mut tmp_out = RefWriteBuffer::new(&mut output[out_pos..out_end]);
                    state = op(&mut tmp_in, &mut tmp_out, eof.get());
                    match state {
                        Ok(BufferOverflow) => assert!(tmp_out.is_full()),
                        _ => {}
                    }
                    in_pos += tmp_in.position();
                    out_pos += tmp_out.position();
                }
                Err(InvalidPadding) => panic!("Invalid Padding"),
                Err(InvalidLength) => panic!("Invalid Length")
            }
        }

        if !eof.get() {
            eof.set(true);
            let mut tmp_out = RefWriteBuffer::new(&mut output[out_pos..out_end(out_pos)]);
            state = op(&mut RefReadBuffer::new(&[]), &mut tmp_out, eof.get());
            out_pos += tmp_out.position();
        }

        loop {
            match state {
                Ok(BufferUnderflow) => {
                    break;
                }
                Ok(BufferOverflow) => {
                    let out_end = out_end(out_pos);
                    let mut tmp_out = RefWriteBuffer::new(&mut output[out_pos..out_end]);
                    state = op(&mut RefReadBuffer::new(&[]), &mut tmp_out, eof.get());
                    assert!(tmp_out.is_full());
                    out_pos += tmp_out.position();
                }
                Err(InvalidPadding) => panic!("Invalid Padding"),
                Err(InvalidLength) => panic!("Invalid Length")
            }
        }
    }

    fn run_inc1_test<T: CipherTest, E: Encryptor, D: Decryptor>(
            test: &T,
            enc: &mut E,
            dec: &mut D) {
        let mut cipher_out: Vec<u8> = repeat(0).take(test.get_cipher().len()).collect();
        run_inc(
            test.get_plain(),
            &mut cipher_out,
            |in_buff: &mut RefReadBuffer, out_buff: &mut RefWriteBuffer, eof: bool| {
                enc.encrypt(in_buff, out_buff, eof)
            },
            || { 0 },
            || { 1 },
            false);
        assert!(test.get_cipher() == &cipher_out[..]);

        let mut plain_out: Vec<u8> = repeat(0).take(test.get_plain().len()).collect();
        run_inc(
            test.get_cipher(),
            &mut plain_out,
            |in_buff: &mut RefReadBuffer, out_buff: &mut RefWriteBuffer, eof: bool| {
                dec.decrypt(in_buff, out_buff, eof)
            },
            || { 0 },
            || { 1 },
            false);
        assert!(test.get_plain() == &plain_out[..]);
    }

    fn run_rand_test<T, E, D, NewEncFunc, NewDecFunc>(
            test: &T,
            mut new_enc: NewEncFunc,
            mut new_dec: NewDecFunc)
            where
                T: CipherTest,
                E: Encryptor,
                D: Decryptor,
                NewEncFunc: FnMut() -> E,
                NewDecFunc: FnMut() -> D{
        use rand;
        use rand::Rng;

        let tmp : &[_] = &[1, 2, 3, 4];
        let mut rng1: rand::StdRng = rand::SeedableRng::from_seed(tmp);
        let mut rng2: rand::StdRng = rand::SeedableRng::from_seed(tmp);
        let mut rng3: rand::StdRng = rand::SeedableRng::from_seed(tmp);
        let max_size = cmp::max(test.get_plain().len(), test.get_cipher().len());

        let mut r1 = || {
            rng1.gen_range(0, max_size)
        };
        let mut r2 = || {
            rng2.gen_range(0, max_size)
        };

        for _ in 0..1000 {
            let mut enc = new_enc();
            let mut dec = new_dec();

            let mut cipher_out: Vec<u8> = repeat(0).take(test.get_cipher().len()).collect();
            run_inc(
                test.get_plain(),
                &mut cipher_out,
                |in_buff: &mut RefReadBuffer, out_buff: &mut RefWriteBuffer, eof: bool| {
                    enc.encrypt(in_buff, out_buff, eof)
                },
                || { r1() },
                || { r2() },
                rng3.gen());
            assert!(test.get_cipher() == &cipher_out[..]);

            let mut plain_out: Vec<u8> = repeat(0).take(test.get_plain().len()).collect();
            run_inc(
                test.get_cipher(),
                &mut plain_out,
                |in_buff: &mut RefReadBuffer, out_buff: &mut RefWriteBuffer, eof: bool| {
                    dec.decrypt(in_buff, out_buff, eof)
                },
                || { r1() },
                || { r2() },
                rng3.gen());
            assert!(test.get_plain() == &plain_out[..]);
        }
    }

    fn run_test<T, E, D, NewEncFunc, NewDecFunc>(
            test: &T,
            mut new_enc: NewEncFunc,
            mut new_dec: NewDecFunc)
            where
                T: CipherTest,
                E: Encryptor,
                D: Decryptor,
                NewEncFunc: FnMut() -> E,
                NewDecFunc: FnMut() -> D{
        run_full_test(test, &mut new_enc(), &mut new_dec());
        run_inc1_test(test, &mut new_enc(), &mut new_dec());
        run_rand_test(test, new_enc, new_dec);
    }

    #[test]
    fn aes_ecb_no_padding() {
        let tests = aes_ecb_no_padding_tests();
        for test in tests.iter() {
            run_test(
                test,
                || {
                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
                    EcbEncryptor::new(aes_enc, NoPadding)
                },
                || {
                    let aes_dec = aessafe::AesSafe128Decryptor::new(&test.key[..]);
                    EcbDecryptor::new(aes_dec, NoPadding)
                });
        }
    }

    #[test]
    fn aes_ecb_pkcs_padding() {
        let tests = aes_ecb_pkcs_padding_tests();
        for test in tests.iter() {
            run_test(
                test,
                || {
                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
                    EcbEncryptor::new(aes_enc, PkcsPadding)
                },
                || {
                    let aes_dec = aessafe::AesSafe128Decryptor::new(&test.key[..]);
                    EcbDecryptor::new(aes_dec, PkcsPadding)
                });
        }
    }

    #[test]
    fn aes_cbc_no_padding() {
        let tests = aes_cbc_no_padding_tests();
        for test in tests.iter() {
            run_test(
                test,
                || {
                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
                    CbcEncryptor::new(aes_enc, NoPadding, test.iv.clone())
                },
                || {
                    let aes_dec = aessafe::AesSafe128Decryptor::new(&test.key[..]);
                    CbcDecryptor::new(aes_dec, NoPadding, test.iv.clone())
                });
        }
    }

    #[test]
    fn aes_cbc_pkcs_padding() {
        let tests = aes_cbc_pkcs_padding_tests();
        for test in tests.iter() {
            run_test(
                test,
                || {
                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
                    CbcEncryptor::new(aes_enc, PkcsPadding, test.iv.clone())
                },
                || {
                    let aes_dec = aessafe::AesSafe128Decryptor::new(&test.key[..]);
                    CbcDecryptor::new(aes_dec, PkcsPadding, test.iv.clone())
                });
        }
    }

    #[test]
    fn aes_ctr() {
        let tests = aes_ctr_tests();
        for test in tests.iter() {
            run_test(
                test,
                || {
                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
                    CtrMode::new(aes_enc, test.ctr.clone())
                },
                || {
                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
                    CtrMode::new(aes_enc, test.ctr.clone())
                });
        }
    }

    #[test]
    fn aes_ctr_x8() {
        let tests = aes_ctr_tests();
        for test in tests.iter() {
            run_test(
                test,
                || {
                    let aes_enc = aessafe::AesSafe128EncryptorX8::new(&test.key[..]);
                    CtrModeX8::new(aes_enc, &test.ctr[..])
                },
                || {
                    let aes_enc = aessafe::AesSafe128EncryptorX8::new(&test.key[..]);
                    CtrModeX8::new(aes_enc, &test.ctr[..])
                });
        }
    }
}

#[cfg(all(test, feature = "with-bench"))]
mod bench {
    use aessafe;
    use blockmodes::{EcbEncryptor, CbcEncryptor, CtrMode, CtrModeX8,
        NoPadding, PkcsPadding};
    use buffer::{ReadBuffer, WriteBuffer, RefReadBuffer, RefWriteBuffer};
    use buffer::BufferResult::{BufferUnderflow, BufferOverflow};
    use symmetriccipher::{Encryptor};

    use test::Bencher;

    #[bench]
    pub fn aes_ecb_no_padding_bench(bh: &mut Bencher) {
        let key = [1u8; 16];
        let plain = [3u8; 512];
        let mut cipher = [3u8; 528];

        let aes_enc = aessafe::AesSafe128Encryptor::new(&key);
        let mut enc = EcbEncryptor::new(aes_enc, NoPadding);

        bh.iter( || {
            enc.reset();

            let mut buff_in = RefReadBuffer::new(&plain);
            let mut buff_out = RefWriteBuffer::new(&mut cipher);

            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
                Ok(BufferUnderflow) => {}
                Ok(BufferOverflow) => panic!("Encryption not completed"),
                Err(_) => panic!("Error"),
            }
        });

        bh.bytes = (plain.len()) as u64;
    }

    #[bench]
    pub fn aes_cbc_pkcs_padding_bench(bh: &mut Bencher) {
        let key = [1u8; 16];
        let iv = [2u8; 16];
        let plain = [3u8; 512];
        let mut cipher = [3u8; 528];

        let aes_enc = aessafe::AesSafe128Encryptor::new(&key);
        let mut enc = CbcEncryptor::new(aes_enc, PkcsPadding, iv.to_vec());

        bh.iter( || {
            enc.reset(&iv);

            let mut buff_in = RefReadBuffer::new(&plain);
            let mut buff_out = RefWriteBuffer::new(&mut cipher);

            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
                Ok(BufferUnderflow) => {}
                Ok(BufferOverflow) => panic!("Encryption not completed"),
                Err(_) => panic!("Error"),
            }
        });

        bh.bytes = (plain.len()) as u64;
    }

    #[bench]
    pub fn aes_ctr_bench(bh: &mut Bencher) {
        let key = [1u8; 16];
        let ctr = [2u8; 16];
        let plain = [3u8; 512];
        let mut cipher = [3u8; 528];

        let aes_enc = aessafe::AesSafe128Encryptor::new(&key);
        let mut enc = CtrMode::new(aes_enc, ctr.to_vec());

        bh.iter( || {
            enc.reset(&ctr);

            let mut buff_in = RefReadBuffer::new(&plain);
            let mut buff_out = RefWriteBuffer::new(&mut cipher);

            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
                Ok(BufferUnderflow) => {}
                Ok(BufferOverflow) => panic!("Encryption not completed"),
                Err(_) => panic!("Error"),
            }
        });

        bh.bytes = (plain.len()) as u64;
    }

    #[bench]
    pub fn aes_ctr_x8_bench(bh: &mut Bencher) {
        let key = [1u8; 16];
        let ctr = [2u8; 16];
        let plain = [3u8; 512];
        let mut cipher = [3u8; 528];

        let aes_enc = aessafe::AesSafe128EncryptorX8::new(&key);
        let mut enc = CtrModeX8::new(aes_enc, &ctr);

        bh.iter( || {
            enc.reset(&ctr);

            let mut buff_in = RefReadBuffer::new(&plain);
            let mut buff_out = RefWriteBuffer::new(&mut cipher);

            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
                Ok(BufferUnderflow) => {}
                Ok(BufferOverflow) => panic!("Encryption not completed"),
                Err(_) => panic!("Error"),
            }
        });

        bh.bytes = (plain.len()) as u64;
    }
}
