]>
git.proxmox.com Git - cargo.git/blob - vendor/openssl-0.9.23/src/aes.rs
1 //! Low level AES IGE functionality
3 //! AES ECB, CBC, XTS, CTR, CFB, GCM and other conventional symmetric encryption
4 //! modes are found in [`symm`]. This is the implementation of AES IGE.
6 //! Advanced Encryption Standard (AES) provides symmetric key cipher that
7 //! the same key is used to encrypt and decrypt data. This implementation
8 //! uses 128, 192, or 256 bit keys. This module provides functions to
9 //! create a new key with [`new_encrypt`] and perform an encryption/decryption
10 //! using that key with [`aes_ige`].
12 //! [`new_encrypt`]: struct.AesKey.html#method.new_encrypt
13 //! [`aes_ige`]: fn.aes_ige.html
15 //! The [`symm`] module should be used in preference to this module in most cases.
16 //! The IGE block cypher is a non-traditional cipher mode. More traditional AES
17 //! encryption methods are found in the [`Crypter`] and [`Cipher`] structs.
19 //! [`symm`]: ../symm/index.html
20 //! [`Crypter`]: ../symm/struct.Crypter.html
21 //! [`Cipher`]: ../symm/struct.Cipher.html
26 //! # extern crate openssl;
28 //! use openssl::aes::{AesKey, KeyError, aes_ige};
29 //! use openssl::symm::Mode;
30 //! use hex::{FromHex, ToHex};
32 //! fn decrypt() -> Result<(), KeyError> {
33 //! let raw_key = "000102030405060708090A0B0C0D0E0F";
34 //! let hex_cipher = "12345678901234561234567890123456";
35 //! let randomness = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
36 //! if let (Ok(key_as_u8), Ok(cipher_as_u8), Ok(mut iv_as_u8)) =
37 //! (Vec::from_hex(raw_key), Vec::from_hex(hex_cipher), Vec::from_hex(randomness)) {
38 //! let key = AesKey::new_encrypt(&key_as_u8)?;
39 //! let mut output = vec![0u8; cipher_as_u8.len()];
40 //! aes_ige(&cipher_as_u8, &mut output, &key, &mut iv_as_u8, Mode::Encrypt);
41 //! assert_eq!(output.to_hex(), "a6ad974d5cea1d36d2f367980907ed32");
55 /// Provides Error handling for parsing keys.
57 pub struct KeyError(());
59 /// The key used to encrypt or decrypt cipher blocks.
60 pub struct AesKey(ffi
::AES_KEY
);
63 /// Prepares a key for encryption.
67 /// Returns an error if the key is not 128, 192, or 256 bits.
68 pub fn new_encrypt(key
: &[u8]) -> Result
<AesKey
, KeyError
> {
70 assert
!(key
.len() <= c_int
::max_value() as usize / 8);
72 let mut aes_key
= mem
::uninitialized();
73 let r
= ffi
::AES_set_encrypt_key(
74 key
.as_ptr() as *const _
,
75 key
.len() as c_int
* 8,
86 /// Prepares a key for decryption.
90 /// Returns an error if the key is not 128, 192, or 256 bits.
91 pub fn new_decrypt(key
: &[u8]) -> Result
<AesKey
, KeyError
> {
93 assert
!(key
.len() <= c_int
::max_value() as usize / 8);
95 let mut aes_key
= mem
::uninitialized();
96 let r
= ffi
::AES_set_decrypt_key(
97 key
.as_ptr() as *const _
,
98 key
.len() as c_int
* 8,
111 /// Performs AES IGE encryption or decryption
113 /// AES IGE (Infinite Garble Extension) is a form of AES block cipher utilized in
114 /// OpenSSL. Infinite Garble referes to propogating forward errors. IGE, like other
115 /// block ciphers implemented for AES requires an initalization vector. The IGE mode
116 /// allows a stream of blocks to be encrypted or decrypted without having the entire
117 /// plaintext available. For more information, visit [AES IGE Encryption].
119 /// This block cipher uses 16 byte blocks. The rust implmentation will panic
120 /// if the input or output does not meet this 16-byte boundry. Attention must
121 /// be made in this low level implementation to pad the value to the 128-bit boundry.
123 /// [AES IGE Encryption]: http://www.links.org/files/openssl-ige.pdf
127 /// Panics if `in_` is not the same length as `out`, if that length is not a multiple of 16, or if
128 /// `iv` is not at least 32 bytes.
129 pub fn aes_ige(in_
: &[u8], out
: &mut [u8], key
: &AesKey
, iv
: &mut [u8], mode
: Mode
) {
131 assert
!(in_
.len() == out
.len());
132 assert
!(in_
.len() % ffi
::AES_BLOCK_SIZE
as usize == 0);
133 assert
!(iv
.len() >= ffi
::AES_BLOCK_SIZE
as usize * 2);
135 let mode
= match mode
{
136 Mode
::Encrypt
=> ffi
::AES_ENCRYPT
,
137 Mode
::Decrypt
=> ffi
::AES_DECRYPT
,
139 ffi
::AES_ige_encrypt(
140 in_
.as_ptr() as *const _
,
141 out
.as_mut_ptr() as *mut _
,
144 iv
.as_mut_ptr() as *mut _
,
157 // From https://www.mgp25.com/AESIGE/
160 let raw_key
= "000102030405060708090A0B0C0D0E0F";
161 let raw_iv
= "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
162 let raw_pt
= "0000000000000000000000000000000000000000000000000000000000000000";
163 let raw_ct
= "1A8519A6557BE652E9DA8E43DA4EF4453CF456B4CA488AA383C79C98B34797CB";
165 let key
= AesKey
::new_encrypt(&Vec
::from_hex(raw_key
).unwrap()).unwrap();
166 let mut iv
= Vec
::from_hex(raw_iv
).unwrap();
167 let pt
= Vec
::from_hex(raw_pt
).unwrap();
168 let ct
= Vec
::from_hex(raw_ct
).unwrap();
170 let mut ct_actual
= vec
![0; ct
.len()];
171 aes_ige(&pt
, &mut ct_actual
, &key
, &mut iv
, Mode
::Encrypt
);
172 assert_eq
!(ct_actual
, ct
);
174 let key
= AesKey
::new_decrypt(&Vec
::from_hex(raw_key
).unwrap()).unwrap();
175 let mut iv
= Vec
::from_hex(raw_iv
).unwrap();
176 let mut pt_actual
= vec
![0; pt
.len()];
177 aes_ige(&ct
, &mut pt_actual
, &key
, &mut iv
, Mode
::Decrypt
);
178 assert_eq
!(pt_actual
, pt
);