use super::{Mechanism, MechanismType};
use crate::error::{Error, Result};
use crate::types::Ulong;
use cryptoki_sys::*;
use log::error;
use std::convert::{TryFrom, TryInto};
use std::ffi::c_void;
use std::marker::PhantomData;
use std::ops::Deref;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct PkcsMgfType {
val: CK_RSA_PKCS_MGF_TYPE,
}
impl PkcsMgfType {
pub const MGF1_SHA1: PkcsMgfType = PkcsMgfType { val: CKG_MGF1_SHA1 };
pub const MGF1_SHA224: PkcsMgfType = PkcsMgfType {
val: CKG_MGF1_SHA224,
};
pub const MGF1_SHA256: PkcsMgfType = PkcsMgfType {
val: CKG_MGF1_SHA256,
};
pub const MGF1_SHA384: PkcsMgfType = PkcsMgfType {
val: CKG_MGF1_SHA384,
};
pub const MGF1_SHA512: PkcsMgfType = PkcsMgfType {
val: CKG_MGF1_SHA512,
};
}
impl Deref for PkcsMgfType {
type Target = CK_RSA_PKCS_MGF_TYPE;
fn deref(&self) -> &Self::Target {
&self.val
}
}
impl From<PkcsMgfType> for CK_RSA_PKCS_MGF_TYPE {
fn from(mgf_type: PkcsMgfType) -> Self {
*mgf_type
}
}
impl TryFrom<CK_RSA_PKCS_MGF_TYPE> for PkcsMgfType {
type Error = Error;
fn try_from(mgf_type: CK_RSA_PKCS_MGF_TYPE) -> Result<Self> {
match mgf_type {
CKG_MGF1_SHA1 => Ok(PkcsMgfType::MGF1_SHA1),
CKG_MGF1_SHA224 => Ok(PkcsMgfType::MGF1_SHA224),
CKG_MGF1_SHA256 => Ok(PkcsMgfType::MGF1_SHA256),
CKG_MGF1_SHA384 => Ok(PkcsMgfType::MGF1_SHA384),
CKG_MGF1_SHA512 => Ok(PkcsMgfType::MGF1_SHA512),
other => {
error!("Mask Generation Function type {other} is not one of the valid values.");
Err(Error::InvalidValue)
}
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct PkcsOaepSource<'a>(Option<&'a [u8]>);
impl<'a> PkcsOaepSource<'a> {
pub fn empty() -> Self {
Self(None)
}
pub fn data_specified(source_data: &'a [u8]) -> Self {
Self(Some(source_data))
}
pub(crate) fn source_ptr(&self) -> *const c_void {
if let Some(source_data) = self.0 {
source_data.as_ptr() as _
} else {
std::ptr::null()
}
}
pub(crate) fn source_len(&self) -> Ulong {
self.0
.unwrap_or_default()
.len()
.try_into()
.expect("usize can not fit in CK_ULONG")
}
pub(crate) fn source_type(&self) -> CK_RSA_PKCS_OAEP_SOURCE_TYPE {
CKZ_DATA_SPECIFIED
}
}
#[derive(Copy, Debug, Clone)]
#[repr(C)]
pub struct PkcsPssParams {
pub hash_alg: MechanismType,
pub mgf: PkcsMgfType,
pub s_len: Ulong,
}
#[derive(Copy, Debug, Clone)]
#[repr(C)]
#[cfg_attr(windows, repr(packed))]
pub struct PkcsOaepParams<'a> {
hash_alg: MechanismType,
mgf: PkcsMgfType,
source: CK_RSA_PKCS_OAEP_SOURCE_TYPE,
source_data: *const c_void,
source_data_len: Ulong,
_marker: PhantomData<&'a [u8]>,
}
impl<'a> PkcsOaepParams<'a> {
pub fn new(
hash_alg: MechanismType,
mgf: PkcsMgfType,
encoding_parameter: PkcsOaepSource<'a>,
) -> Self {
PkcsOaepParams {
hash_alg,
mgf,
source: encoding_parameter.source_type(),
source_data: encoding_parameter.source_ptr(),
source_data_len: encoding_parameter.source_len(),
_marker: PhantomData,
}
}
pub fn hash_alg(&self) -> MechanismType {
self.hash_alg
}
}
impl<'a> From<PkcsOaepParams<'a>> for Mechanism<'a> {
fn from(pkcs_oaep_params: PkcsOaepParams<'a>) -> Self {
Mechanism::RsaPkcsOaep(pkcs_oaep_params)
}
}