|
14 | 14 | // You should have received a copy of the GNU General Public License
|
15 | 15 | // along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
16 | 16 |
|
| 17 | +use block_modes::{BlockMode}; |
| 18 | +use block_modes::block_padding::Pkcs7; |
| 19 | +use block_modes::block_padding::ZeroPadding; |
| 20 | +use block_modes::{ Cbc, Ecb }; |
| 21 | +use raes::{ Aes128, Aes256 }; |
| 22 | +use aes_ctr::{ Aes128Ctr, Aes256Ctr }; |
| 23 | +use aes_ctr::stream_cipher::{ NewStreamCipher, SyncStreamCipher }; |
17 | 24 | use error::SymmError;
|
18 |
| -use rcrypto::blockmodes::{CtrMode, CbcDecryptor, PkcsPadding}; |
19 |
| -use rcrypto::aessafe::{AesSafe128Encryptor, AesSafe128Decryptor}; |
20 |
| -use rcrypto::symmetriccipher::{Encryptor, Decryptor}; |
21 |
| -use rcrypto::buffer::{RefReadBuffer, RefWriteBuffer, WriteBuffer}; |
| 25 | +use raes::block_cipher_trait::generic_array::GenericArray; |
| 26 | + |
| 27 | + |
| 28 | +/// One time encoder/decoder for Ecb mode Aes256 with zero padding |
| 29 | +pub struct AesEcb256(Ecb<Aes256, ZeroPadding>); |
| 30 | + |
| 31 | +impl AesEcb256 { |
| 32 | + |
| 33 | + /// New encoder/decoder, no iv for ecb |
| 34 | + pub fn new(key: &[u8]) -> Result<Self, SymmError> { |
| 35 | + Ok(AesEcb256(Ecb::new_var(key, &[])?)) |
| 36 | + } |
| 37 | + |
| 38 | + /// Encrypt data in place without padding. The data length must be a multiple |
| 39 | + /// of the block size. |
| 40 | + pub fn encrypt(self, content: &mut [u8]) -> Result<(), SymmError> { |
| 41 | + let len = content.len(); |
| 42 | + self.0.encrypt(content, len)?; |
| 43 | + Ok(()) |
| 44 | + } |
| 45 | + |
| 46 | + /// Decrypt data in place without padding. The data length must be a multiple |
| 47 | + /// of the block size. |
| 48 | + pub fn decrypt(self, content: &mut [u8]) -> Result<(), SymmError> { |
| 49 | + self.0.decrypt(content)?; |
| 50 | + Ok(()) |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | + |
| 55 | +/// Reusable encoder/decoder for Aes256 in Ctr mode and no padding |
| 56 | +pub struct AesCtr256(Aes256Ctr); |
| 57 | + |
| 58 | +impl AesCtr256 { |
| 59 | + |
| 60 | + /// New encoder/decoder |
| 61 | + pub fn new(key: &[u8], iv: &[u8]) -> Result<Self, SymmError> { |
| 62 | + Ok(AesCtr256( |
| 63 | + Aes256Ctr::new(GenericArray::from_slice(key), GenericArray::from_slice(iv)) |
| 64 | + )) |
| 65 | + } |
| 66 | + |
| 67 | + /// In place encrypt a content without padding, the content length must be a multiple |
| 68 | + /// of the block size. |
| 69 | + pub fn encrypt(&mut self, content: &mut[u8]) -> Result<(), SymmError> { |
| 70 | + self.0.try_apply_keystream(content)?; |
| 71 | + Ok(()) |
| 72 | + } |
| 73 | + |
| 74 | + /// In place decrypt a content without padding, the content length must be a multiple |
| 75 | + /// of the block size. |
| 76 | + pub fn decrypt(&mut self, content: &mut[u8]) -> Result<(), SymmError> { |
| 77 | + self.0.try_apply_keystream(content)?; |
| 78 | + Ok(()) |
| 79 | + } |
| 80 | +} |
22 | 81 |
|
23 | 82 | /// Encrypt a message (CTR mode).
|
24 | 83 | ///
|
25 | 84 | /// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
|
26 | 85 | /// An error is returned if the input lengths are invalid.
|
| 86 | +/// If possible prefer `inplace_encrypt_128_ctr` to avoid a slice copy. |
27 | 87 | pub fn encrypt_128_ctr(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) -> Result<(), SymmError> {
|
28 |
| - let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); |
29 |
| - encryptor.encrypt(&mut RefReadBuffer::new(plain), &mut RefWriteBuffer::new(dest), true)?; |
| 88 | + let mut encryptor = Aes128Ctr::new( |
| 89 | + GenericArray::from_slice(k), |
| 90 | + GenericArray::from_slice(iv), |
| 91 | + ); |
| 92 | + &mut dest[..plain.len()].copy_from_slice(plain); |
| 93 | + encryptor.try_apply_keystream(dest)?; |
30 | 94 | Ok(())
|
| 95 | + |
| 96 | +} |
| 97 | + |
| 98 | +/// Encrypt a message (CTR mode). |
| 99 | +/// |
| 100 | +/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each. |
| 101 | +/// An error is returned if the input lengths are invalid. |
| 102 | +pub fn inplace_encrypt_128_ctr(k: &[u8], iv: &[u8], data: &mut [u8]) -> Result<(), SymmError> { |
| 103 | + let mut encryptor = Aes128Ctr::new( |
| 104 | + GenericArray::from_slice(k), |
| 105 | + GenericArray::from_slice(iv), |
| 106 | + ); |
| 107 | + encryptor.try_apply_keystream(data)?; |
| 108 | + Ok(()) |
| 109 | + |
31 | 110 | }
|
32 | 111 |
|
33 | 112 | /// Decrypt a message (CTR mode).
|
34 | 113 | ///
|
35 | 114 | /// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
|
36 | 115 | /// An error is returned if the input lengths are invalid.
|
| 116 | +/// If possible prefer `inplace_decrypt_128_ctr` instead. |
37 | 117 | pub fn decrypt_128_ctr(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<(), SymmError> {
|
38 |
| - let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); |
39 |
| - encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut RefWriteBuffer::new(dest), true)?; |
| 118 | + let mut encryptor = Aes128Ctr::new( |
| 119 | + GenericArray::from_slice(k), |
| 120 | + GenericArray::from_slice(iv), |
| 121 | + ); |
| 122 | + |
| 123 | + &mut dest[..encrypted.len()].copy_from_slice(encrypted); |
| 124 | + encryptor.try_apply_keystream(dest)?; |
40 | 125 | Ok(())
|
41 | 126 | }
|
42 | 127 |
|
| 128 | +/// Decrypt a message (CTR mode). |
| 129 | +/// |
| 130 | +/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each. |
| 131 | +/// An error is returned if the input lengths are invalid. |
| 132 | +pub fn inplace_decrypt_128_ctr(k: &[u8], iv: &[u8], data: &mut [u8]) -> Result<(), SymmError> { |
| 133 | + let mut encryptor = Aes128Ctr::new( |
| 134 | + GenericArray::from_slice(k), |
| 135 | + GenericArray::from_slice(iv), |
| 136 | + ); |
| 137 | + |
| 138 | + encryptor.try_apply_keystream(data)?; |
| 139 | + Ok(()) |
| 140 | +} |
| 141 | + |
| 142 | + |
43 | 143 | /// Decrypt a message (CBC mode).
|
44 | 144 | ///
|
45 | 145 | /// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
|
46 | 146 | /// An error is returned if the input lengths are invalid.
|
47 | 147 | pub fn decrypt_128_cbc(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<usize, SymmError> {
|
48 |
| - let mut encryptor = CbcDecryptor::new(AesSafe128Decryptor::new(k), PkcsPadding, iv.to_vec()); |
49 |
| - let len = dest.len(); |
50 |
| - let mut buffer = RefWriteBuffer::new(dest); |
51 |
| - encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut buffer, true)?; |
52 |
| - Ok(len - buffer.remaining()) |
| 148 | + let encryptor = Cbc::<Aes128, Pkcs7>::new_var(k, iv)?; |
| 149 | + &mut dest[..encrypted.len()].copy_from_slice(encrypted); |
| 150 | + let unpad_length = { |
| 151 | + encryptor.decrypt(&mut dest[..encrypted.len()])?.len() |
| 152 | + }; |
| 153 | + Ok(unpad_length) |
| 154 | +} |
| 155 | + |
| 156 | + |
| 157 | +#[cfg(test)] |
| 158 | +mod tests { |
| 159 | + |
| 160 | + use super::*; |
| 161 | + |
| 162 | + // only use for test could be expose in the future |
| 163 | + fn encrypt_128_cbc(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) -> Result<(), SymmError> { |
| 164 | + let encryptor = Cbc::<Aes128, Pkcs7>::new_var(k, iv)?; |
| 165 | + &mut dest[..plain.len()].copy_from_slice(plain); |
| 166 | + encryptor.encrypt(dest, plain.len())?; |
| 167 | + Ok(()) |
| 168 | + } |
| 169 | + |
| 170 | + #[test] |
| 171 | + pub fn test_aes_short() -> Result<(),SymmError> { |
| 172 | + let key = [97, 110, 121, 99, 111, 110, 116, 101, 110, 116, 116, 111, 114, 101, 97, 99, 104, 49, 50, 56, 98, 105, 116, 115, 105, 122, 101, 10]; |
| 173 | + let salt = [109, 121, 115, 97, 108, 116, 115, 104, 111, 117, 108, 100, 102, 105, 108, 108, 115, 111, 109, 109, 101, 98, 121, 116, 101, 108, 101, 110, 103, 116, 104, 10]; |
| 174 | + let content = [83, 111, 109, 101, 32, 99, 111, 110, 116, 101, 110, 116, 32, 116, 111, 32, 116, 101, 115, 116, |
| 175 | + 32, 97, 101, 115, 44, 10, 110, 111, 116, 32, 116, 111, 32, 109, 117, 99, 104, 32, 44, 32, 111, 110, 108, 121, |
| 176 | + 32, 118, 101, 114, 121, 32, 98, 97, 115, 105, 99, 32, 116, 101, 115, 116, 32, 116, 111, 32, 97, 118, 111, 105, |
| 177 | + 100, 32, 111, 98, 118, 105, 111, 117, 115, 32, 114, 101, 103, 114, 101, 115, 115, 105, 111, 110, 32, 119, 104, |
| 178 | + 101, 110, 32, 115, 119, 105, 116, 99, 104, 105, 110, 103, 32, 108, 105, 98, 115, 46, 10]; |
| 179 | + let ctr_enc = [65, 55, 246, 75, 24, 117, 30, 233, 218, 139, 91, 251, 251, 179, 171, 69, 60, 244, 249, 44, 238, 60, |
| 180 | + 10, 66, 71, 10, 199, 111, 54, 24, 124, 223, 153, 250, 159, 154, 164, 109, 232, 82, 20, 199, 182, 40, 174, 104, 64, |
| 181 | + 203, 236, 94, 222, 184, 117, 54, 234, 189, 253, 122, 135, 121, 100, 44, 227, 241, 123, 120, 110, 188, 109, 148, 112, |
| 182 | + 160, 131, 205, 116, 104, 232, 8, 22, 170, 80, 231, 155, 246, 255, 115, 101, 5, 234, 104, 220, 199, 192, 166, 181, 156, |
| 183 | + 113, 255, 187, 51, 38, 128, 75, 29, 237, 178, 205, 98, 101, 110]; |
| 184 | + let cbc_enc = [167, 248, 5, 90, 11, 140, 215, 138, 165, 125, 137, 76, 47, 243, 191, 48, 183, 247, 109, 86, 24, 45, |
| 185 | + 81, 215, 0, 51, 221, 185, 131, 97, 234, 189, 244, 255, 107, 210, 70, 60, 41, 221, 43, 137, 185, 166, 42, 65, 18, 200, |
| 186 | + 151, 233, 255, 192, 109, 25, 105, 115, 161, 209, 126, 235, 99, 192, 241, 241, 19, 249, 87, 244, 28, 146, 186, 189, 108, |
| 187 | + 9, 243, 132, 4, 105, 53, 162, 8, 235, 84, 107, 213, 59, 158, 113, 227, 120, 162, 50, 237, 123, 70, 187, 83, 73, 146, 13, |
| 188 | + 44, 191, 53, 4, 125, 207, 176, 45, 8, 153, 175, 198]; |
| 189 | + let mut dest = vec![0;110]; |
| 190 | + let mut dest_padded = vec![0;112]; |
| 191 | + let mut dest_padded2 = vec![0;128]; // TODO RustLib need an extra 16bytes in dest : looks extra buggy but function is not currently use (keep it private for now) |
| 192 | + encrypt_128_cbc(&key[..16], &salt[..16], &content, &mut dest_padded2)?; |
| 193 | + assert!(&dest_padded2[..112] == &cbc_enc[..]); |
| 194 | + encrypt_128_ctr(&key[..16], &salt[..16], &content, &mut dest)?; |
| 195 | + assert!(&dest[..] == &ctr_enc[..]); |
| 196 | + let mut content_data = content.to_vec(); |
| 197 | + inplace_encrypt_128_ctr(&key[..16], &salt[..16], &mut content_data[..])?; |
| 198 | + assert!(&content_data[..] == &ctr_enc[..]); |
| 199 | + decrypt_128_ctr(&key[..16], &salt[..16], &ctr_enc[..], &mut dest)?; |
| 200 | + assert!(&dest[..] == &content[..]); |
| 201 | + let mut content_data = ctr_enc.to_vec(); |
| 202 | + inplace_decrypt_128_ctr(&key[..16], &salt[..16], &mut content_data[..])?; |
| 203 | + assert!(&content_data[..] == &content[..]); |
| 204 | + let l = decrypt_128_cbc(&key[..16], &salt[..16], &cbc_enc[..], &mut dest_padded)?; |
| 205 | + assert!(&dest_padded[..l] == &content[..]); |
| 206 | + Ok(()) |
| 207 | + } |
53 | 208 | }
|
0 commit comments