Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support vendor defined mechanisms #232

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions cryptoki/src/mechanism/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand All @@ -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;
Expand Down Expand Up @@ -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<MechanismType> {
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)),
Expand Down Expand Up @@ -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<'_> {
Expand Down Expand Up @@ -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,
},
}
}
}
Expand Down Expand Up @@ -1087,6 +1121,8 @@ impl From<&Mechanism<'_>> for CK_MECHANISM {
pParameter: null_mut(),
ulParameterLen: 0,
},
// Vendor defined mechanisms
Mechanism::VendorDefined(vm) => vm.inner,
}
}
}
Expand Down
37 changes: 37 additions & 0 deletions cryptoki/src/mechanism/vendor_defined.rs
Original file line number Diff line number Diff line change
@@ -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: <https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html#_Toc29976545>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are vendor mechanisms only supported in v3 of PKCS #11?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also supported in v2.4. I put v3.0 link here since we are using v3.0 headers now.


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<T>(mechanism_type: MechanismType, params: Option<&'a T>) -> Self {
hug-dev marked this conversation as resolved.
Show resolved Hide resolved
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,
}
}
}
Loading