1 use nettle_sys::{
2     aes192_ctx, nettle_aes192_decrypt, nettle_aes192_encrypt,
3     nettle_aes192_invert_key, nettle_aes192_set_decrypt_key,
4     nettle_aes192_set_encrypt_key,
5 };
6 use std::cmp::min;
7 use std::mem::zeroed;
8 use std::os::raw::c_void;
9 
10 use crate::cipher::RawCipherFunctionPointer;
11 use crate::{cipher::Cipher, Error, Result};
12 
13 /// 192 bit variant of the Advanced Encryption Standard (AES, formerly RIJNDAEL) defined in FIPS 197.
14 pub struct Aes192 {
15     context: aes192_ctx,
16 }
17 
18 impl Aes192 {
19     /// Creates a new `Aes192` instance for decryption that uses the same key as `encrypt`. The
20     /// `encrypt` instance must be configured for encryption. This is faster than calling
21     /// `with_decrypt_key`.
with_inverted_key(encrypt: &Self) -> Self22     pub fn with_inverted_key(encrypt: &Self) -> Self {
23         let mut ctx = unsafe { zeroed() };
24         unsafe {
25             nettle_aes192_invert_key(
26                 &mut ctx as *mut _,
27                 &encrypt.context as *const _,
28             );
29         }
30 
31         Aes192 { context: ctx }
32     }
33 }
34 
35 impl Cipher for Aes192 {
36     const BLOCK_SIZE: usize = ::nettle_sys::AES_BLOCK_SIZE as usize;
37     const KEY_SIZE: usize = ::nettle_sys::AES192_KEY_SIZE as usize;
38 
with_encrypt_key(key: &[u8]) -> Result<Aes192>39     fn with_encrypt_key(key: &[u8]) -> Result<Aes192> {
40         if key.len() != Aes192::KEY_SIZE {
41             return Err(Error::InvalidArgument { argument_name: "key" }.into());
42         }
43 
44         let mut ctx = unsafe { zeroed() };
45         unsafe {
46             nettle_aes192_set_encrypt_key(&mut ctx as *mut _, key.as_ptr());
47         }
48 
49         Ok(Aes192 { context: ctx })
50     }
51 
with_decrypt_key(key: &[u8]) -> Result<Aes192>52     fn with_decrypt_key(key: &[u8]) -> Result<Aes192> {
53         if key.len() != Aes192::KEY_SIZE {
54             return Err(Error::InvalidArgument { argument_name: "key" }.into());
55         }
56 
57         let mut ctx = unsafe { zeroed() };
58         unsafe {
59             nettle_aes192_set_decrypt_key(&mut ctx as *mut _, key.as_ptr());
60         }
61 
62         Ok(Aes192 { context: ctx })
63     }
64 
encrypt(&mut self, dst: &mut [u8], src: &[u8])65     fn encrypt(&mut self, dst: &mut [u8], src: &[u8]) {
66         unsafe {
67             nettle_aes192_encrypt(
68                 &mut self.context as *mut _,
69                 min(src.len(), dst.len()),
70                 dst.as_mut_ptr(),
71                 src.as_ptr(),
72             )
73         };
74     }
75 
decrypt(&mut self, dst: &mut [u8], src: &[u8])76     fn decrypt(&mut self, dst: &mut [u8], src: &[u8]) {
77         unsafe {
78             nettle_aes192_decrypt(
79                 &mut self.context as *mut _,
80                 min(src.len(), dst.len()),
81                 dst.as_mut_ptr(),
82                 src.as_ptr(),
83             )
84         };
85     }
86 
context(&mut self) -> *mut c_void87     fn context(&mut self) -> *mut c_void {
88         ((&mut self.context) as *mut aes192_ctx) as *mut c_void
89     }
90 
raw_encrypt_function() -> RawCipherFunctionPointer91     fn raw_encrypt_function() -> RawCipherFunctionPointer {
92         RawCipherFunctionPointer::new(nettle_aes192_encrypt)
93     }
94 
raw_decrypt_function() -> RawCipherFunctionPointer95     fn raw_decrypt_function() -> RawCipherFunctionPointer {
96         RawCipherFunctionPointer::new(nettle_aes192_decrypt)
97     }
98 }
99 
100 #[cfg(test)]
101 mod tests {
102     use super::*;
103 
104     #[test]
set_key()105     fn set_key() {
106         let key = &(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\x09\x10\x11\x12\x13\x14\x15\x16"[..]);
107         let _ = Aes192::with_encrypt_key(key).unwrap();
108         let _ = Aes192::with_decrypt_key(key).unwrap();
109     }
110 
111     #[test]
round_trip()112     fn round_trip() {
113         let key = vec![
114             0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11,
115             0x12, 0x13, 0x14, 0x15, 0x16, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14,
116             0x15, 0x16,
117         ];
118         let input = vec![
119             0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11,
120             0x12, 0x13, 0x14, 0x15, 0x16,
121         ];
122         let mut cipher = vec![0; 16];
123         let mut output = vec![0; 16];
124 
125         let mut enc = Aes192::with_encrypt_key(&key).unwrap();
126         let mut dec = Aes192::with_decrypt_key(&key).unwrap();
127 
128         enc.encrypt(&mut cipher, &input);
129         dec.decrypt(&mut output, &cipher);
130 
131         assert_eq!(output, input);
132     }
133 
134     #[test]
round_trip_invert()135     fn round_trip_invert() {
136         let key = vec![
137             0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11,
138             0x12, 0x13, 0x14, 0x15, 0x16, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14,
139             0x15, 0x16,
140         ];
141         let input = vec![
142             0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11,
143             0x12, 0x13, 0x14, 0x15, 0x16,
144         ];
145         let mut cipher = vec![0; 16];
146         let mut output = vec![0; 16];
147 
148         let mut enc = Aes192::with_encrypt_key(&key).unwrap();
149         let mut dec = Aes192::with_inverted_key(&enc);
150 
151         enc.encrypt(&mut cipher, &input);
152         dec.decrypt(&mut output, &cipher);
153 
154         assert_eq!(output, input);
155     }
156 }
157