1use 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
22trait BlockProcessor {
26 fn process_block(&mut self, in_hist: &[u8], out_hist: &[u8], input: &[u8], output: &mut [u8]);
29}
30
31pub trait PaddingProcessor {
33 fn pad_input<W: WriteBuffer>(&mut self, input_buffer: &mut W);
37
38 fn strip_output<R: ReadBuffer>(&mut self, output_buffer: &mut R) -> bool;
41}
42
43#[derive(Clone, Copy)]
46enum BlockEngineState {
47 FastMode,
48 NeedInput,
49 NeedOutput,
50 LastInput,
51 LastInput2,
52 Finished,
53 Error(SymmetricCipherError)
54}
55
56struct BlockEngine<P, X> {
60 block_size: usize,
62
63 in_hist: Vec<u8>,
67 out_hist: Vec<u8>,
68
69 in_scratch: OwnedWriteBuffer,
72
73 out_write_scratch: Option<OwnedWriteBuffer>,
80 out_read_scratch: Option<OwnedReadBuffer>,
81
82 processor: P,
84
85 padding: X,
87
88 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 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 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 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 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 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 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 {
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 fn process<R: ReadBuffer, W: WriteBuffer>(
216 &mut self,
217 input: &mut R,
218 output: &mut W,
219 eof: bool) -> Result<BufferResult, SymmetricCipherError> {
220 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 BlockEngineState::FastMode => {
251 self.state = self.fast_mode(input, output);
252 match self.state {
253 BlockEngineState::FastMode => {
254 return Ok(BufferUnderflow);
257 }
258 _ => {}
259 }
260 }
261
262 BlockEngineState::NeedInput => {
268 input.push_to(&mut self.in_scratch);
269 if !input.is_empty() {
270 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 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 BlockEngineState::LastInput => {
302 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 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 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 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#[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#[derive(Clone, Copy)]
430pub struct PkcsPadding;
431
432impl 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
463pub 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
477pub 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
501pub struct EcbEncryptor<T, X> {
503 block_engine: BlockEngine<EcbEncryptorProcessor<T>, X>
504}
505
506impl <T: BlockEncryptor, X: PaddingProcessor> EcbEncryptor<T, X> {
507 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
539pub struct EcbDecryptor<T, X> {
541 block_engine: BlockEngine<EcbDecryptorProcessor<T>, X>
542}
543
544impl <T: BlockDecryptor, X: PaddingProcessor> EcbDecryptor<T, X> {
545 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
581pub struct CbcEncryptor<T, X> {
583 block_engine: BlockEngine<CbcEncryptorProcessor<T>, X>
584}
585
586impl <T: BlockEncryptor, X: PaddingProcessor> CbcEncryptor<T, X> {
587 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
629pub struct CbcDecryptor<T, X> {
631 block_engine: BlockEngine<CbcDecryptorProcessor<T>, X>
632}
633
634impl <T: BlockDecryptor, X: PaddingProcessor> CbcDecryptor<T, X> {
635 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
674pub struct CtrMode<A> {
676 algo: A,
677 ctr: Vec<u8>,
678 bytes: OwnedReadBuffer
679}
680
681impl <A: BlockEncryptor> CtrMode<A> {
682 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
737pub 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 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 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 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 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}