use core::ptr;
use alloc::vec;
use alloc::vec::Vec;
use crate::error::WolfCryptError;
use wolfcrypt_rs::{wc_AesKeyWrap, wc_AesKeyUnWrap};
pub fn aes_wrap_key(kek: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, WolfCryptError> {
if plaintext.len() < 16 || plaintext.len() % 8 != 0 {
return Err(WolfCryptError::INVALID_INPUT);
}
match kek.len() {
16 | 24 | 32 => {}
_ => return Err(WolfCryptError::INVALID_INPUT),
}
let mut out = vec![0u8; plaintext.len() + 8];
let rc = unsafe {
wc_AesKeyWrap(
kek.as_ptr(),
kek.len() as u32,
plaintext.as_ptr(),
plaintext.len() as u32,
out.as_mut_ptr(),
out.len() as u32,
ptr::null(), )
};
if rc <= 0 {
return Err(WolfCryptError::Ffi { code: rc, func: "wc_AesKeyWrap" });
}
let out_len = rc as usize;
if out_len > out.len() {
return Err(WolfCryptError::Ffi { code: -1, func: "wc_AesKeyWrap (output length)" });
}
out.truncate(out_len);
Ok(out)
}
pub fn aes_unwrap_key(kek: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, WolfCryptError> {
if ciphertext.len() < 24 || ciphertext.len() % 8 != 0 {
return Err(WolfCryptError::INVALID_INPUT);
}
match kek.len() {
16 | 24 | 32 => {}
_ => return Err(WolfCryptError::INVALID_INPUT),
}
let mut out = vec![0u8; ciphertext.len()];
let rc = unsafe {
wc_AesKeyUnWrap(
kek.as_ptr(),
kek.len() as u32,
ciphertext.as_ptr(),
ciphertext.len() as u32,
out.as_mut_ptr(),
out.len() as u32,
ptr::null(), )
};
if rc <= 0 {
return Err(WolfCryptError::Ffi { code: rc, func: "wc_AesKeyUnWrap" });
}
let out_len = rc as usize;
if out_len > out.len() {
return Err(WolfCryptError::Ffi { code: -1, func: "wc_AesKeyUnWrap (output length)" });
}
out.truncate(out_len);
Ok(out)
}