// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2017-2020, Linaro Limited
 */

#include <pkcs11.h>
#include <stdbool.h>
#include <stddef.h>

#include "ck_helpers.h"
#include "invoke_ta.h"
#include "pkcs11_processing.h"
#include "pkcs11_token.h"

static const CK_FUNCTION_LIST libckteec_function_list = {
	.version = {
		.major = CK_PKCS11_VERSION_MAJOR,
		.minor = CK_PKCS11_VERSION_MINOR,
	},
	.C_Initialize = C_Initialize,
	.C_Finalize = C_Finalize,
	.C_GetInfo = C_GetInfo,
	.C_GetFunctionList = C_GetFunctionList,
	.C_GetSlotList = C_GetSlotList,
	.C_GetSlotInfo = C_GetSlotInfo,
	.C_GetTokenInfo = C_GetTokenInfo,
	.C_GetMechanismList = C_GetMechanismList,
	.C_GetMechanismInfo = C_GetMechanismInfo,
	.C_InitToken = C_InitToken,
	.C_InitPIN = C_InitPIN,
	.C_SetPIN = C_SetPIN,
	.C_OpenSession = C_OpenSession,
	.C_CloseSession = C_CloseSession,
	.C_CloseAllSessions = C_CloseAllSessions,
	.C_GetSessionInfo = C_GetSessionInfo,
	.C_GetOperationState = C_GetOperationState,
	.C_SetOperationState = C_SetOperationState,
	.C_Login = C_Login,
	.C_Logout = C_Logout,
	.C_CreateObject = C_CreateObject,
	.C_CopyObject = C_CopyObject,
	.C_DestroyObject = C_DestroyObject,
	.C_GetObjectSize = C_GetObjectSize,
	.C_GetAttributeValue = C_GetAttributeValue,
	.C_SetAttributeValue = C_SetAttributeValue,
	.C_FindObjectsInit = C_FindObjectsInit,
	.C_FindObjects = C_FindObjects,
	.C_FindObjectsFinal = C_FindObjectsFinal,
	.C_EncryptInit = C_EncryptInit,
	.C_Encrypt = C_Encrypt,
	.C_EncryptUpdate = C_EncryptUpdate,
	.C_EncryptFinal = C_EncryptFinal,
	.C_DecryptInit = C_DecryptInit,
	.C_Decrypt = C_Decrypt,
	.C_DecryptUpdate = C_DecryptUpdate,
	.C_DecryptFinal = C_DecryptFinal,
	.C_DigestInit = C_DigestInit,
	.C_Digest = C_Digest,
	.C_DigestUpdate = C_DigestUpdate,
	.C_DigestKey = C_DigestKey,
	.C_DigestFinal = C_DigestFinal,
	.C_SignInit = C_SignInit,
	.C_Sign = C_Sign,
	.C_SignUpdate = C_SignUpdate,
	.C_SignFinal = C_SignFinal,
	.C_SignRecoverInit = C_SignRecoverInit,
	.C_SignRecover = C_SignRecover,
	.C_VerifyInit = C_VerifyInit,
	.C_Verify = C_Verify,
	.C_VerifyUpdate = C_VerifyUpdate,
	.C_VerifyFinal = C_VerifyFinal,
	.C_VerifyRecoverInit = C_VerifyRecoverInit,
	.C_VerifyRecover = C_VerifyRecover,
	.C_DigestEncryptUpdate = C_DigestEncryptUpdate,
	.C_DecryptDigestUpdate = C_DecryptDigestUpdate,
	.C_SignEncryptUpdate = C_SignEncryptUpdate,
	.C_DecryptVerifyUpdate = C_DecryptVerifyUpdate,
	.C_GenerateKey = C_GenerateKey,
	.C_GenerateKeyPair = C_GenerateKeyPair,
	.C_WrapKey = C_WrapKey,
	.C_UnwrapKey = C_UnwrapKey,
	.C_DeriveKey = C_DeriveKey,
	.C_SeedRandom = C_SeedRandom,
	.C_GenerateRandom = C_GenerateRandom,
	.C_GetFunctionStatus = C_GetFunctionStatus,
	.C_CancelFunction = C_CancelFunction,
	.C_WaitForSlotEvent = C_WaitForSlotEvent,
};

static bool lib_initiated(void)
{
	return ckteec_invoke_initiated();
}

