From aeef874b92e20062539706a98edc15e9b1b3a057 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Thu, 30 May 2024 22:59:41 +0800 Subject: [PATCH] fixup! fixup! fixup! fixup! fixup! fixup! Support cryptography module --- .../crypto/crypto_adaptors/openssl_adaptor.rs | 28 +++++++--- src/modules/crypto/mod.rs | 54 ++++++++++++++----- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/src/modules/crypto/crypto_adaptors/openssl_adaptor.rs b/src/modules/crypto/crypto_adaptors/openssl_adaptor.rs index ac6c51e..994acc3 100644 --- a/src/modules/crypto/crypto_adaptors/openssl_adaptor.rs +++ b/src/modules/crypto/crypto_adaptors/openssl_adaptor.rs @@ -12,6 +12,14 @@ pub struct AdaptorCTX { } impl AES { + /// This function is the constructor of the AES struct, it returns a new AES object on success. + /// + /// keygen: true stands for generating a key and iv; if false, then the caller needs to feed in + /// the specific key and iv values through the parameters. + /// size: bit-length of AES. If omitted, AESKeySize::AES128 is used as default. + /// mode: cipher mode of AES, such as CBC, GCM, etc. If omitted, CipherMode::CBC is default. + /// key: symmetric key that is used to encrypt and decrypt data. + /// iv: initialization vector. This depends on specific mode, for instance, ECB requires no IV. pub fn new( keygen: bool, size: Option, @@ -76,17 +84,25 @@ impl AES { } ) } + + /// This function returns the key and iv vaule stored in one AES object. + /// + /// Two values are returned in a tuple: the first element represents the key, and the second + /// element represents the IV. Elements may be None if unset. + pub fn get_key_iv(&self) -> (Vec, Vec) { + (self.key.clone(), self.iv.clone()) + } } impl BlockCipher for AES { - fn encrypt(&mut self, plaintext: Vec) -> Result, RvError> { + fn encrypt(&mut self, plaintext: &Vec) -> Result, RvError> { match self.alg { (AESKeySize::AES128, CipherMode::CBC) => { let ciphertext = encrypt( Cipher::aes_128_cbc(), &self.key, Some(&self.iv), - &plaintext).unwrap(); + plaintext).unwrap(); return Ok(ciphertext.to_vec()); } (AESKeySize::AES128, CipherMode::GCM) => { @@ -97,7 +113,7 @@ impl BlockCipher for AES { &self.key, Some(&self.iv), &self.aad.clone().unwrap(), - &plaintext, + plaintext, tag ).unwrap(); self.tag = Some(tag.to_vec()); @@ -174,14 +190,14 @@ impl BlockCipher for AES { Ok(count) } - fn decrypt(&mut self, ciphertext: Vec) -> Result, RvError> { + fn decrypt(&mut self, ciphertext: &Vec) -> Result, RvError> { match self.alg { (AESKeySize::AES128, CipherMode::CBC) => { let plaintext = decrypt( Cipher::aes_128_cbc(), &self.key, Some(&self.iv), - &ciphertext).unwrap(); + ciphertext).unwrap(); return Ok(plaintext.to_vec()); } (AESKeySize::AES128, CipherMode::GCM) => { @@ -191,7 +207,7 @@ impl BlockCipher for AES { &self.key, Some(&self.iv), &self.aad.clone().unwrap(), - &ciphertext, + ciphertext, &self.tag.clone().unwrap() ).unwrap(); return Ok(plaintext.to_vec()); diff --git a/src/modules/crypto/mod.rs b/src/modules/crypto/mod.rs index 3f9016d..ce8b486 100644 --- a/src/modules/crypto/mod.rs +++ b/src/modules/crypto/mod.rs @@ -58,7 +58,7 @@ pub trait BlockCipher { /// /// This function performs a "one-shot' style encryption. The data to be encrypted is fed by /// the `plaintext` parameter, while the ciphertext is returned in another `Vec`. - fn encrypt(&mut self, plaintext: Vec) -> Result, RvError>; + fn encrypt(&mut self, plaintext: &Vec) -> Result, RvError>; /// Stream encryption - update phase. /// @@ -78,7 +78,7 @@ pub trait BlockCipher { /// /// This function performs a "one-shot' style decryption. The data to be decrypted is fed by /// the `ciphertext` parameter, while the plaintext is returned in another `Vec`. - fn decrypt(&mut self, ciphertext: Vec) -> Result, RvError>; + fn decrypt(&mut self, ciphertext: &Vec) -> Result, RvError>; /// Stream decryption - update phase. /// @@ -117,32 +117,60 @@ pub trait AEADCipher: BlockCipher { #[cfg(test)] mod crypto_test { - use crate::modules::crypto::{AES, AESKeySize, CipherMode}; - use crate::modules::crypto::BlockCipher; + use crate::modules::crypto::{AES, AESKeySize, CipherMode, BlockCipher, AEADCipher}; #[test] fn test_aes_keygen() { - let data = b"The best way to not feel hopeless is to get up and do something."; + 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.key.clone()), - Some(aes_encrypter.iv.clone())).unwrap(); + Some(CipherMode::CBC), Some(aes_encrypter.get_key_iv().0), + Some(aes_encrypter.get_key_iv().1)).unwrap(); - let ct = aes_encrypter.encrypt(data.to_vec()).unwrap(); - let pt = aes_decrypter.decrypt(ct).unwrap(); - - assert_eq!(data.to_vec(), pt); + let ct = aes_encrypter.encrypt(&data).unwrap(); + let pt = aes_decrypter.decrypt(&ct).unwrap(); + assert_eq!(data, pt); } #[test] fn test_aes_one_shot() { - assert_eq!(1, 1); + 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() { - assert_eq!(1, 1); + 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(); + + // set aad, encrypt and get tag. + aes_encrypter.set_aad(aad.clone()).unwrap(); + let ct = aes_encrypter.encrypt(&data).unwrap(); + let tag = aes_encrypter.get_tag().unwrap(); + + // set aad, set tag and decrypt. + aes_decrypter.set_aad(aad).unwrap(); + aes_decrypter.set_tag(tag).unwrap(); + let pt = aes_decrypter.decrypt(&ct).unwrap(); + + // evaluate the result. + assert_eq!(data.to_vec(), pt); } #[test]