crypto/
blockmodes.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7// TODO - Optimize the XORs
8// TODO - Maybe use macros to specialize BlockEngine for encryption or decryption?
9// TODO - I think padding could be done better. Maybe macros for BlockEngine would help this too.
10
11use std::cmp;
12use std::iter::repeat;
13
14use buffer::{ReadBuffer, WriteBuffer, OwnedReadBuffer, OwnedWriteBuffer, BufferResult,
15    RefReadBuffer, RefWriteBuffer};
16use buffer::BufferResult::{BufferUnderflow, BufferOverflow};
17use cryptoutil::{self, symm_enc_or_dec};
18use symmetriccipher::{BlockEncryptor, BlockEncryptorX8, Encryptor, BlockDecryptor, Decryptor,
19    SynchronousStreamCipher, SymmetricCipherError};
20use symmetriccipher::SymmetricCipherError::{InvalidPadding, InvalidLength};
21
22/// The BlockProcessor trait is used to implement modes that require processing complete blocks of
23/// data. The methods of this trait are called by the BlockEngine which is in charge of properly
24/// buffering input data.
25trait BlockProcessor {
26    /// Process a block of data. The in_hist and out_hist parameters represent the input and output
27    /// when the last block was processed. These values are necessary for certain modes.
28    fn process_block(&mut self, in_hist: &[u8], out_hist: &[u8], input: &[u8], output: &mut [u8]);
29}
30
31/// A PaddingProcessor handles adding or removing padding
32pub trait PaddingProcessor {
33    /// Add padding to the last block of input data
34    /// If the mode can't handle a non-full block, it signals that error by simply leaving the block
35    /// as it is which will be detected as an InvalidLength error.
36    fn pad_input<W: WriteBuffer>(&mut self, input_buffer: &mut W);
37
38    /// Remove padding from the last block of output data
39    /// If false is returned, the processing fails
40    fn strip_output<R: ReadBuffer>(&mut self, output_buffer: &mut R) -> bool;
41}
42
43/// The BlockEngine is implemented as a state machine with the following states. See comments in the
44/// BlockEngine code for more information on the states.
45#[derive(Clone, Copy)]
46enum BlockEngineState {
47    FastMode,
48    NeedInput,
49    NeedOutput,
50    LastInput,
51    LastInput2,
52    Finished,
53    Error(SymmetricCipherError)
54}
55
56/// BlockEngine buffers input and output data and handles sending complete block of data to the
57/// Processor object. Additionally, BlockEngine handles logic necessary to add or remove padding by
58/// calling the appropriate methods on the Processor object.
59struct BlockEngine<P, X> {
60    /// The block sized expected by the Processor
61    block_size: usize,
62
63    /// in_hist and out_hist keep track of data that was input to and output from the last
64    /// invocation of the process_block() method of the Processor. Depending on the mode, these may
65    /// be empty vectors if history is not needed.
66    in_hist: Vec<u8>,
67    out_hist: Vec<u8>,
68
69    /// If some input data is supplied, but not a complete blocks worth, it is stored in this buffer
70    /// until enough arrives that it can be passed to the process_block() method of the Processor.
71    in_scratch: OwnedWriteBuffer,
72
73    /// If input data is processed but there isn't enough space in the output buffer to store it,
74    /// it is written into out_write_scratch. OwnedWriteBuffer's may be converted into
75    /// OwnedReaderBuffers without re-allocating, so, after being written, out_write_scratch is
76    /// turned into out_read_scratch. After that, if is written to the output as more output becomes
77    /// available. The main point is - only out_write_scratch or out_read_scratch contains a value
78    /// at any given time; never both.
79    out_write_scratch: Option<OwnedWriteBuffer>,
80    out_read_scratch: Option<OwnedReadBuffer>,
81
82    /// The processor that implements the particular block mode.
83    processor: P,
84
85    /// The padding processor
86    padding: X,
87
88    /// The current state of the operation.
89    state: BlockEngineState
90}
91
92fn update_history(in_hist: &mut [u8], out_hist: &mut [u8], last_in: &[u8], last_out: &[u8]) {
93    let in_hist_len = in_hist.len();
94    if in_hist_len > 0 {
95        cryptoutil::copy_memory(
96            &last_in[last_in.len() - in_hist_len..],
97            in_hist);
98    }
99    let out_hist_len = out_hist.len();
100    if out_hist_len > 0 {
101        cryptoutil::copy_memory(
102            &last_out[last_out.len() - out_hist_len..],
103            out_hist);
104    }
105}
106
107impl <P: BlockProcessor, X: PaddingProcessor> BlockEngine<P, X> {
108    /// Create a new BlockProcessor instance with the given processor and block_size. No history
109    /// will be saved.
110    fn new(processor: P, padding: X, block_size: usize) -> BlockEngine<P, X> {
111        BlockEngine {
112            block_size: block_size,
113            in_hist: Vec::new(),
114            out_hist: Vec::new(),
115            in_scratch: OwnedWriteBuffer::new(repeat(0).take(block_size).collect()),
116            out_write_scratch: Some(OwnedWriteBuffer::new(repeat(0).take(block_size).collect())),
117            out_read_scratch: None,
118            processor: processor,
119            padding: padding,
120            state: BlockEngineState::FastMode
121        }
122    }
123
124    /// Create a new BlockProcessor instance with the given processor, block_size, and initial input
125    /// and output history.
126    fn new_with_history(
127            processor: P,
128            padding: X,
129            block_size: usize,
130            in_hist: Vec<u8>,
131            out_hist: Vec<u8>) -> BlockEngine<P, X> {
132        BlockEngine {
133            in_hist: in_hist,
134            out_hist: out_hist,
135            ..BlockEngine::new(processor, padding, block_size)
136        }
137    }
138
139    /// This implements the FastMode state. Ideally, the encryption or decryption operation should
140    /// do the bulk of its work in FastMode. Significantly, FastMode avoids doing copies as much as
141    /// possible. The FastMode state does not handle the final block of data.
142    fn fast_mode<R: ReadBuffer, W: WriteBuffer>(
143            &mut self,
144            input: &mut R,
145            output: &mut W) -> BlockEngineState {
146        fn has_next<R: ReadBuffer, W: WriteBuffer>(
147                input: &mut R,
148                output: &mut W,
149                block_size: usize) -> bool {
150            // Not the greater than - very important since this method must never process the last
151            // block.
152            let enough_input = input.remaining() > block_size;
153            let enough_output = output.remaining() >= block_size;
154            enough_input && enough_output
155        };
156        fn split_at<'a>(vec: &'a [u8], at: usize) -> (&'a [u8], &'a [u8]) {
157            (&vec[..at], &vec[at..])
158        }
159
160        // First block processing. We have to retrieve the history information from self.in_hist and
161        // self.out_hist.
162        if !has_next(input, output, self.block_size) {
163            if input.is_empty() {
164                return BlockEngineState::FastMode;
165            } else {
166                return BlockEngineState::NeedInput;
167            }
168        } else {
169            let next_in = input.take_next(self.block_size);
170            let next_out = output.take_next(self.block_size);
171            self.processor.process_block(
172                &self.in_hist[..],
173                &self.out_hist[..],
174                next_in,
175                next_out);
176        }
177
178        // Process all remaing blocks. We can pull the history out of the buffers without having to
179        // do any copies
180        let next_in_size = self.in_hist.len() + self.block_size;
181        let next_out_size = self.out_hist.len() + self.block_size;
182        while has_next(input, output, self.block_size) {
183            input.rewind(self.in_hist.len());
184            let (in_hist, next_in) = split_at(input.take_next(next_in_size), self.in_hist.len());
185            output.rewind(self.out_hist.len());
186            let (out_hist, next_out) = output.take_next(next_out_size).split_at_mut(
187                self.out_hist.len());
188            self.processor.process_block(
189                in_hist,
190                out_hist,
191                next_in,
192                next_out);
193        }
194
195        // Save the history and then transition to the next state
196        {
197            input.rewind(self.in_hist.len());
198            let last_in = input.take_next(self.in_hist.len());
199            output.rewind(self.out_hist.len());
200            let last_out = output.take_next(self.out_hist.len());
201            update_history(
202                &mut self.in_hist,
203                &mut self.out_hist,
204                last_in,
205                last_out);
206        }
207        if input.is_empty() {
208            BlockEngineState::FastMode
209        } else {
210            BlockEngineState::NeedInput
211        }
212    }
213
214    /// This method implements the BlockEngine state machine.
215    fn process<R: ReadBuffer, W: WriteBuffer>(
216            &mut self,
217            input: &mut R,
218            output: &mut W,
219            eof: bool) -> Result<BufferResult, SymmetricCipherError> {
220        // Process a block of data from in_scratch and write the result to out_write_scratch.
221        // Finally, convert out_write_scratch into out_read_scratch.
222        fn process_scratch<P: BlockProcessor, X: PaddingProcessor>(me: &mut BlockEngine<P, X>) {
223            let mut rin = me.in_scratch.take_read_buffer();
224            let mut wout = me.out_write_scratch.take().unwrap();
225
226            {
227                let next_in = rin.take_remaining();
228                let next_out = wout.take_remaining();
229                me.processor.process_block(
230                    &me.in_hist[..],
231                    &me.out_hist[..],
232                    next_in,
233                    next_out);
234                update_history(
235                    &mut me.in_hist,
236                    &mut me.out_hist,
237                    next_in,
238                    next_out);
239            }
240
241            let rb = wout.into_read_buffer();
242            me.out_read_scratch = Some(rb);
243        };
244
245        loop {
246            match self.state {
247                // FastMode tries to process as much data as possible while minimizing copies.
248                // FastMode doesn't make use of the scratch buffers and only updates the history
249                // just before exiting.
250                BlockEngineState::FastMode => {
251                    self.state = self.fast_mode(input, output);
252                    match self.state {
253                        BlockEngineState::FastMode => {
254                            // If FastMode completes but stays in the FastMode state, it means that
255                            // we've run out of input data.
256                            return Ok(BufferUnderflow);
257                        }
258                        _ => {}
259                    }
260                }
261
262                // The NeedInput mode is entered when there isn't enough data to run in FastMode
263                // anymore. Input data is buffered in in_scratch until there is a full block or eof
264                // occurs. IF eof doesn't occur, the data is processed and then we go to the
265                // NeedOutput state. Otherwise, we go to the LastInput state. This state always
266                // writes all available data into in_scratch before transitioning to the next state.
267                BlockEngineState::NeedInput => {
268                    input.push_to(&mut self.in_scratch);
269                    if !input.is_empty() {
270                        // !is_empty() guarantees two things - in_scratch is full and its not the
271                        // last block. This state must never process the last block.
272                        process_scratch(self);
273                        self.state = BlockEngineState::NeedOutput;
274                    } else {
275                        if eof {
276                            self.state = BlockEngineState::LastInput;
277                        } else {
278                            return Ok(BufferUnderflow);
279                        }
280                    }
281                }
282
283                // The NeedOutput state just writes buffered processed data to the output stream
284                // until all of it has been written.
285                BlockEngineState::NeedOutput => {
286                    let mut rout = self.out_read_scratch.take().unwrap();
287                    rout.push_to(output);
288                    if rout.is_empty() {
289                        self.out_write_scratch = Some(rout.into_write_buffer());
290                        self.state = BlockEngineState::FastMode;
291                    } else {
292                        self.out_read_scratch = Some(rout);
293                        return Ok(BufferOverflow);
294                    }
295                }
296
297                // None of the other states are allowed to process the last block of data since
298                // last block handling is a little tricky due to modes have special needs regarding
299                // padding. When the last block of data is detected, this state is transitioned to
300                // for handling.
301                BlockEngineState::LastInput => {
302                    // We we arrive in this state, we know that all input data that is going to be
303                    // supplied has been suplied and that that data has been written to in_scratch
304                    // by the NeedInput state. Furthermore, we know that one of three things must be
305                    // true about in_scratch:
306                    // 1) It is empty. This only occurs if the input is zero length. We can do last
307                    //    block processing by executing the pad_input() method of the processor
308                    //    which may either pad out to a full block or leave it empty, process the
309                    //    data if it was padded out to a full block, and then pass it to
310                    //    strip_output().
311                    // 2) It is partially filled. This will occur if the input data was not a
312                    //    multiple of the block size. Processing proceeds identically to case #1.
313                    // 3) It is full. This case occurs when the input data was a multiple of the
314                    //    block size. This case is a little trickier, since, depending on the mode,
315                    //    we might actually have 2 blocks worth of data to process - the last user
316                    //    supplied block (currently in in_scratch) and then another block that could
317                    //    be added as padding. Processing proceeds by first processing the data in
318                    //    in_scratch and writing it to out_scratch. Then, the now-empty in_scratch
319                    //    buffer is passed to pad_input() which may leave it empty or write a block
320                    //    of padding to it. If no padding is added, processing proceeds as in cases
321                    //    #1 and #2. However, if padding is added, now have data in in_scratch and
322                    //    also in out_scratch meaning that we can't immediately process the padding
323                    //    data since we have nowhere to put it. So, we transition to the LastInput2
324                    //    state which will first write out the last non-padding block, then process
325                    //    the padding block (in in_scratch) and write it to the now-empty
326                    //    out_scratch.
327                    if !self.in_scratch.is_full() {
328                        self.padding.pad_input(&mut self.in_scratch);
329                        if self.in_scratch.is_full() {
330                            process_scratch(self);
331                            if self.padding.strip_output(self.out_read_scratch.as_mut().unwrap()) {
332                                self.state = BlockEngineState::Finished;
333                            } else {
334                                self.state = BlockEngineState::Error(InvalidPadding);
335                            }
336                        } else if self.in_scratch.is_empty() {
337                            self.state = BlockEngineState::Finished;
338                        } else {
339                            self.state = BlockEngineState::Error(InvalidLength);
340                        }
341                    } else {
342                        process_scratch(self);
343                        self.padding.pad_input(&mut self.in_scratch);
344                        if self.in_scratch.is_full() {
345                            self.state = BlockEngineState::LastInput2;
346                        } else if self.in_scratch.is_empty() {
347                            if self.padding.strip_output(self.out_read_scratch.as_mut().unwrap()) {
348                                self.state = BlockEngineState::Finished;
349                            } else {
350                                self.state = BlockEngineState::Error(InvalidPadding);
351                            }
352                        } else {
353                            self.state = BlockEngineState::Error(InvalidLength);
354                        }
355                    }
356                }
357
358                // See the comments on LastInput for more details. This state handles final blocks
359                // of data in the case that the input was a multiple of the block size and the mode
360                // decided to add a full extra block of padding.
361                BlockEngineState::LastInput2 => {
362                    let mut rout = self.out_read_scratch.take().unwrap();
363                    rout.push_to(output);
364                    if rout.is_empty() {
365                        self.out_write_scratch = Some(rout.into_write_buffer());
366                        process_scratch(self);
367                        if self.padding.strip_output(self.out_read_scratch.as_mut().unwrap()) {
368                            self.state = BlockEngineState::Finished;
369                        } else {
370                            self.state = BlockEngineState::Error(InvalidPadding);
371                        }
372                    } else {
373                        self.out_read_scratch = Some(rout);
374                        return Ok(BufferOverflow);
375                    }
376                }
377
378                // The Finished mode just writes the data in out_scratch to the output until there
379                // is no more data left.
380                BlockEngineState::Finished => {
381                    match self.out_read_scratch {
382                        Some(ref mut rout) => {
383                            rout.push_to(output);
384                            if rout.is_empty() {
385                                return Ok(BufferUnderflow);
386                            } else {
387                                return Ok(BufferOverflow);
388                            }
389                        }
390                        None => { return Ok(BufferUnderflow); }
391                    }
392                }
393
394                // The Error state is used to store error information.
395                BlockEngineState::Error(err) => {
396                    return Err(err);
397                }
398            }
399        }
400    }
401    fn reset(&mut self) {
402        self.state = BlockEngineState::FastMode;
403        self.in_scratch.reset();
404        if self.out_read_scratch.is_some() {
405            let ors = self.out_read_scratch.take().unwrap();
406            let ows = ors.into_write_buffer();
407            self.out_write_scratch = Some(ows);
408        } else {
409            self.out_write_scratch.as_mut().unwrap().reset();
410        }
411    }
412    fn reset_with_history(&mut self, in_hist: &[u8], out_hist: &[u8]) {
413        self.reset();
414        cryptoutil::copy_memory(in_hist, &mut self.in_hist);
415        cryptoutil::copy_memory(out_hist, &mut self.out_hist);
416    }
417}
418
419/// No padding mode for ECB and CBC encryption
420#[derive(Clone, Copy)]
421pub struct NoPadding;
422
423impl PaddingProcessor for NoPadding {
424    fn pad_input<W: WriteBuffer>(&mut self, _: &mut W) { }
425    fn strip_output<R: ReadBuffer>(&mut self, _: &mut R) -> bool { true }
426}
427
428/// PKCS padding mode for ECB and CBC encryption
429#[derive(Clone, Copy)]
430pub struct PkcsPadding;
431
432// This class implements both encryption padding, where padding is added, and decryption padding,
433// where padding is stripped. Since BlockEngine doesn't know if its an Encryption or Decryption
434// operation, it will call both methods if given a chance. So, this class can't be passed directly
435// to BlockEngine. Instead, it must be wrapped with EncPadding or DecPadding which will ensure that
436// only the propper methods are called. The client of the library, however, doesn't have to
437// distinguish encryption padding handling from decryption padding handline, which is the whole
438// point.
439impl PaddingProcessor for PkcsPadding {
440    fn pad_input<W: WriteBuffer>(&mut self, input_buffer: &mut W) {
441        let rem = input_buffer.remaining();
442        assert!(rem != 0 && rem <= 255);
443        for v in input_buffer.take_remaining().iter_mut() {
444            *v = rem as u8;
445        }
446    }
447    fn strip_output<R: ReadBuffer>(&mut self, output_buffer: &mut R) -> bool {
448        let last_byte: u8;
449        {
450            let data = output_buffer.peek_remaining();
451            last_byte = *data.last().unwrap();
452            for &x in data.iter().rev().take(last_byte as usize) {
453                if x != last_byte {
454                    return false;
455                }
456            }
457        }
458        output_buffer.truncate(last_byte as usize);
459        true
460    }
461}
462
463/// Wraps a PaddingProcessor so that only pad_input() will actually be called.
464pub struct EncPadding<X> {
465    padding: X
466}
467
468impl <X: PaddingProcessor> EncPadding<X> {
469    fn wrap(p: X) -> EncPadding<X> { EncPadding { padding: p } }
470}
471
472impl <X: PaddingProcessor> PaddingProcessor for EncPadding<X> {
473    fn pad_input<W: WriteBuffer>(&mut self, a: &mut W) { self.padding.pad_input(a); }
474    fn strip_output<R: ReadBuffer>(&mut self, _: &mut R) -> bool { true }
475}
476
477/// Wraps a PaddingProcessor so that only strip_output() will actually be called.
478pub struct DecPadding<X> {
479    padding: X
480}
481
482impl <X: PaddingProcessor> DecPadding<X> {
483    fn wrap(p: X) -> DecPadding<X> { DecPadding { padding: p } }
484}
485
486impl <X: PaddingProcessor> PaddingProcessor for DecPadding<X> {
487    fn pad_input<W: WriteBuffer>(&mut self, _: &mut W) { }
488    fn strip_output<R: ReadBuffer>(&mut self, a: &mut R) -> bool { self.padding.strip_output(a) }
489}
490
491struct EcbEncryptorProcessor<T> {
492    algo: T
493}
494
495impl <T: BlockEncryptor> BlockProcessor for EcbEncryptorProcessor<T> {
496    fn process_block(&mut self, _: &[u8], _: &[u8], input: &[u8], output: &mut [u8]) {
497        self.algo.encrypt_block(input, output);
498    }
499}
500
501/// ECB Encryption mode
502pub struct EcbEncryptor<T, X> {
503    block_engine: BlockEngine<EcbEncryptorProcessor<T>, X>
504}
505
506impl <T: BlockEncryptor, X: PaddingProcessor> EcbEncryptor<T, X> {
507    /// Create a new ECB encryption mode object
508    pub fn new(algo: T, padding: X) -> EcbEncryptor<T, EncPadding<X>> {
509        let block_size = algo.block_size();
510        let processor = EcbEncryptorProcessor {
511            algo: algo
512        };
513        EcbEncryptor {
514            block_engine: BlockEngine::new(processor, EncPadding::wrap(padding), block_size)
515        }
516    }
517    pub fn reset(&mut self) {
518        self.block_engine.reset();
519    }
520}
521
522impl <T: BlockEncryptor, X: PaddingProcessor> Encryptor for EcbEncryptor<T, X> {
523    fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, eof: bool)
524            -> Result<BufferResult, SymmetricCipherError> {
525        self.block_engine.process(input, output, eof)
526    }
527}
528
529struct EcbDecryptorProcessor<T> {
530    algo: T
531}
532
533impl <T: BlockDecryptor> BlockProcessor for EcbDecryptorProcessor<T> {
534    fn process_block(&mut self, _: &[u8], _: &[u8], input: &[u8], output: &mut [u8]) {
535        self.algo.decrypt_block(input, output);
536    }
537}
538
539/// ECB Decryption mode
540pub struct EcbDecryptor<T, X> {
541    block_engine: BlockEngine<EcbDecryptorProcessor<T>, X>
542}
543
544impl <T: BlockDecryptor, X: PaddingProcessor> EcbDecryptor<T, X> {
545    /// Create a new ECB decryption mode object
546    pub fn new(algo: T, padding: X) -> EcbDecryptor<T, DecPadding<X>> {
547        let block_size = algo.block_size();
548        let processor = EcbDecryptorProcessor {
549            algo: algo
550        };
551        EcbDecryptor {
552            block_engine: BlockEngine::new(processor, DecPadding::wrap(padding), block_size)
553        }
554    }
555    pub fn reset(&mut self) {
556        self.block_engine.reset();
557    }
558}
559
560impl <T: BlockDecryptor, X: PaddingProcessor> Decryptor for EcbDecryptor<T, X> {
561    fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, eof: bool)
562            -> Result<BufferResult, SymmetricCipherError> {
563        self.block_engine.process(input, output, eof)
564    }
565}
566
567struct CbcEncryptorProcessor<T> {
568    algo: T,
569    temp: Vec<u8>
570}
571
572impl <T: BlockEncryptor> BlockProcessor for CbcEncryptorProcessor<T> {
573    fn process_block(&mut self, _: &[u8], out_hist: &[u8], input: &[u8], output: &mut [u8]) {
574        for ((&x, &y), o) in input.iter().zip(out_hist.iter()).zip(self.temp.iter_mut()) {
575            *o = x ^ y;
576        }
577        self.algo.encrypt_block(&self.temp[..], output);
578    }
579}
580
581/// CBC encryption mode
582pub struct CbcEncryptor<T, X> {
583    block_engine: BlockEngine<CbcEncryptorProcessor<T>, X>
584}
585
586impl <T: BlockEncryptor, X: PaddingProcessor> CbcEncryptor<T, X> {
587    /// Create a new CBC encryption mode object
588    pub fn new(algo: T, padding: X, iv: Vec<u8>) -> CbcEncryptor<T, EncPadding<X>> {
589        let block_size = algo.block_size();
590        let processor = CbcEncryptorProcessor {
591            algo: algo,
592            temp: repeat(0).take(block_size).collect()
593        };
594        CbcEncryptor {
595            block_engine: BlockEngine::new_with_history(
596                processor,
597                EncPadding::wrap(padding),
598                block_size,
599                Vec::new(),
600                iv)
601        }
602    }
603    pub fn reset(&mut self, iv: &[u8]) {
604        self.block_engine.reset_with_history(&[], iv);
605    }
606}
607
608impl <T: BlockEncryptor, X: PaddingProcessor> Encryptor for CbcEncryptor<T, X> {
609    fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, eof: bool)
610            -> Result<BufferResult, SymmetricCipherError> {
611        self.block_engine.process(input, output, eof)
612    }
613}
614
615struct CbcDecryptorProcessor<T> {
616    algo: T,
617    temp: Vec<u8>
618}
619
620impl <T: BlockDecryptor> BlockProcessor for CbcDecryptorProcessor<T> {
621    fn process_block(&mut self, in_hist: &[u8], _: &[u8], input: &[u8], output: &mut [u8]) {
622        self.algo.decrypt_block(input, &mut self.temp);
623        for ((&x, &y), o) in self.temp.iter().zip(in_hist.iter()).zip(output.iter_mut()) {
624            *o = x ^ y;
625        }
626    }
627}
628
629/// CBC decryption mode
630pub struct CbcDecryptor<T, X> {
631    block_engine: BlockEngine<CbcDecryptorProcessor<T>, X>
632}
633
634impl <T: BlockDecryptor, X: PaddingProcessor> CbcDecryptor<T, X> {
635    /// Create a new CBC decryption mode object
636    pub fn new(algo: T, padding: X, iv: Vec<u8>) -> CbcDecryptor<T, DecPadding<X>> {
637        let block_size = algo.block_size();
638        let processor = CbcDecryptorProcessor {
639            algo: algo,
640            temp: repeat(0).take(block_size).collect()
641        };
642        CbcDecryptor {
643            block_engine: BlockEngine::new_with_history(
644                processor,
645                DecPadding::wrap(padding),
646                block_size,
647                iv,
648                Vec::new())
649        }
650    }
651    pub fn reset(&mut self, iv: &[u8]) {
652        self.block_engine.reset_with_history(iv, &[]);
653    }
654}
655
656impl <T: BlockDecryptor, X: PaddingProcessor> Decryptor for CbcDecryptor<T, X> {
657    fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, eof: bool)
658            -> Result<BufferResult, SymmetricCipherError> {
659        self.block_engine.process(input, output, eof)
660    }
661}
662
663fn add_ctr(ctr: &mut [u8], mut ammount: u8) {
664    for i in ctr.iter_mut().rev() {
665        let prev = *i;
666        *i = i.wrapping_add(ammount);
667        if *i >= prev {
668            break;
669        }
670        ammount = 1;
671    }
672}
673
674/// CTR Mode
675pub struct CtrMode<A> {
676    algo: A,
677    ctr: Vec<u8>,
678    bytes: OwnedReadBuffer
679}
680
681impl <A: BlockEncryptor> CtrMode<A> {
682    /// Create a new CTR object
683    pub fn new(algo: A, ctr: Vec<u8>) -> CtrMode<A> {
684        let block_size = algo.block_size();
685        CtrMode {
686            algo: algo,
687            ctr: ctr,
688            bytes: OwnedReadBuffer::new_with_len(repeat(0).take(block_size).collect(), 0)
689        }
690    }
691    pub fn reset(&mut self, ctr: &[u8]) {
692        cryptoutil::copy_memory(ctr, &mut self.ctr);
693        self.bytes.reset();
694    }
695    fn process(&mut self, input: &[u8], output: &mut [u8]) {
696        assert!(input.len() == output.len());
697        let len = input.len();
698        let mut i = 0;
699        while i < len {
700            if self.bytes.is_empty() {
701                let mut wb = self.bytes.borrow_write_buffer();
702                self.algo.encrypt_block(&self.ctr[..], wb.take_remaining());
703                add_ctr(&mut self.ctr, 1);
704            }
705            let count = cmp::min(self.bytes.remaining(), len - i);
706            let bytes_it = self.bytes.take_next(count).iter();
707            let in_it = input[i..].iter();
708            let out_it = output[i..].iter_mut();
709            for ((&x, &y), o) in bytes_it.zip(in_it).zip(out_it) {
710                *o = x ^ y;
711            }
712            i += count;
713        }
714    }
715}
716
717impl <A: BlockEncryptor> SynchronousStreamCipher for CtrMode<A> {
718    fn process(&mut self, input: &[u8], output: &mut [u8]) {
719        self.process(input, output);
720    }
721}
722
723impl <A: BlockEncryptor> Encryptor for CtrMode<A> {
724    fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
725            -> Result<BufferResult, SymmetricCipherError> {
726        symm_enc_or_dec(self, input, output)
727    }
728}
729
730impl <A: BlockEncryptor> Decryptor for CtrMode<A> {
731    fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
732            -> Result<BufferResult, SymmetricCipherError> {
733        symm_enc_or_dec(self, input, output)
734    }
735}
736
737/// CTR Mode that operates on 8 blocks at a time
738pub struct CtrModeX8<A> {
739    algo: A,
740    ctr_x8: Vec<u8>,
741    bytes: OwnedReadBuffer
742}
743
744fn construct_ctr_x8(in_ctr: &[u8], out_ctr_x8: &mut [u8]) {
745    for (i, ctr_i) in out_ctr_x8.chunks_mut(in_ctr.len()).enumerate() {
746        cryptoutil::copy_memory(in_ctr, ctr_i);
747        add_ctr(ctr_i, i as u8);
748    }
749}
750
751impl <A: BlockEncryptorX8> CtrModeX8<A> {
752    /// Create a new CTR object that operates on 8 blocks at a time
753    pub fn new(algo: A, ctr: &[u8]) -> CtrModeX8<A> {
754        let block_size = algo.block_size();
755        let mut ctr_x8: Vec<u8> = repeat(0).take(block_size * 8).collect();
756        construct_ctr_x8(ctr, &mut ctr_x8);
757        CtrModeX8 {
758            algo: algo,
759            ctr_x8: ctr_x8,
760            bytes: OwnedReadBuffer::new_with_len(repeat(0).take(block_size * 8).collect(), 0)
761        }
762    }
763    pub fn reset(&mut self, ctr: &[u8]) {
764        construct_ctr_x8(ctr, &mut self.ctr_x8);
765        self.bytes.reset();
766    }
767    fn process(&mut self, input: &[u8], output: &mut [u8]) {
768        // TODO - Can some of this be combined with regular CtrMode?
769        assert!(input.len() == output.len());
770        let len = input.len();
771        let mut i = 0;
772        while i < len {
773            if self.bytes.is_empty() {
774                let mut wb = self.bytes.borrow_write_buffer();
775                self.algo.encrypt_block_x8(&self.ctr_x8[..], wb.take_remaining());
776                for ctr_i in &mut self.ctr_x8.chunks_mut(self.algo.block_size()) {
777                    add_ctr(ctr_i, 8);
778                }
779            }
780            let count = cmp::min(self.bytes.remaining(), len - i);
781            let bytes_it = self.bytes.take_next(count).iter();
782            let in_it = input[i..].iter();
783            let out_it = &mut output[i..];
784            for ((&x, &y), o) in bytes_it.zip(in_it).zip(out_it.iter_mut()) {
785                *o = x ^ y;
786            }
787            i += count;
788        }
789    }
790}
791
792impl <A: BlockEncryptorX8> SynchronousStreamCipher for CtrModeX8<A> {
793    fn process(&mut self, input: &[u8], output: &mut [u8]) {
794        self.process(input, output);
795    }
796}
797
798impl <A: BlockEncryptorX8> Encryptor for CtrModeX8<A> {
799    fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
800            -> Result<BufferResult, SymmetricCipherError> {
801        symm_enc_or_dec(self, input, output)
802    }
803}
804
805impl <A: BlockEncryptorX8> Decryptor for CtrModeX8<A> {
806    fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
807            -> Result<BufferResult, SymmetricCipherError> {
808        symm_enc_or_dec(self, input, output)
809    }
810}
811
812#[cfg(test)]
813mod test {
814    use std::iter::repeat;
815
816    use aessafe;
817    use blockmodes::{EcbEncryptor, EcbDecryptor, CbcEncryptor, CbcDecryptor, CtrMode, CtrModeX8,
818        NoPadding, PkcsPadding};
819    use buffer::{ReadBuffer, WriteBuffer, RefReadBuffer, RefWriteBuffer, BufferResult};
820    use buffer::BufferResult::{BufferUnderflow, BufferOverflow};
821    use symmetriccipher::{Encryptor, Decryptor};
822    use symmetriccipher::SymmetricCipherError::{self, InvalidLength, InvalidPadding};
823
824    use std::cmp;
825
826    trait CipherTest {
827        fn get_plain<'a>(&'a self) -> &'a [u8];
828        fn get_cipher<'a>(&'a self) -> &'a [u8];
829    }
830
831    struct EcbTest {
832        key: Vec<u8>,
833        plain: Vec<u8>,
834        cipher: Vec<u8>
835    }
836
837    impl CipherTest for EcbTest {
838        fn get_plain<'a>(&'a self) -> &'a [u8] {
839            &self.plain[..]
840        }
841        fn get_cipher<'a>(&'a self) -> &'a [u8] {
842            &self.cipher[..]
843        }
844    }
845
846    struct CbcTest {
847        key: Vec<u8>,
848        iv: Vec<u8>,
849        plain: Vec<u8>,
850        cipher: Vec<u8>
851    }
852
853    impl CipherTest for CbcTest {
854        fn get_plain<'a>(&'a self) -> &'a [u8] {
855            &self.plain[..]
856        }
857        fn get_cipher<'a>(&'a self) -> &'a [u8] {
858            &self.cipher[..]
859        }
860    }
861
862    struct CtrTest {
863        key: Vec<u8>,
864        ctr: Vec<u8>,
865        plain: Vec<u8>,
866        cipher: Vec<u8>
867    }
868
869    impl CipherTest for CtrTest {
870        fn get_plain<'a>(&'a self) -> &'a [u8] {
871            &self.plain[..]
872        }
873        fn get_cipher<'a>(&'a self) -> &'a [u8] {
874            &self.cipher[..]
875        }
876    }
877
878    fn aes_ecb_no_padding_tests() -> Vec<EcbTest> {
879        vec![
880            EcbTest {
881                key: repeat(0).take(16).collect(),
882                plain: repeat(0).take(32).collect(),
883                cipher: vec![
884                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
885                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
886                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
887                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e ]
888            }
889        ]
890    }
891
892    fn aes_ecb_pkcs_padding_tests() -> Vec<EcbTest> {
893        vec![
894            EcbTest {
895                key: repeat(0).take(16).collect(),
896                plain: repeat(0).take(32).collect(),
897                cipher: vec![
898                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
899                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
900                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
901                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
902                    0x01, 0x43, 0xdb, 0x63, 0xee, 0x66, 0xb0, 0xcd,
903                    0xff, 0x9f, 0x69, 0x91, 0x76, 0x80, 0x15, 0x1e ]
904            },
905            EcbTest {
906                key: repeat(0).take(16).collect(),
907                plain: repeat(0).take(33).collect(),
908                cipher: vec![
909                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
910                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
911                    0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
912                    0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
913                    0x7a, 0xdc, 0x99, 0xb2, 0x9e, 0x82, 0xb1, 0xb2,
914                    0xb0, 0xa6, 0x5a, 0x38, 0xbc, 0x57, 0x8a, 0x01 ]
915            }
916        ]
917    }
918
919    fn aes_cbc_no_padding_tests() -> Vec<CbcTest> {
920        vec![
921            CbcTest {
922                key: repeat(1).take(16).collect(),
923                iv: repeat(3).take(16).collect(),
924                plain: repeat(2).take(32).collect(),
925                cipher: vec![
926                    0x5e, 0x77, 0xe5, 0x9f, 0x8f, 0x85, 0x94, 0x34,
927                    0x89, 0xa2, 0x41, 0x49, 0xc7, 0x5f, 0x4e, 0xc9,
928                    0xe0, 0x9a, 0x77, 0x36, 0xfb, 0xc8, 0xb2, 0xdc,
929                    0xb3, 0xfb, 0x9f, 0xc0, 0x31, 0x4c, 0xb0, 0xb1 ]
930            }
931        ]
932    }
933
934    fn aes_cbc_pkcs_padding_tests() -> Vec<CbcTest> {
935        vec![
936            CbcTest {
937                key: repeat(1).take(16).collect(),
938                iv: repeat(3).take(16).collect(),
939                plain: repeat(2).take(32).collect(),
940                cipher: vec![
941                    0x5e, 0x77, 0xe5, 0x9f, 0x8f, 0x85, 0x94, 0x34,
942                    0x89, 0xa2, 0x41, 0x49, 0xc7, 0x5f, 0x4e, 0xc9,
943                    0xe0, 0x9a, 0x77, 0x36, 0xfb, 0xc8, 0xb2, 0xdc,
944                    0xb3, 0xfb, 0x9f, 0xc0, 0x31, 0x4c, 0xb0, 0xb1,
945                    0xa4, 0xc2, 0xe4, 0x62, 0xef, 0x7a, 0xe3, 0x7e,
946                    0xef, 0x88, 0xf3, 0x27, 0xbd, 0x9c, 0xc8, 0x4d ]
947            },
948            CbcTest {
949                key: repeat(1).take(16).collect(),
950                iv: repeat(3).take(16).collect(),
951                plain: repeat(2).take(33).collect(),
952                cipher: vec![
953                    0x5e, 0x77, 0xe5, 0x9f, 0x8f, 0x85, 0x94, 0x34,
954                    0x89, 0xa2, 0x41, 0x49, 0xc7, 0x5f, 0x4e, 0xc9,
955                    0xe0, 0x9a, 0x77, 0x36, 0xfb, 0xc8, 0xb2, 0xdc,
956                    0xb3, 0xfb, 0x9f, 0xc0, 0x31, 0x4c, 0xb0, 0xb1,
957                    0x6c, 0x47, 0xcd, 0xec, 0xae, 0xbb, 0x1a, 0x65,
958                    0x04, 0xd2, 0x32, 0x23, 0xa6, 0x8d, 0x4a, 0x65 ]
959            }
960        ]
961    }
962
963    fn aes_ctr_tests() -> Vec<CtrTest> {
964        vec![
965            CtrTest {
966                key: repeat(1).take(16).collect(),
967                ctr: repeat(3).take(16).collect(),
968                plain: repeat(2).take(33).collect(),
969                cipher: vec![
970                    0x64, 0x3e, 0x05, 0x19, 0x79, 0x78, 0xd7, 0x45,
971                    0xa9, 0x10, 0x5f, 0xd8, 0x4c, 0xd7, 0xe6, 0xb1,
972                    0x5f, 0x66, 0xc6, 0x17, 0x4b, 0x25, 0xea, 0x24,
973                    0xe6, 0xf9, 0x19, 0x09, 0xb7, 0xdd, 0x84, 0xfb,
974                    0x86 ]
975            }
976        ]
977    }
978
979    // Test the mode by encrypting all of the data at once
980    fn run_full_test<T: CipherTest, E: Encryptor, D: Decryptor>(
981            test: &T,
982            enc: &mut E,
983            dec: &mut D) {
984        let mut cipher_out: Vec<u8> = repeat(0).take(test.get_cipher().len()).collect();
985        {
986            let mut buff_in = RefReadBuffer::new(test.get_plain());
987            let mut buff_out = RefWriteBuffer::new(&mut cipher_out);
988            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
989                Ok(BufferUnderflow) => {}
990                Ok(BufferOverflow) => panic!("Encryption not completed"),
991                Err(_) => panic!("Error"),
992            }
993        }
994        assert!(test.get_cipher() == &cipher_out[..]);
995
996        let mut plain_out: Vec<u8> = repeat(0).take(test.get_plain().len()).collect();
997        {
998            let mut buff_in = RefReadBuffer::new(test.get_cipher());
999            let mut buff_out = RefWriteBuffer::new(&mut plain_out);
1000            match dec.decrypt(&mut buff_in, &mut buff_out, true) {
1001                Ok(BufferUnderflow) => {}
1002                Ok(BufferOverflow) => panic!("Decryption not completed"),
1003                Err(_) => panic!("Error"),
1004            }
1005        }
1006        assert!(test.get_plain() == &plain_out[..]);
1007    }
1008
1009    /// Run and encryption or decryption operation, passing in variable sized input and output
1010    /// buffers.
1011    ///
1012    /// # Arguments
1013    /// * input - The complete input vector
1014    /// * output - The complete output vector
1015    /// * op - A closure that runs either an encryption or decryption operation
1016    /// * next_in_len - A closure that returns the length to use for the next input buffer; If the
1017    ///                 returned value is not in a valid range, it will be fixed up by this
1018    ///                 function.
1019    /// * next_out_len - A closure that returns the length to use for the next output buffer; If the
1020    ///                  returned value is not in a valid range, it will be fixed up by this
1021    ///                  function.
1022    /// * immediate_eof - Whether eof should be set immediately upon running out of input or if eof
1023    ///                   should be passed only after all input has been consumed.
1024    fn run_inc<OpFunc, NextInFunc, NextOutFunc>(
1025            input: &[u8],
1026            output: &mut [u8],
1027            mut op: OpFunc,
1028            mut next_in_len: NextInFunc,
1029            mut next_out_len: NextOutFunc,
1030            immediate_eof: bool)
1031            where
1032                OpFunc: FnMut(&mut RefReadBuffer, &mut RefWriteBuffer, bool) ->
1033                    Result<BufferResult, SymmetricCipherError>,
1034                NextInFunc: FnMut() -> usize,
1035                NextOutFunc: FnMut() -> usize {
1036        use std::cell::Cell;
1037
1038        let in_len = input.len();
1039        let out_len = output.len();
1040
1041        let mut state: Result<BufferResult, SymmetricCipherError> = Ok(BufferUnderflow);
1042        let mut in_pos: usize = 0;
1043        let mut out_pos: usize = 0;
1044        let eof = Cell::new(false);
1045
1046        let mut in_end = |in_pos: usize, primary: bool| {
1047            if eof.get() {
1048                return in_len;
1049            }
1050            let x = next_in_len();
1051            if x >= in_len && immediate_eof {
1052                eof.set(true);
1053            }
1054            cmp::min(in_len, in_pos + cmp::max(x, if primary { 1 } else { 0 }))
1055        };
1056
1057        let mut out_end = |out_pos: usize| {
1058            let x = next_out_len();
1059            cmp::min(out_len, out_pos + cmp::max(x, 1))
1060        };
1061
1062        loop {
1063            match state {
1064                Ok(BufferUnderflow) => {
1065                    if in_pos == input.len() {
1066                        break;
1067                    }
1068                    let mut tmp_in = RefReadBuffer::new(&input[in_pos..in_end(in_pos, true)]);
1069                    let out_end = out_end(out_pos);
1070                    let mut tmp_out = RefWriteBuffer::new(&mut output[out_pos..out_end]);
1071                    state = op(&mut tmp_in, &mut tmp_out, eof.get());
1072                    match state {
1073                        Ok(BufferUnderflow) => assert!(tmp_in.is_empty()),
1074                        _ => {}
1075                    }
1076                    in_pos += tmp_in.position();
1077                    out_pos += tmp_out.position();
1078                }
1079                Ok(BufferOverflow) => {
1080                    let mut tmp_in = RefReadBuffer::new(&input[in_pos..in_end(in_pos, false)]);
1081                    let out_end = out_end(out_pos);
1082                    let mut tmp_out = RefWriteBuffer::new(&mut output[out_pos..out_end]);
1083                    state = op(&mut tmp_in, &mut tmp_out, eof.get());
1084                    match state {
1085                        Ok(BufferOverflow) => assert!(tmp_out.is_full()),
1086                        _ => {}
1087                    }
1088                    in_pos += tmp_in.position();
1089                    out_pos += tmp_out.position();
1090                }
1091                Err(InvalidPadding) => panic!("Invalid Padding"),
1092                Err(InvalidLength) => panic!("Invalid Length")
1093            }
1094        }
1095
1096        if !eof.get() {
1097            eof.set(true);
1098            let mut tmp_out = RefWriteBuffer::new(&mut output[out_pos..out_end(out_pos)]);
1099            state = op(&mut RefReadBuffer::new(&[]), &mut tmp_out, eof.get());
1100            out_pos += tmp_out.position();
1101        }
1102
1103        loop {
1104            match state {
1105                Ok(BufferUnderflow) => {
1106                    break;
1107                }
1108                Ok(BufferOverflow) => {
1109                    let out_end = out_end(out_pos);
1110                    let mut tmp_out = RefWriteBuffer::new(&mut output[out_pos..out_end]);
1111                    state = op(&mut RefReadBuffer::new(&[]), &mut tmp_out, eof.get());
1112                    assert!(tmp_out.is_full());
1113                    out_pos += tmp_out.position();
1114                }
1115                Err(InvalidPadding) => panic!("Invalid Padding"),
1116                Err(InvalidLength) => panic!("Invalid Length")
1117            }
1118        }
1119    }
1120
1121    fn run_inc1_test<T: CipherTest, E: Encryptor, D: Decryptor>(
1122            test: &T,
1123            enc: &mut E,
1124            dec: &mut D) {
1125        let mut cipher_out: Vec<u8> = repeat(0).take(test.get_cipher().len()).collect();
1126        run_inc(
1127            test.get_plain(),
1128            &mut cipher_out,
1129            |in_buff: &mut RefReadBuffer, out_buff: &mut RefWriteBuffer, eof: bool| {
1130                enc.encrypt(in_buff, out_buff, eof)
1131            },
1132            || { 0 },
1133            || { 1 },
1134            false);
1135        assert!(test.get_cipher() == &cipher_out[..]);
1136
1137        let mut plain_out: Vec<u8> = repeat(0).take(test.get_plain().len()).collect();
1138        run_inc(
1139            test.get_cipher(),
1140            &mut plain_out,
1141            |in_buff: &mut RefReadBuffer, out_buff: &mut RefWriteBuffer, eof: bool| {
1142                dec.decrypt(in_buff, out_buff, eof)
1143            },
1144            || { 0 },
1145            || { 1 },
1146            false);
1147        assert!(test.get_plain() == &plain_out[..]);
1148    }
1149
1150    fn run_rand_test<T, E, D, NewEncFunc, NewDecFunc>(
1151            test: &T,
1152            mut new_enc: NewEncFunc,
1153            mut new_dec: NewDecFunc)
1154            where
1155                T: CipherTest,
1156                E: Encryptor,
1157                D: Decryptor,
1158                NewEncFunc: FnMut() -> E,
1159                NewDecFunc: FnMut() -> D{
1160        use rand;
1161        use rand::Rng;
1162
1163        let tmp : &[_] = &[1, 2, 3, 4];
1164        let mut rng1: rand::StdRng = rand::SeedableRng::from_seed(tmp);
1165        let mut rng2: rand::StdRng = rand::SeedableRng::from_seed(tmp);
1166        let mut rng3: rand::StdRng = rand::SeedableRng::from_seed(tmp);
1167        let max_size = cmp::max(test.get_plain().len(), test.get_cipher().len());
1168
1169        let mut r1 = || {
1170            rng1.gen_range(0, max_size)
1171        };
1172        let mut r2 = || {
1173            rng2.gen_range(0, max_size)
1174        };
1175
1176        for _ in 0..1000 {
1177            let mut enc = new_enc();
1178            let mut dec = new_dec();
1179
1180            let mut cipher_out: Vec<u8> = repeat(0).take(test.get_cipher().len()).collect();
1181            run_inc(
1182                test.get_plain(),
1183                &mut cipher_out,
1184                |in_buff: &mut RefReadBuffer, out_buff: &mut RefWriteBuffer, eof: bool| {
1185                    enc.encrypt(in_buff, out_buff, eof)
1186                },
1187                || { r1() },
1188                || { r2() },
1189                rng3.gen());
1190            assert!(test.get_cipher() == &cipher_out[..]);
1191
1192            let mut plain_out: Vec<u8> = repeat(0).take(test.get_plain().len()).collect();
1193            run_inc(
1194                test.get_cipher(),
1195                &mut plain_out,
1196                |in_buff: &mut RefReadBuffer, out_buff: &mut RefWriteBuffer, eof: bool| {
1197                    dec.decrypt(in_buff, out_buff, eof)
1198                },
1199                || { r1() },
1200                || { r2() },
1201                rng3.gen());
1202            assert!(test.get_plain() == &plain_out[..]);
1203        }
1204    }
1205
1206    fn run_test<T, E, D, NewEncFunc, NewDecFunc>(
1207            test: &T,
1208            mut new_enc: NewEncFunc,
1209            mut new_dec: NewDecFunc)
1210            where
1211                T: CipherTest,
1212                E: Encryptor,
1213                D: Decryptor,
1214                NewEncFunc: FnMut() -> E,
1215                NewDecFunc: FnMut() -> D{
1216        run_full_test(test, &mut new_enc(), &mut new_dec());
1217        run_inc1_test(test, &mut new_enc(), &mut new_dec());
1218        run_rand_test(test, new_enc, new_dec);
1219    }
1220
1221    #[test]
1222    fn aes_ecb_no_padding() {
1223        let tests = aes_ecb_no_padding_tests();
1224        for test in tests.iter() {
1225            run_test(
1226                test,
1227                || {
1228                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
1229                    EcbEncryptor::new(aes_enc, NoPadding)
1230                },
1231                || {
1232                    let aes_dec = aessafe::AesSafe128Decryptor::new(&test.key[..]);
1233                    EcbDecryptor::new(aes_dec, NoPadding)
1234                });
1235        }
1236    }
1237
1238    #[test]
1239    fn aes_ecb_pkcs_padding() {
1240        let tests = aes_ecb_pkcs_padding_tests();
1241        for test in tests.iter() {
1242            run_test(
1243                test,
1244                || {
1245                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
1246                    EcbEncryptor::new(aes_enc, PkcsPadding)
1247                },
1248                || {
1249                    let aes_dec = aessafe::AesSafe128Decryptor::new(&test.key[..]);
1250                    EcbDecryptor::new(aes_dec, PkcsPadding)
1251                });
1252        }
1253    }
1254
1255    #[test]
1256    fn aes_cbc_no_padding() {
1257        let tests = aes_cbc_no_padding_tests();
1258        for test in tests.iter() {
1259            run_test(
1260                test,
1261                || {
1262                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
1263                    CbcEncryptor::new(aes_enc, NoPadding, test.iv.clone())
1264                },
1265                || {
1266                    let aes_dec = aessafe::AesSafe128Decryptor::new(&test.key[..]);
1267                    CbcDecryptor::new(aes_dec, NoPadding, test.iv.clone())
1268                });
1269        }
1270    }
1271
1272    #[test]
1273    fn aes_cbc_pkcs_padding() {
1274        let tests = aes_cbc_pkcs_padding_tests();
1275        for test in tests.iter() {
1276            run_test(
1277                test,
1278                || {
1279                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
1280                    CbcEncryptor::new(aes_enc, PkcsPadding, test.iv.clone())
1281                },
1282                || {
1283                    let aes_dec = aessafe::AesSafe128Decryptor::new(&test.key[..]);
1284                    CbcDecryptor::new(aes_dec, PkcsPadding, test.iv.clone())
1285                });
1286        }
1287    }
1288
1289    #[test]
1290    fn aes_ctr() {
1291        let tests = aes_ctr_tests();
1292        for test in tests.iter() {
1293            run_test(
1294                test,
1295                || {
1296                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
1297                    CtrMode::new(aes_enc, test.ctr.clone())
1298                },
1299                || {
1300                    let aes_enc = aessafe::AesSafe128Encryptor::new(&test.key[..]);
1301                    CtrMode::new(aes_enc, test.ctr.clone())
1302                });
1303        }
1304    }
1305
1306    #[test]
1307    fn aes_ctr_x8() {
1308        let tests = aes_ctr_tests();
1309        for test in tests.iter() {
1310            run_test(
1311                test,
1312                || {
1313                    let aes_enc = aessafe::AesSafe128EncryptorX8::new(&test.key[..]);
1314                    CtrModeX8::new(aes_enc, &test.ctr[..])
1315                },
1316                || {
1317                    let aes_enc = aessafe::AesSafe128EncryptorX8::new(&test.key[..]);
1318                    CtrModeX8::new(aes_enc, &test.ctr[..])
1319                });
1320        }
1321    }
1322}
1323
1324#[cfg(all(test, feature = "with-bench"))]
1325mod bench {
1326    use aessafe;
1327    use blockmodes::{EcbEncryptor, CbcEncryptor, CtrMode, CtrModeX8,
1328        NoPadding, PkcsPadding};
1329    use buffer::{ReadBuffer, WriteBuffer, RefReadBuffer, RefWriteBuffer};
1330    use buffer::BufferResult::{BufferUnderflow, BufferOverflow};
1331    use symmetriccipher::{Encryptor};
1332
1333    use test::Bencher;
1334
1335    #[bench]
1336    pub fn aes_ecb_no_padding_bench(bh: &mut Bencher) {
1337        let key = [1u8; 16];
1338        let plain = [3u8; 512];
1339        let mut cipher = [3u8; 528];
1340
1341        let aes_enc = aessafe::AesSafe128Encryptor::new(&key);
1342        let mut enc = EcbEncryptor::new(aes_enc, NoPadding);
1343
1344        bh.iter( || {
1345            enc.reset();
1346
1347            let mut buff_in = RefReadBuffer::new(&plain);
1348            let mut buff_out = RefWriteBuffer::new(&mut cipher);
1349
1350            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
1351                Ok(BufferUnderflow) => {}
1352                Ok(BufferOverflow) => panic!("Encryption not completed"),
1353                Err(_) => panic!("Error"),
1354            }
1355        });
1356
1357        bh.bytes = (plain.len()) as u64;
1358    }
1359
1360    #[bench]
1361    pub fn aes_cbc_pkcs_padding_bench(bh: &mut Bencher) {
1362        let key = [1u8; 16];
1363        let iv = [2u8; 16];
1364        let plain = [3u8; 512];
1365        let mut cipher = [3u8; 528];
1366
1367        let aes_enc = aessafe::AesSafe128Encryptor::new(&key);
1368        let mut enc = CbcEncryptor::new(aes_enc, PkcsPadding, iv.to_vec());
1369
1370        bh.iter( || {
1371            enc.reset(&iv);
1372
1373            let mut buff_in = RefReadBuffer::new(&plain);
1374            let mut buff_out = RefWriteBuffer::new(&mut cipher);
1375
1376            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
1377                Ok(BufferUnderflow) => {}
1378                Ok(BufferOverflow) => panic!("Encryption not completed"),
1379                Err(_) => panic!("Error"),
1380            }
1381        });
1382
1383        bh.bytes = (plain.len()) as u64;
1384    }
1385
1386    #[bench]
1387    pub fn aes_ctr_bench(bh: &mut Bencher) {
1388        let key = [1u8; 16];
1389        let ctr = [2u8; 16];
1390        let plain = [3u8; 512];
1391        let mut cipher = [3u8; 528];
1392
1393        let aes_enc = aessafe::AesSafe128Encryptor::new(&key);
1394        let mut enc = CtrMode::new(aes_enc, ctr.to_vec());
1395
1396        bh.iter( || {
1397            enc.reset(&ctr);
1398
1399            let mut buff_in = RefReadBuffer::new(&plain);
1400            let mut buff_out = RefWriteBuffer::new(&mut cipher);
1401
1402            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
1403                Ok(BufferUnderflow) => {}
1404                Ok(BufferOverflow) => panic!("Encryption not completed"),
1405                Err(_) => panic!("Error"),
1406            }
1407        });
1408
1409        bh.bytes = (plain.len()) as u64;
1410    }
1411
1412    #[bench]
1413    pub fn aes_ctr_x8_bench(bh: &mut Bencher) {
1414        let key = [1u8; 16];
1415        let ctr = [2u8; 16];
1416        let plain = [3u8; 512];
1417        let mut cipher = [3u8; 528];
1418
1419        let aes_enc = aessafe::AesSafe128EncryptorX8::new(&key);
1420        let mut enc = CtrModeX8::new(aes_enc, &ctr);
1421
1422        bh.iter( || {
1423            enc.reset(&ctr);
1424
1425            let mut buff_in = RefReadBuffer::new(&plain);
1426            let mut buff_out = RefWriteBuffer::new(&mut cipher);
1427
1428            match enc.encrypt(&mut buff_in, &mut buff_out, true) {
1429                Ok(BufferUnderflow) => {}
1430                Ok(BufferOverflow) => panic!("Encryption not completed"),
1431                Err(_) => panic!("Error"),
1432            }
1433        });
1434
1435        bh.bytes = (plain.len()) as u64;
1436    }
1437}