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 /* 30 * General-Purpose Functions 31 * (as defined in PKCS#11 spec section 11.4) 32 */ 33 34 #include <unistd.h> 35 #include <errno.h> 36 #include <string.h> 37 #include "metaGlobal.h" 38 39 extern meta_session_t *meta_sessionlist_head; 40 41 struct CK_FUNCTION_LIST metaslot_functionList = { 42 { 2, 20 }, /* version */ 43 meta_Initialize, 44 meta_Finalize, 45 meta_GetInfo, 46 meta_GetFunctionList, 47 meta_GetSlotList, 48 meta_GetSlotInfo, 49 meta_GetTokenInfo, 50 meta_GetMechanismList, 51 meta_GetMechanismInfo, 52 meta_InitToken, 53 meta_InitPIN, 54 meta_SetPIN, 55 meta_OpenSession, 56 meta_CloseSession, 57 meta_CloseAllSessions, 58 meta_GetSessionInfo, 59 meta_GetOperationState, 60 meta_SetOperationState, 61 meta_Login, 62 meta_Logout, 63 meta_CreateObject, 64 meta_CopyObject, 65 meta_DestroyObject, 66 meta_GetObjectSize, 67 meta_GetAttributeValue, 68 meta_SetAttributeValue, 69 meta_FindObjectsInit, 70 meta_FindObjects, 71 meta_FindObjectsFinal, 72 meta_EncryptInit, 73 meta_Encrypt, 74 meta_EncryptUpdate, 75 meta_EncryptFinal, 76 meta_DecryptInit, 77 meta_Decrypt, 78 meta_DecryptUpdate, 79 meta_DecryptFinal, 80 meta_DigestInit, 81 meta_Digest, 82 meta_DigestUpdate, 83 meta_DigestKey, 84 meta_DigestFinal, 85 meta_SignInit, 86 meta_Sign, 87 meta_SignUpdate, 88 meta_SignFinal, 89 meta_SignRecoverInit, 90 meta_SignRecover, 91 meta_VerifyInit, 92 meta_Verify, 93 meta_VerifyUpdate, 94 meta_VerifyFinal, 95 meta_VerifyRecoverInit, 96 meta_VerifyRecover, 97 meta_DigestEncryptUpdate, 98 meta_DecryptDigestUpdate, 99 meta_SignEncryptUpdate, 100 meta_DecryptVerifyUpdate, 101 meta_GenerateKey, 102 meta_GenerateKeyPair, 103 meta_WrapKey, 104 meta_UnwrapKey, 105 meta_DeriveKey, 106 meta_SeedRandom, 107 meta_GenerateRandom, 108 meta_GetFunctionStatus, 109 meta_CancelFunction, 110 meta_WaitForSlotEvent 111 }; 112 113 static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER; 114 115 ses_to_be_freed_list_t ses_delay_freed; 116 object_to_be_freed_list_t obj_delay_freed; 117 118 /* 119 * meta_Initialize 120 * 121 * This function is never called by the application. It is only 122 * called by uCF to initialize metaslot. The pInitArgs argument is ignored. 123 * 124 */ 125 /*ARGSUSED*/ 126 CK_RV 127 meta_Initialize(CK_VOID_PTR pInitArgs) 128 { 129 CK_RV rv; 130 131 /* Make sure function hasn't been called twice */ 132 (void) pthread_mutex_lock(&initmutex); 133 134 rv = meta_slotManager_initialize(); 135 if (rv != CKR_OK) { 136 (void) pthread_mutex_unlock(&initmutex); 137 return (rv); 138 } 139 140 rv = meta_mechManager_initialize(); 141 if (rv != CKR_OK) { 142 (void) meta_slotManager_finalize(); 143 (void) pthread_mutex_unlock(&initmutex); 144 return (rv); 145 } 146 147 rv = meta_objectManager_initialize(); 148 if (rv != CKR_OK) { 149 (void) meta_slotManager_finalize(); 150 (void) meta_mechManager_finalize(); 151 (void) pthread_mutex_unlock(&initmutex); 152 return (rv); 153 } 154 155 rv = meta_sessionManager_initialize(); 156 if (rv != CKR_OK) { 157 (void) meta_slotManager_finalize(); 158 (void) meta_mechManager_finalize(); 159 (void) meta_objectManager_finalize(); 160 (void) pthread_mutex_unlock(&initmutex); 161 return (rv); 162 } 163 164 meta_slotManager_find_object_token(); 165 166 167 /* Initialize the object_to_be_freed list */ 168 (void) pthread_mutex_init(&obj_delay_freed.obj_to_be_free_mutex, NULL); 169 obj_delay_freed.count = 0; 170 obj_delay_freed.first = NULL; 171 obj_delay_freed.last = NULL; 172 173 /* Initialize the session_to_be_freed list */ 174 (void) pthread_mutex_init(&ses_delay_freed.ses_to_be_free_mutex, NULL); 175 ses_delay_freed.count = 0; 176 ses_delay_freed.first = NULL; 177 ses_delay_freed.last = NULL; 178 179 (void) pthread_mutex_unlock(&initmutex); 180 181 return (CKR_OK); 182 } 183 184 185 /* 186 * meta_Finalize 187 * 188 * Called by uCF only, "pReserved" argument is ignored. 189 */ 190 /*ARGSUSED*/ 191 CK_RV 192 meta_Finalize(CK_VOID_PTR pReserved) 193 { 194 CK_RV rv = CKR_OK; 195 meta_object_t *delay_free_obj, *tmpo; 196 meta_session_t *delay_free_ses, *tmps; 197 198 if (pReserved != NULL) 199 return (CKR_ARGUMENTS_BAD); 200 201 (void) pthread_mutex_lock(&initmutex); 202 203 meta_objectManager_finalize(); 204 205 meta_sessionManager_finalize(); 206 207 meta_mechManager_finalize(); 208 209 meta_slotManager_finalize(); 210 211 /* 212 * free all entries in the delay_freed list 213 */ 214 delay_free_obj = obj_delay_freed.first; 215 while (delay_free_obj != NULL) { 216 tmpo = delay_free_obj->next; 217 free(delay_free_obj); 218 delay_free_obj = tmpo; 219 } 220 (void) pthread_mutex_destroy(&obj_delay_freed.obj_to_be_free_mutex); 221 222 delay_free_ses = ses_delay_freed.first; 223 while (delay_free_ses != NULL) { 224 tmps = delay_free_ses->next; 225 free(delay_free_ses); 226 delay_free_ses = tmps; 227 } 228 (void) pthread_mutex_destroy(&ses_delay_freed.ses_to_be_free_mutex); 229 230 (void) pthread_mutex_unlock(&initmutex); 231 232 return (rv); 233 } 234 235 /* 236 * meta_GetInfo 237 * 238 * NOTE: This function will never be called by applications because it's 239 * hidden behind the uCF C_GetInfo. So, it is not implemented. 240 */ 241 /*ARGSUSED*/ 242 CK_RV 243 meta_GetInfo(CK_INFO_PTR pInfo) 244 { 245 return (CKR_FUNCTION_NOT_SUPPORTED); 246 } 247 248 249 /* 250 * meta_GetFunctionList 251 * 252 * This function is not implemented because metaslot is part of the framework, 253 * so, the framework can just do a static assignment to metaslot's 254 * function list instead of calling this function. 255 */ 256 /*ARGSUSED*/ 257 CK_RV 258 meta_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) 259 { 260 return (CKR_FUNCTION_NOT_SUPPORTED); 261 } 262 263 264 /* 265 * Parallel Function Management Function 266 * (as defined in PKCS#11 spec section 11.16) 267 */ 268 269 /* 270 * This function is no longer supported in this revision of the PKCS#11 271 * standard. It is maintained for backwards compatibility only. 272 */ 273 /* ARGSUSED */ 274 CK_RV 275 meta_GetFunctionStatus(CK_SESSION_HANDLE hSession) 276 { 277 return (CKR_FUNCTION_NOT_PARALLEL); 278 } 279 280 281 /* 282 * This function is no longer supported in this revision of the PKCS#11 283 * standard. It is maintained for backwards compatibility only. 284 */ 285 /* ARGSUSED */ 286 CK_RV 287 meta_CancelFunction(CK_SESSION_HANDLE hSession) 288 { 289 return (CKR_FUNCTION_NOT_PARALLEL); 290 } 291 292 /* 293 * Perform a write that can handle EINTR. 294 */ 295 int 296 looping_write(int fd, void *buf, int len) 297 { 298 char *p = buf; 299 int cc, len2 = 0; 300 301 if (len == 0) 302 return (0); 303 304 do { 305 cc = write(fd, p, len); 306 if (cc < 0) { 307 if (errno == EINTR) 308 continue; 309 return (cc); 310 } else if (cc == 0) { 311 return (len2); 312 } else { 313 p += cc; 314 len2 += cc; 315 len -= cc; 316 } 317 } while (len > 0); 318 return (len2); 319 } 320 321 /* 322 * Perform a read that can handle EINTR. 323 */ 324 int 325 looping_read(int fd, void *buf, int len) 326 { 327 char *p = buf; 328 int cc, len2 = 0; 329 330 do { 331 cc = read(fd, p, len); 332 if (cc < 0) { 333 if (errno == EINTR) 334 continue; 335 return (cc); /* errno is already set */ 336 } else if (cc == 0) { 337 return (len2); 338 } else { 339 p += cc; 340 len2 += cc; 341 len -= cc; 342 } 343 } while (len > 0); 344 return (len2); 345 } 346