tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

lib.rs (41604B)


      1 /* -*- Mode: rust; rust-indent-offset: 4 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 extern crate byteorder;
      7 extern crate pkcs11_bindings;
      8 
      9 pub mod cryptoki;
     10 pub mod manager;
     11 
     12 // Helper macro to prefix log messages with the current thread ID.
     13 #[macro_export]
     14 macro_rules! log_with_thread_id {
     15    ($log_level:ident, $($message:expr),*) => {
     16        $log_level!("{:?} {}", std::thread::current().id(), format_args!($($message),*));
     17    };
     18 }
     19 
     20 // This module defines a few helper macros that can be used to declare the repetitive, boilerplate
     21 // code required to implement a PKCS#11 module. They require the macros `try_to_get_manager_guard`
     22 // and `manager_guard_to_manager` to be defined. Generally speaking, these manager macros are used
     23 // to get a mutable handle on a `Mutex<Option<Manager<...>>>` that represents the state of the
     24 // module.
     25 
     26 /// NB: Requires MANUFACTURER_ID_BYTES and LIBRARY_DESCRIPTION_BYTES to be defined.
     27 #[macro_export]
     28 macro_rules! declare_pkcs11_informational_functions {
     29    () => {
     30        /// This gets called to gather some information about the module. In particular, this
     31        /// implementation supports (portions of) cryptoki (PKCS #11) version 2.2.
     32        extern "C" fn C_GetInfo(pInfo: CK_INFO_PTR) -> CK_RV {
     33            if pInfo.is_null() {
     34                log_with_thread_id!(error, "C_GetInfo: CKR_ARGUMENTS_BAD");
     35                return CKR_ARGUMENTS_BAD;
     36            }
     37            let info = CK_INFO {
     38                cryptokiVersion: CK_VERSION { major: 2, minor: 2 },
     39                manufacturerID: *MANUFACTURER_ID_BYTES,
     40                flags: 0,
     41                libraryDescription: *LIBRARY_DESCRIPTION_BYTES,
     42                libraryVersion: CK_VERSION { major: 0, minor: 0 },
     43            };
     44            unsafe {
     45                *pInfo = info;
     46            }
     47            log_with_thread_id!(debug, "C_GetInfo: CKR_OK");
     48            CKR_OK
     49        }
     50 
     51        /// This gets called twice: once with a null `pSlotList` to get the number of slots
     52        /// (returned via `pulCount`) and a second time to get the ID for each slot.
     53        extern "C" fn C_GetSlotList(
     54            tokenPresent: CK_BBOOL,
     55            pSlotList: CK_SLOT_ID_PTR,
     56            pulCount: CK_ULONG_PTR,
     57        ) -> CK_RV {
     58            if pulCount.is_null() {
     59                log_with_thread_id!(error, "C_GetSlotList: CKR_ARGUMENTS_BAD");
     60                return CKR_ARGUMENTS_BAD;
     61            }
     62            let mut manager_guard = try_to_get_manager_guard!();
     63            let manager = manager_guard_to_manager!(manager_guard);
     64            let slot_ids = manager.get_slot_ids(if tokenPresent == CK_TRUE { true } else { false });
     65            let slot_count: CK_ULONG = slot_ids.len().try_into().unwrap();
     66            if !pSlotList.is_null() {
     67                if unsafe { *pulCount } < slot_count {
     68                    log_with_thread_id!(error, "C_GetSlotList: CKR_BUFFER_TOO_SMALL");
     69                    return CKR_BUFFER_TOO_SMALL;
     70                }
     71                unsafe {
     72                    std::ptr::copy_nonoverlapping(slot_ids.as_ptr(), pSlotList, slot_ids.len());
     73                }
     74            };
     75            unsafe {
     76                *pulCount = slot_count;
     77            }
     78            log_with_thread_id!(debug, "C_GetSlotList: CKR_OK");
     79            CKR_OK
     80        }
     81 
     82        extern "C" fn C_GetSlotInfo(slotID: CK_SLOT_ID, pInfo: CK_SLOT_INFO_PTR) -> CK_RV {
     83            if pInfo.is_null() {
     84                log_with_thread_id!(error, "C_GetSlotInfo: CKR_ARGUMENTS_BAD");
     85                return CKR_ARGUMENTS_BAD;
     86            }
     87            let mut manager_guard = try_to_get_manager_guard!();
     88            let manager = manager_guard_to_manager!(manager_guard);
     89            let Ok(slot_info) = manager.get_slot_info(slotID) else {
     90                log_with_thread_id!(error, "C_GetSlotInfo: CKR_ARGUMENTS_BAD");
     91                return CKR_ARGUMENTS_BAD;
     92            };
     93            unsafe {
     94                *pInfo = slot_info;
     95            }
     96            log_with_thread_id!(debug, "C_GetSlotInfo: CKR_OK");
     97            CKR_OK
     98        }
     99 
    100        extern "C" fn C_GetTokenInfo(slotID: CK_SLOT_ID, pInfo: CK_TOKEN_INFO_PTR) -> CK_RV {
    101            if pInfo.is_null() {
    102                log_with_thread_id!(error, "C_GetTokenInfo: CKR_ARGUMENTS_BAD");
    103                return CKR_ARGUMENTS_BAD;
    104            }
    105            let mut manager_guard = try_to_get_manager_guard!();
    106            let manager = manager_guard_to_manager!(manager_guard);
    107            let Ok(token_info) = manager.get_token_info(slotID) else {
    108                log_with_thread_id!(error, "C_GetTokenInfo: CKR_ARGUMENTS_BAD");
    109                return CKR_ARGUMENTS_BAD;
    110            };
    111            unsafe {
    112                *pInfo = token_info;
    113            }
    114            log_with_thread_id!(debug, "C_GetTokenInfo: CKR_OK");
    115            CKR_OK
    116        }
    117 
    118        extern "C" fn C_GetMechanismList(
    119            slotID: CK_SLOT_ID,
    120            pMechanismList: CK_MECHANISM_TYPE_PTR,
    121            pulCount: CK_ULONG_PTR,
    122        ) -> CK_RV {
    123            if pulCount.is_null() {
    124                log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD");
    125                return CKR_ARGUMENTS_BAD;
    126            }
    127            let mut manager_guard = try_to_get_manager_guard!();
    128            let manager = manager_guard_to_manager!(manager_guard);
    129            let Ok(mechanisms) = manager.get_mechanism_list(slotID) else {
    130                log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD");
    131                return CKR_ARGUMENTS_BAD;
    132            };
    133            let mechanisms_len: CK_ULONG = mechanisms.len().try_into().unwrap();
    134            if !pMechanismList.is_null() {
    135                if unsafe { *pulCount } < mechanisms_len {
    136                    log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD");
    137                    return CKR_ARGUMENTS_BAD;
    138                }
    139                unsafe {
    140                    std::ptr::copy_nonoverlapping(
    141                        mechanisms.as_ptr(),
    142                        pMechanismList,
    143                        mechanisms.len(),
    144                    );
    145                }
    146            }
    147            unsafe {
    148                *pulCount = mechanisms_len;
    149            }
    150            log_with_thread_id!(debug, "C_GetMechanismList: CKR_OK");
    151            CKR_OK
    152        }
    153    };
    154 }
    155 
    156 #[macro_export]
    157 macro_rules! declare_pkcs11_session_functions {
    158    () => {
    159        extern "C" fn C_OpenSession(
    160            slotID: CK_SLOT_ID,
    161            _flags: CK_FLAGS,
    162            _pApplication: CK_VOID_PTR,
    163            _Notify: CK_NOTIFY,
    164            phSession: CK_SESSION_HANDLE_PTR,
    165        ) -> CK_RV {
    166            if phSession.is_null() {
    167                log_with_thread_id!(error, "C_OpenSession: CKR_ARGUMENTS_BAD");
    168                return CKR_ARGUMENTS_BAD;
    169            }
    170            let mut manager_guard = try_to_get_manager_guard!();
    171            let manager = manager_guard_to_manager!(manager_guard);
    172            let session_handle = match manager.open_session(slotID) {
    173                Ok(session_handle) => session_handle,
    174                Err(e) => {
    175                    log_with_thread_id!(error, "C_OpenSession: open_session failed: {}", e);
    176                    return CKR_DEVICE_ERROR;
    177                }
    178            };
    179            unsafe {
    180                *phSession = session_handle;
    181            }
    182            log_with_thread_id!(debug, "C_OpenSession: CKR_OK");
    183            CKR_OK
    184        }
    185 
    186        extern "C" fn C_CloseSession(hSession: CK_SESSION_HANDLE) -> CK_RV {
    187            let mut manager_guard = try_to_get_manager_guard!();
    188            let manager = manager_guard_to_manager!(manager_guard);
    189            if manager.close_session(hSession).is_err() {
    190                log_with_thread_id!(error, "C_CloseSession: CKR_SESSION_HANDLE_INVALID");
    191                return CKR_SESSION_HANDLE_INVALID;
    192            }
    193            log_with_thread_id!(debug, "C_CloseSession: CKR_OK");
    194            CKR_OK
    195        }
    196 
    197        extern "C" fn C_CloseAllSessions(slotID: CK_SLOT_ID) -> CK_RV {
    198            let mut manager_guard = try_to_get_manager_guard!();
    199            let manager = manager_guard_to_manager!(manager_guard);
    200            match manager.close_all_sessions(slotID) {
    201                Ok(()) => {
    202                    log_with_thread_id!(debug, "C_CloseAllSessions: CKR_OK");
    203                    CKR_OK
    204                }
    205                Err(e) => {
    206                    log_with_thread_id!(
    207                        error,
    208                        "C_CloseAllSessions: close_all_sessions failed: {}",
    209                        e
    210                    );
    211                    CKR_DEVICE_ERROR
    212                }
    213            }
    214        }
    215 
    216        extern "C" fn C_GetSessionInfo(
    217            hSession: CK_SESSION_HANDLE,
    218            pInfo: CK_SESSION_INFO_PTR,
    219        ) -> CK_RV {
    220            if pInfo.is_null() {
    221                log_with_thread_id!(error, "C_GetSessionInfo: CKR_ARGUMENTS_BAD");
    222                return CKR_ARGUMENTS_BAD;
    223            }
    224            let mut manager_guard = try_to_get_manager_guard!();
    225            let manager = manager_guard_to_manager!(manager_guard);
    226            let Ok(session_info) = manager.get_session_info(hSession) else {
    227                log_with_thread_id!(error, "C_GetSessionInfo: CKR_ARGUMENTS_BAD");
    228                return CKR_ARGUMENTS_BAD;
    229            };
    230            unsafe {
    231                *pInfo = session_info;
    232            }
    233            log_with_thread_id!(debug, "C_GetSessionInfo: CKR_OK");
    234            CKR_OK
    235        }
    236 
    237        extern "C" fn C_Login(
    238            hSession: CK_SESSION_HANDLE,
    239            _userType: CK_USER_TYPE,
    240            _pPin: CK_UTF8CHAR_PTR,
    241            _ulPinLen: CK_ULONG,
    242        ) -> CK_RV {
    243            let mut manager_guard = try_to_get_manager_guard!();
    244            let manager = manager_guard_to_manager!(manager_guard);
    245            match manager.login(hSession) {
    246                Ok(()) => {
    247                    log_with_thread_id!(debug, "C_Login: CKR_OK");
    248                    CKR_OK
    249                }
    250                Err(e) => {
    251                    log_with_thread_id!(error, "C_Login failed: {}", e);
    252                    CKR_GENERAL_ERROR
    253                }
    254            }
    255        }
    256 
    257        extern "C" fn C_Logout(hSession: CK_SESSION_HANDLE) -> CK_RV {
    258            let mut manager_guard = try_to_get_manager_guard!();
    259            let manager = manager_guard_to_manager!(manager_guard);
    260            match manager.logout(hSession) {
    261                Ok(()) => {
    262                    log_with_thread_id!(debug, "C_Logout: CKR_OK");
    263                    CKR_OK
    264                }
    265                Err(e) => {
    266                    log_with_thread_id!(error, "C_Logout failed: {}", e);
    267                    CKR_GENERAL_ERROR
    268                }
    269            }
    270        }
    271    };
    272 }
    273 
    274 #[macro_export]
    275 macro_rules! declare_pkcs11_find_functions {
    276    () => {
    277        fn trace_attr(prefix: &str, attr: &CK_ATTRIBUTE) {
    278            // Copying out the fields of `attr` avoids making a reference to an unaligned field.
    279            let typ = attr.type_;
    280            let typ = match typ {
    281                CKA_CLASS => "CKA_CLASS".to_string(),
    282                CKA_TOKEN => "CKA_TOKEN".to_string(),
    283                CKA_LABEL => "CKA_LABEL".to_string(),
    284                CKA_ID => "CKA_ID".to_string(),
    285                CKA_VALUE => "CKA_VALUE".to_string(),
    286                CKA_ISSUER => "CKA_ISSUER".to_string(),
    287                CKA_SERIAL_NUMBER => "CKA_SERIAL_NUMBER".to_string(),
    288                CKA_SUBJECT => "CKA_SUBJECT".to_string(),
    289                CKA_PRIVATE => "CKA_PRIVATE".to_string(),
    290                CKA_KEY_TYPE => "CKA_KEY_TYPE".to_string(),
    291                CKA_MODULUS => "CKA_MODULUS".to_string(),
    292                CKA_EC_PARAMS => "CKA_EC_PARAMS".to_string(),
    293                _ => format!("0x{:x}", typ),
    294            };
    295            let value =
    296                unsafe { std::slice::from_raw_parts(attr.pValue as *const u8, attr.ulValueLen as usize) };
    297            let len = attr.ulValueLen;
    298            log_with_thread_id!(
    299                trace,
    300                "{}CK_ATTRIBUTE {{ type: {}, pValue: {:?}, ulValueLen: {} }}",
    301                prefix,
    302                typ,
    303                value,
    304                len
    305            );
    306        }
    307 
    308        const RELEVANT_ATTRIBUTES: &[CK_ATTRIBUTE_TYPE] = &[
    309            CKA_CLASS,
    310            CKA_EC_PARAMS,
    311            CKA_ID,
    312            CKA_ISSUER,
    313            CKA_KEY_TYPE,
    314            CKA_LABEL,
    315            CKA_MODULUS,
    316            CKA_PRIVATE,
    317            CKA_SERIAL_NUMBER,
    318            CKA_SUBJECT,
    319            CKA_TOKEN,
    320            CKA_VALUE,
    321        ];
    322 
    323        /// This gets called to initialize a search for objects matching a given list of attributes.
    324        extern "C" fn C_FindObjectsInit(
    325            hSession: CK_SESSION_HANDLE,
    326            pTemplate: CK_ATTRIBUTE_PTR,
    327            ulCount: CK_ULONG,
    328        ) -> CK_RV {
    329            if pTemplate.is_null() {
    330                log_with_thread_id!(error, "C_FindObjectsInit: CKR_ARGUMENTS_BAD");
    331                return CKR_ARGUMENTS_BAD;
    332            }
    333            let mut attrs = Vec::new();
    334            log_with_thread_id!(trace, "C_FindObjectsInit:");
    335            for i in 0..ulCount as usize {
    336                let attr = unsafe { &*pTemplate.add(i) };
    337                trace_attr("  ", attr);
    338                // Copy out the attribute type to avoid making a reference to an unaligned field.
    339                let attr_type = attr.type_;
    340                if !RELEVANT_ATTRIBUTES.contains(&attr_type) {
    341                    log_with_thread_id!(
    342                        debug,
    343                        "C_FindObjectsInit: irrelevant attribute, returning CKR_ATTRIBUTE_TYPE_INVALID"
    344                    );
    345                    return CKR_ATTRIBUTE_TYPE_INVALID;
    346                }
    347                let slice = unsafe {
    348                    std::slice::from_raw_parts(attr.pValue as *const u8, attr.ulValueLen as usize)
    349                };
    350                attrs.push((attr_type, slice.to_owned()));
    351            }
    352            let mut manager_guard = try_to_get_manager_guard!();
    353            let manager = manager_guard_to_manager!(manager_guard);
    354            match manager.start_search(hSession, attrs) {
    355                Ok(()) => {}
    356                Err(e) => {
    357                    log_with_thread_id!(error, "C_FindObjectsInit: CKR_ARGUMENTS_BAD: {}", e);
    358                    return CKR_ARGUMENTS_BAD;
    359                }
    360            }
    361            log_with_thread_id!(debug, "C_FindObjectsInit: CKR_OK");
    362            CKR_OK
    363        }
    364 
    365        /// This gets called after `C_FindObjectsInit` to get the results of a search.
    366        extern "C" fn C_FindObjects(
    367            hSession: CK_SESSION_HANDLE,
    368            phObject: CK_OBJECT_HANDLE_PTR,
    369            ulMaxObjectCount: CK_ULONG,
    370            pulObjectCount: CK_ULONG_PTR,
    371        ) -> CK_RV {
    372            if phObject.is_null() || pulObjectCount.is_null() || ulMaxObjectCount == 0 {
    373                log_with_thread_id!(error, "C_FindObjects: CKR_ARGUMENTS_BAD");
    374                return CKR_ARGUMENTS_BAD;
    375            }
    376            let mut manager_guard = try_to_get_manager_guard!();
    377            let manager = manager_guard_to_manager!(manager_guard);
    378            let handles = match manager.search(hSession, ulMaxObjectCount as usize) {
    379                Ok(handles) => handles,
    380                Err(e) => {
    381                    log_with_thread_id!(error, "C_FindObjects: CKR_ARGUMENTS_BAD: {}", e);
    382                    return CKR_ARGUMENTS_BAD;
    383                }
    384            };
    385            log_with_thread_id!(debug, "C_FindObjects: found handles {:?}", handles);
    386            if handles.len() > ulMaxObjectCount as usize {
    387                log_with_thread_id!(error, "C_FindObjects: manager returned too many handles");
    388                return CKR_DEVICE_ERROR;
    389            }
    390            unsafe {
    391                *pulObjectCount = handles.len() as CK_ULONG;
    392            }
    393            for (index, handle) in handles.iter().enumerate() {
    394                if index < ulMaxObjectCount as usize {
    395                    unsafe {
    396                        *(phObject.add(index)) = *handle;
    397                    }
    398                }
    399            }
    400            log_with_thread_id!(debug, "C_FindObjects: CKR_OK");
    401            CKR_OK
    402        }
    403 
    404        /// This gets called after `C_FindObjectsInit` and `C_FindObjects` to finish a search.
    405        extern "C" fn C_FindObjectsFinal(hSession: CK_SESSION_HANDLE) -> CK_RV {
    406            let mut manager_guard = try_to_get_manager_guard!();
    407            let manager = manager_guard_to_manager!(manager_guard);
    408            // It would be an error if there were no search for this session, but we can be permissive here.
    409            match manager.clear_search(hSession) {
    410                Ok(()) => {
    411                    log_with_thread_id!(debug, "C_FindObjectsFinal: CKR_OK");
    412                    CKR_OK
    413                }
    414                Err(e) => {
    415                    log_with_thread_id!(error, "C_FindObjectsFinal: clear_search failed: {}", e);
    416                    CKR_DEVICE_ERROR
    417                }
    418            }
    419        }
    420 
    421        /// This gets called to obtain the values of a number of attributes of an object identified
    422        /// by the given handle. If a specified attribute is not defined on the object, the length
    423        /// of that attribute is set to CK_UNAVAILABLE_INFORMATION to indicate that it is not
    424        /// available. This gets called twice: once to obtain the lengths of the attributes and
    425        /// again to get the values.
    426        extern "C" fn C_GetAttributeValue(
    427            hSession: CK_SESSION_HANDLE,
    428            hObject: CK_OBJECT_HANDLE,
    429            pTemplate: CK_ATTRIBUTE_PTR,
    430            ulCount: CK_ULONG,
    431        ) -> CK_RV {
    432            if pTemplate.is_null() {
    433                log_with_thread_id!(error, "C_GetAttributeValue: CKR_ARGUMENTS_BAD");
    434                return CKR_ARGUMENTS_BAD;
    435            }
    436            let mut attr_types = Vec::with_capacity(ulCount as usize);
    437            for i in 0..ulCount as usize {
    438                let attr = unsafe { &*pTemplate.add(i) };
    439                attr_types.push(attr.type_);
    440            }
    441            let mut manager_guard = try_to_get_manager_guard!();
    442            let manager = manager_guard_to_manager!(manager_guard);
    443            let values = match manager.get_attributes(hSession, hObject, attr_types) {
    444                Ok(values) => values,
    445                Err(e) => {
    446                    log_with_thread_id!(error, "C_GetAttributeValue: CKR_ARGUMENTS_BAD ({})", e);
    447                    return CKR_ARGUMENTS_BAD;
    448                }
    449            };
    450            if values.len() != ulCount as usize {
    451                log_with_thread_id!(
    452                    error,
    453                    "C_GetAttributeValue: manager.get_attributes didn't return the right number of values"
    454                );
    455                return CKR_DEVICE_ERROR;
    456            }
    457            for (i, value) in values.iter().enumerate().take(ulCount as usize) {
    458                let attr = unsafe { &mut *pTemplate.add(i) };
    459                if let Some(attr_value) = value {
    460                    if attr.pValue.is_null() {
    461                        attr.ulValueLen = attr_value.len() as CK_ULONG;
    462                    } else {
    463                        let ptr: *mut u8 = attr.pValue as *mut u8;
    464                        if attr_value.len() != attr.ulValueLen as usize {
    465                            log_with_thread_id!(error, "C_GetAttributeValue: incorrect attr size");
    466                            return CKR_ARGUMENTS_BAD;
    467                        }
    468                        unsafe {
    469                            std::ptr::copy_nonoverlapping(attr_value.as_ptr(), ptr, attr_value.len());
    470                        }
    471                    }
    472                } else {
    473                    attr.ulValueLen = CK_UNAVAILABLE_INFORMATION;
    474                }
    475            }
    476            log_with_thread_id!(debug, "C_GetAttributeValue: CKR_OK");
    477            CKR_OK
    478        }
    479 
    480    };
    481 }
    482 
    483 #[macro_export]
    484 macro_rules! declare_pkcs11_sign_functions {
    485    () => {
    486        /// This gets called to set up a sign operation.
    487        extern "C" fn C_SignInit(
    488            hSession: CK_SESSION_HANDLE,
    489            pMechanism: CK_MECHANISM_PTR,
    490            hKey: CK_OBJECT_HANDLE,
    491        ) -> CK_RV {
    492            if pMechanism.is_null() {
    493                log_with_thread_id!(error, "C_SignInit: CKR_ARGUMENTS_BAD");
    494                return CKR_ARGUMENTS_BAD;
    495            }
    496            // Presumably we should validate the mechanism against hKey, but the specification
    497            // doesn't actually seem to require this.
    498            let mechanism = unsafe { *pMechanism };
    499            log_with_thread_id!(debug, "C_SignInit: mechanism is {:?}", mechanism);
    500            let mechanism_params = if mechanism.mechanism == CKM_RSA_PKCS_PSS {
    501                if mechanism.ulParameterLen as usize
    502                    != std::mem::size_of::<CK_RSA_PKCS_PSS_PARAMS>()
    503                {
    504                    let len = mechanism.ulParameterLen;
    505                    log_with_thread_id!(
    506                        error,
    507                        "C_SignInit: bad ulParameterLen for CKM_RSA_PKCS_PSS: {}",
    508                        len
    509                    );
    510                    return CKR_ARGUMENTS_BAD;
    511                }
    512                Some(unsafe { *(mechanism.pParameter as *const CK_RSA_PKCS_PSS_PARAMS) })
    513            } else {
    514                None
    515            };
    516            let mut manager_guard = try_to_get_manager_guard!();
    517            let manager = manager_guard_to_manager!(manager_guard);
    518            match manager.start_sign(hSession, hKey, mechanism_params) {
    519                Ok(()) => {}
    520                Err(e) => {
    521                    log_with_thread_id!(error, "C_SignInit: CKR_GENERAL_ERROR: {}", e);
    522                    return CKR_GENERAL_ERROR;
    523                }
    524            };
    525            log_with_thread_id!(debug, "C_SignInit: CKR_OK");
    526            CKR_OK
    527        }
    528 
    529        /// NSS calls this after `C_SignInit` (there are more ways in the PKCS #11 specification to
    530        /// sign data, but this is the only way supported by these modules).
    531        extern "C" fn C_Sign(
    532            hSession: CK_SESSION_HANDLE,
    533            pData: CK_BYTE_PTR,
    534            ulDataLen: CK_ULONG,
    535            pSignature: CK_BYTE_PTR,
    536            pulSignatureLen: CK_ULONG_PTR,
    537        ) -> CK_RV {
    538            if pData.is_null() || pulSignatureLen.is_null() {
    539                log_with_thread_id!(error, "C_Sign: CKR_ARGUMENTS_BAD");
    540                return CKR_ARGUMENTS_BAD;
    541            }
    542            let data = unsafe { std::slice::from_raw_parts(pData, ulDataLen as usize) };
    543            if pSignature.is_null() {
    544                let mut manager_guard = try_to_get_manager_guard!();
    545                let manager = manager_guard_to_manager!(manager_guard);
    546                match manager.get_signature_length(hSession, data.to_vec()) {
    547                    Ok(signature_length) => unsafe {
    548                        *pulSignatureLen = signature_length as CK_ULONG;
    549                    },
    550                    Err(e) => {
    551                        log_with_thread_id!(error, "C_Sign: get_signature_length failed: {}", e);
    552                        return CKR_GENERAL_ERROR;
    553                    }
    554                }
    555            } else {
    556                let mut manager_guard = try_to_get_manager_guard!();
    557                let manager = manager_guard_to_manager!(manager_guard);
    558                match manager.sign(hSession, data.to_vec()) {
    559                    Ok(signature) => {
    560                        let signature_capacity = unsafe { *pulSignatureLen } as usize;
    561                        if signature_capacity < signature.len() {
    562                            log_with_thread_id!(error, "C_Sign: CKR_ARGUMENTS_BAD");
    563                            return CKR_ARGUMENTS_BAD;
    564                        }
    565                        let ptr: *mut u8 = pSignature as *mut u8;
    566                        unsafe {
    567                            std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len());
    568                            *pulSignatureLen = signature.len() as CK_ULONG;
    569                        }
    570                    }
    571                    Err(e) => {
    572                        log_with_thread_id!(error, "C_Sign: sign failed: {}", e);
    573                        return CKR_GENERAL_ERROR;
    574                    }
    575                }
    576            }
    577            log_with_thread_id!(debug, "C_Sign: CKR_OK");
    578            CKR_OK
    579        }
    580    };
    581 }
    582 
    583 #[macro_export]
    584 macro_rules! declare_unsupported_pkcs11_functions {
    585    () => {
    586        extern "C" fn C_GetMechanismInfo(
    587            _slotID: CK_SLOT_ID,
    588            _type: CK_MECHANISM_TYPE,
    589            _pInfo: CK_MECHANISM_INFO_PTR,
    590        ) -> CK_RV {
    591            log_with_thread_id!(error, "C_GetMechanismInfo: CKR_FUNCTION_NOT_SUPPORTED");
    592            CKR_FUNCTION_NOT_SUPPORTED
    593        }
    594 
    595        extern "C" fn C_InitToken(
    596            _slotID: CK_SLOT_ID,
    597            _pPin: CK_UTF8CHAR_PTR,
    598            _ulPinLen: CK_ULONG,
    599            _pLabel: CK_UTF8CHAR_PTR,
    600        ) -> CK_RV {
    601            log_with_thread_id!(error, "C_InitToken: CKR_FUNCTION_NOT_SUPPORTED");
    602            CKR_FUNCTION_NOT_SUPPORTED
    603        }
    604 
    605        extern "C" fn C_InitPIN(
    606            _hSession: CK_SESSION_HANDLE,
    607            _pPin: CK_UTF8CHAR_PTR,
    608            _ulPinLen: CK_ULONG,
    609        ) -> CK_RV {
    610            log_with_thread_id!(error, "C_InitPIN: CKR_FUNCTION_NOT_SUPPORTED");
    611            CKR_FUNCTION_NOT_SUPPORTED
    612        }
    613 
    614        extern "C" fn C_SetPIN(
    615            _hSession: CK_SESSION_HANDLE,
    616            _pOldPin: CK_UTF8CHAR_PTR,
    617            _ulOldLen: CK_ULONG,
    618            _pNewPin: CK_UTF8CHAR_PTR,
    619            _ulNewLen: CK_ULONG,
    620        ) -> CK_RV {
    621            log_with_thread_id!(error, "C_SetPIN: CKR_FUNCTION_NOT_SUPPORTED");
    622            CKR_FUNCTION_NOT_SUPPORTED
    623        }
    624 
    625        extern "C" fn C_GetOperationState(
    626            _hSession: CK_SESSION_HANDLE,
    627            _pOperationState: CK_BYTE_PTR,
    628            _pulOperationStateLen: CK_ULONG_PTR,
    629        ) -> CK_RV {
    630            log_with_thread_id!(error, "C_GetOperationState: CKR_FUNCTION_NOT_SUPPORTED");
    631            CKR_FUNCTION_NOT_SUPPORTED
    632        }
    633 
    634        extern "C" fn C_SetOperationState(
    635            _hSession: CK_SESSION_HANDLE,
    636            _pOperationState: CK_BYTE_PTR,
    637            _ulOperationStateLen: CK_ULONG,
    638            _hEncryptionKey: CK_OBJECT_HANDLE,
    639            _hAuthenticationKey: CK_OBJECT_HANDLE,
    640        ) -> CK_RV {
    641            log_with_thread_id!(error, "C_SetOperationState: CKR_FUNCTION_NOT_SUPPORTED");
    642            CKR_FUNCTION_NOT_SUPPORTED
    643        }
    644 
    645        extern "C" fn C_CreateObject(
    646            _hSession: CK_SESSION_HANDLE,
    647            _pTemplate: CK_ATTRIBUTE_PTR,
    648            _ulCount: CK_ULONG,
    649            _phObject: CK_OBJECT_HANDLE_PTR,
    650        ) -> CK_RV {
    651            log_with_thread_id!(error, "C_InitPIN: CKR_FUNCTION_NOT_SUPPORTED");
    652            CKR_FUNCTION_NOT_SUPPORTED
    653        }
    654 
    655        extern "C" fn C_CopyObject(
    656            _hSession: CK_SESSION_HANDLE,
    657            _hObject: CK_OBJECT_HANDLE,
    658            _pTemplate: CK_ATTRIBUTE_PTR,
    659            _ulCount: CK_ULONG,
    660            _phNewObject: CK_OBJECT_HANDLE_PTR,
    661        ) -> CK_RV {
    662            log_with_thread_id!(error, "C_CopyObject: CKR_FUNCTION_NOT_SUPPORTED");
    663            CKR_FUNCTION_NOT_SUPPORTED
    664        }
    665 
    666        extern "C" fn C_DestroyObject(
    667            _hSession: CK_SESSION_HANDLE,
    668            _hObject: CK_OBJECT_HANDLE,
    669        ) -> CK_RV {
    670            log_with_thread_id!(error, "C_DestroyObject: CKR_FUNCTION_NOT_SUPPORTED");
    671            CKR_FUNCTION_NOT_SUPPORTED
    672        }
    673 
    674        extern "C" fn C_GetObjectSize(
    675            _hSession: CK_SESSION_HANDLE,
    676            _hObject: CK_OBJECT_HANDLE,
    677            _pulSize: CK_ULONG_PTR,
    678        ) -> CK_RV {
    679            log_with_thread_id!(error, "C_GetObjectSize: CKR_FUNCTION_NOT_SUPPORTED");
    680            CKR_FUNCTION_NOT_SUPPORTED
    681        }
    682 
    683        extern "C" fn C_SetAttributeValue(
    684            _hSession: CK_SESSION_HANDLE,
    685            _hObject: CK_OBJECT_HANDLE,
    686            _pTemplate: CK_ATTRIBUTE_PTR,
    687            _ulCount: CK_ULONG,
    688        ) -> CK_RV {
    689            log_with_thread_id!(error, "C_SetAttributeValue: CKR_FUNCTION_NOT_SUPPORTED");
    690            CKR_FUNCTION_NOT_SUPPORTED
    691        }
    692 
    693        extern "C" fn C_EncryptInit(
    694            _hSession: CK_SESSION_HANDLE,
    695            _pMechanism: CK_MECHANISM_PTR,
    696            _hKey: CK_OBJECT_HANDLE,
    697        ) -> CK_RV {
    698            log_with_thread_id!(error, "C_EncryptInit: CKR_FUNCTION_NOT_SUPPORTED");
    699            CKR_FUNCTION_NOT_SUPPORTED
    700        }
    701 
    702        extern "C" fn C_Encrypt(
    703            _hSession: CK_SESSION_HANDLE,
    704            _pData: CK_BYTE_PTR,
    705            _ulDataLen: CK_ULONG,
    706            _pEncryptedData: CK_BYTE_PTR,
    707            _pulEncryptedDataLen: CK_ULONG_PTR,
    708        ) -> CK_RV {
    709            log_with_thread_id!(error, "C_Encrypt: CKR_FUNCTION_NOT_SUPPORTED");
    710            CKR_FUNCTION_NOT_SUPPORTED
    711        }
    712 
    713        extern "C" fn C_EncryptUpdate(
    714            _hSession: CK_SESSION_HANDLE,
    715            _pPart: CK_BYTE_PTR,
    716            _ulPartLen: CK_ULONG,
    717            _pEncryptedPart: CK_BYTE_PTR,
    718            _pulEncryptedPartLen: CK_ULONG_PTR,
    719        ) -> CK_RV {
    720            log_with_thread_id!(error, "C_EncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED");
    721            CKR_FUNCTION_NOT_SUPPORTED
    722        }
    723 
    724        extern "C" fn C_EncryptFinal(
    725            _hSession: CK_SESSION_HANDLE,
    726            _pLastEncryptedPart: CK_BYTE_PTR,
    727            _pulLastEncryptedPartLen: CK_ULONG_PTR,
    728        ) -> CK_RV {
    729            log_with_thread_id!(error, "C_EncryptFinal: CKR_FUNCTION_NOT_SUPPORTED");
    730            CKR_FUNCTION_NOT_SUPPORTED
    731        }
    732 
    733        extern "C" fn C_DecryptInit(
    734            _hSession: CK_SESSION_HANDLE,
    735            _pMechanism: CK_MECHANISM_PTR,
    736            _hKey: CK_OBJECT_HANDLE,
    737        ) -> CK_RV {
    738            log_with_thread_id!(error, "C_DecryptInit: CKR_FUNCTION_NOT_SUPPORTED");
    739            CKR_FUNCTION_NOT_SUPPORTED
    740        }
    741 
    742        extern "C" fn C_Decrypt(
    743            _hSession: CK_SESSION_HANDLE,
    744            _pEncryptedData: CK_BYTE_PTR,
    745            _ulEncryptedDataLen: CK_ULONG,
    746            _pData: CK_BYTE_PTR,
    747            _pulDataLen: CK_ULONG_PTR,
    748        ) -> CK_RV {
    749            log_with_thread_id!(error, "C_Decrypt: CKR_FUNCTION_NOT_SUPPORTED");
    750            CKR_FUNCTION_NOT_SUPPORTED
    751        }
    752 
    753        extern "C" fn C_DecryptUpdate(
    754            _hSession: CK_SESSION_HANDLE,
    755            _pEncryptedPart: CK_BYTE_PTR,
    756            _ulEncryptedPartLen: CK_ULONG,
    757            _pPart: CK_BYTE_PTR,
    758            _pulPartLen: CK_ULONG_PTR,
    759        ) -> CK_RV {
    760            log_with_thread_id!(error, "C_DecryptUpdate: CKR_FUNCTION_NOT_SUPPORTED");
    761            CKR_FUNCTION_NOT_SUPPORTED
    762        }
    763 
    764        extern "C" fn C_DecryptFinal(
    765            _hSession: CK_SESSION_HANDLE,
    766            _pLastPart: CK_BYTE_PTR,
    767            _pulLastPartLen: CK_ULONG_PTR,
    768        ) -> CK_RV {
    769            log_with_thread_id!(error, "C_DecryptFinal: CKR_FUNCTION_NOT_SUPPORTED");
    770            CKR_FUNCTION_NOT_SUPPORTED
    771        }
    772 
    773        extern "C" fn C_DigestInit(
    774            _hSession: CK_SESSION_HANDLE,
    775            _pMechanism: CK_MECHANISM_PTR,
    776        ) -> CK_RV {
    777            log_with_thread_id!(error, "C_DigestInit: CKR_FUNCTION_NOT_SUPPORTED");
    778            CKR_FUNCTION_NOT_SUPPORTED
    779        }
    780 
    781        extern "C" fn C_Digest(
    782            _hSession: CK_SESSION_HANDLE,
    783            _pData: CK_BYTE_PTR,
    784            _ulDataLen: CK_ULONG,
    785            _pDigest: CK_BYTE_PTR,
    786            _pulDigestLen: CK_ULONG_PTR,
    787        ) -> CK_RV {
    788            log_with_thread_id!(error, "C_Digest: CKR_FUNCTION_NOT_SUPPORTED");
    789            CKR_FUNCTION_NOT_SUPPORTED
    790        }
    791 
    792        extern "C" fn C_DigestUpdate(
    793            _hSession: CK_SESSION_HANDLE,
    794            _pPart: CK_BYTE_PTR,
    795            _ulPartLen: CK_ULONG,
    796        ) -> CK_RV {
    797            log_with_thread_id!(error, "C_DigestUpdate: CKR_FUNCTION_NOT_SUPPORTED");
    798            CKR_FUNCTION_NOT_SUPPORTED
    799        }
    800 
    801        extern "C" fn C_DigestKey(_hSession: CK_SESSION_HANDLE, _hKey: CK_OBJECT_HANDLE) -> CK_RV {
    802            log_with_thread_id!(error, "C_DigestKey: CKR_FUNCTION_NOT_SUPPORTED");
    803            CKR_FUNCTION_NOT_SUPPORTED
    804        }
    805 
    806        extern "C" fn C_DigestFinal(
    807            _hSession: CK_SESSION_HANDLE,
    808            _pDigest: CK_BYTE_PTR,
    809            _pulDigestLen: CK_ULONG_PTR,
    810        ) -> CK_RV {
    811            log_with_thread_id!(error, "C_DigestFinal: CKR_FUNCTION_NOT_SUPPORTED");
    812            CKR_FUNCTION_NOT_SUPPORTED
    813        }
    814 
    815        extern "C" fn C_SignUpdate(
    816            _hSession: CK_SESSION_HANDLE,
    817            _pPart: CK_BYTE_PTR,
    818            _ulPartLen: CK_ULONG,
    819        ) -> CK_RV {
    820            log_with_thread_id!(error, "C_SignUpdate: CKR_FUNCTION_NOT_SUPPORTED");
    821            CKR_FUNCTION_NOT_SUPPORTED
    822        }
    823 
    824        extern "C" fn C_SignFinal(
    825            _hSession: CK_SESSION_HANDLE,
    826            _pSignature: CK_BYTE_PTR,
    827            _pulSignatureLen: CK_ULONG_PTR,
    828        ) -> CK_RV {
    829            log_with_thread_id!(error, "C_SignFinal: CKR_FUNCTION_NOT_SUPPORTED");
    830            CKR_FUNCTION_NOT_SUPPORTED
    831        }
    832 
    833        extern "C" fn C_SignRecoverInit(
    834            _hSession: CK_SESSION_HANDLE,
    835            _pMechanism: CK_MECHANISM_PTR,
    836            _hKey: CK_OBJECT_HANDLE,
    837        ) -> CK_RV {
    838            log_with_thread_id!(error, "C_SignRecoverInit: CKR_FUNCTION_NOT_SUPPORTED");
    839            CKR_FUNCTION_NOT_SUPPORTED
    840        }
    841 
    842        extern "C" fn C_SignRecover(
    843            _hSession: CK_SESSION_HANDLE,
    844            _pData: CK_BYTE_PTR,
    845            _ulDataLen: CK_ULONG,
    846            _pSignature: CK_BYTE_PTR,
    847            _pulSignatureLen: CK_ULONG_PTR,
    848        ) -> CK_RV {
    849            log_with_thread_id!(error, "C_SignRecover: CKR_FUNCTION_NOT_SUPPORTED");
    850            CKR_FUNCTION_NOT_SUPPORTED
    851        }
    852 
    853        extern "C" fn C_VerifyInit(
    854            _hSession: CK_SESSION_HANDLE,
    855            _pMechanism: CK_MECHANISM_PTR,
    856            _hKey: CK_OBJECT_HANDLE,
    857        ) -> CK_RV {
    858            log_with_thread_id!(error, "C_VerifyInit: CKR_FUNCTION_NOT_SUPPORTED");
    859            CKR_FUNCTION_NOT_SUPPORTED
    860        }
    861 
    862        extern "C" fn C_Verify(
    863            _hSession: CK_SESSION_HANDLE,
    864            _pData: CK_BYTE_PTR,
    865            _ulDataLen: CK_ULONG,
    866            _pSignature: CK_BYTE_PTR,
    867            _ulSignatureLen: CK_ULONG,
    868        ) -> CK_RV {
    869            log_with_thread_id!(error, "C_Verify: CKR_FUNCTION_NOT_SUPPORTED");
    870            CKR_FUNCTION_NOT_SUPPORTED
    871        }
    872 
    873        extern "C" fn C_VerifyUpdate(
    874            _hSession: CK_SESSION_HANDLE,
    875            _pPart: CK_BYTE_PTR,
    876            _ulPartLen: CK_ULONG,
    877        ) -> CK_RV {
    878            log_with_thread_id!(error, "C_VerifyUpdate: CKR_FUNCTION_NOT_SUPPORTED");
    879            CKR_FUNCTION_NOT_SUPPORTED
    880        }
    881 
    882        extern "C" fn C_VerifyFinal(
    883            _hSession: CK_SESSION_HANDLE,
    884            _pSignature: CK_BYTE_PTR,
    885            _ulSignatureLen: CK_ULONG,
    886        ) -> CK_RV {
    887            log_with_thread_id!(error, "C_VerifyFinal: CKR_FUNCTION_NOT_SUPPORTED");
    888            CKR_FUNCTION_NOT_SUPPORTED
    889        }
    890 
    891        extern "C" fn C_VerifyRecoverInit(
    892            _hSession: CK_SESSION_HANDLE,
    893            _pMechanism: CK_MECHANISM_PTR,
    894            _hKey: CK_OBJECT_HANDLE,
    895        ) -> CK_RV {
    896            log_with_thread_id!(error, "C_VerifyRecoverInit: CKR_FUNCTION_NOT_SUPPORTED");
    897            CKR_FUNCTION_NOT_SUPPORTED
    898        }
    899 
    900        extern "C" fn C_VerifyRecover(
    901            _hSession: CK_SESSION_HANDLE,
    902            _pSignature: CK_BYTE_PTR,
    903            _ulSignatureLen: CK_ULONG,
    904            _pData: CK_BYTE_PTR,
    905            _pulDataLen: CK_ULONG_PTR,
    906        ) -> CK_RV {
    907            log_with_thread_id!(error, "C_VerifyRecover: CKR_FUNCTION_NOT_SUPPORTED");
    908            CKR_FUNCTION_NOT_SUPPORTED
    909        }
    910 
    911        extern "C" fn C_DigestEncryptUpdate(
    912            _hSession: CK_SESSION_HANDLE,
    913            _pPart: CK_BYTE_PTR,
    914            _ulPartLen: CK_ULONG,
    915            _pEncryptedPart: CK_BYTE_PTR,
    916            _pulEncryptedPartLen: CK_ULONG_PTR,
    917        ) -> CK_RV {
    918            log_with_thread_id!(error, "C_DigestEncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED");
    919            CKR_FUNCTION_NOT_SUPPORTED
    920        }
    921 
    922        extern "C" fn C_DecryptDigestUpdate(
    923            _hSession: CK_SESSION_HANDLE,
    924            _pEncryptedPart: CK_BYTE_PTR,
    925            _ulEncryptedPartLen: CK_ULONG,
    926            _pPart: CK_BYTE_PTR,
    927            _pulPartLen: CK_ULONG_PTR,
    928        ) -> CK_RV {
    929            log_with_thread_id!(error, "C_DecryptDigestUpdate: CKR_FUNCTION_NOT_SUPPORTED");
    930            CKR_FUNCTION_NOT_SUPPORTED
    931        }
    932 
    933        extern "C" fn C_SignEncryptUpdate(
    934            _hSession: CK_SESSION_HANDLE,
    935            _pPart: CK_BYTE_PTR,
    936            _ulPartLen: CK_ULONG,
    937            _pEncryptedPart: CK_BYTE_PTR,
    938            _pulEncryptedPartLen: CK_ULONG_PTR,
    939        ) -> CK_RV {
    940            log_with_thread_id!(error, "C_SignEncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED");
    941            CKR_FUNCTION_NOT_SUPPORTED
    942        }
    943 
    944        extern "C" fn C_DecryptVerifyUpdate(
    945            _hSession: CK_SESSION_HANDLE,
    946            _pEncryptedPart: CK_BYTE_PTR,
    947            _ulEncryptedPartLen: CK_ULONG,
    948            _pPart: CK_BYTE_PTR,
    949            _pulPartLen: CK_ULONG_PTR,
    950        ) -> CK_RV {
    951            log_with_thread_id!(error, "C_DecryptVerifyUpdate: CKR_FUNCTION_NOT_SUPPORTED");
    952            CKR_FUNCTION_NOT_SUPPORTED
    953        }
    954 
    955        extern "C" fn C_GenerateKey(
    956            _hSession: CK_SESSION_HANDLE,
    957            _pMechanism: CK_MECHANISM_PTR,
    958            _pTemplate: CK_ATTRIBUTE_PTR,
    959            _ulCount: CK_ULONG,
    960            _phKey: CK_OBJECT_HANDLE_PTR,
    961        ) -> CK_RV {
    962            log_with_thread_id!(error, "C_GenerateKey: CKR_FUNCTION_NOT_SUPPORTED");
    963            CKR_FUNCTION_NOT_SUPPORTED
    964        }
    965 
    966        extern "C" fn C_GenerateKeyPair(
    967            _hSession: CK_SESSION_HANDLE,
    968            _pMechanism: CK_MECHANISM_PTR,
    969            _pPublicKeyTemplate: CK_ATTRIBUTE_PTR,
    970            _ulPublicKeyAttributeCount: CK_ULONG,
    971            _pPrivateKeyTemplate: CK_ATTRIBUTE_PTR,
    972            _ulPrivateKeyAttributeCount: CK_ULONG,
    973            _phPublicKey: CK_OBJECT_HANDLE_PTR,
    974            _phPrivateKey: CK_OBJECT_HANDLE_PTR,
    975        ) -> CK_RV {
    976            log_with_thread_id!(error, "C_GenerateKeyPair: CKR_FUNCTION_NOT_SUPPORTED");
    977            CKR_FUNCTION_NOT_SUPPORTED
    978        }
    979 
    980        extern "C" fn C_WrapKey(
    981            _hSession: CK_SESSION_HANDLE,
    982            _pMechanism: CK_MECHANISM_PTR,
    983            _hWrappingKey: CK_OBJECT_HANDLE,
    984            _hKey: CK_OBJECT_HANDLE,
    985            _pWrappedKey: CK_BYTE_PTR,
    986            _pulWrappedKeyLen: CK_ULONG_PTR,
    987        ) -> CK_RV {
    988            log_with_thread_id!(error, "C_WrapKey: CKR_FUNCTION_NOT_SUPPORTED");
    989            CKR_FUNCTION_NOT_SUPPORTED
    990        }
    991 
    992        extern "C" fn C_UnwrapKey(
    993            _hSession: CK_SESSION_HANDLE,
    994            _pMechanism: CK_MECHANISM_PTR,
    995            _hUnwrappingKey: CK_OBJECT_HANDLE,
    996            _pWrappedKey: CK_BYTE_PTR,
    997            _ulWrappedKeyLen: CK_ULONG,
    998            _pTemplate: CK_ATTRIBUTE_PTR,
    999            _ulAttributeCount: CK_ULONG,
   1000            _phKey: CK_OBJECT_HANDLE_PTR,
   1001        ) -> CK_RV {
   1002            log_with_thread_id!(error, "C_UnwrapKey: CKR_FUNCTION_NOT_SUPPORTED");
   1003            CKR_FUNCTION_NOT_SUPPORTED
   1004        }
   1005 
   1006        extern "C" fn C_DeriveKey(
   1007            _hSession: CK_SESSION_HANDLE,
   1008            _pMechanism: CK_MECHANISM_PTR,
   1009            _hBaseKey: CK_OBJECT_HANDLE,
   1010            _pTemplate: CK_ATTRIBUTE_PTR,
   1011            _ulAttributeCount: CK_ULONG,
   1012            _phKey: CK_OBJECT_HANDLE_PTR,
   1013        ) -> CK_RV {
   1014            log_with_thread_id!(error, "C_DeriveKey: CKR_FUNCTION_NOT_SUPPORTED");
   1015            CKR_FUNCTION_NOT_SUPPORTED
   1016        }
   1017 
   1018        extern "C" fn C_SeedRandom(
   1019            _hSession: CK_SESSION_HANDLE,
   1020            _pSeed: CK_BYTE_PTR,
   1021            _ulSeedLen: CK_ULONG,
   1022        ) -> CK_RV {
   1023            log_with_thread_id!(error, "C_SeedRandom: CKR_FUNCTION_NOT_SUPPORTED");
   1024            CKR_FUNCTION_NOT_SUPPORTED
   1025        }
   1026 
   1027        extern "C" fn C_GenerateRandom(
   1028            _hSession: CK_SESSION_HANDLE,
   1029            _RandomData: CK_BYTE_PTR,
   1030            _ulRandomLen: CK_ULONG,
   1031        ) -> CK_RV {
   1032            log_with_thread_id!(error, "C_GenerateRandom: CKR_FUNCTION_NOT_SUPPORTED");
   1033            CKR_FUNCTION_NOT_SUPPORTED
   1034        }
   1035 
   1036        extern "C" fn C_GetFunctionStatus(_hSession: CK_SESSION_HANDLE) -> CK_RV {
   1037            log_with_thread_id!(error, "C_GetFunctionStatus: CKR_FUNCTION_NOT_SUPPORTED");
   1038            CKR_FUNCTION_NOT_SUPPORTED
   1039        }
   1040 
   1041        extern "C" fn C_CancelFunction(_hSession: CK_SESSION_HANDLE) -> CK_RV {
   1042            log_with_thread_id!(error, "C_CancelFunction: CKR_FUNCTION_NOT_SUPPORTED");
   1043            CKR_FUNCTION_NOT_SUPPORTED
   1044        }
   1045 
   1046        extern "C" fn C_WaitForSlotEvent(
   1047            _flags: CK_FLAGS,
   1048            _pSlot: CK_SLOT_ID_PTR,
   1049            _pRserved: CK_VOID_PTR,
   1050        ) -> CK_RV {
   1051            log_with_thread_id!(error, "C_WaitForSlotEvent: CKR_FUNCTION_NOT_SUPPORTED");
   1052            CKR_FUNCTION_NOT_SUPPORTED
   1053        }
   1054    };
   1055 }