use std::fmt::Debug;
use std::sync::LazyLock;
use crate::error::Result;
use crate::mechanism::{Derive, Mechanism, Mechanisms};
use crate::native::simplekdf::{PubFromPrivOperation, SimpleKDFOperation};
use crate::object::ObjectFactories;
use crate::pkcs11::*;
static SIMPLE_KDF_MECH: LazyLock<Box<dyn Mechanism>> = LazyLock::new(|| {
Box::new(SimpleKDFMechanism {
info: CK_MECHANISM_INFO {
ulMinKeySize: 0,
ulMaxKeySize: CK_ULONG::try_from(u32::MAX).unwrap(),
flags: CKF_DERIVE,
},
})
});
static PUB_FROM_PRIV_MECH: LazyLock<Box<dyn Mechanism>> = LazyLock::new(|| {
Box::new(SimpleKDFMechanism {
info: CK_MECHANISM_INFO {
ulMinKeySize: 0,
ulMaxKeySize: 0,
flags: CKF_DERIVE,
},
})
});
pub fn register(mechs: &mut Mechanisms, _: &mut ObjectFactories) {
for ckm in &[
CKM_CONCATENATE_BASE_AND_KEY,
CKM_CONCATENATE_BASE_AND_DATA,
CKM_CONCATENATE_DATA_AND_BASE,
CKM_XOR_BASE_AND_DATA,
CKM_EXTRACT_KEY_FROM_KEY,
] {
mechs.add_mechanism(*ckm, &(*SIMPLE_KDF_MECH));
}
mechs.add_mechanism(CKM_PUB_KEY_FROM_PRIV_KEY, &(*PUB_FROM_PRIV_MECH));
}
#[derive(Debug)]
struct SimpleKDFMechanism {
info: CK_MECHANISM_INFO,
}
impl Mechanism for SimpleKDFMechanism {
fn info(&self) -> &CK_MECHANISM_INFO {
&self.info
}
fn derive_operation(&self, mech: &CK_MECHANISM) -> Result<Box<dyn Derive>> {
if self.info.flags & CKF_DERIVE != CKF_DERIVE {
return Err(CKR_MECHANISM_INVALID)?;
}
match mech.mechanism {
CKM_CONCATENATE_BASE_AND_KEY
| CKM_CONCATENATE_BASE_AND_DATA
| CKM_CONCATENATE_DATA_AND_BASE
| CKM_XOR_BASE_AND_DATA
| CKM_EXTRACT_KEY_FROM_KEY => {
Ok(Box::new(SimpleKDFOperation::new(mech)?))
}
CKM_PUB_KEY_FROM_PRIV_KEY => {
Ok(Box::new(PubFromPrivOperation::new(mech)?))
}
_ => Err(CKR_MECHANISM_INVALID)?,
}
}
}