1use crate::boring::{CryptDecodeParam, HashType};
2mod curve;
3pub mod cipher;
4mod aead;
5
6use crate::boring::bindings::*;
7use crate::error::RlsResult;
8pub use aead::AeadCrypto;
9pub use cipher::Cipher;
10pub use curve::EvpCurve;
11
12use crate::boring::CryptEncodeParam;
13use crate::extend::Aead;
14use crate::hash::Hmac;
15use crate::RlsError;
16
17#[cfg_attr(feature = "export", repr(C))]
18#[allow(non_camel_case_types)]
19pub enum CipherType {
20 AES_128_CBC = 0,
21 AES_192_CBC = 1,
22 AES_256_CBC = 2,
23 AES_128_ECB = 3,
24 AES_192_ECB = 4,
25 AES_256_ECB = 5,
26 AES_128_CTR = 6,
27 AES_192_CTR = 7,
28 AES_256_CTR = 8,
29 AES_128_GCM = 9,
30 AES_192_GCM = 10,
31 AES_256_GCM = 11,
32 AES_128_OFB = 12,
33 AES_192_OFB = 13,
34 AES_256_OFB = 14,
35 DES_CBC = 15,
36 DES_ECB = 16,
37 RC4 = 17,
38}
39
40impl CipherType {
41 pub fn as_boring(&self) -> *const EVP_CIPHER {
42 match self {
43 CipherType::AES_128_CBC => unsafe { EVP_aes_128_cbc() }
44 CipherType::AES_192_CBC => unsafe { EVP_aes_192_cbc() }
45 CipherType::AES_256_CBC => unsafe { EVP_aes_256_cbc() }
46 CipherType::AES_128_ECB => unsafe { EVP_aes_128_ecb() }
47 CipherType::AES_192_ECB => unsafe { EVP_aes_192_ecb() }
48 CipherType::AES_256_ECB => unsafe { EVP_aes_256_ecb() }
49 CipherType::AES_128_CTR => unsafe { EVP_aes_128_ctr() }
50 CipherType::AES_192_CTR => unsafe { EVP_aes_192_ctr() }
51 CipherType::AES_256_CTR => unsafe { EVP_aes_256_ctr() }
52 CipherType::AES_128_GCM => unsafe { EVP_aes_128_gcm() }
53 CipherType::AES_192_GCM => unsafe { EVP_aes_192_gcm() }
54 CipherType::AES_256_GCM => unsafe { EVP_aes_256_gcm() }
55 CipherType::AES_128_OFB => unsafe { EVP_aes_128_ofb() }
56 CipherType::AES_192_OFB => unsafe { EVP_aes_192_ofb() }
57 CipherType::AES_256_OFB => unsafe { EVP_aes_256_ofb() }
58 CipherType::DES_CBC => unsafe { EVP_des_cbc() }
59 CipherType::DES_ECB => unsafe { EVP_des_ecb() }
60 CipherType::RC4 => unsafe { EVP_rc4() }
61 }
62 }
63}
64
65
66pub struct CipherCrypto {
67 mac_key: Vec<u8>,
68 key: Vec<u8>,
69 cipher: Cipher,
70 hash: HashType,
71}
72
73impl CipherCrypto {
74 pub fn new(aead: &Aead, key: Vec<u8>, mac: Vec<u8>, hash: HashType) -> RlsResult<CipherCrypto> {
75 let cipher = match aead {
76 Aead::AES_128_CBC_SHA => Cipher::aes_128_cbc(),
77 Aead::AES_256_CBC_SHA => Cipher::aes_256_cbc(),
78 _ => return Err("not suite, but in suite".into())
79 };
80 Ok(CipherCrypto {
81 mac_key: mac,
82 cipher,
83 key,
84 hash,
85 })
86 }
87
88 pub fn encrypt(&self, param: CryptEncodeParam) -> RlsResult<()> {
94 self.cipher.init_encrypt(self.key.as_ptr(), param.iv.as_ptr())?;
95 let mut hmac = Hmac::new(&self.mac_key, self.hash)?;
96 hmac.update(param.seq.to_be_bytes())?;
97 hmac.update(¶m.buffer.head()[..3])?;
98 hmac.update((param.buffer.origin_payload().len() as u16).to_be_bytes())?;
99 hmac.update(param.buffer.origin_payload())?;
100 let mac = hmac.finalize()?;
101 let context = param.buffer.origin_payload().as_ptr();
102 let out = param.buffer.encrypted_buffer().as_mut_ptr();
103 let plain_len = self.cipher.encrypt_update(context, param.buffer.origin_payload().len(), out)?;
104 let out = unsafe { out.add(plain_len) };
105 let mac_len = self.cipher.encrypt_update(mac.as_ptr(), mac.len(), out)?;
106 let padding_len = 16 - (param.buffer.origin_payload().len() + mac.len() + 1) % 16;
107 let padding = vec![padding_len as u8; padding_len + 1];
108 let out = unsafe { out.add(mac_len) };
109 let padding_len = self.cipher.encrypt_update(padding.as_ptr(), padding.len(), out)?;
110 let out = unsafe { out.add(padding_len) };
111 let final_len = self.cipher.encrypt_finalize(out)?;
112 let len = plain_len + mac_len + padding_len + final_len;
113 param.buffer.set_encrypted_len(len);
114 Ok(())
115 }
116
117 pub fn decrypt(&self, param: CryptDecodeParam) -> RlsResult<usize> {
118 self.cipher.init_decrypt(self.key.as_ptr(), param.iv.as_ptr())?;
119 let context = param.buffer.encrypted_payload().as_ptr();
120 let out = param.buffer.decrypted_buffer().as_mut_ptr();
121 let out_len = self.cipher.decrypt_update(context, param.buffer.encrypted_payload().len(), out)?;
122 let out = unsafe { out.add(out_len) };
123 let final_len = self.cipher.decrypt_finalize(out)?;
124 let len = out_len + final_len;
125 let padding_len = param.buffer.decrypted_buffer()[len - 1] as usize;
126 let len = len - padding_len - 1;
127 let mut hmac = Hmac::new(&self.mac_key, self.hash)?;
128 hmac.update(param.seq.to_be_bytes())?;
129 hmac.update(¶m.buffer.head()[..3])?;
130 hmac.update((len as u16 - 20).to_be_bytes())?;
131 hmac.update(¶m.buffer.decrypted_buffer()[..len - 20])?;
132 let cmac = hmac.finalize()?;
133 let mac = ¶m.buffer.decrypted_buffer()[len - 20..len - 1];
134 let res = unsafe { CRYPTO_memcmp(cmac.as_ptr() as *const _, mac.as_ptr() as *const _, mac.len()) };
135 if res != 0 { return Err(RlsError::CipherMacError); }
136 Ok(len - 20)
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use crate::boring::evp::CipherCrypto;
143 use crate::boring::{CryptDecodeParam, CryptEncodeParam, HashType};
144 use crate::buffer::{RecordDecodeBuffer, RecordEncodeBuffer};
145 use crate::extend::Aead;
146 use crate::{base64, rand, Cipher, RecordType};
147
148 #[test]
149 fn test_cipher() {
150 let mut cipher = Cipher::aes_192_ctr();
151 cipher.set_secret_key("1234567812345678", Some("1234567812345678"));
152 let res = cipher.encrypt(b"foobar".to_vec()).unwrap();
153 println!("{}", base64::b64encode(&res).unwrap());
154
155 let res = cipher.decrypt(res).unwrap();
156 println!("{}", String::from_utf8(res).unwrap());
157 }
158
159 #[test]
160 fn test_cipher_cryptor() {
161 let aead = Aead::AES_128_CBC_SHA;
162 let key = rand::random::<[u8; 16]>().to_vec();
163 let iv = rand::random::<[u8; 16]>();
164 println!("{:?}", iv);
165 let mut buffer = [0; 1024];
166 let payload = [1, 2, 3, 4, 5, 61, 2, 3, 4, 5, 6, 7, 8, 9, 23, 23];
168 let mac_key = [12; 20];
169 let mut record_buffer = RecordEncodeBuffer::new(RecordType::HandShake, &mut buffer, &payload, &aead);
170 record_buffer.add_explicit_iv(&iv);
171
172 let crypto = CipherCrypto::new(&aead, key, mac_key.to_vec(), HashType::Sha1).unwrap();
173 crypto.encrypt(CryptEncodeParam {
174 nonce: &[0; 12],
175 iv: &iv,
176 aad: &[0; 13],
177 seq: &0,
178 buffer: &mut record_buffer,
179 }).unwrap();
180 let len = record_buffer.record_len();
181 println!("{}", len);
182 println!("{:?}", &buffer[..len + 10]);
183 println!("-----------------encrypted---------------------");
184 let mut decoded_buffer = vec![0; 1024];
185 let mut record_buffer = RecordDecodeBuffer::from_buffer(&buffer[..len], &mut decoded_buffer, &aead).unwrap();
186 let len = crypto.decrypt(CryptDecodeParam {
187 nonce: &[0; 12],
188 iv: &iv,
189 aad: &[0; 13],
190 seq: &0,
191 buffer: &mut record_buffer,
192 }).unwrap();
193 println!("{:?}", &decoded_buffer[..len]);
194 }
195}