]> git.proxmox.com Git - cargo.git/blame - vendor/openssl-0.9.15/src/aes.rs
New upstream version 0.22.0
[cargo.git] / vendor / openssl-0.9.15 / src / aes.rs
CommitLineData
3ee932bc
VK
1//! Low level AES functionality
2//!
3//! The `symm` module should be used in preference to this module in most cases.
4use ffi;
5use std::mem;
6use libc::c_int;
7
8use symm::Mode;
9
10#[derive(Debug)]
11pub struct KeyError(());
12
13pub struct AesKey(ffi::AES_KEY);
14
15impl AesKey {
16 /// Prepares a key for encryption.
17 ///
18 /// # Failure
19 ///
20 /// Returns an error if the key is not 128, 192, or 256 bits.
21 pub fn new_encrypt(key: &[u8]) -> Result<AesKey, KeyError> {
22 unsafe {
23 assert!(key.len() <= c_int::max_value() as usize / 8);
24
25 let mut aes_key = mem::uninitialized();
82fc9e21
VK
26 let r = ffi::AES_set_encrypt_key(
27 key.as_ptr() as *const _,
28 key.len() as c_int * 8,
29 &mut aes_key,
30 );
3ee932bc
VK
31 if r == 0 {
32 Ok(AesKey(aes_key))
33 } else {
34 Err(KeyError(()))
35 }
36 }
37 }
38
39 /// Prepares a key for decryption.
40 ///
41 /// # Failure
42 ///
43 /// Returns an error if the key is not 128, 192, or 256 bits.
44 pub fn new_decrypt(key: &[u8]) -> Result<AesKey, KeyError> {
45 unsafe {
46 assert!(key.len() <= c_int::max_value() as usize / 8);
47
48 let mut aes_key = mem::uninitialized();
82fc9e21
VK
49 let r = ffi::AES_set_decrypt_key(
50 key.as_ptr() as *const _,
51 key.len() as c_int * 8,
52 &mut aes_key,
53 );
3ee932bc
VK
54
55 if r == 0 {
56 Ok(AesKey(aes_key))
57 } else {
58 Err(KeyError(()))
59 }
60 }
61 }
62}
63
64/// Performs AES IGE encryption or decryption
65///
66/// # Panics
67///
68/// Panics if `in_` is not the same length as `out`, if that length is not a multiple of 16, or if
69/// `iv` is not at least 32 bytes.
70pub fn aes_ige(in_: &[u8], out: &mut [u8], key: &AesKey, iv: &mut [u8], mode: Mode) {
71 unsafe {
72 assert!(in_.len() == out.len());
73 assert!(in_.len() % ffi::AES_BLOCK_SIZE as usize == 0);
74 assert!(iv.len() >= ffi::AES_BLOCK_SIZE as usize * 2);
75
76 let mode = match mode {
77 Mode::Encrypt => ffi::AES_ENCRYPT,
78 Mode::Decrypt => ffi::AES_DECRYPT,
79 };
82fc9e21
VK
80 ffi::AES_ige_encrypt(
81 in_.as_ptr() as *const _,
82 out.as_mut_ptr() as *mut _,
83 in_.len(),
84 &key.0,
85 iv.as_mut_ptr() as *mut _,
86 mode,
87 );
3ee932bc
VK
88 }
89}
90
91#[cfg(test)]
92mod test {
93 use hex::FromHex;
94
95 use symm::Mode;
96 use super::*;
97
98 // From https://www.mgp25.com/AESIGE/
99 #[test]
100 fn ige_vector_1() {
101 let raw_key = "000102030405060708090A0B0C0D0E0F";
102 let raw_iv = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
103 let raw_pt = "0000000000000000000000000000000000000000000000000000000000000000";
104 let raw_ct = "1A8519A6557BE652E9DA8E43DA4EF4453CF456B4CA488AA383C79C98B34797CB";
105
106 let key = AesKey::new_encrypt(&Vec::from_hex(raw_key).unwrap()).unwrap();
107 let mut iv = Vec::from_hex(raw_iv).unwrap();
108 let pt = Vec::from_hex(raw_pt).unwrap();
109 let ct = Vec::from_hex(raw_ct).unwrap();
110
111 let mut ct_actual = vec![0; ct.len()];
112 aes_ige(&pt, &mut ct_actual, &key, &mut iv, Mode::Encrypt);
113 assert_eq!(ct_actual, ct);
114
115 let key = AesKey::new_decrypt(&Vec::from_hex(raw_key).unwrap()).unwrap();
116 let mut iv = Vec::from_hex(raw_iv).unwrap();
117 let mut pt_actual = vec![0; pt.len()];
118 aes_ige(&ct, &mut pt_actual, &key, &mut iv, Mode::Decrypt);
119 assert_eq!(pt_actual, pt);
120 }
121}