ctaes_sys/
lib.rs

1#[macro_use]
2extern crate failure;
3extern crate typenum;
4extern crate generic_array;
5extern crate libc;
6
7use failure::Error;
8use typenum::{U15, U32};
9use generic_array::{GenericArray, ArrayLength};
10use libc::c_uchar;
11
12#[repr(C)]
13#[derive(Debug, Copy, Clone, Default)]
14pub struct AES_state {
15    pub slice: [u16; 8],
16}
17
18#[repr(C)]
19#[derive(Debug, Copy, Clone, Default)]
20pub struct AES256_ctx {
21    pub rk: [AES_state; 15],
22}
23
24#[link_name = "ctaes"]
25extern "C" {
26    pub fn AES256_init(ctx: *mut AES256_ctx, key32: *const c_uchar);
27
28    pub fn AES256_encrypt(
29        ctx: *const AES256_ctx,
30        blocks: usize,
31        cipher16: *mut c_uchar,
32        plain16: *const c_uchar,
33    );
34
35    pub fn AES256_decrypt(
36        ctx: *const AES256_ctx,
37        blocks: usize,
38        plain16: *mut c_uchar,
39        cipher16: *const c_uchar,
40    );
41}
42
43#[derive(Debug, Copy, Clone, Default)]
44pub struct AESGCMState(pub [u16; 8]);
45
46impl AESGCMState {
47    fn as_c_repr(&self) -> AES_state {
48        AES_state { slice: self.0 }
49    }
50
51    fn from_c_repr(repr: AES_state) -> AESGCMState {
52        AESGCMState(repr.slice)
53    }
54}
55
56#[derive(Debug, Copy, Clone, Default)]
57pub struct AESGCM256(pub GenericArray<AESGCMState, U15>);
58
59impl AESGCM256 {
60    fn as_c_repr(&self) -> AES256_ctx {
61        let mut arr = [AES_state::default(); 15];
62        for i in 0..15 {
63            arr[i] = self.0[i].as_c_repr();
64        }
65        AES256_ctx { rk: arr }
66    }
67
68    fn from_c_repr(repr: AES256_ctx) -> AESGCM256 {
69        let mut arr = GenericArray::<AESGCMState, U15>::default();
70        for i in 0..15 {
71            arr[i] = AESGCMState::from_c_repr(repr.rk[i]);
72        }
73        AESGCM256(arr)
74    }
75}
76
77pub trait AESGCMCipher {
78    type Ctx;
79    type KeySize: ArrayLength<u8>;
80    fn new(key: GenericArray<u8, Self::KeySize>) -> Self;
81    fn encrypt(&mut self, plain: &[u8]) -> Result<Vec<u8>, Error>;
82    fn decrypt(&mut self, ciph: &[u8]) -> Result<Vec<u8>, Error>;
83}
84
85pub type AES256GCMKey = GenericArray<u8, U32>;
86
87impl AESGCMCipher for AESGCM256 {
88    type Ctx = AESGCM256;
89    type KeySize = U32;
90
91    fn new(key: AES256GCMKey) -> Self {
92        let mut ctx = AES256_ctx::default();
93        unsafe {
94            AES256_init(&mut ctx, key.as_slice().as_ptr());
95        }
96        AESGCM256::from_c_repr(ctx)
97    }
98
99    fn encrypt(&mut self, plain: &[u8]) -> Result<Vec<u8>, Error> {
100        let ctx = self.as_c_repr();
101        let len = plain.len();
102        if len % 16 != 0 {
103            return Err(format_err!("invalid length"));
104        }
105        let blocks = len / 16;
106        let mut ciph = Vec::new();
107        for _ in 0..blocks {
108            ciph.extend_from_slice(&[0u8; 16][..]);
109        }
110        unsafe {
111            AES256_encrypt(&ctx, blocks, ciph.as_mut_ptr(), plain.as_ptr());
112        }
113        Ok(ciph)
114    }
115
116    fn decrypt(&mut self, ciph: &[u8]) -> Result<Vec<u8>, Error> {
117        let ctx = self.as_c_repr();
118        let len = ciph.len();
119        if len % 16 != 0 {
120            return Err(format_err!("invalid length"));
121        }
122        let blocks = len / 16;
123        let mut plain = Vec::new();
124        for _ in 0..blocks {
125            plain.extend_from_slice(&[0u8; 16][..]);
126        }
127        unsafe {
128            AES256_decrypt(&ctx, blocks, plain.as_mut_ptr(), ciph.as_ptr());
129        }
130        Ok(plain)
131    }
132}
133
134#[cfg(test)]
135mod tests {
136    extern crate hex;
137
138    use super::*;
139
140    fn test_vectors() -> Vec<(String, String, String)> {
141        vec![
142            (
143                "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f".to_string(),
144                "00112233445566778899aabbccddeeff".to_string(),
145                "8ea2b7ca516745bfeafc49904b496089".to_string()
146            ),
147            (
148                "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4".to_string(),
149                "6bc1bee22e409f96e93d7e117393172a".to_string(),
150                "f3eed1bdb5d2a03c064b5a7e3db181f8".to_string()
151            ),
152            (
153                "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4".to_string(),
154                "ae2d8a571e03ac9c9eb76fac45af8e51".to_string(),
155                "591ccb10d410ed26dc5ba74a31362870".to_string()
156            ),
157            (
158                "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4".to_string(),
159                "30c81c46a35ce411e5fbc1191a0a52ef".to_string(),
160                "b6ed21b99ca6f4f9f153e7b1beafed1d".to_string()
161            ),
162            (
163                "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4".to_string(),
164                "f69f2445df4f9b17ad2b417be66c3710".to_string(),
165                "23304b7a39f9f3ff067d8d8f9e24ecc7".to_string()
166            ),
167        ]
168    }
169
170    #[test]
171    fn aes_gcm_encrypt_test_vectors() {
172        for v in test_vectors() {
173            let key = *AES256GCMKey::from_slice(hex::decode(v.0).unwrap().as_slice());
174            let mut cipher = AESGCM256::new(key);
175            let res = cipher.encrypt(hex::decode(v.1).unwrap().as_slice()).unwrap();
176            let test = hex::decode(v.2).unwrap();
177            assert_eq!(res, test.as_slice())
178        }
179    }
180
181    #[test]
182    fn aes_gcm_decrypt_test_vectors() {
183        for v in test_vectors() {
184            let key = *AES256GCMKey::from_slice(hex::decode(v.0).unwrap().as_slice());
185            let mut cipher = AESGCM256::new(key);
186            let res = cipher.decrypt(hex::decode(v.2).unwrap().as_slice()).unwrap();
187            let test = hex::decode(v.1).unwrap();
188            assert_eq!(res, test.as_slice())
189        }
190    }
191}