diff options
-rw-r--r-- | pkcs11.c | 243 |
1 files changed, 153 insertions, 90 deletions
@@ -380,6 +380,33 @@ static CK_RV _p11_error_from_hal(const hal_error_t err, const char * const file, #undef hal_p11_error_case +/* + * All (?) public functions should test whether we've been initialized or not. + * Where practical, we bury this check in other boilerplate. + */ + +#if USE_POSIX + +#define p11_uninitialized() (!initialized_pid) + +#else + +#define p11_uninitialized() (0) + +#endif + +/* + * Handle unsupported functions. + */ + +#define UNSUPPORTED_FUNCTION(_name_) \ + do { \ + ENTER_PUBLIC_FUNCTION(_name_); \ + if (p11_uninitialized()) \ + return CKR_CRYPTOKI_NOT_INITIALIZED; \ + return CKR_FUNCTION_NOT_SUPPORTED; \ + } while (0) + /* @@ -609,10 +636,16 @@ static int sql_finalize_and_clear(sqlite3_stmt **q) /* * Slightly higher-level macros for common operations. + * + * Since the locking code depends on initialization, + * attempting to lock anything when not initialized + * is a failure, by definition. */ #define mutex_lock_or_return_failure(_m_) \ do { \ + if (p11_uninitialized()) \ + return CKR_CRYPTOKI_NOT_INITIALIZED; \ CK_RV _rv = mutex_lock(_m_); \ if (_rv != CKR_OK) \ return _rv; \ @@ -1979,21 +2012,26 @@ static int p11_session_consistent_login(void) /* * PKCS #11 likes space-padded rather than null-terminated strings. + * This requires minor antics so that we can use a printf()-like API + * while neither overflowing the caller's buffer nor truncating the + * output if it happens to be exactly the target length. */ static int psnprintf(void *buffer_, size_t size, const char *format, ...) { - char *buffer = buffer_; + char buffer[size + 1]; size_t i, n; va_list ap; va_start(ap, format); - i = n = vsnprintf(buffer, size, format, ap); + i = n = vsnprintf(buffer, sizeof(buffer), format, ap); va_end(ap); while (i < size) buffer[i++] = ' '; + memcpy(buffer_, buffer, size); + return n; } @@ -2435,6 +2473,7 @@ static CK_RV generate_keypair(p11_session_t *session, handle_flavor_t private_handle_flavor = handle_flavor_session_object; hal_key_flags_t public_flags = 0; hal_key_flags_t private_flags = 0; + int in_transaction = 0; CK_RV rv; int i; @@ -2465,6 +2504,8 @@ static CK_RV generate_keypair(p11_session_t *session, if (!sql_exec("BEGIN")) lose(CKR_FUNCTION_FAILED); + in_transaction = 1; + if ((public_handle = p11_object_create(session, public_handle_flavor, pPublicKeyTemplate, ulPublicKeyAttributeCount, public_descriptor, pMechanism)) == CK_INVALID_HANDLE) @@ -2489,7 +2530,7 @@ static CK_RV generate_keypair(p11_session_t *session, return CKR_OK; fail: - if (!sql_exec("ROLLBACK")) + if (in_transaction && !sql_exec("ROLLBACK")) rv = CKR_GENERAL_ERROR; return rv; } @@ -2508,22 +2549,14 @@ static CK_RV p11_check_create_attributes(const p11_session_t *session, const CK_ULONG ulCount, const p11_descriptor_t * const descriptor) { + const CK_BBOOL *cka_private = NULL; + const CK_BBOOL *cka_token = NULL; CK_RV rv = CKR_OK; int i; assert(session != NULL && pTemplate != NULL && descriptor != NULL); /* - * Read-only sessions can't create objects, doh. - */ - - switch (session->state) { - case CKS_RO_PUBLIC_SESSION: - case CKS_RO_USER_FUNCTIONS: - lose(CKR_SESSION_READ_ONLY); - } - - /* * Check values provided in the template. */ @@ -2535,6 +2568,15 @@ static CK_RV p11_check_create_attributes(const p11_session_t *session, if ((rv = p11_template_check_1(type, val, len, descriptor, P11_DESCRIPTOR_FORBIDDEN_BY_CREATEOBJECT)) != CKR_OK) goto fail; + + switch (type) { + case CKA_TOKEN: + cka_token = val; + break; + case CKA_PRIVATE: + cka_private = val; + break; + } } /* @@ -2547,6 +2589,23 @@ static CK_RV p11_check_create_attributes(const p11_session_t *session, goto fail; /* + * Read-only sessions can't create objects, doh. + * Well, except when they can, thanks, PKCS #11. + */ + + switch (session->state) { + case CKS_RO_PUBLIC_SESSION: + if (cka_private == NULL || *cka_private) + lose(CKR_SESSION_READ_ONLY); + /* Fall through */ + + case CKS_RO_USER_FUNCTIONS: + if (cka_token != NULL && *cka_token) + lose(CKR_SESSION_READ_ONLY); + /* Fall through */ + } + + /* * If we get this far, we're happy. Maybe. */ @@ -2940,6 +2999,9 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, if (pSlotList != NULL && *pulCount < 1) return CKR_BUFFER_TOO_SMALL; + if (p11_uninitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + *pulCount = 1; if (pSlotList != NULL) @@ -2963,6 +3025,9 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, if (slotID != P11_ONE_AND_ONLY_SLOT) return CKR_SLOT_ID_INVALID; + if (p11_uninitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + memset(pInfo, 0, sizeof(*pInfo)); /* @@ -3292,6 +3357,7 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, ENTER_PUBLIC_FUNCTION(C_CreateObject); CK_OBJECT_HANDLE handle = CK_INVALID_HANDLE; + int in_transaction = 0; p11_session_t *session; CK_RV rv; @@ -3347,6 +3413,8 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, if (!sql_exec("BEGIN")) lose(CKR_FUNCTION_FAILED); + in_transaction = 1; + if ((handle = p11_object_create(session, flavor, pTemplate, ulCount, descriptor, NULL)) == CK_INVALID_HANDLE) lose(CKR_FUNCTION_FAILED); @@ -3390,7 +3458,7 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, return mutex_unlock(p11_global_mutex); fail: - if (!sql_exec("ROLLBACK")) + if (in_transaction && !sql_exec("ROLLBACK")) rv = CKR_GENERAL_ERROR; mutex_unlock_return_with_rv(rv, p11_global_mutex); } @@ -4521,6 +4589,9 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID, if (slotID != P11_ONE_AND_ONLY_SLOT) return CKR_SLOT_ID_INVALID; + if (p11_uninitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + #if 0 /* * Perhaps revisit this after adding an RPC call to let us check @@ -4537,7 +4608,6 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID, case CKM_SHA_1: case CKM_SHA1_RSA_PKCS: case CKM_SHA_1_HMAC: - case CKM_ECDSA_SHA1: algorithm = hal_digest_algorithm_sha1; break; @@ -4681,6 +4751,9 @@ CK_RV C_GetInfo(CK_INFO_PTR pInfo) if (pInfo == NULL) return CKR_ARGUMENTS_BAD; + if (p11_uninitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + memset(pInfo, 0, sizeof(*pInfo)); pInfo->cryptokiVersion.major = 2; pInfo->cryptokiVersion.minor = 30; @@ -4703,6 +4776,9 @@ CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, if (slotID != P11_ONE_AND_ONLY_SLOT) return CKR_SLOT_ID_INVALID; + if (p11_uninitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + memset(pInfo, 0, sizeof(*pInfo)); psnprintf(pInfo->slotDescription, sizeof(pInfo->slotDescription), "cryptech.is slot on alpha"); psnprintf(pInfo->manufacturerID, sizeof(pInfo->manufacturerID), "cryptech.is project"); @@ -4719,7 +4795,7 @@ CK_RV C_GetMechanismList(CK_SLOT_ID slotID, CK_ULONG_PTR pulCount) { static const CK_MECHANISM_TYPE mechanisms[] = { - CKM_ECDSA_SHA1, CKM_ECDSA_SHA224, CKM_ECDSA_SHA256, CKM_ECDSA_SHA384, CKM_ECDSA_SHA512, CKM_ECDSA, CKM_EC_KEY_PAIR_GEN, + CKM_ECDSA_SHA224, CKM_ECDSA_SHA256, CKM_ECDSA_SHA384, CKM_ECDSA_SHA512, CKM_ECDSA, CKM_EC_KEY_PAIR_GEN, CKM_SHA1_RSA_PKCS, CKM_SHA224_RSA_PKCS, CKM_SHA256_RSA_PKCS, CKM_SHA384_RSA_PKCS, CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_SHA_1, CKM_SHA224, CKM_SHA256, CKM_SHA384, CKM_SHA512, #if 0 @@ -4737,6 +4813,9 @@ CK_RV C_GetMechanismList(CK_SLOT_ID slotID, if (slotID != P11_ONE_AND_ONLY_SLOT) return CKR_SLOT_ID_INVALID; + if (p11_uninitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + CK_RV rv = CKR_OK; if (pMechanismList != NULL && *pulCount < mechanisms_len) @@ -4753,6 +4832,33 @@ CK_RV C_GetMechanismList(CK_SLOT_ID slotID, /* + * Legacy functions. These are basically just unimplemented functions + * which return a different error code to keep test suites happy. + */ + +CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE hSession) +{ + ENTER_PUBLIC_FUNCTION(C_GetFunctionStatus); + + if (p11_uninitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + return CKR_FUNCTION_NOT_PARALLEL; +} + +CK_RV C_CancelFunction(CK_SESSION_HANDLE hSession) +{ + ENTER_PUBLIC_FUNCTION(C_CancelFunction); + + if (p11_uninitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + return CKR_FUNCTION_NOT_PARALLEL; +} + + + +/* * Stubs for unsupported functions below here. Per the PKCS #11 * specification, it's OK to skip implementing almost any function in * the API, but if one does so, one must provide a stub which returns @@ -4771,8 +4877,7 @@ CK_RV C_GenerateKey(CK_SESSION_HANDLE hSession, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) { - ENTER_PUBLIC_FUNCTION(C_GenerateKey); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_GenerateKey); } CK_RV C_InitToken(CK_SLOT_ID slotID, @@ -4780,16 +4885,14 @@ CK_RV C_InitToken(CK_SLOT_ID slotID, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel) { - ENTER_PUBLIC_FUNCTION(C_InitToken); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_InitToken); } CK_RV C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) { - ENTER_PUBLIC_FUNCTION(C_InitPIN); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_InitPIN); } CK_RV C_SetPIN(CK_SESSION_HANDLE hSession, @@ -4798,16 +4901,14 @@ CK_RV C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen) { - ENTER_PUBLIC_FUNCTION(C_SetPIN); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_SetPIN); } CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) { - ENTER_PUBLIC_FUNCTION(C_GetOperationState); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_GetOperationState); } CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession, @@ -4816,8 +4917,7 @@ CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) { - ENTER_PUBLIC_FUNCTION(C_SetOperationState); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_SetOperationState); } CK_RV C_CopyObject(CK_SESSION_HANDLE hSession, @@ -4826,16 +4926,14 @@ CK_RV C_CopyObject(CK_SESSION_HANDLE hSession, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject) { - ENTER_PUBLIC_FUNCTION(C_CopyObject); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_CopyObject); } CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) { - ENTER_PUBLIC_FUNCTION(C_GetObjectSize); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_GetObjectSize); } CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession, @@ -4843,16 +4941,14 @@ CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - ENTER_PUBLIC_FUNCTION(C_SetAttributeValue); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_SetAttributeValue); } CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - ENTER_PUBLIC_FUNCTION(C_EncryptInit); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_EncryptInit); } CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, @@ -4861,8 +4957,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) { - ENTER_PUBLIC_FUNCTION(C_Encrypt); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_Encrypt); } CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession, @@ -4871,24 +4966,21 @@ CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { - ENTER_PUBLIC_FUNCTION(C_EncryptUpdate); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_EncryptUpdate); } CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen) { - ENTER_PUBLIC_FUNCTION(C_EncryptFinal); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_EncryptFinal); } CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - ENTER_PUBLIC_FUNCTION(C_DecryptInit); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_DecryptInit); } CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, @@ -4897,8 +4989,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { - ENTER_PUBLIC_FUNCTION(C_Decrypt); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_Decrypt); } CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession, @@ -4907,31 +4998,27 @@ CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { - ENTER_PUBLIC_FUNCTION(C_DecryptUpdate); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_DecryptUpdate); } CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen) { - ENTER_PUBLIC_FUNCTION(C_DecryptFinal); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_DecryptFinal); } CK_RV C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) { - ENTER_PUBLIC_FUNCTION(C_DigestKey); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_DigestKey); } CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - ENTER_PUBLIC_FUNCTION(C_SignRecoverInit); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_SignRecoverInit); } CK_RV C_SignRecover(CK_SESSION_HANDLE hSession, @@ -4940,16 +5027,14 @@ CK_RV C_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { - ENTER_PUBLIC_FUNCTION(C_SignRecover); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_SignRecover); } CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - ENTER_PUBLIC_FUNCTION(C_VerifyRecoverInit); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_VerifyRecoverInit); } CK_RV C_VerifyRecover(CK_SESSION_HANDLE hSession, @@ -4958,8 +5043,7 @@ CK_RV C_VerifyRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { - ENTER_PUBLIC_FUNCTION(C_VerifyRecover); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_VerifyRecover); } CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, @@ -4968,8 +5052,7 @@ CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { - ENTER_PUBLIC_FUNCTION(C_DigestEncryptUpdate); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_DigestEncryptUpdate); } CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, @@ -4978,8 +5061,7 @@ CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { - ENTER_PUBLIC_FUNCTION(C_DecryptDigestUpdate); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_DecryptDigestUpdate); } CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, @@ -4988,8 +5070,7 @@ CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { - ENTER_PUBLIC_FUNCTION(C_SignEncryptUpdate); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_SignEncryptUpdate); } CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, @@ -4998,8 +5079,7 @@ CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { - ENTER_PUBLIC_FUNCTION(C_DecryptVerifyUpdate); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_DecryptVerifyUpdate); } CK_RV C_WrapKey(CK_SESSION_HANDLE hSession, @@ -5009,8 +5089,7 @@ CK_RV C_WrapKey(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) { - ENTER_PUBLIC_FUNCTION(C_WrapKey); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_WrapKey); } CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, @@ -5022,8 +5101,7 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { - ENTER_PUBLIC_FUNCTION(C_UnwrapKey); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_UnwrapKey); } CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, @@ -5033,36 +5111,21 @@ CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { - ENTER_PUBLIC_FUNCTION(C_DeriveKey); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_DeriveKey); } CK_RV C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) { - ENTER_PUBLIC_FUNCTION(C_SeedRandom); - return CKR_FUNCTION_NOT_SUPPORTED; -} - -CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE hSession) -{ - ENTER_PUBLIC_FUNCTION(C_GetFunctionStatus); - return CKR_FUNCTION_NOT_SUPPORTED; -} - -CK_RV C_CancelFunction(CK_SESSION_HANDLE hSession) -{ - ENTER_PUBLIC_FUNCTION(C_CancelFunction); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_SeedRandom); } CK_RV C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pRserved) { - ENTER_PUBLIC_FUNCTION(C_WaitForSlotEvent); - return CKR_FUNCTION_NOT_SUPPORTED; + UNSUPPORTED_FUNCTION(C_WaitForSlotEvent); } /* |