17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <fcntl.h> 307c478bd9Sstevel@tonic-gate #include <pthread.h> 317c478bd9Sstevel@tonic-gate #include <strings.h> 327c478bd9Sstevel@tonic-gate #include <unistd.h> /* for pid */ 337c478bd9Sstevel@tonic-gate #include <errno.h> 347c478bd9Sstevel@tonic-gate #include <security/cryptoki.h> 357c478bd9Sstevel@tonic-gate #include "kernelGlobal.h" 367c478bd9Sstevel@tonic-gate #include "kernelSession.h" 377c478bd9Sstevel@tonic-gate #include "kernelSlot.h" 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #pragma fini(kernel_fini) 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate static struct CK_FUNCTION_LIST functionList = { 427c478bd9Sstevel@tonic-gate { 2, 11 }, /* version */ 437c478bd9Sstevel@tonic-gate C_Initialize, 447c478bd9Sstevel@tonic-gate C_Finalize, 457c478bd9Sstevel@tonic-gate C_GetInfo, 467c478bd9Sstevel@tonic-gate C_GetFunctionList, 477c478bd9Sstevel@tonic-gate C_GetSlotList, 487c478bd9Sstevel@tonic-gate C_GetSlotInfo, 497c478bd9Sstevel@tonic-gate C_GetTokenInfo, 507c478bd9Sstevel@tonic-gate C_GetMechanismList, 517c478bd9Sstevel@tonic-gate C_GetMechanismInfo, 527c478bd9Sstevel@tonic-gate C_InitToken, 537c478bd9Sstevel@tonic-gate C_InitPIN, 547c478bd9Sstevel@tonic-gate C_SetPIN, 557c478bd9Sstevel@tonic-gate C_OpenSession, 567c478bd9Sstevel@tonic-gate C_CloseSession, 577c478bd9Sstevel@tonic-gate C_CloseAllSessions, 587c478bd9Sstevel@tonic-gate C_GetSessionInfo, 597c478bd9Sstevel@tonic-gate C_GetOperationState, 607c478bd9Sstevel@tonic-gate C_SetOperationState, 617c478bd9Sstevel@tonic-gate C_Login, 627c478bd9Sstevel@tonic-gate C_Logout, 637c478bd9Sstevel@tonic-gate C_CreateObject, 647c478bd9Sstevel@tonic-gate C_CopyObject, 657c478bd9Sstevel@tonic-gate C_DestroyObject, 667c478bd9Sstevel@tonic-gate C_GetObjectSize, 677c478bd9Sstevel@tonic-gate C_GetAttributeValue, 687c478bd9Sstevel@tonic-gate C_SetAttributeValue, 697c478bd9Sstevel@tonic-gate C_FindObjectsInit, 707c478bd9Sstevel@tonic-gate C_FindObjects, 717c478bd9Sstevel@tonic-gate C_FindObjectsFinal, 727c478bd9Sstevel@tonic-gate C_EncryptInit, 737c478bd9Sstevel@tonic-gate C_Encrypt, 747c478bd9Sstevel@tonic-gate C_EncryptUpdate, 757c478bd9Sstevel@tonic-gate C_EncryptFinal, 767c478bd9Sstevel@tonic-gate C_DecryptInit, 777c478bd9Sstevel@tonic-gate C_Decrypt, 787c478bd9Sstevel@tonic-gate C_DecryptUpdate, 797c478bd9Sstevel@tonic-gate C_DecryptFinal, 807c478bd9Sstevel@tonic-gate C_DigestInit, 817c478bd9Sstevel@tonic-gate C_Digest, 827c478bd9Sstevel@tonic-gate C_DigestUpdate, 837c478bd9Sstevel@tonic-gate C_DigestKey, 847c478bd9Sstevel@tonic-gate C_DigestFinal, 857c478bd9Sstevel@tonic-gate C_SignInit, 867c478bd9Sstevel@tonic-gate C_Sign, 877c478bd9Sstevel@tonic-gate C_SignUpdate, 887c478bd9Sstevel@tonic-gate C_SignFinal, 897c478bd9Sstevel@tonic-gate C_SignRecoverInit, 907c478bd9Sstevel@tonic-gate C_SignRecover, 917c478bd9Sstevel@tonic-gate C_VerifyInit, 927c478bd9Sstevel@tonic-gate C_Verify, 937c478bd9Sstevel@tonic-gate C_VerifyUpdate, 947c478bd9Sstevel@tonic-gate C_VerifyFinal, 957c478bd9Sstevel@tonic-gate C_VerifyRecoverInit, 967c478bd9Sstevel@tonic-gate C_VerifyRecover, 977c478bd9Sstevel@tonic-gate C_DigestEncryptUpdate, 987c478bd9Sstevel@tonic-gate C_DecryptDigestUpdate, 997c478bd9Sstevel@tonic-gate C_SignEncryptUpdate, 1007c478bd9Sstevel@tonic-gate C_DecryptVerifyUpdate, 1017c478bd9Sstevel@tonic-gate C_GenerateKey, 1027c478bd9Sstevel@tonic-gate C_GenerateKeyPair, 1037c478bd9Sstevel@tonic-gate C_WrapKey, 1047c478bd9Sstevel@tonic-gate C_UnwrapKey, 1057c478bd9Sstevel@tonic-gate C_DeriveKey, 1067c478bd9Sstevel@tonic-gate C_SeedRandom, 1077c478bd9Sstevel@tonic-gate C_GenerateRandom, 1087c478bd9Sstevel@tonic-gate C_GetFunctionStatus, 1097c478bd9Sstevel@tonic-gate C_CancelFunction, 1107c478bd9Sstevel@tonic-gate C_WaitForSlotEvent 1117c478bd9Sstevel@tonic-gate }; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate boolean_t kernel_initialized = B_FALSE; 1147c478bd9Sstevel@tonic-gate static pid_t kernel_pid = 0; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate int kernel_fd = -1; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate /* protects kernel_initialized and entrance to C_Initialize/Finalize */ 1207c478bd9Sstevel@tonic-gate static pthread_mutex_t globalmutex = PTHREAD_MUTEX_INITIALIZER; 1217c478bd9Sstevel@tonic-gate 122*01223cbaSmcpowers ses_to_be_freed_list_t ses_delay_freed; 123*01223cbaSmcpowers object_to_be_freed_list_t obj_delay_freed; 124*01223cbaSmcpowers 125*01223cbaSmcpowers static void finalize_common(); 1267c478bd9Sstevel@tonic-gate static void cleanup_library(); 1277c478bd9Sstevel@tonic-gate static void kernel_fini(); 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate CK_RV 1307c478bd9Sstevel@tonic-gate C_Initialize(CK_VOID_PTR pInitArgs) 1317c478bd9Sstevel@tonic-gate { 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate int initialize_pid; 1347c478bd9Sstevel@tonic-gate boolean_t supplied_ok; 1357c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate /* 1387c478bd9Sstevel@tonic-gate * Grab lock to insure that only one thread enters this 1397c478bd9Sstevel@tonic-gate * function at a time. 1407c478bd9Sstevel@tonic-gate */ 1417c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&globalmutex); 1427c478bd9Sstevel@tonic-gate initialize_pid = getpid(); 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate if (kernel_initialized) { 1457c478bd9Sstevel@tonic-gate if (initialize_pid == kernel_pid) { 1467c478bd9Sstevel@tonic-gate /* 1477c478bd9Sstevel@tonic-gate * This process has called C_Initialize already 1487c478bd9Sstevel@tonic-gate */ 1497c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&globalmutex); 1507c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_ALREADY_INITIALIZED); 1517c478bd9Sstevel@tonic-gate } else { 1527c478bd9Sstevel@tonic-gate /* 1537c478bd9Sstevel@tonic-gate * A fork has happened and the child is 1547c478bd9Sstevel@tonic-gate * reinitializing. Do a cleanup_library to close 1557c478bd9Sstevel@tonic-gate * out any state from the parent, and then 1567c478bd9Sstevel@tonic-gate * continue on. 1577c478bd9Sstevel@tonic-gate */ 1587c478bd9Sstevel@tonic-gate cleanup_library(); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate if (pInitArgs != NULL) { 1637c478bd9Sstevel@tonic-gate CK_C_INITIALIZE_ARGS *initargs1 = 1647c478bd9Sstevel@tonic-gate (CK_C_INITIALIZE_ARGS *) pInitArgs; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate /* pReserved must be NULL */ 1677c478bd9Sstevel@tonic-gate if (initargs1->pReserved != NULL) { 1687c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&globalmutex); 1697c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate /* 1737c478bd9Sstevel@tonic-gate * ALL supplied function pointers need to have the value 1747c478bd9Sstevel@tonic-gate * either NULL or non-NULL. 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate supplied_ok = (initargs1->CreateMutex == NULL && 1777c478bd9Sstevel@tonic-gate initargs1->DestroyMutex == NULL && 1787c478bd9Sstevel@tonic-gate initargs1->LockMutex == NULL && 1797c478bd9Sstevel@tonic-gate initargs1->UnlockMutex == NULL) || 1807c478bd9Sstevel@tonic-gate (initargs1->CreateMutex != NULL && 1817c478bd9Sstevel@tonic-gate initargs1->DestroyMutex != NULL && 1827c478bd9Sstevel@tonic-gate initargs1->LockMutex != NULL && 1837c478bd9Sstevel@tonic-gate initargs1->UnlockMutex != NULL); 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate if (!supplied_ok) { 1867c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&globalmutex); 1877c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate /* 1917c478bd9Sstevel@tonic-gate * When the CKF_OS_LOCKING_OK flag isn't set and mutex 1927c478bd9Sstevel@tonic-gate * function pointers are supplied by an application, 1937c478bd9Sstevel@tonic-gate * return an error. We must be able to use our own locks. 1947c478bd9Sstevel@tonic-gate */ 1957c478bd9Sstevel@tonic-gate if (!(initargs1->flags & CKF_OS_LOCKING_OK) && 1967c478bd9Sstevel@tonic-gate (initargs1->CreateMutex != NULL)) { 1977c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&globalmutex); 1987c478bd9Sstevel@tonic-gate return (CKR_CANT_LOCK); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate while ((kernel_fd = open(CRYPTO_DEVICE, O_RDWR)) < 0) { 2037c478bd9Sstevel@tonic-gate if (errno != EINTR) 2047c478bd9Sstevel@tonic-gate break; 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate if (kernel_fd < 0) { 2077c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&globalmutex); 2087c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate /* Mark kernel_fd "close on exec" */ 2127c478bd9Sstevel@tonic-gate (void) fcntl(kernel_fd, F_SETFD, FD_CLOEXEC); 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate /* Initialize the slot table */ 2157c478bd9Sstevel@tonic-gate rv = kernel_slottable_init(); 2167c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2177c478bd9Sstevel@tonic-gate (void) close(kernel_fd); 2187c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&globalmutex); 2197c478bd9Sstevel@tonic-gate return (rv); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 222*01223cbaSmcpowers /* Initialize the object_to_be_freed list */ 223*01223cbaSmcpowers (void) pthread_mutex_init(&obj_delay_freed.obj_to_be_free_mutex, NULL); 224*01223cbaSmcpowers obj_delay_freed.count = 0; 225*01223cbaSmcpowers obj_delay_freed.first = NULL; 226*01223cbaSmcpowers obj_delay_freed.last = NULL; 227*01223cbaSmcpowers 228*01223cbaSmcpowers /* Initialize the session_to_be_freed list */ 229*01223cbaSmcpowers (void) pthread_mutex_init(&ses_delay_freed.ses_to_be_free_mutex, NULL); 230*01223cbaSmcpowers ses_delay_freed.count = 0; 231*01223cbaSmcpowers ses_delay_freed.first = NULL; 232*01223cbaSmcpowers ses_delay_freed.last = NULL; 233*01223cbaSmcpowers 2347c478bd9Sstevel@tonic-gate kernel_initialized = B_TRUE; 2357c478bd9Sstevel@tonic-gate kernel_pid = initialize_pid; 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&globalmutex); 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate return (CKR_OK); 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate /* 2457c478bd9Sstevel@tonic-gate * C_Finalize is a wrapper around finalize_common. The 2467c478bd9Sstevel@tonic-gate * globalmutex should be locked by C_Finalize(). 2477c478bd9Sstevel@tonic-gate */ 2487c478bd9Sstevel@tonic-gate CK_RV 2497c478bd9Sstevel@tonic-gate C_Finalize(CK_VOID_PTR pReserved) 2507c478bd9Sstevel@tonic-gate { 251*01223cbaSmcpowers int i; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&globalmutex); 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate if (!kernel_initialized) { 2567c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* Check to see if pReseved is NULL */ 2607c478bd9Sstevel@tonic-gate if (pReserved != NULL) { 2617c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* 2657c478bd9Sstevel@tonic-gate * Delete all the sessions for each slot and release the allocated 2667c478bd9Sstevel@tonic-gate * resources 2677c478bd9Sstevel@tonic-gate */ 2687c478bd9Sstevel@tonic-gate for (i = 0; i < slot_count; i++) { 269*01223cbaSmcpowers kernel_delete_all_sessions(i, B_FALSE); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate 272*01223cbaSmcpowers finalize_common(); 273*01223cbaSmcpowers 274*01223cbaSmcpowers (void) pthread_mutex_unlock(&globalmutex); 275*01223cbaSmcpowers 276*01223cbaSmcpowers return (CKR_OK); 277*01223cbaSmcpowers } 278*01223cbaSmcpowers 279*01223cbaSmcpowers /* 280*01223cbaSmcpowers * finalize_common() does the work for C_Finalize. globalmutex 281*01223cbaSmcpowers * must be held before calling this function. 282*01223cbaSmcpowers */ 283*01223cbaSmcpowers static void 284*01223cbaSmcpowers finalize_common() { 285*01223cbaSmcpowers 286*01223cbaSmcpowers int i; 287*01223cbaSmcpowers kernel_object_t *delay_free_obj, *tmpo; 288*01223cbaSmcpowers kernel_session_t *delay_free_ses, *tmps; 289*01223cbaSmcpowers 2907c478bd9Sstevel@tonic-gate /* 2917c478bd9Sstevel@tonic-gate * Free the resources allocated for the slot table and reset 2927c478bd9Sstevel@tonic-gate * slot_count to 0. 2937c478bd9Sstevel@tonic-gate */ 2947c478bd9Sstevel@tonic-gate if (slot_count > 0) { 2957c478bd9Sstevel@tonic-gate for (i = 0; i < slot_count; i++) { 2967c478bd9Sstevel@tonic-gate (void) pthread_mutex_destroy(&slot_table[i]->sl_mutex); 2977c478bd9Sstevel@tonic-gate (void) free(slot_table[i]); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate (void) free(slot_table); 3007c478bd9Sstevel@tonic-gate slot_count = 0; 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate /* Close CRYPTO_DEVICE */ 3047c478bd9Sstevel@tonic-gate if (kernel_fd >= 0) { 3057c478bd9Sstevel@tonic-gate (void) close(kernel_fd); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate kernel_fd = -1; 3097c478bd9Sstevel@tonic-gate kernel_initialized = B_FALSE; 3107c478bd9Sstevel@tonic-gate kernel_pid = 0; 3117c478bd9Sstevel@tonic-gate 312*01223cbaSmcpowers /* 313*01223cbaSmcpowers * free all entries in the delay_freed list 314*01223cbaSmcpowers */ 315*01223cbaSmcpowers delay_free_obj = obj_delay_freed.first; 316*01223cbaSmcpowers while (delay_free_obj != NULL) { 317*01223cbaSmcpowers tmpo = delay_free_obj->next; 318*01223cbaSmcpowers free(delay_free_obj); 319*01223cbaSmcpowers delay_free_obj = tmpo; 320*01223cbaSmcpowers } 321*01223cbaSmcpowers (void) pthread_mutex_destroy(&obj_delay_freed.obj_to_be_free_mutex); 322*01223cbaSmcpowers 323*01223cbaSmcpowers delay_free_ses = ses_delay_freed.first; 324*01223cbaSmcpowers while (delay_free_ses != NULL) { 325*01223cbaSmcpowers tmps = delay_free_ses->next; 326*01223cbaSmcpowers free(delay_free_ses); 327*01223cbaSmcpowers delay_free_ses = tmps; 328*01223cbaSmcpowers } 329*01223cbaSmcpowers (void) pthread_mutex_destroy(&ses_delay_freed.ses_to_be_free_mutex); 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate /* 3337c478bd9Sstevel@tonic-gate * This function cleans up all the resources in the library (user space only) 3347c478bd9Sstevel@tonic-gate */ 3357c478bd9Sstevel@tonic-gate static void 3367c478bd9Sstevel@tonic-gate cleanup_library() 3377c478bd9Sstevel@tonic-gate { 3387c478bd9Sstevel@tonic-gate int i; 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate /* 3417c478bd9Sstevel@tonic-gate * Delete all the sessions for each slot and release the allocated 3427c478bd9Sstevel@tonic-gate * resources from the library. The boolean argument TRUE indicates 3437c478bd9Sstevel@tonic-gate * that we only wants to clean up the resource in the library only. 3447c478bd9Sstevel@tonic-gate * We don't want to clean up the corresponding kernel part of 3457c478bd9Sstevel@tonic-gate * resources, because they are used by the parent process still. 3467c478bd9Sstevel@tonic-gate */ 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate for (i = 0; i < slot_count; i++) { 349*01223cbaSmcpowers kernel_delete_all_sessions(i, B_TRUE); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate 352*01223cbaSmcpowers finalize_common(); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate /* 3567c478bd9Sstevel@tonic-gate * kernel_fini() function required to make sure complete cleanup 3577c478bd9Sstevel@tonic-gate * is done if pkcs11_kernel is ever unloaded without 3587c478bd9Sstevel@tonic-gate * a C_Finalize() call. 3597c478bd9Sstevel@tonic-gate */ 3607c478bd9Sstevel@tonic-gate static void 3617c478bd9Sstevel@tonic-gate kernel_fini() 3627c478bd9Sstevel@tonic-gate { 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&globalmutex); 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate /* if we're not initilized, do not attempt to finalize */ 3677c478bd9Sstevel@tonic-gate if (!kernel_initialized) { 3687c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&globalmutex); 3697c478bd9Sstevel@tonic-gate return; 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate cleanup_library(); 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&globalmutex); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate CK_RV 3787c478bd9Sstevel@tonic-gate C_GetInfo(CK_INFO_PTR pInfo) 3797c478bd9Sstevel@tonic-gate { 3807c478bd9Sstevel@tonic-gate if (!kernel_initialized) 3817c478bd9Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED); 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate if (pInfo == NULL) { 3847c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate /* Check if the cryptoki was initialized */ 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR; 3907c478bd9Sstevel@tonic-gate pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR; 3917c478bd9Sstevel@tonic-gate (void) strncpy((char *)pInfo->manufacturerID, 3927c478bd9Sstevel@tonic-gate MANUFACTURER_ID, 32); 3937c478bd9Sstevel@tonic-gate pInfo->flags = 0; 3947c478bd9Sstevel@tonic-gate (void) strncpy((char *)pInfo->libraryDescription, 3957c478bd9Sstevel@tonic-gate LIBRARY_DESCRIPTION, 32); 3967c478bd9Sstevel@tonic-gate pInfo->libraryVersion.major = LIBRARY_VERSION_MAJOR; 3977c478bd9Sstevel@tonic-gate pInfo->libraryVersion.minor = LIBRARY_VERSION_MINOR; 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate return (CKR_OK); 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate CK_RV 4037c478bd9Sstevel@tonic-gate C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) 4047c478bd9Sstevel@tonic-gate { 4057c478bd9Sstevel@tonic-gate if (ppFunctionList == NULL) { 4067c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate *ppFunctionList = &functionList; 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate return (CKR_OK); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate /* 4157c478bd9Sstevel@tonic-gate * PKCS#11 states that C_GetFunctionStatus should always return 4167c478bd9Sstevel@tonic-gate * CKR_FUNCTION_NOT_PARALLEL 4177c478bd9Sstevel@tonic-gate */ 4187c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 4197c478bd9Sstevel@tonic-gate CK_RV 4207c478bd9Sstevel@tonic-gate C_GetFunctionStatus(CK_SESSION_HANDLE hSession) 4217c478bd9Sstevel@tonic-gate { 4227c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_NOT_PARALLEL); 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate /* 4267c478bd9Sstevel@tonic-gate * PKCS#11 states that C_CancelFunction should always return 4277c478bd9Sstevel@tonic-gate * CKR_FUNCTION_NOT_PARALLEL 4287c478bd9Sstevel@tonic-gate */ 4297c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 4307c478bd9Sstevel@tonic-gate CK_RV 4317c478bd9Sstevel@tonic-gate C_CancelFunction(CK_SESSION_HANDLE hSession) 4327c478bd9Sstevel@tonic-gate { 4337c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_NOT_PARALLEL); 4347c478bd9Sstevel@tonic-gate } 435