1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <fcntl.h> 30 #include <pthread.h> 31 #include <strings.h> 32 #include <unistd.h> /* for pid */ 33 #include <errno.h> 34 #include <security/cryptoki.h> 35 #include "kernelGlobal.h" 36 #include "kernelSession.h" 37 #include "kernelSlot.h" 38 39 #pragma fini(kernel_fini) 40 41 static struct CK_FUNCTION_LIST functionList = { 42 { 2, 11 }, /* version */ 43 C_Initialize, 44 C_Finalize, 45 C_GetInfo, 46 C_GetFunctionList, 47 C_GetSlotList, 48 C_GetSlotInfo, 49 C_GetTokenInfo, 50 C_GetMechanismList, 51 C_GetMechanismInfo, 52 C_InitToken, 53 C_InitPIN, 54 C_SetPIN, 55 C_OpenSession, 56 C_CloseSession, 57 C_CloseAllSessions, 58 C_GetSessionInfo, 59 C_GetOperationState, 60 C_SetOperationState, 61 C_Login, 62 C_Logout, 63 C_CreateObject, 64 C_CopyObject, 65 C_DestroyObject, 66 C_GetObjectSize, 67 C_GetAttributeValue, 68 C_SetAttributeValue, 69 C_FindObjectsInit, 70 C_FindObjects, 71 C_FindObjectsFinal, 72 C_EncryptInit, 73 C_Encrypt, 74 C_EncryptUpdate, 75 C_EncryptFinal, 76 C_DecryptInit, 77 C_Decrypt, 78 C_DecryptUpdate, 79 C_DecryptFinal, 80 C_DigestInit, 81 C_Digest, 82 C_DigestUpdate, 83 C_DigestKey, 84 C_DigestFinal, 85 C_SignInit, 86 C_Sign, 87 C_SignUpdate, 88 C_SignFinal, 89 C_SignRecoverInit, 90 C_SignRecover, 91 C_VerifyInit, 92 C_Verify, 93 C_VerifyUpdate, 94 C_VerifyFinal, 95 C_VerifyRecoverInit, 96 C_VerifyRecover, 97 C_DigestEncryptUpdate, 98 C_DecryptDigestUpdate, 99 C_SignEncryptUpdate, 100 C_DecryptVerifyUpdate, 101 C_GenerateKey, 102 C_GenerateKeyPair, 103 C_WrapKey, 104 C_UnwrapKey, 105 C_DeriveKey, 106 C_SeedRandom, 107 C_GenerateRandom, 108 C_GetFunctionStatus, 109 C_CancelFunction, 110 C_WaitForSlotEvent 111 }; 112 113 boolean_t kernel_initialized = B_FALSE; 114 static pid_t kernel_pid = 0; 115 116 int kernel_fd = -1; 117 118 119 /* protects kernel_initialized and entrance to C_Initialize/Finalize */ 120 static pthread_mutex_t globalmutex = PTHREAD_MUTEX_INITIALIZER; 121 122 static CK_RV finalize_common(CK_VOID_PTR pReserved); 123 static void cleanup_library(); 124 static void kernel_fini(); 125 126 CK_RV 127 C_Initialize(CK_VOID_PTR pInitArgs) 128 { 129 130 int initialize_pid; 131 boolean_t supplied_ok; 132 CK_RV rv = CKR_OK; 133 134 /* 135 * Grab lock to insure that only one thread enters this 136 * function at a time. 137 */ 138 (void) pthread_mutex_lock(&globalmutex); 139 initialize_pid = getpid(); 140 141 if (kernel_initialized) { 142 if (initialize_pid == kernel_pid) { 143 /* 144 * This process has called C_Initialize already 145 */ 146 (void) pthread_mutex_unlock(&globalmutex); 147 return (CKR_CRYPTOKI_ALREADY_INITIALIZED); 148 } else { 149 /* 150 * A fork has happened and the child is 151 * reinitializing. Do a cleanup_library to close 152 * out any state from the parent, and then 153 * continue on. 154 */ 155 cleanup_library(); 156 } 157 } 158 159 if (pInitArgs != NULL) { 160 CK_C_INITIALIZE_ARGS *initargs1 = 161 (CK_C_INITIALIZE_ARGS *) pInitArgs; 162 163 /* pReserved must be NULL */ 164 if (initargs1->pReserved != NULL) { 165 (void) pthread_mutex_unlock(&globalmutex); 166 return (CKR_ARGUMENTS_BAD); 167 } 168 169 /* 170 * ALL supplied function pointers need to have the value 171 * either NULL or non-NULL. 172 */ 173 supplied_ok = (initargs1->CreateMutex == NULL && 174 initargs1->DestroyMutex == NULL && 175 initargs1->LockMutex == NULL && 176 initargs1->UnlockMutex == NULL) || 177 (initargs1->CreateMutex != NULL && 178 initargs1->DestroyMutex != NULL && 179 initargs1->LockMutex != NULL && 180 initargs1->UnlockMutex != NULL); 181 182 if (!supplied_ok) { 183 (void) pthread_mutex_unlock(&globalmutex); 184 return (CKR_ARGUMENTS_BAD); 185 } 186 187 /* 188 * When the CKF_OS_LOCKING_OK flag isn't set and mutex 189 * function pointers are supplied by an application, 190 * return an error. We must be able to use our own locks. 191 */ 192 if (!(initargs1->flags & CKF_OS_LOCKING_OK) && 193 (initargs1->CreateMutex != NULL)) { 194 (void) pthread_mutex_unlock(&globalmutex); 195 return (CKR_CANT_LOCK); 196 } 197 } 198 199 while ((kernel_fd = open(CRYPTO_DEVICE, O_RDWR)) < 0) { 200 if (errno != EINTR) 201 break; 202 } 203 if (kernel_fd < 0) { 204 (void) pthread_mutex_unlock(&globalmutex); 205 return (CKR_FUNCTION_FAILED); 206 } 207 208 /* Mark kernel_fd "close on exec" */ 209 (void) fcntl(kernel_fd, F_SETFD, FD_CLOEXEC); 210 211 /* Initialize the slot table */ 212 rv = kernel_slottable_init(); 213 if (rv != CKR_OK) { 214 (void) close(kernel_fd); 215 (void) pthread_mutex_unlock(&globalmutex); 216 return (rv); 217 } 218 219 kernel_initialized = B_TRUE; 220 kernel_pid = initialize_pid; 221 222 (void) pthread_mutex_unlock(&globalmutex); 223 224 return (CKR_OK); 225 226 } 227 228 229 /* 230 * C_Finalize is a wrapper around finalize_common. The 231 * globalmutex should be locked by C_Finalize(). 232 */ 233 CK_RV 234 C_Finalize(CK_VOID_PTR pReserved) 235 { 236 237 CK_RV rv; 238 239 (void) pthread_mutex_lock(&globalmutex); 240 241 rv = finalize_common(pReserved); 242 243 (void) pthread_mutex_unlock(&globalmutex); 244 245 return (rv); 246 } 247 248 /* 249 * finalize_common() does the work for C_Finalize. globalmutex 250 * must be held before calling this function. 251 */ 252 static CK_RV 253 finalize_common(CK_VOID_PTR pReserved) { 254 255 int i; 256 257 if (!kernel_initialized) { 258 return (CKR_CRYPTOKI_NOT_INITIALIZED); 259 } 260 261 /* Check to see if pReseved is NULL */ 262 if (pReserved != NULL) { 263 return (CKR_ARGUMENTS_BAD); 264 } 265 266 /* 267 * Delete all the sessions for each slot and release the allocated 268 * resources 269 */ 270 for (i = 0; i < slot_count; i++) { 271 (void) kernel_delete_all_sessions(i, B_FALSE); 272 } 273 274 /* 275 * Free the resources allocated for the slot table and reset 276 * slot_count to 0. 277 */ 278 if (slot_count > 0) { 279 for (i = 0; i < slot_count; i++) { 280 (void) pthread_mutex_destroy(&slot_table[i]->sl_mutex); 281 (void) free(slot_table[i]); 282 } 283 (void) free(slot_table); 284 slot_count = 0; 285 } 286 287 /* Close CRYPTO_DEVICE */ 288 if (kernel_fd >= 0) { 289 (void) close(kernel_fd); 290 } 291 292 kernel_fd = -1; 293 kernel_initialized = B_FALSE; 294 kernel_pid = 0; 295 296 return (CKR_OK); 297 } 298 299 /* 300 * This function cleans up all the resources in the library (user space only) 301 */ 302 static void 303 cleanup_library() 304 { 305 int i; 306 307 /* 308 * Delete all the sessions for each slot and release the allocated 309 * resources from the library. The boolean argument TRUE indicates 310 * that we only wants to clean up the resource in the library only. 311 * We don't want to clean up the corresponding kernel part of 312 * resources, because they are used by the parent process still. 313 */ 314 315 for (i = 0; i < slot_count; i++) { 316 (void) kernel_delete_all_sessions(i, B_TRUE); 317 } 318 319 /* 320 * Free the resources allocated for the slot table and reset 321 * slot_count to 0. 322 */ 323 if (slot_count > 0) { 324 for (i = 0; i < slot_count; i++) { 325 (void) pthread_mutex_destroy(&slot_table[i]->sl_mutex); 326 (void) free(slot_table[i]); 327 } 328 (void) free(slot_table); 329 slot_count = 0; 330 } 331 332 /* Close CRYPTO_DEVICE */ 333 if (kernel_fd >= 0) { 334 (void) close(kernel_fd); 335 } 336 337 kernel_fd = -1; 338 kernel_initialized = B_FALSE; 339 kernel_pid = 0; 340 341 } 342 343 /* 344 * kernel_fini() function required to make sure complete cleanup 345 * is done if pkcs11_kernel is ever unloaded without 346 * a C_Finalize() call. 347 */ 348 static void 349 kernel_fini() 350 { 351 352 (void) pthread_mutex_lock(&globalmutex); 353 354 /* if we're not initilized, do not attempt to finalize */ 355 if (!kernel_initialized) { 356 (void) pthread_mutex_unlock(&globalmutex); 357 return; 358 } 359 360 cleanup_library(); 361 362 (void) pthread_mutex_unlock(&globalmutex); 363 } 364 365 CK_RV 366 C_GetInfo(CK_INFO_PTR pInfo) 367 { 368 if (!kernel_initialized) 369 return (CKR_CRYPTOKI_NOT_INITIALIZED); 370 371 if (pInfo == NULL) { 372 return (CKR_ARGUMENTS_BAD); 373 } 374 375 /* Check if the cryptoki was initialized */ 376 377 pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR; 378 pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR; 379 (void) strncpy((char *)pInfo->manufacturerID, 380 MANUFACTURER_ID, 32); 381 pInfo->flags = 0; 382 (void) strncpy((char *)pInfo->libraryDescription, 383 LIBRARY_DESCRIPTION, 32); 384 pInfo->libraryVersion.major = LIBRARY_VERSION_MAJOR; 385 pInfo->libraryVersion.minor = LIBRARY_VERSION_MINOR; 386 387 return (CKR_OK); 388 } 389 390 CK_RV 391 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) 392 { 393 if (ppFunctionList == NULL) { 394 return (CKR_ARGUMENTS_BAD); 395 } 396 397 *ppFunctionList = &functionList; 398 399 return (CKR_OK); 400 } 401 402 /* 403 * PKCS#11 states that C_GetFunctionStatus should always return 404 * CKR_FUNCTION_NOT_PARALLEL 405 */ 406 /*ARGSUSED*/ 407 CK_RV 408 C_GetFunctionStatus(CK_SESSION_HANDLE hSession) 409 { 410 return (CKR_FUNCTION_NOT_PARALLEL); 411 } 412 413 /* 414 * PKCS#11 states that C_CancelFunction should always return 415 * CKR_FUNCTION_NOT_PARALLEL 416 */ 417 /*ARGSUSED*/ 418 CK_RV 419 C_CancelFunction(CK_SESSION_HANDLE hSession) 420 { 421 return (CKR_FUNCTION_NOT_PARALLEL); 422 } 423