CK_RV C_Initialize(CK_VOID_PTR pInitArgs)
{
	CK_C_INITIALIZE_ARGS_PTR args = NULL;
	CK_RV rv = 0;

	if (pInitArgs) {
		args = (CK_C_INITIALIZE_ARGS_PTR)pInitArgs;

		/* Reserved must be set to NULL in this version of PKCS#11 */
		if (args->reserved)
			return CKR_ARGUMENTS_BAD;
	}

	rv = ckteec_invoke_init();

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CANT_LOCK,
		     CKR_CRYPTOKI_ALREADY_INITIALIZED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_NEED_TO_CREATE_THREADS, CKR_OK,
		     CKR_MUTEX_BAD);

	return rv;
}

CK_RV C_Finalize(CK_VOID_PTR pReserved)
{
	CK_RV rv = 0;

	/* Reserved must be set to NULL in this version of PKCS#11 */
	if (pReserved)
		return CKR_ARGUMENTS_BAD;

	rv = ckteec_invoke_terminate();

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK);

	return rv;
}

CK_RV C_GetInfo(CK_INFO_PTR pInfo)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_get_info(pInfo);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK);

	return rv;
}

CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
{
	if (!ppFunctionList)
		return CKR_ARGUMENTS_BAD;

	/* Discard the const attribute when exporting the list address */
	*ppFunctionList = (void *)&libckteec_function_list;

	return CKR_OK;
}

CK_RV C_GetSlotList(CK_BBOOL tokenPresent,
		    CK_SLOT_ID_PTR pSlotList,
		    CK_ULONG_PTR pulCount)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_slot_get_list(tokenPresent, pSlotList, pulCount);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK);

	return rv;
}

CK_RV C_GetSlotInfo(CK_SLOT_ID slotID,
		    CK_SLOT_INFO_PTR pInfo)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_slot_get_info(slotID, pInfo);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR,
		     CKR_HOST_MEMORY, CKR_OK, CKR_SLOT_ID_INVALID);

	return rv;
}

CK_RV C_InitToken(CK_SLOT_ID slotID,
		  CK_UTF8CHAR_PTR pPin,
		  CK_ULONG ulPinLen,
		  CK_UTF8CHAR_PTR pLabel)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_init_token(slotID, pPin, ulPinLen, pLabel);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_PIN_INCORRECT, CKR_PIN_LOCKED, CKR_SESSION_EXISTS,
		     CKR_SLOT_ID_INVALID, CKR_TOKEN_NOT_PRESENT,
		     CKR_TOKEN_NOT_RECOGNIZED, CKR_TOKEN_WRITE_PROTECTED);

	return rv;
}

CK_RV C_GetTokenInfo(CK_SLOT_ID slotID,
		     CK_TOKEN_INFO_PTR pInfo)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_token_get_info(slotID, pInfo);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_SLOT_ID_INVALID, CKR_TOKEN_NOT_PRESENT,
		     CKR_TOKEN_NOT_RECOGNIZED, CKR_ARGUMENTS_BAD);

	return rv;
}

CK_RV C_GetMechanismList(CK_SLOT_ID slotID,
			 CK_MECHANISM_TYPE_PTR pMechanismList,
			 CK_ULONG_PTR pulCount)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_token_mechanism_ids(slotID, pMechanismList, pulCount);

	ASSERT_CK_RV(rv, CKR_BUFFER_TOO_SMALL, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK, CKR_SLOT_ID_INVALID, CKR_TOKEN_NOT_PRESENT,
		     CKR_TOKEN_NOT_RECOGNIZED, CKR_ARGUMENTS_BAD);

	return rv;
}

CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
			 CK_MECHANISM_TYPE type,
			 CK_MECHANISM_INFO_PTR pInfo)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_token_mechanism_info(slotID, type, pInfo);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_MECHANISM_INVALID,
		     CKR_OK, CKR_SLOT_ID_INVALID, CKR_TOKEN_NOT_PRESENT,
		     CKR_TOKEN_NOT_RECOGNIZED, CKR_ARGUMENTS_BAD);

	return rv;
}

