diff --git a/cryptoki/src/mechanism/mod.rs b/cryptoki/src/mechanism/mod.rs index c91ece76..88b4a7ee 100644 --- a/cryptoki/src/mechanism/mod.rs +++ b/cryptoki/src/mechanism/mod.rs @@ -8,6 +8,7 @@ pub mod elliptic_curve; pub mod hkdf; mod mechanism_info; pub mod rsa; +pub mod vendor_defined; use crate::error::Error; use cryptoki_sys::*; @@ -18,6 +19,7 @@ use std::fmt::Formatter; use std::mem::size_of; use std::ops::Deref; use std::ptr::null_mut; +use vendor_defined::VendorDefinedMechanism; use crate::mechanism::rsa::PkcsOaepParams; pub use mechanism_info::MechanismInfo; @@ -298,6 +300,31 @@ impl MechanismType { /// HKDF-DATA mechanism pub const HKDF_DATA: MechanismType = MechanismType { val: CKM_HKDF_DATA }; + /// Create vendor defined mechanism + /// + /// # Arguments + /// + /// * `val` - The value of vendor defined mechanism + /// + /// # Errors + /// + /// If `val` is less then `CKM_VENDOR_DEFINED`, a `Error::InvalidValue` will be returned + /// + /// # Examples + /// ```rust + /// use cryptoki::mechanism::{vendor_defined::CKM_VENDOR_DEFINED, MechanismType}; + /// + /// let some_custom_mech: MechanismType = + /// MechanismType::new_vendor_defined(CKM_VENDOR_DEFINED | 0x00000001).unwrap(); + /// ``` + pub fn new_vendor_defined(val: CK_MECHANISM_TYPE) -> crate::error::Result { + if val < CKM_VENDOR_DEFINED { + Err(Error::InvalidValue) + } else { + Ok(MechanismType { val }) + } + } + pub(crate) fn stringify(mech: CK_MECHANISM_TYPE) -> String { match mech { CKM_RSA_PKCS_KEY_PAIR_GEN => String::from(stringify!(CKM_RSA_PKCS_KEY_PAIR_GEN)), @@ -937,6 +964,9 @@ pub enum Mechanism<'a> { HkdfDerive(hkdf::HkdfParams<'a>), /// HKDF-DATA mechanism HkdfData(hkdf::HkdfParams<'a>), + + /// Vendor defined mechanism + VendorDefined(VendorDefinedMechanism<'a>), } impl Mechanism<'_> { @@ -1008,6 +1038,10 @@ impl Mechanism<'_> { Mechanism::HkdfKeyGen => MechanismType::HKDF_KEY_GEN, Mechanism::HkdfDerive(_) => MechanismType::HKDF_DERIVE, Mechanism::HkdfData(_) => MechanismType::HKDF_DATA, + + Mechanism::VendorDefined(vm) => MechanismType { + val: vm.inner.mechanism, + }, } } } @@ -1087,6 +1121,8 @@ impl From<&Mechanism<'_>> for CK_MECHANISM { pParameter: null_mut(), ulParameterLen: 0, }, + // Vendor defined mechanisms + Mechanism::VendorDefined(vm) => vm.inner, } } } diff --git a/cryptoki/src/mechanism/vendor_defined.rs b/cryptoki/src/mechanism/vendor_defined.rs new file mode 100644 index 00000000..cce5bdb7 --- /dev/null +++ b/cryptoki/src/mechanism/vendor_defined.rs @@ -0,0 +1,37 @@ +// Copyright 2024 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +//! Mechanism types are defined with the objects and mechanism descriptions that use them. +//! Vendor defined values for this type may also be specified. +//! See: + +use std::{marker::PhantomData, ptr::null_mut}; + +pub use cryptoki_sys::CKM_VENDOR_DEFINED; +use cryptoki_sys::CK_MECHANISM; + +use super::{make_mechanism, MechanismType}; + +/// Vendor defined mechanism. +#[derive(Debug, Clone, Copy)] +pub struct VendorDefinedMechanism<'a> { + pub(crate) inner: CK_MECHANISM, + /// Marker type to ensure we don't outlive the data + _marker: PhantomData<&'a [u8]>, +} + +impl<'a> VendorDefinedMechanism<'a> { + /// Create a new vendor defined mechanism. + pub fn new(mechanism_type: MechanismType, params: Option<&'a T>) -> Self { + Self { + inner: match params { + Some(params) => make_mechanism(mechanism_type.val, params), + None => CK_MECHANISM { + mechanism: mechanism_type.val, + pParameter: null_mut(), + ulParameterLen: 0, + }, + }, + _marker: PhantomData, + } + } +}