diff --git a/src/aes.rs b/src/aes.rs index c4da949..6b353c3 100644 --- a/src/aes.rs +++ b/src/aes.rs @@ -14,7 +14,7 @@ use symmetriccipher::{Encryptor, Decryptor, SynchronousStreamCipher}; use util; /// AES key size -#[derive(Copy)] +#[derive(Clone, Copy)] pub enum KeySize { KeySize128, KeySize192, diff --git a/src/aesni.rs b/src/aesni.rs index c02698d..998b388 100644 --- a/src/aesni.rs +++ b/src/aesni.rs @@ -14,12 +14,16 @@ pub struct AesNiEncryptor { round_keys: [u8; 240] } +impl Clone for AesNiEncryptor { fn clone(&self) -> AesNiEncryptor { *self } } + #[derive(Copy)] pub struct AesNiDecryptor { rounds: u8, round_keys: [u8; 240] } +impl Clone for AesNiDecryptor { fn clone(&self) -> AesNiDecryptor { *self } } + /// The number of rounds as well as a function to setup an appropriately sized key. type RoundSetupInfo = (u8, fn(&[u8], KeyType, &mut [u8])); diff --git a/src/aessafe.rs b/src/aessafe.rs index d3e9183..99d3fab 100644 --- a/src/aessafe.rs +++ b/src/aessafe.rs @@ -139,7 +139,7 @@ macro_rules! define_aes_struct( $name:ident, $rounds:expr ) => ( - #[derive(Copy)] + #[derive(Clone, Copy)] pub struct $name { sk: [Bs8State; ($rounds + 1)] } @@ -227,7 +227,7 @@ macro_rules! define_aes_struct_x8( $name:ident, $rounds:expr ) => ( - #[derive(Copy)] + #[derive(Clone, Copy)] pub struct $name { sk: [Bs8State; ($rounds + 1)] } @@ -453,7 +453,7 @@ fn decrypt_core(state: &S, sk: &[S]) -> S { tmp } -#[derive(Copy)] +#[derive(Clone, Copy)] struct Bs8State(T, T, T, T, T, T, T, T); impl Bs8State { @@ -634,7 +634,7 @@ impl + Copy> Bs8State { } } -#[derive(Copy)] +#[derive(Clone, Copy)] struct Bs4State(T, T, T, T); impl Bs4State { @@ -658,7 +658,7 @@ impl + Copy> Bs4State { } } -#[derive(Copy)] +#[derive(Clone, Copy)] struct Bs2State(T, T); impl Bs2State { diff --git a/src/blake2b.rs b/src/blake2b.rs index 6c8ed0a..f28d58a 100644 --- a/src/blake2b.rs +++ b/src/blake2b.rs @@ -52,6 +52,8 @@ pub struct Blake2b { computed: bool, // whether the final digest has been computed } +impl Clone for Blake2b { fn clone(&self) -> Blake2b { *self } } + struct Blake2bParam { digest_length: u8, key_length: u8, diff --git a/src/blockmodes.rs b/src/blockmodes.rs index c66e4c6..114ce6e 100644 --- a/src/blockmodes.rs +++ b/src/blockmodes.rs @@ -42,7 +42,7 @@ pub trait PaddingProcessor { /// The BlockEngine is implemented as a state machine with the following states. See comments in the /// BlockEngine code for more information on the states. -#[derive(Copy)] +#[derive(Clone, Copy)] enum BlockEngineState { FastMode, NeedInput, @@ -417,7 +417,7 @@ impl BlockEngine { } /// No padding mode for ECB and CBC encryption -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct NoPadding; impl PaddingProcessor for NoPadding { @@ -426,7 +426,7 @@ impl PaddingProcessor for NoPadding { } /// PKCS padding mode for ECB and CBC encryption -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct PkcsPadding; // This class implements both encryption padding, where padding is added, and decryption padding, diff --git a/src/blowfish.rs b/src/blowfish.rs index 07a123c..201d9eb 100644 --- a/src/blowfish.rs +++ b/src/blowfish.rs @@ -8,7 +8,7 @@ use cryptoutil::{read_u32v_be, write_u32_be}; use symmetriccipher::{BlockEncryptor, BlockDecryptor}; use step_by::RangeExt; -#[derive(Copy)] +#[derive(Clone,Copy)] pub struct Blowfish { s: [[u32; 256]; 4], p: [u32; 18] @@ -240,7 +240,7 @@ impl Blowfish { } } } - + // Bcrypt key schedule. pub fn salted_expand_key(&mut self, salt: &[u8], key: &[u8]) { let mut key_pos = 0; @@ -264,7 +264,7 @@ impl Blowfish { r = new_r; self.s[i][j] = l; self.s[i][j+1] = r; - + let (new_l, new_r) = self.encrypt(l ^ next_u32_wrap(salt, &mut salt_pos), r ^ next_u32_wrap(salt, &mut salt_pos)); l = new_l; r = new_r; @@ -533,7 +533,7 @@ mod test { assert!(test.ciphertext[..] == output[..]); } } - + #[test] fn decrypt_eay_test_vectors() { let tests = eay_test_vectors(); @@ -558,7 +558,7 @@ mod bench { let plaintext = [1u8; 8]; let state = Blowfish::new(&key); let mut ciphertext = [0u8; 8]; - + bh.iter(|| { state.encrypt_block(&plaintext, &mut ciphertext); }); diff --git a/src/buffer.rs b/src/buffer.rs index cd9476c..c9ad3e9 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -8,7 +8,7 @@ use std::cmp; use cryptoutil; -#[derive(Copy)] +#[derive(Clone,Copy)] pub enum BufferResult { BufferUnderflow, BufferOverflow diff --git a/src/chacha20.rs b/src/chacha20.rs index 4509f28..59e8e9a 100644 --- a/src/chacha20.rs +++ b/src/chacha20.rs @@ -10,7 +10,7 @@ use symmetriccipher::{Encryptor, Decryptor, SynchronousStreamCipher, SymmetricCi use cryptoutil::{read_u32_le, symm_enc_or_dec, write_u32_le, xor_keystream}; use simd::u32x4; -#[derive(Copy)] +#[derive(Clone,Copy)] struct ChaChaState { a: u32x4, b: u32x4, @@ -25,6 +25,8 @@ pub struct ChaCha20 { offset : usize, } +impl Clone for ChaCha20 { fn clone(&self) -> ChaCha20 { *self } } + macro_rules! swizzle{ ($b: expr, $c: expr, $d: expr) => {{ let u32x4(b10, b11, b12, b13) = $b; @@ -69,7 +71,7 @@ macro_rules! round{ macro_rules! rotate { ($a: expr, $b: expr, $c:expr) => {{ - let v = $a ^ $b; + let v = $a ^ $b; let r = S32 - $c; let right = v >> r; $a = (v << $c) ^ right @@ -112,7 +114,7 @@ impl ChaCha20 { } fn expand(key: &[u8], nonce: &[u8]) -> ChaChaState { - + let constant = match key.len() { 16 => b"expand 16-byte k", 32 => b"expand 32-byte k", diff --git a/src/chacha20poly1305.rs b/src/chacha20poly1305.rs index 6a7ba8c..56e43a5 100644 --- a/src/chacha20poly1305.rs +++ b/src/chacha20poly1305.rs @@ -12,7 +12,7 @@ use poly1305::Poly1305; use mac::Mac; use cryptoutil::{write_u64_le}; use util::fixed_time_eq; -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct ChaCha20Poly1305 { cipher : ChaCha20, mac: Poly1305, @@ -99,7 +99,7 @@ mod test { aad: Vec, tag: Vec } - + #[test] fn test_chacha20_256_poly1305_boringssl_vectors_encrypt() { @@ -748,17 +748,17 @@ mod bench { bh.iter( || { let mut cipher = ChaCha20Poly1305::new(&[0; 32], &[0; 8], &aad); let mut decipher = ChaCha20Poly1305::new(&[0; 32], &[0; 8], &aad); - + let mut output = [0u8; 10]; let mut tag = [0u8; 16]; let mut output2 = [0u8; 10]; cipher.encrypt(&input, &mut output, &mut tag); decipher.decrypt(&output, &mut output2, &tag); - + }); bh.bytes = 10u64; } - + #[bench] pub fn chacha20poly1305_1k(bh: & mut Bencher) { @@ -767,16 +767,16 @@ mod bench { bh.iter( || { let mut cipher = ChaCha20Poly1305::new(&[0; 32], &[0; 8], &aad); let mut decipher = ChaCha20Poly1305::new(&[0; 32], &[0; 8], &aad); - + let mut output = [0u8; 1024]; let mut tag = [0u8; 16]; let mut output2 = [0u8; 1024]; - + cipher.encrypt(&input, &mut output, &mut tag); decipher.decrypt(&output, &mut output2, &tag); }); bh.bytes = 1024u64; - + } #[bench] @@ -786,16 +786,16 @@ mod bench { bh.iter( || { let mut cipher = ChaCha20Poly1305::new(&[0; 32], &[0; 8], &aad); let mut decipher = ChaCha20Poly1305::new(&[0; 32], &[0; 8], &aad); - + let mut output = [0u8; 65536]; let mut tag = [0u8; 16]; let mut output2 = [0u8; 65536]; - + cipher.encrypt(&input, &mut output, &mut tag); decipher.decrypt(&output, &mut output2, &tag); }); bh.bytes = 65536u64; - + } -} \ No newline at end of file +} diff --git a/src/cryptoutil.rs b/src/cryptoutil.rs index b84fdf7..b78ef29 100644 --- a/src/cryptoutil.rs +++ b/src/cryptoutil.rs @@ -446,6 +446,8 @@ pub struct FixedBuffer64 { buffer_idx: usize, } +impl Clone for FixedBuffer64 { fn clone(&self) -> FixedBuffer64 { *self } } + impl FixedBuffer64 { /// Create a new buffer pub fn new() -> FixedBuffer64 { diff --git a/src/curve25519.rs b/src/curve25519.rs index 7c007ef..1413d80 100644 --- a/src/curve25519.rs +++ b/src/curve25519.rs @@ -11,7 +11,7 @@ t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on context. */ -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct Fe(pub [i32; 10]); impl PartialEq for Fe { @@ -1062,14 +1062,14 @@ impl Fe { } } -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct GeP2 { x: Fe, y: Fe, z: Fe, } -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct GeP3 { x: Fe, y: Fe, @@ -1077,7 +1077,7 @@ pub struct GeP3 { t: Fe, } -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct GeP1P1 { x: Fe, y: Fe, @@ -1085,14 +1085,14 @@ pub struct GeP1P1 { t: Fe, } -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct GePrecomp { y_plus_x: Fe, y_minus_x: Fe, xy2d: Fe, } -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct GeCached { y_plus_x: Fe, y_minus_x: Fe, diff --git a/src/fortuna.rs b/src/fortuna.rs index 6248e1b..42e6435 100644 --- a/src/fortuna.rs +++ b/src/fortuna.rs @@ -20,7 +20,7 @@ * is designed to be timing-attack resistant. The speed hit from this * is in line with a "safety first" API, but be aware of it. * - * Fortuna was originally described in + * Fortuna was originally described in * Practical Cryptography, Niels Ferguson and Bruce Schneier. * John Wiley & Sons, 2003. * @@ -147,7 +147,7 @@ impl FortunaGenerator { /// A single entropy pool (not public) -#[derive(Copy)] +#[derive(Clone, Copy)] struct Pool { state: Sha256, count: usize @@ -194,7 +194,7 @@ impl Fortuna { } } - /// Adds a random event `e` from source `s` to entropy pool `i` (PC 9.5.6) + /// Adds a random event `e` from source `s` to entropy pool `i` (PC 9.5.6) pub fn add_random_event(&mut self, s: u8, i: usize, e: &[u8]) { assert!(i <= NUM_POOLS); // These restrictions (and `s` in [0, 255]) are part of the Fortuna spec. @@ -352,7 +352,7 @@ mod tests { 50, 68, 236, 107, 133, 18, 217, 219, 46, 134, 169, 156, 211, 74, 163, 17, 100, 173, 26, 70, 246, 193, 57, 164, 167, 175, 233, 220, 160, 114, - 2, 200, 215, 80, 207, 218, 85, 58, 235, 117, + 2, 200, 215, 80, 207, 218, 85, 58, 235, 117, 177, 223, 87, 192, 50, 251, 61, 65, 141, 100, 59, 228, 23, 215, 58, 107, 248, 248, 103, 57, 127, 31, 241, 91, 230, 33, 0, 164, 77, 46]; @@ -411,7 +411,7 @@ mod tests { // from Crypto.Random.Fortuna import FortunaAccumulator // x = FortunaAccumulator.FortunaAccumulator() - // x.add_random_event(0, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") + // x.add_random_event(0, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") // x.add_random_event(0, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") // x.add_random_event(1, 0, "\1\2") // x.add_random_event(1, 1, "\1\2") @@ -433,7 +433,7 @@ mod tests { f.add_random_event(0, 0, &[0; 32]); f.add_random_event(0, 0, &[0; 32]); - // x.add_random_event(0, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") + // x.add_random_event(0, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") // x.add_random_event(0, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") // print list(bytearray(x.random_data(100))) let expected = [101, 123, 175, 157, 142, 202, 211, 47, 149, 214, @@ -513,4 +513,3 @@ mod bench { bh.bytes = bytes.len() as u64; } } - diff --git a/src/ghash.rs b/src/ghash.rs index 2f7c1bc..9bc9c20 100644 --- a/src/ghash.rs +++ b/src/ghash.rs @@ -25,7 +25,7 @@ use simd; // A struct representing an element in GF(2^128) // x^0 is the msb, while x^127 is the lsb -#[derive(Copy)] +#[derive(Clone, Copy)] struct Gf128 { d: simd::u32x4 } impl Gf128 { @@ -108,6 +108,8 @@ pub struct Ghash { finished: bool } +impl Clone for Ghash { fn clone(&self) -> Ghash { *self } } + /// A structure representing the state of a GHASH computation, after input for C was provided #[derive(Copy)] pub struct GhashWithC { @@ -118,6 +120,8 @@ pub struct GhashWithC { rest: Option<[u8; 16]> } +impl Clone for GhashWithC { fn clone(&self) -> GhashWithC { *self } } + fn update(state: &mut Gf128, len: &mut usize, data: &[u8], srest: &mut Option<[u8; 16]>, hs: &[Gf128; 128]) { let rest_len = *len % 16; diff --git a/src/hc128.rs b/src/hc128.rs index f62d1a3..c16f9a1 100644 --- a/src/hc128.rs +++ b/src/hc128.rs @@ -3,12 +3,12 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. - - + + use buffer::{BufferResult, RefReadBuffer, RefWriteBuffer}; use symmetriccipher::{Encryptor, Decryptor, SynchronousStreamCipher, SymmetricCipherError}; use cryptoutil::{read_u32_le, symm_enc_or_dec, write_u32_le}; - + use std::ptr; @@ -20,14 +20,16 @@ pub struct Hc128 { output: [u8; 4], output_index: usize } - + +impl Clone for Hc128 { fn clone(&self) -> Hc128 { *self } } + impl Hc128 { pub fn new(key: &[u8], nonce: &[u8]) -> Hc128 { assert!(key.len() == 16); assert!(nonce.len() == 16); let mut hc128 = Hc128 { p: [0; 512], q: [0; 512], cnt: 0, output: [0; 4], output_index: 0 }; hc128.init(&key, &nonce); - + hc128 } @@ -59,17 +61,17 @@ impl Hc128 { ptr::copy_nonoverlapping(w.as_ptr().offset(256), self.p.as_mut_ptr(), 512); ptr::copy_nonoverlapping(w.as_ptr().offset(768), self.q.as_mut_ptr(), 512); } - + for i in 0..512 { self.p[i] = self.step(); } for i in 0..512 { self.q[i] = self.step(); - } - + } + self.cnt = 0; } - + fn step(&mut self) -> u32 { let j : usize = self.cnt & 0x1FF; @@ -89,10 +91,10 @@ impl Hc128 { ret = (self.p[(self.q[dim_j12] & 0xFF) as usize].wrapping_add(self.p[(((self.q[dim_j12] >> 16) & 0xFF) + 256) as usize])) ^ self.q[j]; } - self.cnt = (self.cnt + 1) & 0x3FF; + self.cnt = (self.cnt + 1) & 0x3FF; ret } - + fn next(&mut self) -> u8 { if self.output_index == 0 { let step = self.step(); @@ -128,15 +130,15 @@ impl SynchronousStreamCipher for Hc128 { let mut data_index = 0; let data_index_end = data_index + input.len(); - /* Process any unused keystream (self.buffer) + /* Process any unused keystream (self.buffer) * remaining from previous operations */ while self.output_index > 0 && data_index < data_index_end { output[data_index] = input[data_index] ^ self.next(); data_index += 1; } - /* Process input data blockwise until depleted, - * or remaining length less than block size + /* Process input data blockwise until depleted, + * or remaining length less than block size * (size of the keystream buffer, self.buffer : 4 bytes) */ while data_index + 4 <= data_index_end { let data_index_inc = data_index + 4; @@ -151,7 +153,7 @@ impl SynchronousStreamCipher for Hc128 { data_index = data_index_inc; } - /* Process remaining data, if any + /* Process remaining data, if any * (e.g. input length not divisible by 4) */ while data_index < data_index_end { output[data_index] = input[data_index] ^ self.next(); @@ -160,14 +162,14 @@ impl SynchronousStreamCipher for Hc128 { } } } - + impl Encryptor for Hc128 { fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool) -> Result { symm_enc_or_dec(self, input, output) } } - + impl Decryptor for Hc128 { fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool) -> Result { @@ -175,7 +177,7 @@ impl Decryptor for Hc128 { } } - + #[cfg(test)] mod test { use hc128::Hc128; @@ -247,19 +249,19 @@ mod test { let expected_output = expected_output_hex.from_hex().unwrap(); let mut output = [0u8; 64]; - + let mut hc128 = Hc128::new(&key, &nonce); hc128.process(&input, &mut output); assert!(&output[..] == &expected_output[..]); } } - + #[cfg(test)] mod bench { use test::Bencher; use symmetriccipher::SynchronousStreamCipher; use hc128::Hc128; - + #[bench] pub fn hc128_10(bh: & mut Bencher) { let mut hc128 = Hc128::new(&[0; 16], &[0; 16]); @@ -270,7 +272,7 @@ mod bench { }); bh.bytes = input.len() as u64; } - + #[bench] pub fn hc128_1k(bh: & mut Bencher) { let mut hc128 = Hc128::new(&[0; 16], &[0; 16]); @@ -281,7 +283,7 @@ mod bench { }); bh.bytes = input.len() as u64; } - + #[bench] pub fn hc128_64k(bh: & mut Bencher) { let mut hc128 = Hc128::new(&[0; 16], &[0; 16]); diff --git a/src/lib.rs b/src/lib.rs index cb9a3d2..0bafff8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(negate_unsigned)] #![cfg_attr(test, feature(test))] extern crate rand; diff --git a/src/poly1305.rs b/src/poly1305.rs index 0ef705b..cb3d31c 100644 --- a/src/poly1305.rs +++ b/src/poly1305.rs @@ -12,7 +12,7 @@ use std::cmp::min; use cryptoutil::{read_u32_le, write_u32_le}; use mac::{Mac, MacResult}; -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct Poly1305 { r : [u32; 5], h : [u32; 5], diff --git a/src/rc4.rs b/src/rc4.rs index 72106d2..26af433 100644 --- a/src/rc4.rs +++ b/src/rc4.rs @@ -20,6 +20,8 @@ pub struct Rc4 { state: [u8; 256] } +impl Clone for Rc4 { fn clone(&self) -> Rc4 { *self } } + impl Rc4 { pub fn new(key: &[u8]) -> Rc4 { assert!(key.len() >= 1 && key.len() <= 256); diff --git a/src/ripemd160.rs b/src/ripemd160.rs index 4857091..56e66ff 100644 --- a/src/ripemd160.rs +++ b/src/ripemd160.rs @@ -32,7 +32,7 @@ const DIGEST_BUF_LEN: usize = 5; const WORK_BUF_LEN: usize = 16; /// Structure representing the state of a Ripemd160 computation -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct Ripemd160 { h: [u32; DIGEST_BUF_LEN], length_bits: u64, @@ -366,7 +366,7 @@ impl Digest for Ripemd160 { * Adds the input `msg` to the hash. This method can be called repeatedly * for use with streaming messages. */ - fn input(&mut self, msg: &[u8]) { + fn input(&mut self, msg: &[u8]) { assert!(!self.computed); // Assumes that msg.len() can be converted to u64 without overflow self.length_bits = add_bytes_to_bits(self.length_bits, msg.len() as u64); @@ -374,13 +374,13 @@ impl Digest for Ripemd160 { self.buffer.input(msg, |d: &[u8]| {process_msg_block(d, &mut *st_h);} ); } - + /** * Returns the resulting digest of the entire message. * Note: `out` must be at least 20 bytes (160 bits) */ - fn result(&mut self, out: &mut [u8]) { - + fn result(&mut self, out: &mut [u8]) { + if !self.computed { let st_h = &mut self.h; self.buffer.standard_padding(8, |d: &[u8]| { process_msg_block(d, &mut *st_h) }); @@ -391,7 +391,7 @@ impl Digest for Ripemd160 { self.computed = true; } - + write_u32_le(&mut out[0..4], self.h[0]); write_u32_le(&mut out[4..8], self.h[1]); write_u32_le(&mut out[8..12], self.h[2]); @@ -446,7 +446,7 @@ mod tests { 0x4au8, 0x9cu8, 0x0cu8, 0x88u8, 0xe4u8, 0x05u8, 0xa0u8, 0x6cu8, 0x27u8, 0xdcu8, 0xf4u8, 0x9au8, - 0xdau8, 0x62u8, 0xebu8, 0x2bu8, + 0xdau8, 0x62u8, 0xebu8, 0x2bu8, ], output_str: "12a053384a9c0c88e405a06c27dcf49ada62eb2b" }, @@ -469,7 +469,7 @@ mod tests { 0x69u8, 0x09u8, 0x33u8, 0x83u8, 0x5eu8, 0xb8u8, 0xb6u8, 0xadu8, 0x0bu8, 0x77u8, 0xe7u8, 0xb6u8, - 0xf1u8, 0x4au8, 0xcau8, 0xd7u8, + 0xf1u8, 0x4au8, 0xcau8, 0xd7u8, ], output_str: "132072df690933835eb8b6ad0b77e7b6f14acad7", }, diff --git a/src/salsa20.rs b/src/salsa20.rs index af98d3d..333d915 100644 --- a/src/salsa20.rs +++ b/src/salsa20.rs @@ -11,7 +11,7 @@ use simd::u32x4; use std::cmp; -#[derive(Copy)] +#[derive(Clone, Copy)] struct SalsaState { a: u32x4, b: u32x4, @@ -26,6 +26,8 @@ pub struct Salsa20 { offset: usize, } +impl Clone for Salsa20 { fn clone(&self) -> Salsa20 { *self } } + const S7:u32x4 = u32x4(7, 7, 7, 7); const S9:u32x4 = u32x4(9, 9, 9, 9); const S13:u32x4 = u32x4(13, 13, 13, 13); @@ -271,16 +273,16 @@ mod test { 0x9A, 0x31, 0x02, 0x20, 0x50, 0x85, 0x99, 0x36, 0xDA, 0x52, 0xFC, 0xEE, 0x21, 0x80, 0x05, 0x16, 0x4F, 0x26, 0x7C, 0xB6, 0x5F, 0x5C, 0xFD, 0x7F, - 0x2B, 0x4F, 0x97, 0xE0, 0xFF, 0x16, 0x92, 0x4A, + 0x2B, 0x4F, 0x97, 0xE0, 0xFF, 0x16, 0x92, 0x4A, 0x52, 0xDF, 0x26, 0x95, 0x15, 0x11, 0x0A, 0x07, - 0xF9, 0xE4, 0x60, 0xBC, 0x65, 0xEF, 0x95, 0xDA, + 0xF9, 0xE4, 0x60, 0xBC, 0x65, 0xEF, 0x95, 0xDA, 0x58, 0xF7, 0x40, 0xB7, 0xD1, 0xDB, 0xB0, 0xAA]; let mut salsa20 = Salsa20::new(&key, &nonce); salsa20.process(&input, &mut stream); assert!(stream[..] == result[..]); } - + #[test] fn test_salsa20_256bit_ecrypt_set_1_vector_0() { let key = @@ -330,7 +332,7 @@ mod test { #[test] fn test_xsalsa20_cryptopp() { - let key = + let key = [0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, 0xd4, 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, 0x46, 0xc7, 0x60, 0x09, 0x54, 0x9e, 0xac, 0x64, 0x74, 0xf2, @@ -383,7 +385,7 @@ mod bench { }); bh.bytes = input.len() as u64; } - + #[bench] pub fn salsa20_1k(bh: & mut Bencher) { let mut salsa20 = Salsa20::new(&[0; 32], &[0; 8]); @@ -394,7 +396,7 @@ mod bench { }); bh.bytes = input.len() as u64; } - + #[bench] pub fn salsa20_64k(bh: & mut Bencher) { let mut salsa20 = Salsa20::new(&[0; 32], &[0; 8]); diff --git a/src/sha1.rs b/src/sha1.rs index fe637ed..3ed9a49 100644 --- a/src/sha1.rs +++ b/src/sha1.rs @@ -379,7 +379,7 @@ fn mk_result(st: &mut Sha1, rs: &mut [u8]) { } /// Structure representing the state of a Sha1 computation -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct Sha1 { h: [u32; STATE_LEN], length_bits: u64, diff --git a/src/sha2.rs b/src/sha2.rs index b081b8a..a278dbf 100644 --- a/src/sha2.rs +++ b/src/sha2.rs @@ -968,7 +968,7 @@ static H512_TRUNC_224: [u64; STATE_LEN] = [ // A structure that represents that state of a digest computation for the SHA-2 512 family of digest // functions -#[derive(Copy)] +#[derive(Clone, Copy)] struct Engine256State { h: [u32; 8], } @@ -1031,7 +1031,7 @@ pub const K32X4: [u32x4; 16] = [ // A structure that keeps track of the state of the Sha-256 operation and contains the logic // necessary to perform the final calculations. -#[derive(Copy)] +#[derive(Clone, Copy)] struct Engine256 { length_bits: u64, buffer: FixedBuffer64, @@ -1081,7 +1081,7 @@ impl Engine256 { /// The SHA-256 hash algorithm with the SHA-256 initial hash value. -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct Sha256 { engine: Engine256 } @@ -1137,7 +1137,7 @@ static H256: [u32; STATE_LEN] = [ /// The SHA-256 hash algorithm with the SHA-224 initial hash value. The result is truncated to 224 bits. -#[derive(Copy)] +#[derive(Clone, Copy)] pub struct Sha224 { engine: Engine256 } diff --git a/src/simd.rs b/src/simd.rs index 6138d42..53f6d20 100644 --- a/src/simd.rs +++ b/src/simd.rs @@ -23,7 +23,7 @@ impl SimdExt for fake::u32x4 { mod fake { use std::ops::{Add, BitAnd, BitOr, BitXor, Shl, Shr, Sub}; - #[derive(Copy, PartialEq, Eq)] + #[derive(Clone, Copy, PartialEq, Eq)] #[allow(non_camel_case_types)] pub struct u32x4(pub u32, pub u32, pub u32, pub u32); @@ -107,7 +107,7 @@ mod fake { } } - #[derive(Copy)] + #[derive(Clone, Copy)] #[allow(non_camel_case_types)] pub struct u64x2(pub u64, pub u64); @@ -119,4 +119,3 @@ mod fake { } } } - diff --git a/src/sosemanuk.rs b/src/sosemanuk.rs index 5b050d7..977286a 100644 --- a/src/sosemanuk.rs +++ b/src/sosemanuk.rs @@ -3,16 +3,16 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. - - + + use buffer::{BufferResult, RefReadBuffer, RefWriteBuffer}; use symmetriccipher::{Encryptor, Decryptor, SynchronousStreamCipher, SymmetricCipherError}; use cryptoutil::{read_u32_le, symm_enc_or_dec, write_u32v_le}; - + use cryptoutil::copy_memory; -const ALPHA_MUL_TABLE : [u32; 256] = +const ALPHA_MUL_TABLE : [u32; 256] = [ 0x00000000, 0xE19FCF13, 0x6B973726, 0x8A08F835, 0xD6876E4C, 0x3718A15F, 0xBD10596A, 0x5C8F9679, @@ -80,7 +80,7 @@ const ALPHA_MUL_TABLE : [u32; 256] = 0xB55B4DDE, 0x54C482CD, 0xDECC7AF8, 0x3F53B5EB ]; -const ALPHA_DIV_TABLE : [u32; 256] = +const ALPHA_DIV_TABLE : [u32; 256] = [ 0x00000000, 0x180F40CD, 0x301E8033, 0x2811C0FE, 0x603CA966, 0x7833E9AB, 0x50222955, 0x482D6998, @@ -157,20 +157,22 @@ pub struct Sosemanuk { output: [u8; 80], offset: u32 } - + +impl Clone for Sosemanuk { fn clone(&self) -> Sosemanuk { *self } } + impl Sosemanuk { pub fn new(key: &[u8], nonce: &[u8]) -> Sosemanuk { let mut sosemanuk = Sosemanuk { lfsr: [0; 10], fsm_r: [0; 2], subkeys: [0; 100], output: [0; 80], offset: 80 }; - + assert!(key.len() <= 32); assert!(nonce.len() <= 16); - + key_setup(&key, &mut sosemanuk.subkeys); iv_setup(&nonce, &mut sosemanuk.subkeys, &mut sosemanuk.lfsr, &mut sosemanuk.fsm_r); - + sosemanuk } - + fn advance_state(&mut self) { let mut s0 = self.lfsr[0]; let mut s1 = self.lfsr[1]; @@ -194,10 +196,10 @@ impl Sosemanuk { let mut v2 : u32; let mut v3 : u32; let mut tt : u32; - + let ref mul_alpha = ALPHA_MUL_TABLE; let ref div_alpha = ALPHA_DIV_TABLE; - + tt = r1; //r1 = r2 + (s1 ^ ((r1 & 0x01) != 0 ? s8 : 0)); r1 = r2.wrapping_add(s1 ^ match r1 & 0x01 { @@ -209,7 +211,7 @@ impl Sosemanuk { s0 = ((s0 << 8) ^ mul_alpha[s0 as usize >> 24]) ^ ((s3 >> 8) ^ div_alpha[s3 as usize & 0xFF]) ^ s9; f0 = s9.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s2 ^ ((r1 & 0x01) != 0 ? s9 : 0)); r1 = r2.wrapping_add(s2 ^ match r1 & 0x01 { @@ -221,7 +223,7 @@ impl Sosemanuk { s1 = ((s1 << 8) ^ mul_alpha[s1 as usize >> 24]) ^ ((s4 >> 8) ^ div_alpha[s4 as usize & 0xFF]) ^ s0; f1 = s0.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s3 ^ ((r1 & 0x01) != 0 ? s0 : 0)); r1 = r2.wrapping_add(s3 ^ match r1 & 0x01 { @@ -233,7 +235,7 @@ impl Sosemanuk { s2 = ((s2 << 8) ^ mul_alpha[s2 as usize >> 24]) ^ ((s5 >> 8) ^ div_alpha[s5 as usize & 0xFF]) ^ s1; f2 = s1.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s4 ^ ((r1 & 0x01) != 0 ? s1 : 0)); r1 = r2.wrapping_add(s4 ^ match r1 & 0x01 { @@ -245,7 +247,7 @@ impl Sosemanuk { s3 = ((s3 << 8) ^ mul_alpha[s3 as usize >> 24]) ^ ((s6 >> 8) ^ div_alpha[s6 as usize & 0xFF]) ^ s2; f3 = s2.wrapping_add(r1) ^ r2; - + /* * Apply the third S-box (number 2) on (f3, f2, f1, f0). */ @@ -265,7 +267,7 @@ impl Sosemanuk { f1 ^= f3; f1 ^= f4; f4 = !f4; - + /* * S-box result is in (f2, f3, f1, f4). */ @@ -283,7 +285,7 @@ impl Sosemanuk { s4 = ((s4 << 8) ^ mul_alpha[s4 as usize >> 24]) ^ ((s7 >> 8) ^ div_alpha[s7 as usize & 0xFF]) ^ s3; f0 = s3.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s6 ^ ((r1 & 0x01) != 0 ? s3 : 0)); r1 = r2.wrapping_add(s6 ^ match r1 & 0x01 { @@ -295,7 +297,7 @@ impl Sosemanuk { s5 = ((s5 << 8) ^ mul_alpha[s5 as usize >> 24]) ^ ((s8 >> 8) ^ div_alpha[s8 as usize & 0xFF]) ^ s4; f1 = s4.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s7 ^ ((r1 & 0x01) != 0 ? s4 : 0)); r1 = r2.wrapping_add(s7 ^ match r1 & 0x01 { @@ -307,7 +309,7 @@ impl Sosemanuk { s6 = ((s6 << 8) ^ mul_alpha[s6 as usize >> 24]) ^ ((s9 >> 8) ^ div_alpha[s9 as usize & 0xFF]) ^ s5; f2 = s5.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s8 ^ ((r1 & 0x01) != 0 ? s5 : 0)); r1 = r2.wrapping_add(s8 ^ match r1 & 0x01 { @@ -319,7 +321,7 @@ impl Sosemanuk { s7 = ((s7 << 8) ^ mul_alpha[s7 as usize >> 24]) ^ ((s0 >> 8) ^ div_alpha[s0 as usize & 0xFF]) ^ s6; f3 = s6.wrapping_add(r1) ^ r2; - + /* * Apply the third S-box (number 2) on (f3, f2, f1, f0). */ @@ -339,7 +341,7 @@ impl Sosemanuk { f1 ^= f3; f1 ^= f4; f4 = !f4; - + /* * S-box result is in (f2, f3, f1, f4). */ @@ -357,7 +359,7 @@ impl Sosemanuk { s8 = ((s8 << 8) ^ mul_alpha[s8 as usize >> 24]) ^ ((s1 >> 8) ^ div_alpha[s1 as usize & 0xFF]) ^ s7; f0 = s7.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s0 ^ ((r1 & 0x01) != 0 ? s7 : 0)); r1 = r2.wrapping_add(s0 ^ match r1 & 0x01 { @@ -369,7 +371,7 @@ impl Sosemanuk { s9 = ((s9 << 8) ^ mul_alpha[s9 as usize >> 24]) ^ ((s2 >> 8) ^ div_alpha[s2 as usize & 0xFF]) ^ s8; f1 = s8.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s1 ^ ((r1 & 0x01) != 0 ? s8 : 0)); r1 = r2.wrapping_add(s1 ^ match r1 & 0x01 { @@ -381,7 +383,7 @@ impl Sosemanuk { s0 = ((s0 << 8) ^ mul_alpha[s0 as usize >> 24]) ^ ((s3 >> 8) ^ div_alpha[s3 as usize & 0xFF]) ^ s9; f2 = s9.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s2 ^ ((r1 & 0x01) != 0 ? s9 : 0)); r1 = r2.wrapping_add(s2 ^ match r1 & 0x01 { @@ -393,7 +395,7 @@ impl Sosemanuk { s1 = ((s1 << 8) ^ mul_alpha[s1 as usize >> 24]) ^ ((s4 >> 8) ^ div_alpha[s4 as usize & 0xFF]) ^ s0; f3 = s0.wrapping_add(r1) ^ r2; - + /* * Apply the third S-box (number 2) on (f3, f2, f1, f0). */ @@ -413,7 +415,7 @@ impl Sosemanuk { f1 ^= f3; f1 ^= f4; f4 = !f4; - + /* * S-box result is in (f2, f3, f1, f4). */ @@ -431,7 +433,7 @@ impl Sosemanuk { s2 = ((s2 << 8) ^ mul_alpha[s2 as usize >> 24]) ^ ((s5 >> 8) ^ div_alpha[s5 as usize & 0xFF]) ^ s1; f0 = s1.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s4 ^ ((r1 & 0x01) != 0 ? s1 : 0)); r1 = r2.wrapping_add(s4 ^ match r1 & 0x01 { @@ -443,7 +445,7 @@ impl Sosemanuk { s3 = ((s3 << 8) ^ mul_alpha[s3 as usize >> 24]) ^ ((s6 >> 8) ^ div_alpha[s6 as usize & 0xFF]) ^ s2; f1 = s2.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s5 ^ ((r1 & 0x01) != 0 ? s2 : 0)); r1 = r2.wrapping_add(s5 ^ match r1 & 0x01 { @@ -455,7 +457,7 @@ impl Sosemanuk { s4 = ((s4 << 8) ^ mul_alpha[s4 as usize >> 24]) ^ ((s7 >> 8) ^ div_alpha[s7 as usize & 0xFF]) ^ s3; f2 = s3.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s6 ^ ((r1 & 0x01) != 0 ? s3 : 0)); r1 = r2.wrapping_add(s6 ^ match r1 & 0x01 { @@ -467,7 +469,7 @@ impl Sosemanuk { s5 = ((s5 << 8) ^ mul_alpha[s5 as usize >> 24]) ^ ((s8 >> 8) ^ div_alpha[s8 as usize & 0xFF]) ^ s4; f3 = s4.wrapping_add(r1) ^ r2; - + /* * Apply the third S-box (number 2) on (f3, f2, f1, f0). */ @@ -487,13 +489,13 @@ impl Sosemanuk { f1 ^= f3; f1 ^= f4; f4 = !f4; - + /* * S-box result is in (f2, f3, f1, f4). */ let sbox_res = [(f2 ^ v0), (f3 ^ v1), (f1 ^ v2), (f4 ^ v3)]; write_u32v_le(&mut self.output[48..64], &sbox_res); - + tt = r1; //r1 = r2 + (s7 ^ ((r1 & 0x01) != 0 ? s4 : 0)); r1 = r2.wrapping_add(s7 ^ match r1 & 0x01 { @@ -505,7 +507,7 @@ impl Sosemanuk { s6 = ((s6 << 8) ^ mul_alpha[s6 as usize >> 24]) ^ ((s9 >> 8) ^ div_alpha[s9 as usize & 0xFF]) ^ s5; f0 = s5.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s8 ^ ((r1 & 0x01) != 0 ? s5 : 0)); r1 = r2.wrapping_add(s8 ^ match r1 & 0x01 { @@ -517,7 +519,7 @@ impl Sosemanuk { s7 = ((s7 << 8) ^ mul_alpha[s7 as usize >> 24]) ^ ((s0 >> 8) ^ div_alpha[s0 as usize & 0xFF]) ^ s6; f1 = s6.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s9 ^ ((r1 & 0x01) != 0 ? s6 : 0)); r1 = r2.wrapping_add(s9 ^ match r1 & 0x01 { @@ -529,7 +531,7 @@ impl Sosemanuk { s8 = ((s8 << 8) ^ mul_alpha[s8 as usize >> 24]) ^ ((s1 >> 8) ^ div_alpha[s1 as usize & 0xFF]) ^ s7; f2 = s7.wrapping_add(r1) ^ r2; - + tt = r1; //r1 = r2 + (s0 ^ ((r1 & 0x01) != 0 ? s7 : 0)); r1 = r2.wrapping_add(s0 ^ match r1 & 0x01 { @@ -541,7 +543,7 @@ impl Sosemanuk { s9 = ((s9 << 8) ^ mul_alpha[s9 as usize >> 24]) ^ ( ( s2 >> 8) ^ div_alpha[s2 as usize & 0xFF]) ^ s8; f3 = s8.wrapping_add(r1) ^ r2; - + /* * Apply the third S-box (number 2) on (f3, f2, f1, f0). */ @@ -561,13 +563,13 @@ impl Sosemanuk { f1 ^= f3; f1 ^= f4; f4 = !f4; - + /* * S-box result is in (f2, f3, f1, f4). */ let sbox_res = [(f2 ^ v0), (f3 ^ v1), (f1 ^ v2), (f4 ^ v3)]; write_u32v_le(&mut self.output[64..80], &sbox_res); - + self.lfsr[0] = s0; self.lfsr[1] = s1; self.lfsr[2] = s2; @@ -582,7 +584,7 @@ impl Sosemanuk { self.fsm_r[1] = r2; self.offset = 0; } - + fn next(&mut self) -> u8 { if self.offset == 80 { self.advance_state(); @@ -593,7 +595,7 @@ impl Sosemanuk { } } - + fn key_setup(key : &[u8], subkeys : &mut[u32; 100]) { let mut full_key : [u8; 32] = [0; 32]; if key.len() < 32 { @@ -602,7 +604,7 @@ fn key_setup(key : &[u8], subkeys : &mut[u32; 100]) { } else { copy_memory(&key[0..32], &mut full_key[0..32]); } - + let mut w0 = read_u32_le(&full_key[0..4]); let mut w1 = read_u32_le(&full_key[4..8]); let mut w2 = read_u32_le(&full_key[8..12]); @@ -618,7 +620,7 @@ fn key_setup(key : &[u8], subkeys : &mut[u32; 100]) { let mut r4 : u32; let mut tt : u32; let mut i = 0; - + tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (0)); w0 = tt.rotate_left(11); tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (0 + 1)); @@ -1483,7 +1485,7 @@ fn key_setup(key : &[u8], subkeys : &mut[u32; 100]) { subkeys[i] = r3; i+=1; subkeys[i] = r4; } - + fn iv_setup(iv : &[u8], subkeys : &mut[u32; 100], lfsr : &mut[u32; 10], fsm_r : &mut[u32; 2]) { let mut nonce : [u8; 16] = [0; 16]; if iv.len() < 16 { @@ -1491,7 +1493,7 @@ fn iv_setup(iv : &[u8], subkeys : &mut[u32; 100], lfsr : &mut[u32; 10], fsm_r : } else { copy_memory(&iv[0..16], &mut nonce[0..16]); } - + let mut r0 : u32; let mut r1 : u32; let mut r2 : u32; @@ -1501,7 +1503,7 @@ fn iv_setup(iv : &[u8], subkeys : &mut[u32; 100], lfsr : &mut[u32; 10], fsm_r : r1 = read_u32_le(&nonce[4..8]); r2 = read_u32_le(&nonce[8..12]); r3 = read_u32_le(&nonce[12..16]); - + r0 ^= subkeys[0]; r1 ^= subkeys[0 + 1]; r2 ^= subkeys[0 + 2]; @@ -2300,7 +2302,7 @@ fn iv_setup(iv : &[u8], subkeys : &mut[u32; 100], lfsr : &mut[u32; 10], fsm_r : lfsr[0] = r3; } - + impl SynchronousStreamCipher for Sosemanuk { fn process(&mut self, input: &[u8], output: &mut [u8]) { assert!(input.len() == output.len()); @@ -2309,14 +2311,14 @@ impl SynchronousStreamCipher for Sosemanuk { } } } - + impl Encryptor for Sosemanuk { fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool) -> Result { symm_enc_or_dec(self, input, output) } } - + impl Decryptor for Sosemanuk { fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool) -> Result { @@ -2324,7 +2326,7 @@ impl Decryptor for Sosemanuk { } } - + #[cfg(test)] mod test { use sosemanuk::Sosemanuk; @@ -2488,7 +2490,7 @@ mod bench { }); bh.bytes = input.len() as u64; } - + #[bench] pub fn sosemanuk_1k(bh: & mut Bencher) { let mut sosemanuk = Sosemanuk::new(&[0; 32], &[0; 16]); @@ -2499,7 +2501,7 @@ mod bench { }); bh.bytes = input.len() as u64; } - + #[bench] pub fn sosemanuk_64k(bh: & mut Bencher) { let mut sosemanuk = Sosemanuk::new(&[0; 32], &[0; 16]); diff --git a/src/symmetriccipher.rs b/src/symmetriccipher.rs index 771541a..43b52c2 100644 --- a/src/symmetriccipher.rs +++ b/src/symmetriccipher.rs @@ -27,7 +27,7 @@ pub trait BlockDecryptorX8 { fn decrypt_block_x8(&self, input: &[u8], output: &mut [u8]); } -#[derive(Debug, Copy)] +#[derive(Debug, Clone, Copy)] pub enum SymmetricCipherError { InvalidLength, InvalidPadding