CK_RV C_OpenSession(CK_SLOT_ID slotID,
		    CK_FLAGS flags,
		    CK_VOID_PTR pApplication,
		    CK_NOTIFY Notify,
		    CK_SESSION_HANDLE_PTR phSession)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_open_session(slotID, flags, pApplication, Notify,
				     phSession);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_SESSION_COUNT, CKR_SESSION_PARALLEL_NOT_SUPPORTED,
		     CKR_SESSION_READ_WRITE_SO_EXISTS, CKR_SLOT_ID_INVALID,
		     CKR_TOKEN_NOT_PRESENT, CKR_TOKEN_NOT_RECOGNIZED,
		     CKR_TOKEN_WRITE_PROTECTED, CKR_ARGUMENTS_BAD);

	return rv;
}

CK_RV C_CloseSession(CK_SESSION_HANDLE hSession)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_close_session(hSession);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_CloseAllSessions(CK_SLOT_ID slotID)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_close_all_sessions(slotID);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_SLOT_ID_INVALID, CKR_TOKEN_NOT_PRESENT);

	return rv;
}

CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession,
		       CK_SESSION_INFO_PTR pInfo)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_get_session_info(hSession, pInfo);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_ARGUMENTS_BAD);

	return rv;
}

CK_RV C_InitPIN(CK_SESSION_HANDLE hSession,
		CK_UTF8CHAR_PTR pPin,
		CK_ULONG ulPinLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_init_pin(hSession, pPin, ulPinLen);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_PIN_INVALID, CKR_PIN_LEN_RANGE, CKR_SESSION_CLOSED,
		     CKR_SESSION_READ_ONLY, CKR_SESSION_HANDLE_INVALID,
		     CKR_TOKEN_WRITE_PROTECTED, CKR_USER_NOT_LOGGED_IN,
		     CKR_ARGUMENTS_BAD);

	return rv;
}

CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
	       CK_UTF8CHAR_PTR pOldPin,
	       CK_ULONG ulOldLen,
	       CK_UTF8CHAR_PTR pNewPin,
	       CK_ULONG ulNewLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_set_pin(hSession, pOldPin, ulOldLen, pNewPin, ulNewLen);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK, CKR_PIN_INCORRECT, CKR_PIN_INVALID,
		     CKR_PIN_LEN_RANGE, CKR_PIN_LOCKED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY,
		     CKR_TOKEN_WRITE_PROTECTED, CKR_ARGUMENTS_BAD);

	return rv;
}

CK_RV C_Login(CK_SESSION_HANDLE hSession,
	      CK_USER_TYPE userType,
	      CK_UTF8CHAR_PTR pPin,
	      CK_ULONG ulPinLen)

{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_login(hSession, userType, pPin, ulPinLen);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_PIN_INCORRECT,
		     CKR_PIN_LOCKED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY_EXISTS,
		     CKR_USER_ALREADY_LOGGED_IN,
		     CKR_USER_ANOTHER_ALREADY_LOGGED_IN,
		     CKR_USER_PIN_NOT_INITIALIZED, CKR_USER_TOO_MANY_TYPES,
		     CKR_USER_TYPE_INVALID);

	return rv;
}

CK_RV C_Logout(CK_SESSION_HANDLE hSession)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_logout(hSession);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession,
			  CK_BYTE_PTR pOperationState,
			  CK_ULONG_PTR pulOperationStateLen)
{
	(void)hSession;
	(void)pOperationState;
	(void)pulOperationStateLen;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession,
			  CK_BYTE_PTR pOperationState,
			  CK_ULONG ulOperationStateLen,
			  CK_OBJECT_HANDLE hEncryptionKey,
			  CK_OBJECT_HANDLE hAuthenticationKey)
{
	(void)hSession;
	(void)pOperationState;
	(void)ulOperationStateLen;
	(void)hEncryptionKey;
	(void)hAuthenticationKey;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_CreateObject(CK_SESSION_HANDLE hSession,
		     CK_ATTRIBUTE_PTR pTemplate,
		     CK_ULONG ulCount,
		     CK_OBJECT_HANDLE_PTR phObject)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_create_object(hSession, pTemplate, ulCount, phObject);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_READ_ONLY,
		     CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_VALUE_INVALID,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CURVE_NOT_SUPPORTED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_DOMAIN_PARAMS_INVALID, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK, CKR_PIN_EXPIRED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY,
		     CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT,
		     CKR_TOKEN_WRITE_PROTECTED, CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_CopyObject(CK_SESSION_HANDLE hSession,
		   CK_OBJECT_HANDLE hObject,
		   CK_ATTRIBUTE_PTR pTemplate,
		   CK_ULONG ulCount,
		   CK_OBJECT_HANDLE_PTR phNewObject)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_copy_object(hSession, hObject, pTemplate, ulCount,
				    phNewObject);

	ASSERT_CK_RV(rv, CKR_ACTION_PROHIBITED, CKR_ARGUMENTS_BAD,
		     CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_TYPE_INVALID,
		     CKR_ATTRIBUTE_VALUE_INVALID, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OBJECT_HANDLE_INVALID, CKR_OK, CKR_PIN_EXPIRED,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_SESSION_READ_ONLY, CKR_TEMPLATE_INCONSISTENT,
		     CKR_TOKEN_WRITE_PROTECTED, CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession,
		      CK_OBJECT_HANDLE hObject)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_destroy_object(hSession, hObject);

	ASSERT_CK_RV(rv, CKR_ACTION_PROHIBITED, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OBJECT_HANDLE_INVALID, CKR_OK, CKR_PIN_EXPIRED,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_SESSION_READ_ONLY, CKR_TOKEN_WRITE_PROTECTED);

	return rv;
}

CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession,
		      CK_OBJECT_HANDLE hObject,
		      CK_ULONG_PTR pulSize)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_get_object_size(hSession, hObject, pulSize);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_INFORMATION_SENSITIVE, CKR_OBJECT_HANDLE_INVALID,
		     CKR_OK, CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession,
			  CK_OBJECT_HANDLE hObject,
			  CK_ATTRIBUTE_PTR pTemplate,
			  CK_ULONG ulCount)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_get_attribute_value(hSession, hObject, pTemplate, ulCount);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_SENSITIVE,
		     CKR_ATTRIBUTE_TYPE_INVALID, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OBJECT_HANDLE_INVALID, CKR_OK, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession,
			  CK_OBJECT_HANDLE hObject,
			  CK_ATTRIBUTE_PTR pTemplate,
			  CK_ULONG ulCount)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_set_attribute_value(hSession, hObject, pTemplate, ulCount);

	ASSERT_CK_RV(rv, CKR_ACTION_PROHIBITED, CKR_ARGUMENTS_BAD,
		     CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_TYPE_INVALID,
		     CKR_ATTRIBUTE_VALUE_INVALID, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OBJECT_HANDLE_INVALID, CKR_OK, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY,
		     CKR_TEMPLATE_INCONSISTENT, CKR_TOKEN_WRITE_PROTECTED,
		     CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession,
			CK_ATTRIBUTE_PTR pTemplate,
			CK_ULONG ulCount)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_find_objects_init(hSession, pTemplate, ulCount);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_TYPE_INVALID,
		     CKR_ATTRIBUTE_VALUE_INVALID, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK, CKR_OPERATION_ACTIVE, CKR_PIN_EXPIRED,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_FindObjects(CK_SESSION_HANDLE hSession,
		    CK_OBJECT_HANDLE_PTR phObject,
		    CK_ULONG ulMaxObjectCount,
		    CK_ULONG_PTR pulObjectCount)

{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_find_objects(hSession, phObject,
				     ulMaxObjectCount, pulObjectCount);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK, CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_find_objects_final(hSession);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession,
		    CK_MECHANISM_PTR pMechanism,
		    CK_OBJECT_HANDLE hKey)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_encdecrypt_init(hSession, pMechanism, hKey, CK_FALSE);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_KEY_FUNCTION_NOT_PERMITTED, CKR_KEY_HANDLE_INVALID,
		     CKR_KEY_SIZE_RANGE, CKR_KEY_TYPE_INCONSISTENT,
		     CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID,
		     CKR_OK, CKR_OPERATION_ACTIVE, CKR_PIN_EXPIRED,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_Encrypt(CK_SESSION_HANDLE hSession,
		CK_BYTE_PTR pData,
		CK_ULONG ulDataLen,
		CK_BYTE_PTR pEncryptedData,
		CK_ULONG_PTR pulEncryptedDataLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_encdecrypt_oneshot(hSession, pData, ulDataLen,
					   pEncryptedData, pulEncryptedDataLen,
					   CK_FALSE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DATA_LEN_RANGE,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession,
		      CK_BYTE_PTR pPart,
		      CK_ULONG ulPartLen,
		      CK_BYTE_PTR pEncryptedData,
		      CK_ULONG_PTR pulEncryptedDataLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_encdecrypt_update(hSession, pPart, ulPartLen,
					  pEncryptedData,
					  pulEncryptedDataLen, CK_FALSE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DATA_LEN_RANGE,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession,
		     CK_BYTE_PTR pLastEncryptedPart,
		     CK_ULONG_PTR pulLastEncryptedPartLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_encdecrypt_final(hSession, pLastEncryptedPart,
					 pulLastEncryptedPartLen, CK_FALSE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DATA_LEN_RANGE,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession,
		    CK_MECHANISM_PTR pMechanism,
		    CK_OBJECT_HANDLE hKey)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_encdecrypt_init(hSession, pMechanism, hKey, CK_TRUE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_KEY_FUNCTION_NOT_PERMITTED, CKR_KEY_HANDLE_INVALID,
		     CKR_KEY_SIZE_RANGE, CKR_KEY_TYPE_INCONSISTENT,
		     CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID,
		     CKR_OK, CKR_OPERATION_ACTIVE, CKR_PIN_EXPIRED,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_Decrypt(CK_SESSION_HANDLE hSession,
		CK_BYTE_PTR pEncryptedData,
		CK_ULONG ulEncryptedDataLen,
		CK_BYTE_PTR pData,
		CK_ULONG_PTR pulDataLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_encdecrypt_oneshot(hSession, pEncryptedData,
					   ulEncryptedDataLen,
					   pData, pulDataLen, CK_TRUE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession,
		      CK_BYTE_PTR pEncryptedPart,
		      CK_ULONG ulEncryptedPartLen,
		      CK_BYTE_PTR pPart,
		      CK_ULONG_PTR pulPartLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_encdecrypt_update(hSession, pEncryptedPart,
					  ulEncryptedPartLen,
					  pPart, pulPartLen, CK_TRUE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession,
		     CK_BYTE_PTR pLastPart,
		     CK_ULONG_PTR pulLastPartLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_encdecrypt_final(hSession, pLastPart, pulLastPartLen,
					 CK_TRUE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_DigestInit(CK_SESSION_HANDLE hSession,
		   CK_MECHANISM_PTR pMechanism)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_digest_init(hSession, pMechanism);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_MECHANISM_INVALID,
		     CKR_MECHANISM_PARAM_INVALID, CKR_OK, CKR_OPERATION_ACTIVE,
		     CKR_PIN_EXPIRED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_Digest(CK_SESSION_HANDLE hSession,
	       CK_BYTE_PTR pData,
	       CK_ULONG ulDataLen,
	       CK_BYTE_PTR pDigest,
	       CK_ULONG_PTR pulDigestLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_digest_oneshot(hSession, pData, ulDataLen, pDigest,
				       pulDigestLen);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession,
		     CK_BYTE_PTR pPart,
		     CK_ULONG ulPartLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_digest_update(hSession, pPart, ulPartLen);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_DigestKey(CK_SESSION_HANDLE hSession,
		  CK_OBJECT_HANDLE hKey)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_digest_key(hSession, hKey);

	ASSERT_CK_RV(rv, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_KEY_HANDLE_INVALID, CKR_KEY_INDIGESTIBLE,
		     CKR_KEY_SIZE_RANGE, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession,
		    CK_BYTE_PTR pDigest,
		    CK_ULONG_PTR pulDigestLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_digest_final(hSession, pDigest, pulDigestLen);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
		 CK_MECHANISM_PTR pMechanism,
		 CK_OBJECT_HANDLE hKey)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_signverify_init(hSession, pMechanism, hKey, CK_TRUE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_KEY_FUNCTION_NOT_PERMITTED, CKR_KEY_HANDLE_INVALID,
		     CKR_KEY_SIZE_RANGE, CKR_KEY_TYPE_INCONSISTENT,
		     CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID,
		     CKR_OK, CKR_OPERATION_ACTIVE, CKR_PIN_EXPIRED,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_Sign(CK_SESSION_HANDLE hSession,
	     CK_BYTE_PTR pData,
	     CK_ULONG ulDataLen,
	     CK_BYTE_PTR pSignature,
	     CK_ULONG_PTR pulSignatureLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_signverify_oneshot(hSession, pData, ulDataLen,
					   pSignature, pulSignatureLen,
					   CK_TRUE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DATA_INVALID,
		     CKR_DATA_LEN_RANGE, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY,
		     CKR_DEVICE_REMOVED, CKR_FUNCTION_CANCELED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK, CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_USER_NOT_LOGGED_IN,
		     CKR_FUNCTION_REJECTED);

	return rv;
}

CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession,
		   CK_BYTE_PTR pPart,
		   CK_ULONG ulPartLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_signverify_update(hSession, pPart, ulPartLen, CK_TRUE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DATA_LEN_RANGE, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY,
		     CKR_DEVICE_REMOVED, CKR_FUNCTION_CANCELED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK, CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
		  CK_BYTE_PTR pSignature,
		  CK_ULONG_PTR pulSignatureLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_signverify_final(hSession, pSignature, pulSignatureLen,
					 CK_TRUE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DATA_LEN_RANGE,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_USER_NOT_LOGGED_IN,
		     CKR_FUNCTION_REJECTED);

	return rv;
}

CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession,
			CK_MECHANISM_PTR pMechanism,
			CK_OBJECT_HANDLE hKey)
{
	(void)hSession;
	(void)pMechanism;
	(void)hKey;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_SignRecover(CK_SESSION_HANDLE hSession,
		    CK_BYTE_PTR pData,
		    CK_ULONG ulDataLen,
		    CK_BYTE_PTR pSignature,
		    CK_ULONG_PTR pulSignatureLen)
{
	(void)hSession;
	(void)pData;
	(void)ulDataLen;
	(void)pSignature;
	(void)pulSignatureLen;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
		   CK_MECHANISM_PTR pMechanism,
		   CK_OBJECT_HANDLE hKey)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_signverify_init(hSession, pMechanism, hKey, CK_FALSE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_KEY_FUNCTION_NOT_PERMITTED, CKR_KEY_HANDLE_INVALID,
		     CKR_KEY_SIZE_RANGE, CKR_KEY_TYPE_INCONSISTENT,
		     CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID,
		     CKR_OK, CKR_OPERATION_ACTIVE, CKR_PIN_EXPIRED,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_Verify(CK_SESSION_HANDLE hSession,
	       CK_BYTE_PTR pData,
	       CK_ULONG ulDataLen,
	       CK_BYTE_PTR pSignature,
	       CK_ULONG ulSignatureLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
	CK_ULONG out_size = ulSignatureLen;

	if (lib_initiated())
		rv = ck_signverify_oneshot(hSession, pData, ulDataLen,
					   pSignature, &out_size,
					   CK_FALSE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DATA_INVALID, CKR_DATA_LEN_RANGE, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_SIGNATURE_INVALID,
		     CKR_SIGNATURE_LEN_RANGE);

	return rv;
}

CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession,
		     CK_BYTE_PTR pPart,
		     CK_ULONG ulPartLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_signverify_update(hSession, pPart, ulPartLen, CK_FALSE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DATA_LEN_RANGE, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY,
		     CKR_DEVICE_REMOVED, CKR_FUNCTION_CANCELED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK, CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID);

	return rv;
}

CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
		    CK_BYTE_PTR pSignature,
		    CK_ULONG ulSignatureLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_signverify_final(hSession, pSignature, &ulSignatureLen,
					 CK_FALSE);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DATA_LEN_RANGE, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY,
		     CKR_DEVICE_REMOVED, CKR_FUNCTION_CANCELED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_OK, CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_SIGNATURE_INVALID,
		     CKR_SIGNATURE_LEN_RANGE);

	return rv;
}

CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
			  CK_MECHANISM_PTR pMechanism,
			  CK_OBJECT_HANDLE hKey)
{
	(void)hSession;
	(void)pMechanism;
	(void)hKey;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_VerifyRecover(CK_SESSION_HANDLE hSession,
		      CK_BYTE_PTR pSignature,
		      CK_ULONG ulSignatureLen,
		      CK_BYTE_PTR pData,
		      CK_ULONG_PTR pulDataLen)
{
	(void)hSession;
	(void)pSignature;
	(void)ulSignatureLen;
	(void)pData;
	(void)pulDataLen;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,
			    CK_BYTE_PTR pPart,
			    CK_ULONG ulPartLen,
			    CK_BYTE_PTR pEncryptedPart,
			    CK_ULONG_PTR pulEncryptedPartLen)
{
	(void)hSession;
	(void)pPart;
	(void)ulPartLen;
	(void)pEncryptedPart;
	(void)pulEncryptedPartLen;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
			    CK_BYTE_PTR pEncryptedPart,
			    CK_ULONG ulEncryptedPartLen,
			    CK_BYTE_PTR pPart,
			    CK_ULONG_PTR pulPartLen)
{
	(void)hSession;
	(void)pEncryptedPart;
	(void)ulEncryptedPartLen;
	(void)pPart;
	(void)pulPartLen;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
			  CK_BYTE_PTR pPart,
			  CK_ULONG ulPartLen,
			  CK_BYTE_PTR pEncryptedPart,
			  CK_ULONG_PTR pulEncryptedPartLen)
{
	(void)hSession;
	(void)pPart;
	(void)ulPartLen;
	(void)pEncryptedPart;
	(void)pulEncryptedPartLen;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
			    CK_BYTE_PTR pEncryptedPart,
			    CK_ULONG ulEncryptedPartLen,
			    CK_BYTE_PTR pPart,
			    CK_ULONG_PTR pulPartLen)
{
	(void)hSession;
	(void)pEncryptedPart;
	(void)ulEncryptedPartLen;
	(void)pPart;
	(void)pulPartLen;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}

CK_RV C_GenerateKey(CK_SESSION_HANDLE hSession,
		    CK_MECHANISM_PTR pMechanism,
		    CK_ATTRIBUTE_PTR pTemplate,
		    CK_ULONG ulCount,
		    CK_OBJECT_HANDLE_PTR phKey)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_generate_key(hSession, pMechanism, pTemplate, ulCount,
				     phKey);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_READ_ONLY,
		     CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_VALUE_INVALID,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CURVE_NOT_SUPPORTED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_MECHANISM_INVALID,
		     CKR_MECHANISM_PARAM_INVALID, CKR_OK, CKR_OPERATION_ACTIVE,
		     CKR_PIN_EXPIRED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY,
		     CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT,
		     CKR_TOKEN_WRITE_PROTECTED, CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession,
			CK_MECHANISM_PTR pMechanism,
			CK_ATTRIBUTE_PTR pPublicKeyTemplate,
			CK_ULONG ulPublicKeyAttributeCount,
			CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
			CK_ULONG ulPrivateKeyAttributeCount,
			CK_OBJECT_HANDLE_PTR phPublicKey,
			CK_OBJECT_HANDLE_PTR phPrivateKey)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_generate_key_pair(hSession, pMechanism,
					  pPublicKeyTemplate,
					  ulPublicKeyAttributeCount,
					  pPrivateKeyTemplate,
					  ulPrivateKeyAttributeCount,
					  phPublicKey, phPrivateKey);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_READ_ONLY,
		     CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_VALUE_INVALID,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CURVE_NOT_SUPPORTED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_DOMAIN_PARAMS_INVALID, CKR_FUNCTION_CANCELED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID,
		     CKR_OK, CKR_OPERATION_ACTIVE, CKR_PIN_EXPIRED,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_SESSION_READ_ONLY, CKR_TEMPLATE_INCOMPLETE,
		     CKR_TEMPLATE_INCONSISTENT, CKR_TOKEN_WRITE_PROTECTED,
		     CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_WrapKey(CK_SESSION_HANDLE hSession,
		CK_MECHANISM_PTR pMechanism,
		CK_OBJECT_HANDLE hWrappingKey,
		CK_OBJECT_HANDLE hKey,
		CK_BYTE_PTR pWrappedKey,
		CK_ULONG_PTR pulWrappedKeyLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_wrap_key(hSession, pMechanism, hWrappingKey, hKey,
				 pWrappedKey, pulWrappedKeyLen);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_KEY_HANDLE_INVALID,
		     CKR_KEY_NOT_WRAPPABLE, CKR_KEY_SIZE_RANGE,
		     CKR_KEY_UNEXTRACTABLE, CKR_MECHANISM_INVALID,
		     CKR_MECHANISM_PARAM_INVALID, CKR_OK, CKR_OPERATION_ACTIVE,
		     CKR_PIN_EXPIRED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_USER_NOT_LOGGED_IN,
		     CKR_WRAPPING_KEY_HANDLE_INVALID,
		     CKR_WRAPPING_KEY_SIZE_RANGE,
		     CKR_WRAPPING_KEY_TYPE_INCONSISTENT);

	return rv;
}

CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession,
		  CK_MECHANISM_PTR pMechanism,
		  CK_OBJECT_HANDLE hUnwrappingKey,
		  CK_BYTE_PTR pWrappedKey,
		  CK_ULONG ulWrappedKeyLen,
		  CK_ATTRIBUTE_PTR pTemplate,
		  CK_ULONG ulCount,
		  CK_OBJECT_HANDLE_PTR phKey)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_unwrap_key(hSession, pMechanism, hUnwrappingKey,
				   pWrappedKey, ulWrappedKeyLen, pTemplate,
				   ulCount, phKey);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_READ_ONLY,
		     CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_VALUE_INVALID,
		     CKR_BUFFER_TOO_SMALL, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_CURVE_NOT_SUPPORTED, CKR_DEVICE_ERROR,
		     CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_DOMAIN_PARAMS_INVALID, CKR_FUNCTION_CANCELED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID, CKR_OK,
		     CKR_OPERATION_ACTIVE, CKR_PIN_EXPIRED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY,
		     CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT,
		     CKR_TOKEN_WRITE_PROTECTED,
		     CKR_UNWRAPPING_KEY_HANDLE_INVALID,
		     CKR_UNWRAPPING_KEY_SIZE_RANGE,
		     CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT,
		     CKR_USER_NOT_LOGGED_IN, CKR_WRAPPED_KEY_INVALID,
		     CKR_WRAPPED_KEY_LEN_RANGE);

	return rv;
}

CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession,
		  CK_MECHANISM_PTR pMechanism,
		  CK_OBJECT_HANDLE hBaseKey,
		  CK_ATTRIBUTE_PTR pTemplate,
		  CK_ULONG ulCount,
		  CK_OBJECT_HANDLE_PTR phKey)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_derive_key(hSession, pMechanism, hBaseKey, pTemplate,
				   ulCount, phKey);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_READ_ONLY,
		     CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_VALUE_INVALID,
		     CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CURVE_NOT_SUPPORTED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_DOMAIN_PARAMS_INVALID, CKR_FUNCTION_CANCELED,
		     CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY,
		     CKR_KEY_HANDLE_INVALID, CKR_KEY_SIZE_RANGE,
		     CKR_KEY_TYPE_INCONSISTENT, CKR_MECHANISM_INVALID,
		     CKR_MECHANISM_PARAM_INVALID, CKR_OK, CKR_OPERATION_ACTIVE,
		     CKR_PIN_EXPIRED, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_SESSION_READ_ONLY,
		     CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT,
		     CKR_TOKEN_WRITE_PROTECTED, CKR_USER_NOT_LOGGED_IN,
		     CKR_DATA_LEN_RANGE);

	return rv;
}

