From ee385afaede1c444ba9162e6e8a03f37e6ce461d Mon Sep 17 00:00:00 2001 From: Alexandru Placinta Date: Fri, 9 Jan 2026 22:33:10 +0100 Subject: [PATCH 1/3] Add mutex lifecycle draft --- cryptoki/src/context/locking.rs | 163 +++++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 1 deletion(-) diff --git a/cryptoki/src/context/locking.rs b/cryptoki/src/context/locking.rs index 6568d930..bcce21aa 100644 --- a/cryptoki/src/context/locking.rs +++ b/cryptoki/src/context/locking.rs @@ -3,9 +3,13 @@ //! Locking related type use bitflags::bitflags; -use cryptoki_sys::{self, CK_C_INITIALIZE_ARGS, CK_FLAGS}; +use cryptoki_sys::{ + self, CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_MUTEX_BAD, CKR_MUTEX_NOT_LOCKED, CKR_OK, + CK_C_INITIALIZE_ARGS, CK_FLAGS, CK_RV, +}; use std::{ + mem::ManuallyDrop, os::raw::c_void, ptr::{self, NonNull}, }; @@ -21,6 +25,163 @@ bitflags! { } } +/// Error that occurs during mutex creation +#[derive(Copy, Clone, Debug)] +pub enum CreateError { + /// CKR_GENERAL_ERROR + GeneralError, + ///CKR_HOST_MEMORY + HostMemory, +} + +impl From for CK_RV { + fn from(value: CreateError) -> Self { + match value { + CreateError::GeneralError => CKR_GENERAL_ERROR, + CreateError::HostMemory => CKR_HOST_MEMORY, + } + } +} + +/// Error that occurs during mutex destruction +#[derive(Copy, Clone, Debug)] +pub enum DestroyError { + /// CKR_GENERAL_ERROR + GeneralError, + /// CKR_HOST_MEMORY + HostMemory, + /// CKR_MUTEX_BAD + MutexBad, +} + +impl From for CK_RV { + fn from(value: DestroyError) -> Self { + match value { + DestroyError::GeneralError => CKR_GENERAL_ERROR, + DestroyError::HostMemory => CKR_HOST_MEMORY, + DestroyError::MutexBad => CKR_MUTEX_BAD, + } + } +} + +/// Error that occurs during mutex lock +#[derive(Copy, Clone, Debug)] +pub enum LockError { + /// CKR_GENERAL_ERROR + GeneralError, + /// CKR_HOST_MEMORY + HostMemory, + /// CKR_MUTEX_BAD + MutexBad, +} + +impl From for CK_RV { + fn from(value: LockError) -> Self { + match value { + LockError::GeneralError => CKR_GENERAL_ERROR, + LockError::HostMemory => CKR_HOST_MEMORY, + LockError::MutexBad => CKR_MUTEX_BAD, + } + } +} + +/// Error that occurs during mutex unlock +#[derive(Copy, Clone, Debug)] +pub enum UnlockError { + /// CKR_GENERAL_ERROR + GeneralError, + /// CKR_HOST_MEMORY + HostMemory, + /// CKR_MUTEX_BAD + MutexBad, + /// CKR_MUTEX_NOT_LOCKED + MutexNotLocked, +} + +impl From for CK_RV { + fn from(value: UnlockError) -> Self { + match value { + UnlockError::GeneralError => CKR_GENERAL_ERROR, + UnlockError::HostMemory => CKR_HOST_MEMORY, + UnlockError::MutexBad => CKR_MUTEX_BAD, + UnlockError::MutexNotLocked => CKR_MUTEX_NOT_LOCKED, + } + } +} + +/// Trait to manage lifecycle of mutex objects +pub trait MutexLifeCycle: Send + Sync { + /// Creates a mutex + fn create() -> Result, CreateError>; + + /// Destroys a mutex + fn destroy(&mut self) -> Result<(), DestroyError>; + + /// Locks a mutex + fn lock(&self) -> Result<(), DestroyError>; + + /// Unlocks a mutex + fn unlock(&self) -> Result<(), UnlockError>; +} + +unsafe extern "C" fn create_mutex( + ptr_ptr: *mut *mut ::std::os::raw::c_void, +) -> CK_RV { + match M::create() { + Ok(mutex) => { + // SAFETY: This is called by the PKCS#11 library when it needs to + // create a mutex so ptr_ptr contains the address of a valid pointer + unsafe { + *ptr_ptr = Box::into_raw(mutex) as *mut c_void; + } + + CKR_OK + } + Err(err) => err.into(), + } +} + +unsafe extern "C" fn destroy_mutex( + mutex_ptr: *mut ::std::os::raw::c_void, +) -> CK_RV { + // SAFETY: This is invoked after create_mutex + // Here we want to drop so ManuallyDrop is not necessary + let mut mutex = unsafe { Box::::from_raw(mutex_ptr as *mut M) }; + + match mutex.destroy() { + Ok(_) => CKR_OK, + Err(err) => err.into(), + } +} + +unsafe extern "C" fn lock_mutex( + mutex_ptr: *mut ::std::os::raw::c_void, +) -> CK_RV { + // SAFETY: This is invoked after create_mutex + let boxed_mutex = unsafe { Box::::from_raw(mutex_ptr as *mut M) }; + // Avoid the call of Box::drop at the end of the function + let mutex = ManuallyDrop::new(boxed_mutex); + + match mutex.lock() { + Ok(_) => CKR_OK, + Err(err) => err.into(), + } +} + +unsafe extern "C" fn unlock_mutex( + mutex_ptr: *mut ::std::os::raw::c_void, +) -> CK_RV { + // SAFETY: This is invoked after create_mutex + let boxed_mutex = unsafe { Box::::from_raw(mutex_ptr as *mut M) }; + // Avoid the call of Box::drop at the end of the function + let mutex = ManuallyDrop::new(boxed_mutex); + + match mutex.unlock() { + Ok(_) => CKR_OK, + Err(err) => err.into(), + } +} + /// Argument for the initialize function #[derive(Debug, Clone, Copy)] pub struct CInitializeArgs { From 0ef1dcca406bdb1d01a0f525f918e7b935427cde Mon Sep 17 00:00:00 2001 From: Alexandru Placinta Date: Sat, 10 Jan 2026 17:59:20 +0100 Subject: [PATCH 2/3] Add CInitializeArgsWithMutex type --- cryptoki/src/context/locking.rs | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/cryptoki/src/context/locking.rs b/cryptoki/src/context/locking.rs index bcce21aa..3650f6ed 100644 --- a/cryptoki/src/context/locking.rs +++ b/cryptoki/src/context/locking.rs @@ -9,6 +9,7 @@ use cryptoki_sys::{ }; use std::{ + marker::PhantomData, mem::ManuallyDrop, os::raw::c_void, ptr::{self, NonNull}, @@ -267,3 +268,53 @@ impl From for CK_C_INITIALIZE_ARGS { } } } + +/// Argument for the initialize function +#[derive(Debug, Clone, Copy)] +pub struct CInitializeArgsWithMutex { + flags: CInitializeFlags, + p_reserved: Option>, + _phantom: PhantomData, +} + +impl CInitializeArgsWithMutex { + /// Create a new `CInitializeArgsWithMutex` with the given mutex manager and flags + pub fn new(flags: CInitializeFlags) -> Self { + Self { + flags, + p_reserved: None, + _phantom: PhantomData, + } + } + + /// Create a new `CInitializeArgsWithMutex` with the given mutex manager, flags and reserved pointer. + pub const unsafe fn new_with_reserved( + flags: CInitializeFlags, + p_reserved: NonNull, + ) -> Self { + Self { + flags, + p_reserved: Some(p_reserved), + _phantom: PhantomData, + } + } +} + +impl From> for CK_C_INITIALIZE_ARGS { + fn from(c_initialize_args: CInitializeArgsWithMutex) -> Self { + let flags = c_initialize_args.flags.bits(); + let p_reserved = c_initialize_args + .p_reserved + .map(|non_null| non_null.as_ptr()) + .unwrap_or_else(ptr::null_mut); + + Self { + CreateMutex: Some(create_mutex:: as _), + DestroyMutex: Some(destroy_mutex:: as _), + LockMutex: Some(lock_mutex:: as _), + UnlockMutex: Some(unlock_mutex:: as _), + flags, + pReserved: p_reserved, + } + } +} From f64bca30ceca7cfa962a2f8e4be7219b623f54c8 Mon Sep 17 00:00:00 2001 From: Alexandru Placinta Date: Sat, 10 Jan 2026 18:06:56 +0100 Subject: [PATCH 3/3] Adapt cryptoki::context::Pkcs11::initialize --- cryptoki/src/context/general_purpose.rs | 7 +++++-- cryptoki/src/context/mod.rs | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cryptoki/src/context/general_purpose.rs b/cryptoki/src/context/general_purpose.rs index ff511bb1..93662a8a 100644 --- a/cryptoki/src/context/general_purpose.rs +++ b/cryptoki/src/context/general_purpose.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 //! General-purpose functions -use crate::context::{CInitializeArgs, Info, Pkcs11}; +use crate::context::{Info, Pkcs11}; use crate::error::{Result, Rv}; use cryptoki_sys::{CK_C_INITIALIZE_ARGS, CK_INFO}; use paste::paste; @@ -12,7 +12,10 @@ use std::ptr; // See public docs on stub in parent mod.rs #[inline(always)] -pub(super) fn initialize(ctx: &Pkcs11, init_args: CInitializeArgs) -> Result<()> { +pub(super) fn initialize(ctx: &Pkcs11, init_args: T) -> Result<()> +where + CK_C_INITIALIZE_ARGS: From, +{ // if no args are specified, library expects NULL let mut init_args = CK_C_INITIALIZE_ARGS::from(init_args); let init_args_ptr = &mut init_args; diff --git a/cryptoki/src/context/mod.rs b/cryptoki/src/context/mod.rs index 627ca3df..1a0b236d 100644 --- a/cryptoki/src/context/mod.rs +++ b/cryptoki/src/context/mod.rs @@ -24,6 +24,7 @@ mod locking; mod session_management; mod slot_token_management; +use cryptoki_sys::CK_C_INITIALIZE_ARGS; pub use general_purpose::*; pub use info::*; pub use locking::*; @@ -161,7 +162,10 @@ impl Pkcs11 { } /// Initialize the PKCS11 library - pub fn initialize(&self, init_args: CInitializeArgs) -> Result<()> { + pub fn initialize(&self, init_args: T) -> Result<()> + where + CK_C_INITIALIZE_ARGS: From, + { initialize(self, init_args) }