#[macro_use]
extern crate serde_derive;
extern crate base64;
extern crate blake2;
extern crate hmac;
extern crate pbkdf2;
extern crate rand;
extern crate serde;
mod random;
mod serial;
use std::fmt;
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Debug)]
#[repr(u32)]
pub enum KeyType {
Aes128 = 32,
Aes256 = 64,
}
#[derive(Clone)]
pub struct Key {
tt: KeyType,
key: KeyBuf,
}
#[derive(Clone, Copy)]
union KeyBuf {
_32: [u8; 32],
_64: [u8; 64],
}
impl Key {
pub fn new(tt: KeyType) -> Self {
Self {
tt: tt.clone(),
key: random::generate(tt),
}
}
pub fn from_pw(tt: KeyType, pw: &str, user: &str) -> Self {
Key {
tt: tt.clone(),
key: random::expand(tt, pw, user),
}
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
match self.tt {
KeyType::Aes128 => &self.key._32,
KeyType::Aes256 => &self.key._64,
}
}
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe {
match self.tt {
KeyType::Aes128 => &mut self.key._32,
KeyType::Aes256 => &mut self.key._64,
}
}
}
pub fn len(&self) -> usize {
match self.tt {
KeyType::Aes128 => 32,
KeyType::Aes256 => 64,
}
}
}
impl PartialEq for Key {
fn eq(&self, o: &Self) -> bool {
if self.tt != o.tt {
return false;
}
use KeyType::*;
let len = match self.tt {
Aes128 => 32,
Aes256 => 64,
};
let mut ret = true;
(0..len).for_each(|i| unsafe {
if match self.tt {
Aes128 => self.key._32[i] != o.key._32[i],
Aes256 => self.key._64[i] != o.key._64[i],
} {
ret = false;
}
});
ret
}
}
impl Eq for Key {}
impl fmt::Debug for Key {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Key: type: {} – {:?}", &self.tt, unsafe {
match &self.tt {
KeyType::Aes128 => base64::encode(&self.key._32[..4]),
KeyType::Aes256 => base64::encode(&self.key._64[..4]),
}
})
}
}
impl fmt::Display for KeyType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
KeyType::Aes128 => "Aes128",
KeyType::Aes256 => "Aes256",
}
)
}
}