From 5e4c31160d73085d12e07be1a95a787fea9206d1 Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 30 Sep 2020 15:46:56 +0100 Subject: [PATCH] transmute aes key --- Cargo.toml | 2 +- src/aes.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7ca47a6..23506fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptohelpers" -version = "1.4.0" +version = "1.4.1" license= "MIT" description = "Collection of helpers and simplifying functions for cryptography things" authors = ["Avril "] diff --git a/src/aes.rs b/src/aes.rs index d046ca4..97a8f9d 100644 --- a/src/aes.rs +++ b/src/aes.rs @@ -31,6 +31,7 @@ const BLOCKSIZE: usize = 16; /// A key and IV for the AES algorithm #[derive(Debug, PartialEq, Eq, Clone, Hash, Default)] #[cfg_attr(feature="serialise", derive(Serialize,Deserialize))] +#[repr(align(1))] pub struct AesKey { key: [u8; KEYSIZE], iv: [u8; IVSIZE], @@ -63,6 +64,30 @@ impl AesKey Self{key,iv} } + /// Consume into the key and IV parts + pub const fn into_parts(self) -> ([u8; KEYSIZE], [u8; IVSIZE]) + { + (self.key, self.iv) + } + + /// Consume this instance into the full byte buffer + pub fn into_bytes(self) -> [u8; KEYSIZE+IVSIZE] + { + unsafe { std::mem::transmute(self) } + } + + /// Consume a full byte buffer into an AES key + pub fn from_bytes(from: [u8; KEYSIZE+IVSIZE]) -> Self + { + unsafe { std::mem::transmute(from) } + } + + /// Create a zero inisialised key + #[inline] pub const fn empty() -> Self + { + Self { iv: [0; IVSIZE], key: [0; KEYSIZE]} + } + /// Create a new instance from slices pub fn from_slice(key: impl AsRef<[u8]>, iv: impl AsRef<[u8]>) -> Result { @@ -232,3 +257,26 @@ where F: io::Read + ?Sized, } pub use crate::error::aes::Error; + +#[cfg(test)] +mod tests +{ + #[test] + fn transmute_safe() + { + use std::mem::{size_of, align_of}; + + assert_eq!(size_of::(), size_of::<[u8; super::KEYSIZE + super::IVSIZE]>()); + assert_eq!(align_of::(), align_of::<[u8; super::KEYSIZE + super::IVSIZE]>()); + let key = super::AesKey::generate().unwrap(); + + let bytes = Vec::from(key.as_ref()); + let tbytes = key.clone().into_bytes(); + + let nkey = super::AesKey::from_bytes(tbytes); + + assert_eq!(nkey, key); + assert_eq!(&bytes[..], &tbytes[..]); + assert_eq!(key.as_ref(), &tbytes[..]); + } +}