Created
April 9, 2022 10:15
-
-
Save KerfuffleV2/03b0de1ea8d696b63622d5b64226f1be to your computer and use it in GitHub Desktop.
AES CBC thing for /u/PeksyTiger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "testaes" | |
version = "0.1.0" | |
edition = "2021" | |
[dependencies] | |
aes = { version = "=0.8.1", features = [] } | |
cipher = { version = "=0.4.3", features = ["block-padding"] } | |
cbc = { version = "=0.1.2", features = ["block-padding", "std"] } | |
anyhow = "1" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(dead_code)] | |
// PLEASE NOTE: The safety of using the functions in this way is not something | |
// I can verify personally. It's easy to make serious mistakes using Crypto and | |
// I am not an expert. | |
use anyhow::Result; | |
use aes::{ | |
cipher::{ | |
block_padding::{Padding, Pkcs7}, | |
generic_array::GenericArray, | |
AlgorithmName, Block, BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncryptMut, KeyInit, | |
KeyIvInit, | |
}, | |
{Aes128, Aes192, Aes256}, | |
}; | |
// Also see: https://docs.rs/cbc/latest/cbc/ | |
pub trait CipherTraitBundle: | |
BlockCipher + BlockEncryptMut + BlockDecrypt + BlockDecryptMut + AlgorithmName + std::fmt::Debug | |
{ | |
type Padding: Padding<Self::BlockSize>; | |
} | |
impl CipherTraitBundle for Aes128 { | |
type Padding = Pkcs7; | |
} | |
impl CipherTraitBundle for Aes192 { | |
type Padding = Pkcs7; | |
} | |
impl CipherTraitBundle for Aes256 { | |
type Padding = Pkcs7; | |
} | |
#[derive(Debug)] | |
pub struct Test<CI: CipherTraitBundle> { | |
enc: cbc::Encryptor<CI>, | |
dec: cbc::Decryptor<CI>, | |
} | |
// I'm assuming you're always using Pkcs7 as the padding. If you want to be able to | |
// instantiate Test<...> with different types of padding then you probably need to move | |
// the associated type out of CipherTraitBundle and make your struct take a generic for the padding. | |
// Example below: | |
// | |
// pub struct Test2<CI: CipherTraitBundle, PAD: Padding<CI::BlockSize>> { | |
// enc: cbc::Encryptor<CI>, | |
// dec: cbc::Decryptor<CI>, | |
// _pad_marker: std::marker::PhantomData<*const PAD>, | |
// } | |
type TestAes128Cbc = Test<Aes128>; | |
type TestAes192Cbc = Test<Aes192>; | |
type TestAes256Cbc = Test<Aes256>; | |
impl<CI: CipherTraitBundle> Test<CI> { | |
pub fn new(key: GenericArray<u8, CI::KeySize>, iv: GenericArray<u8, CI::BlockSize>) -> Self | |
where | |
CI: KeyInit, | |
{ | |
// Using new_from_slices is also possible, but it is a fallible function. | |
// let enc = cbc::Encryptor::<CI>::new_from_slices(&key, &iv).expect("Invalid key/iv"); | |
// let dec = cbc::Decryptor::<CI>::new_from_slices(&key, &iv).expect("Invalid key/iv"); | |
let enc = cbc::Encryptor::<CI>::new(&key, &iv); | |
let dec = cbc::Decryptor::<CI>::new(&key, &iv); | |
Self { enc, dec } | |
} | |
// The next two functions consume the struct, which may or may not be what you want. | |
pub fn into_encrypted<R: AsRef<[u8]>>(self, plaintext: R) -> Vec<u8> { | |
self.enc | |
.encrypt_padded_vec_mut::<CI::Padding>(plaintext.as_ref()) | |
} | |
pub fn into_decrypted<R: AsRef<[u8]>>(self, ciphertext: R) -> Result<Vec<u8>> { | |
self.dec | |
.decrypt_padded_vec_mut::<CI::Padding>(ciphertext.as_ref()) | |
.map_err(anyhow::Error::from) | |
} | |
// These functions will encrypt/decrypt a block in place without consuming the struct. | |
// You're responsible for making sure the data is in the correct format. | |
pub fn encrypt_block_mut(&mut self, block: &mut Block<CI>) { | |
self.enc.encrypt_block_mut(block) | |
} | |
pub fn decrypt_block_mut(&mut self, block: &mut Block<CI>) { | |
self.dec.decrypt_block_mut(block) | |
} | |
} | |
fn main() { | |
let test_aes128 = | |
TestAes128Cbc::new(GenericArray::from([0u8; 16]), GenericArray::from([0u8; 16])); | |
let test_aes192 = | |
TestAes192Cbc::new(GenericArray::from([0u8; 24]), GenericArray::from([0u8; 16])); | |
println!("{test_aes128:?}"); | |
println!("{test_aes192:?}"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment