use zeroize::Zeroize;
use crate::error::BackendError;
use crate::limits::KEY_BYTES_MAX;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct KeyHandle(u16);
impl KeyHandle {
#[must_use]
pub const fn new(index: u16) -> Self {
Self(index)
}
#[must_use]
pub const fn index(self) -> u16 {
self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum KeyKind {
Aes128,
Aes192,
Aes256,
TripleDesDouble, }
impl KeyKind {
#[must_use]
pub const fn clear_len(self) -> usize {
match self {
KeyKind::Aes192 => 24,
KeyKind::Aes256 => 32,
KeyKind::Aes128 | KeyKind::TripleDesDouble => 16,
}
}
}
pub trait KeyBackend: Send + Sync + 'static {
fn import_key(&self, kind: KeyKind, bytes: &[u8]) -> Result<KeyHandle, BackendError>;
fn generate_key(&self, kind: KeyKind) -> Result<KeyHandle, BackendError>;
fn compute_kcv(&self, h: &KeyHandle) -> Result<[u8; 3], BackendError>;
fn random_bytes(&self, out: &mut [u8]) -> Result<(), BackendError>;
fn ct_eq(&self, a: &[u8], b: &[u8]) -> bool;
}
pub struct ExportedKey {
bytes: [u8; KEY_BYTES_MAX],
len: usize,
}
impl ExportedKey {
#[must_use]
pub fn from_slice(src: &[u8]) -> Option<Self> {
if src.len() > KEY_BYTES_MAX {
return None;
}
let mut bytes = [0u8; KEY_BYTES_MAX];
bytes[..src.len()].copy_from_slice(src);
Some(Self {
bytes,
len: src.len(),
})
}
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
&self.bytes[..self.len]
}
}
impl Zeroize for ExportedKey {
fn zeroize(&mut self) {
self.bytes.zeroize();
self.len = 0;
}
}
impl Drop for ExportedKey {
fn drop(&mut self) {
self.zeroize();
}
}
impl core::ops::Deref for ExportedKey {
type Target = [u8];
fn deref(&self) -> &[u8] {
self.as_bytes()
}
}
pub trait ExportableKeyBackend: KeyBackend {
fn export_key_dangerous(&self, h: &KeyHandle) -> Result<ExportedKey, BackendError>;
}