22// SPDX-License-Identifier: Apache-2.0
33//! Locking related type
44
5- use cryptoki_sys:: { CKF_LIBRARY_CANT_CREATE_OS_THREADS , CKF_OS_LOCKING_OK , CK_FLAGS , CK_RV } ;
5+ use bitflags:: bitflags;
6+ use cryptoki_sys:: {
7+ CKF_LIBRARY_CANT_CREATE_OS_THREADS , CKF_OS_LOCKING_OK , CKR_GENERAL_ERROR , CKR_HOST_MEMORY ,
8+ CKR_MUTEX_BAD , CKR_MUTEX_NOT_LOCKED , CKR_OK , CK_FLAGS , CK_RV ,
9+ } ;
610
711use std:: {
812 os:: raw:: c_void,
913 ptr:: { self , NonNull } ,
1014} ;
1115
12- /// Function pointer that creates a mutex
13- pub type CreateMutexFn = unsafe extern "C" fn ( * mut * mut :: std:: os:: raw:: c_void ) -> CK_RV ;
16+ /// Error that occurs during mutex creation
17+ #[ derive( Copy , Clone , Debug ) ]
18+ pub enum CreateError {
19+ /// CKR_GENERAL_ERROR
20+ GeneralError ,
21+ ///CKR_HOST_MEMORY
22+ HostMemory ,
23+ }
1424
15- /// Function pointer that destroys a mutex
16- pub type DestroyMutexFn = unsafe extern "C" fn ( * mut :: std:: os:: raw:: c_void ) -> CK_RV ;
25+ impl From < CreateError > for CK_RV {
26+ fn from ( value : CreateError ) -> Self {
27+ match value {
28+ CreateError :: GeneralError => CKR_GENERAL_ERROR ,
29+ CreateError :: HostMemory => CKR_HOST_MEMORY ,
30+ }
31+ }
32+ }
1733
18- /// Function pointer that locks a mutex
19- pub type LockMutexFn = unsafe extern "C" fn ( * mut :: std:: os:: raw:: c_void ) -> CK_RV ;
34+ /// Error that occurs during mutex destruction
35+ #[ derive( Copy , Clone , Debug ) ]
36+ pub enum DestroyError {
37+ /// CKR_GENERAL_ERROR
38+ GeneralError ,
39+ /// CKR_HOST_MEMORY
40+ HostMemory ,
41+ /// CKR_MUTEX_BAD
42+ MutexBad ,
43+ }
2044
21- /// Function pointer that unlocks a mutex
22- pub type UnlockMutexFn = unsafe extern "C" fn ( * mut :: std:: os:: raw:: c_void ) -> CK_RV ;
45+ impl From < DestroyError > for CK_RV {
46+ fn from ( value : DestroyError ) -> Self {
47+ match value {
48+ DestroyError :: GeneralError => CKR_GENERAL_ERROR ,
49+ DestroyError :: HostMemory => CKR_HOST_MEMORY ,
50+ DestroyError :: MutexBad => CKR_MUTEX_BAD ,
51+ }
52+ }
53+ }
2354
24- /// Provides function pointers for mutex-handling to ensure safe multi-threaded access.
55+ /// Error that occurs during mutex lock
2556#[ derive( Copy , Clone , Debug ) ]
26- pub struct CustomMutexHandling {
27- create_mutex : CreateMutexFn ,
28- destroy_mutex : DestroyMutexFn ,
29- lock_mutex : LockMutexFn ,
30- unlock_mutex : UnlockMutexFn ,
57+ pub enum LockError {
58+ /// CKR_GENERAL_ERROR
59+ GeneralError ,
60+ /// CKR_HOST_MEMORY
61+ HostMemory ,
62+ /// CKR_MUTEX_BAD
63+ MutexBad ,
3164}
3265
33- impl CustomMutexHandling {
34- /// Create a new `CustomMutexHandling` with the given function pointers
35- /// to handle library's thread safety.
36- ///
37- /// # Safety
38- /// Considered unsafe due to user's ability to pass any function pointer.
39- pub const unsafe fn new (
40- create_mutex : CreateMutexFn ,
41- destroy_mutex : DestroyMutexFn ,
42- lock_mutex : LockMutexFn ,
43- unlock_mutex : UnlockMutexFn ,
44- ) -> Self {
45- Self {
46- create_mutex : create_mutex,
47- destroy_mutex : destroy_mutex,
48- lock_mutex : lock_mutex,
49- unlock_mutex : unlock_mutex,
66+ impl From < LockError > for CK_RV {
67+ fn from ( value : LockError ) -> Self {
68+ match value {
69+ LockError :: GeneralError => CKR_GENERAL_ERROR ,
70+ LockError :: HostMemory => CKR_HOST_MEMORY ,
71+ LockError :: MutexBad => CKR_MUTEX_BAD ,
5072 }
5173 }
5274}
5375
54- /// Flags to set for the initialize function
76+ /// Error that occurs during mutex unlock
5577#[ derive( Copy , Clone , Debug ) ]
56- pub enum CInitializeFlags {
57- /// The library won’t be accessed from multiple threads simultaneously
58- None ,
59- /// The library may not create its own threads
60- NoOsThreads ,
61- /// The library can use the native OS library for locking or the custom
62- OsThreads ,
63- /// The library needs to use the supplied function pointers
64- /// for mutex-handling to ensure safe multi-threaded access.
65- CustomMutexHandling ( CustomMutexHandling ) ,
66- /// The library needs to use either the native operating system primitives
67- /// or the supplied function pointers for mutex-handling to ensure safe
68- /// multi-threaded access
69- OsThreadsOrCustomMutexHandling ( CustomMutexHandling ) ,
78+ pub enum UnlockError {
79+ /// CKR_GENERAL_ERROR
80+ GeneralError ,
81+ /// CKR_HOST_MEMORY
82+ HostMemory ,
83+ /// CKR_MUTEX_BAD
84+ MutexBad ,
85+ /// CKR_MUTEX_NOT_LOCKED
86+ MutexNotLocked ,
87+ }
88+
89+ impl From < UnlockError > for CK_RV {
90+ fn from ( value : UnlockError ) -> Self {
91+ match value {
92+ UnlockError :: GeneralError => CKR_GENERAL_ERROR ,
93+ UnlockError :: HostMemory => CKR_HOST_MEMORY ,
94+ UnlockError :: MutexBad => CKR_MUTEX_BAD ,
95+ UnlockError :: MutexNotLocked => CKR_MUTEX_NOT_LOCKED ,
96+ }
97+ }
98+ }
99+
100+ /// Trait to manage lifecycle of mutex objects
101+ pub trait MutexLifeCycle {
102+ /// Creates a mutex
103+ fn create ( ) -> Result < Box < Self > , CreateError > ;
104+
105+ /// Destroys a mutex
106+ fn destroy ( & mut self ) -> Result < ( ) , DestroyError > ;
107+
108+ /// Locks a mutex
109+ fn lock ( & self ) -> Result < ( ) , DestroyError > ;
110+
111+ /// Unlocks a mutex
112+ fn unlock ( & self ) -> Result < ( ) , UnlockError > ;
113+ }
114+
115+ unsafe extern "C" fn create_mutex < M : MutexLifeCycle > (
116+ ptr_ptr : * mut * mut :: std:: os:: raw:: c_void ,
117+ ) -> CK_RV {
118+ match M :: create ( ) {
119+ Ok ( mutex) => {
120+ * ptr_ptr = Box :: into_raw ( mutex) as * mut c_void ;
121+ CKR_OK
122+ }
123+ Err ( err) => err. into ( ) ,
124+ }
125+ }
126+
127+ unsafe extern "C" fn destroy_mutex < M : MutexLifeCycle > (
128+ mutex_ptr : * mut :: std:: os:: raw:: c_void ,
129+ ) -> CK_RV {
130+ // SAFETY: This is invoked after create_mutex
131+ let mut mutex = unsafe { Box :: < M > :: from_raw ( mutex_ptr as * mut M ) } ;
132+
133+ match mutex. destroy ( ) {
134+ Ok ( _) => CKR_OK ,
135+ Err ( err) => err. into ( ) ,
136+ }
137+ }
138+
139+ unsafe extern "C" fn lock_mutex < M : MutexLifeCycle > (
140+ mutex_ptr : * mut :: std:: os:: raw:: c_void ,
141+ ) -> CK_RV {
142+ // SAFETY: This is invoked after create_mutex
143+ let mutex = unsafe { Box :: < M > :: from_raw ( mutex_ptr as * mut M ) } ;
144+
145+ match mutex. lock ( ) {
146+ Ok ( _) => CKR_OK ,
147+ Err ( err) => err. into ( ) ,
148+ }
149+ }
150+
151+ unsafe extern "C" fn unlock_mutex < M : MutexLifeCycle > (
152+ mutex_ptr : * mut :: std:: os:: raw:: c_void ,
153+ ) -> CK_RV {
154+ // SAFETY: This is invoked after create_mutex
155+ let mutex = unsafe { Box :: < M > :: from_raw ( mutex_ptr as * mut M ) } ;
156+ match mutex. unlock ( ) {
157+ Ok ( _) => CKR_OK ,
158+ Err ( err) => err. into ( ) ,
159+ }
160+ }
161+
162+ bitflags ! {
163+ /// Flags to set for the initialize function
164+ #[ derive( Debug , Clone , Copy ) ]
165+ pub struct CInitializeFlags : CK_FLAGS {
166+ /// The library can use the native OS library for locking or the custom
167+ const OS_LOCKING_OK = CKF_OS_LOCKING_OK ;
168+ /// The library may not create its own threads
169+ const LIBRARY_CANT_CREATE_OS_THREADS = CKF_LIBRARY_CANT_CREATE_OS_THREADS ;
170+ }
70171}
71172
72- #[ derive( Copy , Clone , Debug ) ]
73173/// Argument for the initialize function
74- pub struct CInitializeArgs {
174+ #[ derive( Debug , Clone , Copy ) ]
175+ pub struct CInitializeArgs < M > {
75176 flags : CInitializeFlags ,
177+ mutex_lifecycle : Option < M > ,
76178 p_reserved : Option < NonNull < c_void > > ,
77179}
78180
79- impl CInitializeArgs {
181+ impl CInitializeArgs < ( ) > {
80182 /// Create a new `CInitializeArgs` with the given flags
81183 ///
82184 /// # Examples
83185 /// ```
84186 /// use cryptoki::context::{CInitializeArgs, CInitializeFlags};
85187 ///
86- /// let args = CInitializeArgs::new(CInitializeFlags::OsThreads );
188+ /// let args = CInitializeArgs::<()>:: new(CInitializeFlags::OS_LOCKING_OK | CInitializeFlags::LIBRARY_CANT_CREATE_OS_THREADS );
87189 /// ```
190+ pub fn new ( flags : CInitializeFlags ) -> Self {
191+ Self {
192+ flags,
193+ mutex_lifecycle : None ,
194+ p_reserved : None ,
195+ }
196+ }
197+
198+ /// Create a new `CInitializeArgs` with the given flags and reserved pointer.
199+ ///
200+ /// # Safety
201+ /// Considered unsafe due to the user's ability to pass any pointer.
202+ ///
203+ /// The user is responsible for managing the memory behind the pointer.
204+ pub const unsafe fn new_with_reserved (
205+ flags : CInitializeFlags ,
206+ p_reserved : NonNull < c_void > ,
207+ ) -> Self {
208+ Self {
209+ flags,
210+ mutex_lifecycle : None ,
211+ p_reserved : Some ( p_reserved) ,
212+ }
213+ }
214+ }
215+
216+ impl < M : MutexLifeCycle > CInitializeArgs < M > {
217+ /// Create a new `CInitializeArgs` with the given flags
88218 pub const fn new ( flags : CInitializeFlags ) -> Self {
89219 Self {
90220 flags,
221+ mutex_lifecycle : None ,
91222 p_reserved : None ,
92223 }
93224 }
@@ -104,69 +235,47 @@ impl CInitializeArgs {
104235 ) -> Self {
105236 Self {
106237 flags,
238+ mutex_lifecycle : None ,
107239 p_reserved : Some ( p_reserved) ,
108240 }
109241 }
110242}
111243
112- impl From < CInitializeArgs > for cryptoki_sys:: CK_C_INITIALIZE_ARGS {
113- fn from ( c_initialize_args : CInitializeArgs ) -> Self {
114- let mut flags = CK_FLAGS :: default ( ) ;
244+ impl From < CInitializeArgs < ( ) > > for cryptoki_sys:: CK_C_INITIALIZE_ARGS {
245+ fn from ( c_initialize_args : CInitializeArgs < ( ) > ) -> Self {
246+ let flags = c_initialize_args. flags . bits ( ) ;
247+ let p_reserved = c_initialize_args
248+ . p_reserved
249+ . map ( |non_null| non_null. as_ptr ( ) )
250+ . unwrap_or_else ( ptr:: null_mut) ;
251+
252+ Self {
253+ CreateMutex : None ,
254+ DestroyMutex : None ,
255+ LockMutex : None ,
256+ UnlockMutex : None ,
257+ flags,
258+ pReserved : p_reserved,
259+ }
260+ }
261+ }
262+
263+ impl < M : MutexLifeCycle > From < CInitializeArgs < M > > for cryptoki_sys:: CK_C_INITIALIZE_ARGS {
264+ fn from ( c_initialize_args : CInitializeArgs < M > ) -> Self {
265+ let flags = c_initialize_args. flags . bits ( ) ;
115266 let p_reserved = c_initialize_args
116267 . p_reserved
117268 . map ( |non_null| non_null. as_ptr ( ) )
118269 . unwrap_or_else ( ptr:: null_mut) ;
270+ let mutex_lifecycle = c_initialize_args. mutex_lifecycle ;
119271
120- match c_initialize_args. flags {
121- CInitializeFlags :: None => Self {
122- CreateMutex : None ,
123- DestroyMutex : None ,
124- LockMutex : None ,
125- UnlockMutex : None ,
126- flags,
127- pReserved : p_reserved,
128- } ,
129- CInitializeFlags :: NoOsThreads => {
130- flags |= CKF_LIBRARY_CANT_CREATE_OS_THREADS ;
131- Self {
132- flags,
133- CreateMutex : None ,
134- DestroyMutex : None ,
135- LockMutex : None ,
136- UnlockMutex : None ,
137- pReserved : p_reserved,
138- }
139- }
140- CInitializeFlags :: OsThreads => {
141- flags |= CKF_OS_LOCKING_OK ;
142- Self {
143- flags,
144- CreateMutex : None ,
145- DestroyMutex : None ,
146- LockMutex : None ,
147- UnlockMutex : None ,
148- pReserved : p_reserved,
149- }
150- }
151- CInitializeFlags :: CustomMutexHandling ( custom_mutex_handling) => Self {
152- flags,
153- CreateMutex : Some ( custom_mutex_handling. create_mutex ) ,
154- DestroyMutex : Some ( custom_mutex_handling. destroy_mutex ) ,
155- LockMutex : Some ( custom_mutex_handling. lock_mutex ) ,
156- UnlockMutex : Some ( custom_mutex_handling. unlock_mutex ) ,
157- pReserved : p_reserved,
158- } ,
159- CInitializeFlags :: OsThreadsOrCustomMutexHandling ( custom_mutex_handling) => {
160- flags |= CKF_OS_LOCKING_OK ;
161- Self {
162- flags,
163- CreateMutex : Some ( custom_mutex_handling. create_mutex ) ,
164- DestroyMutex : Some ( custom_mutex_handling. destroy_mutex ) ,
165- LockMutex : Some ( custom_mutex_handling. lock_mutex ) ,
166- UnlockMutex : Some ( custom_mutex_handling. unlock_mutex ) ,
167- pReserved : p_reserved,
168- }
169- }
272+ Self {
273+ CreateMutex : mutex_lifecycle. as_ref ( ) . map ( |_| create_mutex :: < M > as _ ) ,
274+ DestroyMutex : mutex_lifecycle. as_ref ( ) . map ( |_| destroy_mutex :: < M > as _ ) ,
275+ LockMutex : mutex_lifecycle. as_ref ( ) . map ( |_| lock_mutex :: < M > as _ ) ,
276+ UnlockMutex : mutex_lifecycle. as_ref ( ) . map ( |_| unlock_mutex :: < M > as _ ) ,
277+ flags,
278+ pReserved : p_reserved,
170279 }
171280 }
172281}
0 commit comments