use cryptoki_sys::*;
use std::{convert::TryInto, ffi::c_void, marker::PhantomData, ptr::null_mut};
#[derive(Debug, Clone, Copy)]
pub enum EddsaSignatureScheme<'a> {
Pure,
Ed25519,
Ed25519ctx(&'a [u8]),
Ed25519ph(&'a [u8]),
Ed448(&'a [u8]),
Ed448ph(&'a [u8]),
}
impl EddsaSignatureScheme<'_> {
pub fn into_params(&self) -> *mut c_void {
match self {
EddsaSignatureScheme::Pure | EddsaSignatureScheme::Ed25519 => null_mut(),
EddsaSignatureScheme::Ed448(context) | EddsaSignatureScheme::Ed25519ctx(context) => {
&CK_EDDSA_PARAMS {
phFlag: false.into(),
pContextData: context.as_ptr() as *mut _,
ulContextDataLen: context
.len()
.try_into()
.expect("usize can not fit in CK_ULONG"),
} as *const CK_EDDSA_PARAMS as *mut _
}
EddsaSignatureScheme::Ed448ph(context) | EddsaSignatureScheme::Ed25519ph(context) => {
&CK_EDDSA_PARAMS {
phFlag: true.into(),
pContextData: context.as_ptr() as *mut _,
ulContextDataLen: context
.len()
.try_into()
.expect("usize can not fit in CK_ULONG"),
} as *const CK_EDDSA_PARAMS as *mut _
}
}
}
}
#[derive(Copy, Debug, Clone)]
#[repr(transparent)]
pub struct EddsaParams<'a> {
inner: Option<CK_EDDSA_PARAMS>,
_marker: PhantomData<&'a [u8]>,
}
impl EddsaParams<'_> {
pub fn new(scheme: EddsaSignatureScheme) -> Self {
let params =
match scheme {
EddsaSignatureScheme::Pure | EddsaSignatureScheme::Ed25519 => None,
EddsaSignatureScheme::Ed25519ctx(context)
| EddsaSignatureScheme::Ed448(context) => Some({
CK_EDDSA_PARAMS {
phFlag: false.into(),
pContextData: context.as_ptr() as *mut _,
ulContextDataLen: context
.len()
.try_into()
.expect("usize can not fit in CK_ULONG"),
}
}),
EddsaSignatureScheme::Ed25519ph(context)
| EddsaSignatureScheme::Ed448ph(context) => Some({
CK_EDDSA_PARAMS {
phFlag: true.into(),
pContextData: context.as_ptr() as *mut _,
ulContextDataLen: context
.len()
.try_into()
.expect("usize can not fit in CK_ULONG"),
}
}),
};
Self {
inner: params,
_marker: PhantomData,
}
}
pub fn inner(&self) -> Option<&CK_EDDSA_PARAMS> {
self.inner.as_ref()
}
}