use crate::errors::RvError;
#[cfg(feature = "crypto_adaptor_openssl")]
use crypto_adaptors::openssl_adaptor::AdaptorCTX;
#[cfg(feature = "crypto_adaptor_tongsuo")]
use crypto_adaptors::tongsuo_adaptor::AdaptorCTX;
pub mod crypto_adaptors;
#[derive(PartialEq)]
pub enum CipherMode {
CBC,
GCM,
CCM,
}
pub enum AESKeySize {
AES128,
AES192,
AES256,
}
pub enum PublicKeyType {
RSA,
ECDSA,
SM2,
}
#[allow(dead_code)]
pub struct AES {
alg: (AESKeySize, CipherMode),
key: Vec<u8>,
iv: Vec<u8>,
aad: Option<Vec<u8>>,
tag: Option<Vec<u8>>,
ctx: Option<AdaptorCTX>,
}
#[allow(dead_code)]
pub struct SM4 {
mode: CipherMode,
key: Vec<u8>,
iv: Vec<u8>,
aad: Option<Vec<u8>>,
tag: Option<Vec<u8>>,
ctx: Option<AdaptorCTX>,
}
#[cfg_attr(feature = "crypto_adaptor_tongsuo", doc = "~~~")]
#[cfg_attr(not(feature = "crypto_adaptor_tongsuo"), doc = "~~~ignore")]
pub trait BlockCipher {
fn encrypt(&mut self, plaintext: &Vec<u8>) -> Result<Vec<u8>, RvError>;
fn encrypt_update(&mut self, plaintext: Vec<u8>, ciphertext: &mut Vec<u8>) -> Result<usize, RvError>;
fn encrypt_final(&mut self, ciphertext: &mut Vec<u8>) -> Result<usize, RvError>;
fn decrypt(&mut self, ciphertext: &Vec<u8>) -> Result<Vec<u8>, RvError>;
fn decrypt_update(&mut self, ciphertext: Vec<u8>, plaintext: &mut Vec<u8>) -> Result<usize, RvError>;
fn decrypt_final(&mut self, plaintext: &mut Vec<u8>) -> Result<usize, RvError>;
}
#[cfg_attr(feature = "crypto_adaptor_tongsuo", doc = "~~~")]
#[cfg_attr(not(feature = "crypto_adaptor_tongsuo"), doc = "~~~ignore")]
pub trait AEADCipher: BlockCipher {
fn set_aad(&mut self, aad: Vec<u8>) -> Result<(), RvError>;
fn get_tag(&mut self) -> Result<Vec<u8>, RvError>;
fn set_tag(&mut self, tag: Vec<u8>) -> Result<(), RvError>;
}
pub trait PublicKey {
fn keygen() -> Result<(), RvError>;
}
pub trait Signature: PublicKey {
fn sign(&mut self, data: &Vec<u8>) -> Result<Vec<u8>, RvError>;
fn verify(&mut self, data: &Vec<u8>, sig: &Vec<u8>) -> Result<bool, RvError>;
}
pub trait Encryption: PublicKey {
fn encrypt(&mut self, plaintext: &Vec<u8>) -> Result<Vec<u8>, RvError>;
fn decrypt(&mut self, ciphertext: &Vec<u8>) -> Result<Vec<u8>, RvError>;
}
#[cfg(test)]
mod crypto_test {
use crate::modules::crypto::{AES, AESKeySize, CipherMode, BlockCipher, AEADCipher};
#[cfg(feature = "crypto_adaptor_tongsuo")]
use crate::modules::crypto::SM4;
#[test]
fn test_aes_keygen() {
let data = b"The best way to not feel hopeless is to get up and do something.".to_vec();
let mut aes_encrypter = AES::new(true, Some(AESKeySize::AES128),
Some(CipherMode::CBC), None, None).unwrap();
let mut aes_decrypter = AES::new(false, Some(AESKeySize::AES128),
Some(CipherMode::CBC), Some(aes_encrypter.get_key_iv().0),
Some(aes_encrypter.get_key_iv().1)).unwrap();
let ct = aes_encrypter.encrypt(&data).unwrap();
let pt = aes_decrypter.decrypt(&ct).unwrap();
assert_eq!(data, pt);
}
#[test]
fn test_aes_one_shot() {
let data = b"The best way to not feel hopeless is to get up and do something.".to_vec();
let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F".to_vec();
let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07".to_vec();
let mut aes_encrypter = AES::new(false, Some(AESKeySize::AES128),
Some(CipherMode::CBC), Some(key.clone()), Some(iv.clone())).unwrap();
let mut aes_decrypter = AES::new(false, Some(AESKeySize::AES128),
Some(CipherMode::CBC), Some(key), Some(iv)).unwrap();
let ct = aes_encrypter.encrypt(&data).unwrap();
let pt = aes_decrypter.decrypt(&ct).unwrap();
assert_eq!(data.to_vec(), pt);
}
#[test]
fn test_aes_aead_one_shot() {
let data = b"The best way to not feel hopeless is to get up and do something.".to_vec();
let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F".to_vec();
let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07".to_vec();
let aad = b"some additional authenticated data.".to_vec();
let mut aes_encrypter = AES::new(false, Some(AESKeySize::AES128),
Some(CipherMode::GCM), Some(key.clone()), Some(iv.clone())).unwrap();
let mut aes_decrypter = AES::new(false, Some(AESKeySize::AES128),
Some(CipherMode::GCM), Some(key), Some(iv)).unwrap();
aes_encrypter.set_aad(aad.clone()).unwrap();
let ct = aes_encrypter.encrypt(&data).unwrap();
let tag = aes_encrypter.get_tag().unwrap();
aes_decrypter.set_aad(aad).unwrap();
aes_decrypter.set_tag(tag).unwrap();
let pt = aes_decrypter.decrypt(&ct).unwrap();
assert_eq!(data.to_vec(), pt);
}
#[test]
fn test_aes_stream() {
let data: [&[u8]; 2] = [b"The best way to not feel hopeless ",
b"is to get up and do something."];
let data2 = b"The best way to not feel hopeless is to get up and do something.";
let data_len = data.iter().fold(0, |sum, x| sum + x.len());
let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F".to_vec();
let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07".to_vec();
let mut aes_encrypter = AES::new(false, Some(AESKeySize::AES128),
Some(CipherMode::CBC), Some(key.clone()), Some(iv.clone())).unwrap();
let mut aes_decrypter = AES::new(false, Some(AESKeySize::AES128),
Some(CipherMode::CBC), Some(key), Some(iv)).unwrap();
let mut ct: Vec<u8> = vec![];
let mut v1: Vec<u8> = vec![0; data_len + 16];
let mut v2: Vec<u8>= vec![0; data_len + 16];
let mut v3: Vec<u8>= vec![0; data_len + 16];
let mut count = aes_encrypter.encrypt_update((&data[0]).to_vec(), &mut v1).unwrap();
v1.truncate(count);
count = aes_encrypter.encrypt_update((&data[1]).to_vec(), &mut v2).unwrap();
v2.truncate(count);
count = aes_encrypter.encrypt_final(&mut v3).unwrap();
v3.truncate(count);
ct.extend(v1);
ct.extend(v2);
ct.extend(v3);
let data_len2 = ct.len();
let mut pt1: Vec<u8> = vec![0; data_len2 + 16];
let mut pt2: Vec<u8>= vec![0; data_len2 + 16];
let mut pt3: Vec<u8>= vec![0; data_len2 + 16];
let mut pt: Vec<u8> = vec![];
let cts = [&ct[..9], &ct[9..]];
count = aes_decrypter.decrypt_update((&cts[0]).to_vec(), &mut pt1).unwrap();
pt1.truncate(count);
count = aes_decrypter.decrypt_update((&cts[1]).to_vec(), &mut pt2).unwrap();
pt2.truncate(count);
count = aes_decrypter.decrypt_final(&mut pt3).unwrap();
pt3.truncate(count);
pt.extend(pt1);
pt.extend(pt2);
pt.extend(pt3);
assert_eq!(data2.to_vec(), pt);
}
#[test]
fn test_aes_aead_stream() {
let data: [&[u8]; 2] = [b"The best way to not feel hopeless ",
b"is to get up and do something."];
let data2 = b"The best way to not feel hopeless is to get up and do something.";
let data_len = data.iter().fold(0, |sum, x| sum + x.len());
let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F".to_vec();
let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07".to_vec();
let aad = b"some additional authenticated data.".to_vec();
let mut aes_encrypter = AES::new(false, Some(AESKeySize::AES128),
Some(CipherMode::GCM), Some(key.clone()), Some(iv.clone())).unwrap();
let mut aes_decrypter = AES::new(false, Some(AESKeySize::AES128),
Some(CipherMode::GCM), Some(key), Some(iv)).unwrap();
let mut ct: Vec<u8> = vec![];
aes_encrypter.set_aad(aad.clone()).unwrap();
let mut v1: Vec<u8> = vec![0; data_len + 16];
let mut v2: Vec<u8>= vec![0; data_len + 16];
let mut v3: Vec<u8>= vec![0; data_len + 16];
let mut count = aes_encrypter.encrypt_update((&data[0]).to_vec(), &mut v1).unwrap();
v1.truncate(count);
count = aes_encrypter.encrypt_update((&data[1]).to_vec(), &mut v2).unwrap();
v2.truncate(count);
count = aes_encrypter.encrypt_final(&mut v3).unwrap();
v3.truncate(count);
ct.extend(v1);
ct.extend(v2);
ct.extend(v3);
let tag = aes_encrypter.get_tag().unwrap();
aes_decrypter.set_aad(aad).unwrap();
aes_decrypter.set_tag(tag).unwrap();
let data_len2 = ct.len();
let mut pt1: Vec<u8> = vec![0; data_len2 + 16];
let mut pt2: Vec<u8>= vec![0; data_len2 + 16];
let mut pt3: Vec<u8>= vec![0; data_len2 + 16];
let mut pt: Vec<u8> = vec![];
let cts = [&ct[..9], &ct[9..]];
count = aes_decrypter.decrypt_update((&cts[0]).to_vec(), &mut pt1).unwrap();
pt1.truncate(count);
count = aes_decrypter.decrypt_update((&cts[1]).to_vec(), &mut pt2).unwrap();
pt2.truncate(count);
count = aes_decrypter.decrypt_final(&mut pt3).unwrap();
pt3.truncate(count);
pt.extend(pt1);
pt.extend(pt2);
pt.extend(pt3);
assert_eq!(data2.to_vec(), pt);
}
#[cfg(feature = "crypto_adaptor_tongsuo")]
#[test]
fn test_sm4_keygen() {
let data = b"The best way to not feel hopeless is to get up and do something.".to_vec();
let mut sm4_encrypter = SM4::new(true, Some(CipherMode::CBC), None, None).unwrap();
let mut sm4_decrypter = SM4::new(false, Some(CipherMode::CBC),
Some(sm4_encrypter.get_key_iv().0), Some(sm4_encrypter.get_key_iv().1)).unwrap();
let ct = sm4_encrypter.encrypt(&data).unwrap();
let pt = sm4_decrypter.decrypt(&ct).unwrap();
assert_eq!(data, pt);
}
#[cfg(feature = "crypto_adaptor_tongsuo")]
#[test]
fn test_sm4_one_shot() {
let data = b"The best way to not feel hopeless is to get up and do something.".to_vec();
let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F".to_vec();
let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07".to_vec();
let mut sm4_encrypter = SM4::new(false, Some(CipherMode::CBC),
Some(key.clone()), Some(iv.clone())).unwrap();
let mut sm4_decrypter = SM4::new(false, Some(CipherMode::CBC),
Some(key), Some(iv)).unwrap();
let ct = sm4_encrypter.encrypt(&data).unwrap();
let pt = sm4_decrypter.decrypt(&ct).unwrap();
assert_eq!(data.to_vec(), pt);
}
#[cfg(feature = "crypto_adaptor_tongsuo")]
#[test]
fn test_sm4_aead_one_shot() {
let data = b"The best way to not feel hopeless is to get up and do something.".to_vec();
let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F".to_vec();
let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07".to_vec();
let aad = b"some additional authenticated data.".to_vec();
let mut sm4_encrypter = SM4::new(false, Some(CipherMode::GCM),
Some(key.clone()), Some(iv.clone())).unwrap();
let mut sm4_decrypter = SM4::new(false, Some(CipherMode::GCM),
Some(key), Some(iv)).unwrap();
sm4_encrypter.set_aad(aad.clone()).unwrap();
let ct = sm4_encrypter.encrypt(&data).unwrap();
let tag = sm4_encrypter.get_tag().unwrap();
sm4_decrypter.set_aad(aad).unwrap();
sm4_decrypter.set_tag(tag).unwrap();
let pt = sm4_decrypter.decrypt(&ct).unwrap();
assert_eq!(data.to_vec(), pt);
}
#[cfg(feature = "crypto_adaptor_tongsuo")]
#[test]
fn test_sm4_stream() {
let data: [&[u8]; 2] = [b"The best way to not feel hopeless ",
b"is to get up and do something."];
let data2 = b"The best way to not feel hopeless is to get up and do something.";
let data_len = data.iter().fold(0, |sum, x| sum + x.len());
let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F".to_vec();
let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07".to_vec();
let mut sm4_encrypter = SM4::new(false, Some(CipherMode::CBC),
Some(key.clone()), Some(iv.clone())).unwrap();
let mut sm4_decrypter = SM4::new(false, Some(CipherMode::CBC),
Some(key), Some(iv)).unwrap();
let mut ct: Vec<u8> = vec![];
let mut v1: Vec<u8> = vec![0; data_len + 16];
let mut v2: Vec<u8>= vec![0; data_len + 16];
let mut v3: Vec<u8>= vec![0; data_len + 16];
let mut count = sm4_encrypter.encrypt_update((&data[0]).to_vec(), &mut v1).unwrap();
v1.truncate(count);
count = sm4_encrypter.encrypt_update((&data[1]).to_vec(), &mut v2).unwrap();
v2.truncate(count);
count = sm4_encrypter.encrypt_final(&mut v3).unwrap();
v3.truncate(count);
ct.extend(v1);
ct.extend(v2);
ct.extend(v3);
let data_len2 = ct.len();
let mut pt1: Vec<u8> = vec![0; data_len2 + 16];
let mut pt2: Vec<u8>= vec![0; data_len2 + 16];
let mut pt3: Vec<u8>= vec![0; data_len2 + 16];
let mut pt: Vec<u8> = vec![];
let cts = [&ct[..9], &ct[9..]];
count = sm4_decrypter.decrypt_update((&cts[0]).to_vec(), &mut pt1).unwrap();
pt1.truncate(count);
count = sm4_decrypter.decrypt_update((&cts[1]).to_vec(), &mut pt2).unwrap();
pt2.truncate(count);
count = sm4_decrypter.decrypt_final(&mut pt3).unwrap();
pt3.truncate(count);
pt.extend(pt1);
pt.extend(pt2);
pt.extend(pt3);
assert_eq!(data2.to_vec(), pt);
}
#[cfg(feature = "crypto_adaptor_tongsuo")]
#[test]
fn test_sm4_aead_stream() {
let data: [&[u8]; 2] = [b"The best way to not feel hopeless ",
b"is to get up and do something."];
let data2 = b"The best way to not feel hopeless is to get up and do something.";
let data_len = data.iter().fold(0, |sum, x| sum + x.len());
let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F".to_vec();
let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07".to_vec();
let aad = b"some additional authenticated data.".to_vec();
let mut sm4_encrypter = SM4::new(false, Some(CipherMode::GCM),
Some(key.clone()), Some(iv.clone())).unwrap();
let mut sm4_decrypter = SM4::new(false, Some(CipherMode::GCM),
Some(key), Some(iv)).unwrap();
let mut ct: Vec<u8> = vec![];
sm4_encrypter.set_aad(aad.clone()).unwrap();
let mut v1: Vec<u8> = vec![0; data_len + 16];
let mut v2: Vec<u8>= vec![0; data_len + 16];
let mut v3: Vec<u8>= vec![0; data_len + 16];
let mut count = sm4_encrypter.encrypt_update((&data[0]).to_vec(), &mut v1).unwrap();
v1.truncate(count);
count = sm4_encrypter.encrypt_update((&data[1]).to_vec(), &mut v2).unwrap();
v2.truncate(count);
count = sm4_encrypter.encrypt_final(&mut v3).unwrap();
v3.truncate(count);
ct.extend(v1);
ct.extend(v2);
ct.extend(v3);
let tag = sm4_encrypter.get_tag().unwrap();
sm4_decrypter.set_aad(aad).unwrap();
sm4_decrypter.set_tag(tag).unwrap();
let data_len2 = ct.len();
let mut pt1: Vec<u8> = vec![0; data_len2 + 16];
let mut pt2: Vec<u8>= vec![0; data_len2 + 16];
let mut pt3: Vec<u8>= vec![0; data_len2 + 16];
let mut pt: Vec<u8> = vec![];
let cts = [&ct[..9], &ct[9..]];
count = sm4_decrypter.decrypt_update((&cts[0]).to_vec(), &mut pt1).unwrap();
pt1.truncate(count);
count = sm4_decrypter.decrypt_update((&cts[1]).to_vec(), &mut pt2).unwrap();
pt2.truncate(count);
count = sm4_decrypter.decrypt_final(&mut pt3).unwrap();
pt3.truncate(count);
pt.extend(pt1);
pt.extend(pt2);
pt.extend(pt3);
assert_eq!(data2.to_vec(), pt);
}
}