CK_RV C_SeedRandom(CK_SESSION_HANDLE hSession,
		   CK_BYTE_PTR pSeed,
		   CK_ULONG ulSeedLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_seed_random(hSession, pSeed, ulSeedLen);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_ACTIVE, CKR_RANDOM_SEED_NOT_SUPPORTED,
		     CKR_RANDOM_NO_RNG, CKR_SESSION_CLOSED,
		     CKR_SESSION_HANDLE_INVALID, CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession,
		       CK_BYTE_PTR pRandomData,
		       CK_ULONG ulRandomLen)
{
	CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;

	if (lib_initiated())
		rv = ck_generate_random(hSession, pRandomData, ulRandomLen);

	ASSERT_CK_RV(rv, CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED,
		     CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED,
		     CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED,
		     CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK,
		     CKR_OPERATION_ACTIVE, CKR_RANDOM_NO_RNG,
		     CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID,
		     CKR_USER_NOT_LOGGED_IN);

	return rv;
}

CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
{
	(void)hSession;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_PARALLEL;
}

CK_RV C_CancelFunction(CK_SESSION_HANDLE hSession)
{
	(void)hSession;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_PARALLEL;
}

CK_RV C_WaitForSlotEvent(CK_FLAGS flags,
			 CK_SLOT_ID_PTR slotID,
			 CK_VOID_PTR pReserved)
{
	(void)flags;
	(void)slotID;
	(void)pReserved;

	if (!lib_initiated())
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	return CKR_FUNCTION_NOT_SUPPORTED;
}
