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 5034448feSmcpowers * Common Development and Distribution License (the "License"). 6034448feSmcpowers * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*1f49a79aSZdenek Kotala * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <stdio.h> 277c478bd9Sstevel@tonic-gate #include <stdlib.h> 287c478bd9Sstevel@tonic-gate #include <strings.h> 297c478bd9Sstevel@tonic-gate #include <errno.h> 307c478bd9Sstevel@tonic-gate #include <security/cryptoki.h> 317c478bd9Sstevel@tonic-gate #include <cryptoutil.h> 327c478bd9Sstevel@tonic-gate #include "kernelGlobal.h" 337c478bd9Sstevel@tonic-gate #include "kernelObject.h" 347c478bd9Sstevel@tonic-gate #include "kernelSession.h" 357c478bd9Sstevel@tonic-gate #include "kernelSlot.h" 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /* 387c478bd9Sstevel@tonic-gate * Add an object to the session's object list. 397c478bd9Sstevel@tonic-gate * 407c478bd9Sstevel@tonic-gate * This function will acquire the lock on the session, and release 417c478bd9Sstevel@tonic-gate * that lock after adding the object to the session's object list. 427c478bd9Sstevel@tonic-gate */ 437c478bd9Sstevel@tonic-gate void 447c478bd9Sstevel@tonic-gate kernel_add_object_to_session(kernel_object_t *objp, kernel_session_t *sp) 457c478bd9Sstevel@tonic-gate { 467c478bd9Sstevel@tonic-gate /* Acquire the session lock. */ 477c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&sp->session_mutex); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* Insert the new object in front of session's object list. */ 507c478bd9Sstevel@tonic-gate if (sp->object_list == NULL) { 517c478bd9Sstevel@tonic-gate sp->object_list = objp; 527c478bd9Sstevel@tonic-gate objp->next = NULL; 537c478bd9Sstevel@tonic-gate objp->prev = NULL; 547c478bd9Sstevel@tonic-gate } else { 557c478bd9Sstevel@tonic-gate sp->object_list->prev = objp; 567c478bd9Sstevel@tonic-gate objp->next = sp->object_list; 577c478bd9Sstevel@tonic-gate objp->prev = NULL; 587c478bd9Sstevel@tonic-gate sp->object_list = objp; 597c478bd9Sstevel@tonic-gate } 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate /* Release the session lock. */ 627c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&sp->session_mutex); 637c478bd9Sstevel@tonic-gate } 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* 667c478bd9Sstevel@tonic-gate * Clean up and release the storage allocated to the object. 677c478bd9Sstevel@tonic-gate * 687c478bd9Sstevel@tonic-gate * The function is called either with the object lock being held 697c478bd9Sstevel@tonic-gate * (by caller kernel_delete_object()), or there is no object lock 707c478bd9Sstevel@tonic-gate * yet (by kernel_build_XXX_object() during creating an object). 717c478bd9Sstevel@tonic-gate */ 727c478bd9Sstevel@tonic-gate void 737c478bd9Sstevel@tonic-gate kernel_cleanup_object(kernel_object_t *objp) 747c478bd9Sstevel@tonic-gate { 757c478bd9Sstevel@tonic-gate /* 767c478bd9Sstevel@tonic-gate * Free the storage allocated to a secret key object. 777c478bd9Sstevel@tonic-gate */ 78bbbb143bSmcpowers if (objp->class == CKO_SECRET_KEY) { 79034448feSmcpowers if (OBJ_SEC(objp) != NULL && OBJ_SEC_VALUE(objp) != NULL) { 807c478bd9Sstevel@tonic-gate bzero(OBJ_SEC_VALUE(objp), OBJ_SEC_VALUE_LEN(objp)); 817c478bd9Sstevel@tonic-gate free(OBJ_SEC_VALUE(objp)); 827c478bd9Sstevel@tonic-gate OBJ_SEC_VALUE(objp) = NULL; 837c478bd9Sstevel@tonic-gate OBJ_SEC_VALUE_LEN(objp) = 0; 847c478bd9Sstevel@tonic-gate } 857c478bd9Sstevel@tonic-gate free(OBJ_SEC(objp)); 867c478bd9Sstevel@tonic-gate OBJ_SEC(objp) = NULL; 877c478bd9Sstevel@tonic-gate } else { 887c478bd9Sstevel@tonic-gate kernel_cleanup_object_bigint_attrs(objp); 897c478bd9Sstevel@tonic-gate } 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate /* 927c478bd9Sstevel@tonic-gate * Free the storage allocated to the extra attribute list. 937c478bd9Sstevel@tonic-gate */ 947c478bd9Sstevel@tonic-gate kernel_cleanup_extra_attr(objp); 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate /* 987c478bd9Sstevel@tonic-gate * Create a new object. Copy the attributes that can be modified 997c478bd9Sstevel@tonic-gate * (in the boolean attribute mask field and extra attribute list) 1007c478bd9Sstevel@tonic-gate * from the old object to the new object. 1017c478bd9Sstevel@tonic-gate * 1027c478bd9Sstevel@tonic-gate * The caller of this function holds the lock on the old object. 1037c478bd9Sstevel@tonic-gate */ 1047c478bd9Sstevel@tonic-gate CK_RV 1057c478bd9Sstevel@tonic-gate kernel_copy_object(kernel_object_t *old_object, kernel_object_t **new_object, 1067c478bd9Sstevel@tonic-gate boolean_t copy_everything, kernel_session_t *sp) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 1097c478bd9Sstevel@tonic-gate kernel_object_t *new_objp = NULL; 1107c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_INFO_PTR attrp; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate /* Allocate new object. */ 1137c478bd9Sstevel@tonic-gate new_objp = calloc(1, sizeof (kernel_object_t)); 1147c478bd9Sstevel@tonic-gate if (new_objp == NULL) 1157c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate new_objp->class = old_object->class; 1187c478bd9Sstevel@tonic-gate new_objp->bool_attr_mask = old_object->bool_attr_mask; 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate attrp = old_object->extra_attrlistp; 1217c478bd9Sstevel@tonic-gate while (attrp) { 1227c478bd9Sstevel@tonic-gate /* 1237c478bd9Sstevel@tonic-gate * Copy the attribute_info struct from the old 1247c478bd9Sstevel@tonic-gate * object to a new attribute_info struct, and add 1257c478bd9Sstevel@tonic-gate * that new struct to the extra attribute list 1267c478bd9Sstevel@tonic-gate * of the new object. 1277c478bd9Sstevel@tonic-gate */ 1287c478bd9Sstevel@tonic-gate rv = kernel_copy_extra_attr(attrp, new_objp); 1297c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1307c478bd9Sstevel@tonic-gate kernel_cleanup_extra_attr(new_objp); 1317c478bd9Sstevel@tonic-gate free(new_objp); 1327c478bd9Sstevel@tonic-gate return (rv); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate attrp = attrp->next; 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate *new_object = new_objp; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate if (!copy_everything) { 1407c478bd9Sstevel@tonic-gate /* done with copying all information that can be modified */ 1417c478bd9Sstevel@tonic-gate return (CKR_OK); 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate /* 1457c478bd9Sstevel@tonic-gate * Copy the rest of the object. 1467c478bd9Sstevel@tonic-gate * Certain fields that are not appropriate for coping will be 1477c478bd9Sstevel@tonic-gate * initialized. 1487c478bd9Sstevel@tonic-gate */ 1497c478bd9Sstevel@tonic-gate new_objp->key_type = old_object->key_type; 1507c478bd9Sstevel@tonic-gate new_objp->magic_marker = old_object->magic_marker; 1517c478bd9Sstevel@tonic-gate new_objp->mechanism = old_object->mechanism; 1527c478bd9Sstevel@tonic-gate new_objp->session_handle = (CK_SESSION_HANDLE)sp; 1537c478bd9Sstevel@tonic-gate (void) pthread_mutex_init(&(new_objp->object_mutex), NULL); 1547c478bd9Sstevel@tonic-gate /* copy key related information */ 1557c478bd9Sstevel@tonic-gate switch (new_objp->class) { 1567c478bd9Sstevel@tonic-gate case CKO_PUBLIC_KEY: 1577c478bd9Sstevel@tonic-gate rv = kernel_copy_public_key_attr(OBJ_PUB(old_object), 1587c478bd9Sstevel@tonic-gate &(OBJ_PUB(new_objp)), new_objp->key_type); 1597c478bd9Sstevel@tonic-gate break; 1607c478bd9Sstevel@tonic-gate case CKO_PRIVATE_KEY: 1617c478bd9Sstevel@tonic-gate rv = kernel_copy_private_key_attr(OBJ_PRI(old_object), 1627c478bd9Sstevel@tonic-gate &(OBJ_PRI(new_objp)), new_objp->key_type); 1637c478bd9Sstevel@tonic-gate break; 1647c478bd9Sstevel@tonic-gate case CKO_SECRET_KEY: 1657c478bd9Sstevel@tonic-gate rv = kernel_copy_secret_key_attr(OBJ_SEC(old_object), 1667c478bd9Sstevel@tonic-gate &(OBJ_SEC(new_objp))); 1677c478bd9Sstevel@tonic-gate break; 1687c478bd9Sstevel@tonic-gate default: 1697c478bd9Sstevel@tonic-gate /* should never be this case */ 1707c478bd9Sstevel@tonic-gate break; 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * don't need to cleanup the memory from failure of copying 1757c478bd9Sstevel@tonic-gate * any key related stuff. Each individual function for 1767c478bd9Sstevel@tonic-gate * copying key attr will free the memory if it fails 1777c478bd9Sstevel@tonic-gate */ 1787c478bd9Sstevel@tonic-gate kernel_cleanup_extra_attr(new_objp); 1797c478bd9Sstevel@tonic-gate free(new_objp); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate return (rv); 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate /* 1857c478bd9Sstevel@tonic-gate * Copy the attributes (in the boolean attribute mask field and 1867c478bd9Sstevel@tonic-gate * extra attribute list) from the new object back to the original 1877c478bd9Sstevel@tonic-gate * object. Also, clean up and release all the storage in the extra 1887c478bd9Sstevel@tonic-gate * attribute list of the original object. 1897c478bd9Sstevel@tonic-gate * 1907c478bd9Sstevel@tonic-gate * The caller of this function holds the lock on the old object. 1917c478bd9Sstevel@tonic-gate */ 1927c478bd9Sstevel@tonic-gate void 1937c478bd9Sstevel@tonic-gate kernel_merge_object(kernel_object_t *old_object, kernel_object_t *new_object) 1947c478bd9Sstevel@tonic-gate { 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate old_object->bool_attr_mask = new_object->bool_attr_mask; 1977c478bd9Sstevel@tonic-gate kernel_cleanup_extra_attr(old_object); 1987c478bd9Sstevel@tonic-gate old_object->extra_attrlistp = new_object->extra_attrlistp; 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate /* 2037c478bd9Sstevel@tonic-gate * Create a new object struct. If it is a session object, add the object to 2047c478bd9Sstevel@tonic-gate * the session's object list. If it is a token object, add it to the slot's 2057c478bd9Sstevel@tonic-gate * token object list. The caller does not hold the slot lock. 2067c478bd9Sstevel@tonic-gate */ 2077c478bd9Sstevel@tonic-gate CK_RV 2087c478bd9Sstevel@tonic-gate kernel_add_object(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 2097c478bd9Sstevel@tonic-gate CK_ULONG *objecthandle_p, kernel_session_t *sp) 2107c478bd9Sstevel@tonic-gate { 2117c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 2127c478bd9Sstevel@tonic-gate kernel_object_t *new_objp = NULL; 2137c478bd9Sstevel@tonic-gate kernel_slot_t *pslot; 2147c478bd9Sstevel@tonic-gate crypto_object_create_t objc; 2157c478bd9Sstevel@tonic-gate CK_BBOOL is_pri_obj; 2167c478bd9Sstevel@tonic-gate CK_BBOOL is_token_obj = B_FALSE; 2177c478bd9Sstevel@tonic-gate int r; 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate new_objp = calloc(1, sizeof (kernel_object_t)); 2207c478bd9Sstevel@tonic-gate if (new_objp == NULL) { 2217c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 2227c478bd9Sstevel@tonic-gate goto fail_cleanup; 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate new_objp->extra_attrlistp = NULL; 2267c478bd9Sstevel@tonic-gate new_objp->is_lib_obj = B_TRUE; 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate /* 2297c478bd9Sstevel@tonic-gate * If the HW provider supports object creation, create the object 2307c478bd9Sstevel@tonic-gate * in the HW provider by calling the CRYPTO_OBJECT_CREATE ioctl. 2317c478bd9Sstevel@tonic-gate * Otherwise, create the object in the library. 2327c478bd9Sstevel@tonic-gate */ 2337c478bd9Sstevel@tonic-gate pslot = slot_table[sp->ses_slotid]; 2347c478bd9Sstevel@tonic-gate if (pslot->sl_func_list.fl_object_create) { 2357c478bd9Sstevel@tonic-gate new_objp->is_lib_obj = B_FALSE; 2367c478bd9Sstevel@tonic-gate objc.oc_session = sp->k_session; 2377c478bd9Sstevel@tonic-gate objc.oc_count = ulCount; 2387c478bd9Sstevel@tonic-gate rv = process_object_attributes(pTemplate, ulCount, 2397c478bd9Sstevel@tonic-gate &objc.oc_attributes, &is_token_obj); 2407c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2417c478bd9Sstevel@tonic-gate goto fail_cleanup; 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate /* Cannot create a token object with a READ-ONLY session */ 2457c478bd9Sstevel@tonic-gate if (is_token_obj && sp->ses_RO) { 2467c478bd9Sstevel@tonic-gate free_object_attributes(objc.oc_attributes, ulCount); 2477c478bd9Sstevel@tonic-gate rv = CKR_SESSION_READ_ONLY; 2487c478bd9Sstevel@tonic-gate goto fail_cleanup; 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_CREATE, 2527c478bd9Sstevel@tonic-gate &objc)) < 0) { 2537c478bd9Sstevel@tonic-gate if (errno != EINTR) 2547c478bd9Sstevel@tonic-gate break; 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate if (r < 0) { 2577c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 2587c478bd9Sstevel@tonic-gate } else { 2597c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(objc.oc_return_value); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate free_object_attributes(objc.oc_attributes, ulCount); 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2657c478bd9Sstevel@tonic-gate goto fail_cleanup; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* Get the CKA_PRIVATE value of this object. */ 2697c478bd9Sstevel@tonic-gate new_objp->k_handle = objc.oc_handle; 2707c478bd9Sstevel@tonic-gate rv = get_cka_private_value(sp, new_objp->k_handle, 2717c478bd9Sstevel@tonic-gate &is_pri_obj); 2727c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2737c478bd9Sstevel@tonic-gate goto fail_cleanup; 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate /* Set the PRIVATE_BOOL_ON and TOKEN_BOOL_ON attributes */ 2777c478bd9Sstevel@tonic-gate if (is_pri_obj) 2787c478bd9Sstevel@tonic-gate new_objp->bool_attr_mask |= PRIVATE_BOOL_ON; 2797c478bd9Sstevel@tonic-gate else 2807c478bd9Sstevel@tonic-gate new_objp->bool_attr_mask &= ~PRIVATE_BOOL_ON; 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate if (is_token_obj) 2837c478bd9Sstevel@tonic-gate new_objp->bool_attr_mask |= TOKEN_BOOL_ON; 2847c478bd9Sstevel@tonic-gate else 2857c478bd9Sstevel@tonic-gate new_objp->bool_attr_mask &= ~TOKEN_BOOL_ON; 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate } else { 2887c478bd9Sstevel@tonic-gate /* 2897c478bd9Sstevel@tonic-gate * Create the object in the library. 2907c478bd9Sstevel@tonic-gate * Validate attribute template and fill in the attributes 2917c478bd9Sstevel@tonic-gate * in the kernel_object_t. 2927c478bd9Sstevel@tonic-gate */ 293034448feSmcpowers rv = kernel_build_object(pTemplate, ulCount, new_objp, sp, 294034448feSmcpowers KERNEL_CREATE_OBJ); 2957c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2967c478bd9Sstevel@tonic-gate goto fail_cleanup; 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate /* Initialize the rest of stuffs in kernel_object_t. */ 3017c478bd9Sstevel@tonic-gate (void) pthread_mutex_init(&new_objp->object_mutex, NULL); 3027c478bd9Sstevel@tonic-gate new_objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC; 3037c478bd9Sstevel@tonic-gate new_objp->session_handle = (CK_SESSION_HANDLE)sp; 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate if (is_token_obj) { 3067c478bd9Sstevel@tonic-gate /* Add the new object to the slot's token object list. */ 3077c478bd9Sstevel@tonic-gate pslot = slot_table[sp->ses_slotid]; 3087c478bd9Sstevel@tonic-gate kernel_add_token_object_to_slot(new_objp, pslot); 3097c478bd9Sstevel@tonic-gate } else { 3107c478bd9Sstevel@tonic-gate /* Add the new object to the session's object list. */ 3117c478bd9Sstevel@tonic-gate kernel_add_object_to_session(new_objp, sp); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* Type casting the address of an object struct to an object handle. */ 3157c478bd9Sstevel@tonic-gate *objecthandle_p = (CK_ULONG)new_objp; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate return (CKR_OK); 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate fail_cleanup: 3207c478bd9Sstevel@tonic-gate if (new_objp) { 3217c478bd9Sstevel@tonic-gate /* 3227c478bd9Sstevel@tonic-gate * If the object is created in the HW provider, the storage 3237c478bd9Sstevel@tonic-gate * allocated for the ioctl call is always cleaned up after 3247c478bd9Sstevel@tonic-gate * the call. If the object is created in the library, 3257c478bd9Sstevel@tonic-gate * the storage allocated inside of this object should 3267c478bd9Sstevel@tonic-gate * have been cleaned up in the kernel_build_object() 3277c478bd9Sstevel@tonic-gate * after an error occurred. Therefore, we can safely 3287c478bd9Sstevel@tonic-gate * free the object. 3297c478bd9Sstevel@tonic-gate */ 3307c478bd9Sstevel@tonic-gate free(new_objp); 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate return (rv); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate /* 3377c478bd9Sstevel@tonic-gate * Remove an object from the session's object list. 3387c478bd9Sstevel@tonic-gate * 3397c478bd9Sstevel@tonic-gate * The caller of this function holds the session lock. 3407c478bd9Sstevel@tonic-gate */ 34101223cbaSmcpowers CK_RV 3427c478bd9Sstevel@tonic-gate kernel_remove_object_from_session(kernel_object_t *objp, kernel_session_t *sp) 3437c478bd9Sstevel@tonic-gate { 34401223cbaSmcpowers kernel_object_t *tmp_objp; 34501223cbaSmcpowers boolean_t found = B_FALSE; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate /* 3487c478bd9Sstevel@tonic-gate * Remove the object from the session's object list. 3497c478bd9Sstevel@tonic-gate */ 35001223cbaSmcpowers if ((sp == NULL) || 35101223cbaSmcpowers (sp->magic_marker != KERNELTOKEN_SESSION_MAGIC)) { 35201223cbaSmcpowers return (CKR_SESSION_HANDLE_INVALID); 35301223cbaSmcpowers } 35401223cbaSmcpowers 35501223cbaSmcpowers if ((sp->object_list == NULL) || (objp == NULL) || 35601223cbaSmcpowers (objp->magic_marker != KERNELTOKEN_OBJECT_MAGIC)) { 35701223cbaSmcpowers return (CKR_OBJECT_HANDLE_INVALID); 35801223cbaSmcpowers } 35901223cbaSmcpowers 36001223cbaSmcpowers tmp_objp = sp->object_list; 36101223cbaSmcpowers while (tmp_objp) { 36201223cbaSmcpowers if (tmp_objp == objp) { 36301223cbaSmcpowers found = B_TRUE; 36401223cbaSmcpowers break; 36501223cbaSmcpowers } 36601223cbaSmcpowers tmp_objp = tmp_objp->next; 36701223cbaSmcpowers } 36801223cbaSmcpowers if (!found) 36901223cbaSmcpowers return (CKR_OBJECT_HANDLE_INVALID); 37001223cbaSmcpowers 3717c478bd9Sstevel@tonic-gate if (sp->object_list == objp) { 3727c478bd9Sstevel@tonic-gate /* Object is the first one in the list. */ 3737c478bd9Sstevel@tonic-gate if (objp->next) { 3747c478bd9Sstevel@tonic-gate sp->object_list = objp->next; 3757c478bd9Sstevel@tonic-gate objp->next->prev = NULL; 3767c478bd9Sstevel@tonic-gate } else { 3777c478bd9Sstevel@tonic-gate /* Object is the only one in the list. */ 3787c478bd9Sstevel@tonic-gate sp->object_list = NULL; 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate } else { 3817c478bd9Sstevel@tonic-gate /* Object is not the first one in the list. */ 3827c478bd9Sstevel@tonic-gate if (objp->next) { 3837c478bd9Sstevel@tonic-gate /* Object is in the middle of the list. */ 3847c478bd9Sstevel@tonic-gate objp->prev->next = objp->next; 3857c478bd9Sstevel@tonic-gate objp->next->prev = objp->prev; 3867c478bd9Sstevel@tonic-gate } else { 3877c478bd9Sstevel@tonic-gate /* Object is the last one in the list. */ 3887c478bd9Sstevel@tonic-gate objp->prev->next = NULL; 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate } 39101223cbaSmcpowers return (CKR_OK); 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate 39401223cbaSmcpowers static void 395*1f49a79aSZdenek Kotala kernel_delete_object_cleanup(kernel_object_t *objp, boolean_t wrapper_only) 39601223cbaSmcpowers { 39701223cbaSmcpowers /* Acquire the lock on the object. */ 39801223cbaSmcpowers (void) pthread_mutex_lock(&objp->object_mutex); 39901223cbaSmcpowers 40001223cbaSmcpowers /* 40101223cbaSmcpowers * Make sure another thread hasn't freed the object. 40201223cbaSmcpowers */ 40301223cbaSmcpowers if (objp->magic_marker != KERNELTOKEN_OBJECT_MAGIC) { 40401223cbaSmcpowers (void) pthread_mutex_unlock(&objp->object_mutex); 40501223cbaSmcpowers return; 40601223cbaSmcpowers } 40701223cbaSmcpowers 40801223cbaSmcpowers /* 40901223cbaSmcpowers * The deletion of an object must be blocked when the object 41001223cbaSmcpowers * reference count is not zero. This means if any object related 41101223cbaSmcpowers * operation starts prior to the delete object operation gets in, 41201223cbaSmcpowers * the object deleting thread must wait for the non-deleting 41301223cbaSmcpowers * operation to be completed before it can proceed the delete 41401223cbaSmcpowers * operation. 415*1f49a79aSZdenek Kotala * 416*1f49a79aSZdenek Kotala * Unless we are being forced to shut everything down, this only 417*1f49a79aSZdenek Kotala * happens if the library's _fini() is running not if someone 418*1f49a79aSZdenek Kotala * explicitly called C_Finalize(). 41901223cbaSmcpowers */ 420*1f49a79aSZdenek Kotala if (wrapper_only) { 421*1f49a79aSZdenek Kotala objp->obj_refcnt = 0; 422*1f49a79aSZdenek Kotala } 423*1f49a79aSZdenek Kotala 42401223cbaSmcpowers while (objp->obj_refcnt != 0) { 42501223cbaSmcpowers /* 42601223cbaSmcpowers * We set the OBJECT_REFCNT_WAITING flag before we put 42701223cbaSmcpowers * this deleting thread in a wait state, so other non-deleting 42801223cbaSmcpowers * operation thread will signal to wake it up only when 42901223cbaSmcpowers * the object reference count becomes zero and this flag 43001223cbaSmcpowers * is set. 43101223cbaSmcpowers */ 43201223cbaSmcpowers objp->obj_delete_sync |= OBJECT_REFCNT_WAITING; 43301223cbaSmcpowers (void) pthread_cond_wait(&objp->obj_free_cond, 43401223cbaSmcpowers &objp->object_mutex); 43501223cbaSmcpowers } 43601223cbaSmcpowers 43701223cbaSmcpowers objp->obj_delete_sync &= ~OBJECT_REFCNT_WAITING; 43801223cbaSmcpowers 43901223cbaSmcpowers /* Mark object as no longer valid. */ 44001223cbaSmcpowers objp->magic_marker = 0; 44101223cbaSmcpowers 44201223cbaSmcpowers (void) pthread_cond_destroy(&objp->obj_free_cond); 44301223cbaSmcpowers } 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate /* 4467c478bd9Sstevel@tonic-gate * Delete a session object: 4477c478bd9Sstevel@tonic-gate * - Remove the object from the session's object list. 4487c478bd9Sstevel@tonic-gate * - Release the storage allocated to the object. 4497c478bd9Sstevel@tonic-gate * 4507c478bd9Sstevel@tonic-gate * The boolean argument ses_lock_held is used to indicate that whether 4517c478bd9Sstevel@tonic-gate * the caller holds the session lock or not. 4527c478bd9Sstevel@tonic-gate * - When called by kernel_delete_all_objects_in_session() or 4537c478bd9Sstevel@tonic-gate * kernel_delete_pri_objects_in_slot() -- ses_lock_held = TRUE. 4547c478bd9Sstevel@tonic-gate * 4557c478bd9Sstevel@tonic-gate * The boolean argument wrapper_only is used to indicate that whether 4567c478bd9Sstevel@tonic-gate * the caller only wants to clean up the object wrapper from the library and 4577c478bd9Sstevel@tonic-gate * needs not to make an ioctl call. 4587c478bd9Sstevel@tonic-gate * - This argument only applies to the object created in the provider level. 4597c478bd9Sstevel@tonic-gate * - When called by kernel_cleanup_pri_objects_in_slot(), wrapper_only is TRUE. 4607c478bd9Sstevel@tonic-gate * - When called by C_DestroyObject(), wrapper_only is FALSE. 4617c478bd9Sstevel@tonic-gate * - When called by kernel_delete_all_objects_in_session(), the value of 4627c478bd9Sstevel@tonic-gate * wrapper_only depends on its caller. 4637c478bd9Sstevel@tonic-gate */ 4647c478bd9Sstevel@tonic-gate CK_RV 4657c478bd9Sstevel@tonic-gate kernel_delete_session_object(kernel_session_t *sp, kernel_object_t *objp, 4667c478bd9Sstevel@tonic-gate boolean_t ses_lock_held, boolean_t wrapper_only) 4677c478bd9Sstevel@tonic-gate { 4687c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 4697c478bd9Sstevel@tonic-gate crypto_object_destroy_t obj_destroy; 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate /* 4727c478bd9Sstevel@tonic-gate * Check to see if the caller holds the lock on the session. 4737c478bd9Sstevel@tonic-gate * If not, we need to acquire that lock in order to proceed. 4747c478bd9Sstevel@tonic-gate */ 4757c478bd9Sstevel@tonic-gate if (!ses_lock_held) { 4767c478bd9Sstevel@tonic-gate /* Acquire the session lock. */ 4777c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&sp->session_mutex); 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate /* Remove the object from the session's object list first. */ 48101223cbaSmcpowers rv = kernel_remove_object_from_session(objp, sp); 4827c478bd9Sstevel@tonic-gate if (!ses_lock_held) { 4837c478bd9Sstevel@tonic-gate /* 4847c478bd9Sstevel@tonic-gate * If the session lock is obtained by this function, 4857c478bd9Sstevel@tonic-gate * then release that lock after removing the object 4867c478bd9Sstevel@tonic-gate * from session's object list. 4877c478bd9Sstevel@tonic-gate * We want the releasing of the object storage to 4887c478bd9Sstevel@tonic-gate * be done without holding the session lock. 4897c478bd9Sstevel@tonic-gate */ 4907c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&sp->session_mutex); 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate 49301223cbaSmcpowers if (rv != CKR_OK) 49401223cbaSmcpowers return (rv); 4957c478bd9Sstevel@tonic-gate 496*1f49a79aSZdenek Kotala kernel_delete_object_cleanup(objp, wrapper_only); 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate /* Destroy the object. */ 4997c478bd9Sstevel@tonic-gate if (objp->is_lib_obj) { 5007c478bd9Sstevel@tonic-gate /* 5017c478bd9Sstevel@tonic-gate * If this object is created in the library, cleanup the 5027c478bd9Sstevel@tonic-gate * contents of this object such as free all the storage 5037c478bd9Sstevel@tonic-gate * allocated for this object. 5047c478bd9Sstevel@tonic-gate */ 5057c478bd9Sstevel@tonic-gate kernel_cleanup_object(objp); 5067c478bd9Sstevel@tonic-gate } else { 5077c478bd9Sstevel@tonic-gate /* 5087c478bd9Sstevel@tonic-gate * This object is created in the HW provider. If wrapper_only 5097c478bd9Sstevel@tonic-gate * is FALSE, make an ioctl call to destroy it in kernel. 5107c478bd9Sstevel@tonic-gate */ 5117c478bd9Sstevel@tonic-gate if (!wrapper_only) { 5127c478bd9Sstevel@tonic-gate obj_destroy.od_session = sp->k_session; 5137c478bd9Sstevel@tonic-gate obj_destroy.od_handle = objp->k_handle; 5147c478bd9Sstevel@tonic-gate 51501223cbaSmcpowers while (ioctl(kernel_fd, CRYPTO_OBJECT_DESTROY, 51601223cbaSmcpowers &obj_destroy) < 0) { 5177c478bd9Sstevel@tonic-gate if (errno != EINTR) 5187c478bd9Sstevel@tonic-gate break; 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate /* 5227c478bd9Sstevel@tonic-gate * Ignore ioctl return codes for a session object. 5237c478bd9Sstevel@tonic-gate * If the kernel can not delete a session object, it 5247c478bd9Sstevel@tonic-gate * is likely caused by the HW provider. There's not 5257c478bd9Sstevel@tonic-gate * much that can be done. The library will still 5267c478bd9Sstevel@tonic-gate * cleanup the object wrapper in the library. The HW 5277c478bd9Sstevel@tonic-gate * provider will destroy all session objects when 5287c478bd9Sstevel@tonic-gate * the application exits. 5297c478bd9Sstevel@tonic-gate */ 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 53301223cbaSmcpowers /* Reset OBJECT_IS_DELETING flag. */ 53401223cbaSmcpowers objp->obj_delete_sync &= ~OBJECT_IS_DELETING; 53501223cbaSmcpowers 5367c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&objp->object_mutex); 5377c478bd9Sstevel@tonic-gate /* Destroy the object lock */ 5387c478bd9Sstevel@tonic-gate (void) pthread_mutex_destroy(&objp->object_mutex); 5397c478bd9Sstevel@tonic-gate /* Free the object itself */ 54001223cbaSmcpowers kernel_object_delay_free(objp); 5417c478bd9Sstevel@tonic-gate 54201223cbaSmcpowers return (CKR_OK); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate /* 5467c478bd9Sstevel@tonic-gate * Delete all the objects in a session. The caller holds the lock 5477c478bd9Sstevel@tonic-gate * on the session. If the wrapper_only argument is TRUE, the caller only 5487c478bd9Sstevel@tonic-gate * want to clean up object wrappers in the library. 5497c478bd9Sstevel@tonic-gate */ 5507c478bd9Sstevel@tonic-gate void 5517c478bd9Sstevel@tonic-gate kernel_delete_all_objects_in_session(kernel_session_t *sp, 5527c478bd9Sstevel@tonic-gate boolean_t wrapper_only) 5537c478bd9Sstevel@tonic-gate { 5547c478bd9Sstevel@tonic-gate kernel_object_t *objp = sp->object_list; 5557c478bd9Sstevel@tonic-gate kernel_object_t *objp1; 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate /* Delete all the objects in the session. */ 5587c478bd9Sstevel@tonic-gate while (objp) { 5597c478bd9Sstevel@tonic-gate objp1 = objp->next; 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate /* 5627c478bd9Sstevel@tonic-gate * Delete an session object by calling 5637c478bd9Sstevel@tonic-gate * kernel_delete_session_object(): 5647c478bd9Sstevel@tonic-gate * - The 3rd TRUE boolean argument indicates that the caller 5657c478bd9Sstevel@tonic-gate * holds the session lock. 5667c478bd9Sstevel@tonic-gate * - The 4th boolean argument indicates whether we only want 5677c478bd9Sstevel@tonic-gate * clean up object wrappers in the library. 5687c478bd9Sstevel@tonic-gate */ 5697c478bd9Sstevel@tonic-gate (void) kernel_delete_session_object(sp, objp, B_TRUE, 5707c478bd9Sstevel@tonic-gate wrapper_only); 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate objp = objp1; 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate static CK_RV 5777c478bd9Sstevel@tonic-gate add_to_search_result(kernel_object_t *obj, find_context_t *fcontext, 5787c478bd9Sstevel@tonic-gate CK_ULONG *num_result_alloc) 5797c478bd9Sstevel@tonic-gate { 5807c478bd9Sstevel@tonic-gate /* 5817c478bd9Sstevel@tonic-gate * allocate space for storing results if the currently 5827c478bd9Sstevel@tonic-gate * allocated space is not enough 5837c478bd9Sstevel@tonic-gate */ 5847c478bd9Sstevel@tonic-gate if (*num_result_alloc <= fcontext->num_results) { 5857c478bd9Sstevel@tonic-gate fcontext->objs_found = realloc(fcontext->objs_found, 5867c478bd9Sstevel@tonic-gate sizeof (kernel_object_t *) * (*num_result_alloc + BUFSIZ)); 5877c478bd9Sstevel@tonic-gate if (fcontext->objs_found == NULL) { 5887c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate *num_result_alloc += BUFSIZ; 5917c478bd9Sstevel@tonic-gate } 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate (fcontext->objs_found)[(fcontext->num_results)++] = obj; 5947c478bd9Sstevel@tonic-gate return (CKR_OK); 5957c478bd9Sstevel@tonic-gate } 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate static CK_RV 5987c478bd9Sstevel@tonic-gate search_for_objects(kernel_session_t *sp, CK_ATTRIBUTE_PTR pTemplate, 5997c478bd9Sstevel@tonic-gate CK_ULONG ulCount, find_context_t *fcontext) 6007c478bd9Sstevel@tonic-gate { 6017c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 6027c478bd9Sstevel@tonic-gate kernel_object_t *obj; 603c2e31228SViswanathan Kannappan CK_OBJECT_CLASS pclasses[6]; /* classes attrs possibly exist */ 6047c478bd9Sstevel@tonic-gate CK_ULONG num_pclasses; /* number of possible classes */ 6057c478bd9Sstevel@tonic-gate CK_ULONG num_result_alloc = 0; /* spaces allocated for results */ 6067c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 6077c478bd9Sstevel@tonic-gate kernel_slot_t *pslot; 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate if (ulCount > 0) { 6107c478bd9Sstevel@tonic-gate /* there are some search requirement */ 6117c478bd9Sstevel@tonic-gate kernel_process_find_attr(pclasses, &num_pclasses, 6127c478bd9Sstevel@tonic-gate pTemplate, ulCount); 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate /* Acquire the slot lock */ 6167c478bd9Sstevel@tonic-gate pslot = slot_table[sp->ses_slotid]; 6177c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&pslot->sl_mutex); 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate /* 6207c478bd9Sstevel@tonic-gate * Go through all objects in each session. 6217c478bd9Sstevel@tonic-gate * Acquire individual session lock for the session 6227c478bd9Sstevel@tonic-gate * we are searching. 6237c478bd9Sstevel@tonic-gate */ 6247c478bd9Sstevel@tonic-gate session_p = pslot->sl_sess_list; 6257c478bd9Sstevel@tonic-gate while (session_p) { 6267c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 6277c478bd9Sstevel@tonic-gate obj = session_p->object_list; 6287c478bd9Sstevel@tonic-gate while (obj) { 6297c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&obj->object_mutex); 6307c478bd9Sstevel@tonic-gate if (ulCount > 0) { 6317c478bd9Sstevel@tonic-gate if (kernel_find_match_attrs(obj, pclasses, 6327c478bd9Sstevel@tonic-gate num_pclasses, pTemplate, ulCount)) { 6337c478bd9Sstevel@tonic-gate rv = add_to_search_result( 6347c478bd9Sstevel@tonic-gate obj, fcontext, &num_result_alloc); 6357c478bd9Sstevel@tonic-gate } 6367c478bd9Sstevel@tonic-gate } else { 6377c478bd9Sstevel@tonic-gate /* no search criteria, just record the object */ 6387c478bd9Sstevel@tonic-gate rv = add_to_search_result(obj, fcontext, 6397c478bd9Sstevel@tonic-gate &num_result_alloc); 6407c478bd9Sstevel@tonic-gate } 6417c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&obj->object_mutex); 6427c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 6437c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock( 6447c478bd9Sstevel@tonic-gate &session_p->session_mutex); 6457c478bd9Sstevel@tonic-gate goto cleanup; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate obj = obj->next; 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 6507c478bd9Sstevel@tonic-gate session_p = session_p->next; 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate 6537c478bd9Sstevel@tonic-gate cleanup: 6547c478bd9Sstevel@tonic-gate /* Release the slot lock */ 6557c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&pslot->sl_mutex); 6567c478bd9Sstevel@tonic-gate return (rv); 6577c478bd9Sstevel@tonic-gate } 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate /* 6607c478bd9Sstevel@tonic-gate * Initialize the context for C_FindObjects() calls 6617c478bd9Sstevel@tonic-gate */ 6627c478bd9Sstevel@tonic-gate CK_RV 6637c478bd9Sstevel@tonic-gate kernel_find_objects_init(kernel_session_t *sp, CK_ATTRIBUTE_PTR pTemplate, 6647c478bd9Sstevel@tonic-gate CK_ULONG ulCount) 6657c478bd9Sstevel@tonic-gate { 6667c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 6677c478bd9Sstevel@tonic-gate CK_OBJECT_CLASS class; /* for kernel_validate_attr(). Value unused */ 6687c478bd9Sstevel@tonic-gate find_context_t *fcontext; 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate if (ulCount) { 6717c478bd9Sstevel@tonic-gate rv = kernel_validate_attr(pTemplate, ulCount, &class); 6727c478bd9Sstevel@tonic-gate /* Make sure all attributes in template are valid */ 6737c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 6747c478bd9Sstevel@tonic-gate return (rv); 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate /* prepare the find context */ 6797c478bd9Sstevel@tonic-gate fcontext = calloc(1, sizeof (find_context_t)); 6807c478bd9Sstevel@tonic-gate if (fcontext == NULL) { 6817c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 6827c478bd9Sstevel@tonic-gate } 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate rv = search_for_objects(sp, pTemplate, ulCount, fcontext); 6857c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 6867c478bd9Sstevel@tonic-gate free(fcontext); 6877c478bd9Sstevel@tonic-gate return (rv); 6887c478bd9Sstevel@tonic-gate } 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate /* store the find_context in the session */ 6917c478bd9Sstevel@tonic-gate sp->find_objects.context = (CK_VOID_PTR)fcontext; 6927c478bd9Sstevel@tonic-gate 6937c478bd9Sstevel@tonic-gate return (rv); 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate void 6977c478bd9Sstevel@tonic-gate kernel_find_objects_final(kernel_session_t *sp) 6987c478bd9Sstevel@tonic-gate { 6997c478bd9Sstevel@tonic-gate find_context_t *fcontext; 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate fcontext = sp->find_objects.context; 7027c478bd9Sstevel@tonic-gate sp->find_objects.context = NULL; 7037c478bd9Sstevel@tonic-gate sp->find_objects.flags = 0; 7047c478bd9Sstevel@tonic-gate if (fcontext->objs_found != NULL) { 7057c478bd9Sstevel@tonic-gate free(fcontext->objs_found); 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate free(fcontext); 7097c478bd9Sstevel@tonic-gate } 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate void 7127c478bd9Sstevel@tonic-gate kernel_find_objects(kernel_session_t *sp, CK_OBJECT_HANDLE *obj_found, 7137c478bd9Sstevel@tonic-gate CK_ULONG max_obj_requested, CK_ULONG *found_obj_count) 7147c478bd9Sstevel@tonic-gate { 7157c478bd9Sstevel@tonic-gate find_context_t *fcontext; 7167c478bd9Sstevel@tonic-gate CK_ULONG num_obj_found = 0; 7177c478bd9Sstevel@tonic-gate CK_ULONG i; 7187c478bd9Sstevel@tonic-gate kernel_object_t *obj; 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate fcontext = sp->find_objects.context; 7217c478bd9Sstevel@tonic-gate 7227c478bd9Sstevel@tonic-gate for (i = fcontext->next_result_index; 7237c478bd9Sstevel@tonic-gate ((num_obj_found < max_obj_requested) && 7247c478bd9Sstevel@tonic-gate (i < fcontext->num_results)); 7257c478bd9Sstevel@tonic-gate i++) { 7267c478bd9Sstevel@tonic-gate obj = fcontext->objs_found[i]; 7277c478bd9Sstevel@tonic-gate if (obj != NULL) { 7287c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&obj->object_mutex); 7297c478bd9Sstevel@tonic-gate /* a sanity check to make sure the obj is still valid */ 7307c478bd9Sstevel@tonic-gate if (obj->magic_marker == KERNELTOKEN_OBJECT_MAGIC) { 7317c478bd9Sstevel@tonic-gate obj_found[num_obj_found] = 7327c478bd9Sstevel@tonic-gate (CK_OBJECT_HANDLE)obj; 7337c478bd9Sstevel@tonic-gate num_obj_found++; 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&obj->object_mutex); 7367c478bd9Sstevel@tonic-gate } 7377c478bd9Sstevel@tonic-gate } 7387c478bd9Sstevel@tonic-gate fcontext->next_result_index = i; 7397c478bd9Sstevel@tonic-gate *found_obj_count = num_obj_found; 7407c478bd9Sstevel@tonic-gate } 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate /* 7437c478bd9Sstevel@tonic-gate * Add an token object to the token object list in slot. 7447c478bd9Sstevel@tonic-gate * 7457c478bd9Sstevel@tonic-gate * This function will acquire the lock on the slot, and release 7467c478bd9Sstevel@tonic-gate * that lock after adding the object to the slot's token object list. 7477c478bd9Sstevel@tonic-gate */ 7487c478bd9Sstevel@tonic-gate void 7497c478bd9Sstevel@tonic-gate kernel_add_token_object_to_slot(kernel_object_t *objp, kernel_slot_t *pslot) 7507c478bd9Sstevel@tonic-gate { 7517c478bd9Sstevel@tonic-gate /* Acquire the slot lock. */ 7527c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&pslot->sl_mutex); 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate /* Insert the new object in front of slot's token object list. */ 7557c478bd9Sstevel@tonic-gate if (pslot->sl_tobj_list == NULL) { 7567c478bd9Sstevel@tonic-gate pslot->sl_tobj_list = objp; 7577c478bd9Sstevel@tonic-gate objp->next = NULL; 7587c478bd9Sstevel@tonic-gate objp->prev = NULL; 7597c478bd9Sstevel@tonic-gate } else { 7607c478bd9Sstevel@tonic-gate pslot->sl_tobj_list->prev = objp; 7617c478bd9Sstevel@tonic-gate objp->next = pslot->sl_tobj_list; 7627c478bd9Sstevel@tonic-gate objp->prev = NULL; 7637c478bd9Sstevel@tonic-gate pslot->sl_tobj_list = objp; 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate /* Release the slot lock. */ 7677c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&pslot->sl_mutex); 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate 7707c478bd9Sstevel@tonic-gate /* 7717c478bd9Sstevel@tonic-gate * Remove an token object from the slot's token object list. 7727c478bd9Sstevel@tonic-gate * This routine is called by kernel_delete_token_object(). 7737c478bd9Sstevel@tonic-gate * The caller of this function hold the slot lock. 7747c478bd9Sstevel@tonic-gate */ 7757c478bd9Sstevel@tonic-gate void 7767c478bd9Sstevel@tonic-gate kernel_remove_token_object_from_slot(kernel_slot_t *pslot, 7777c478bd9Sstevel@tonic-gate kernel_object_t *objp) 7787c478bd9Sstevel@tonic-gate { 7797c478bd9Sstevel@tonic-gate 7807c478bd9Sstevel@tonic-gate if (pslot->sl_tobj_list == objp) { 7817c478bd9Sstevel@tonic-gate /* Object is the first one in the list */ 7827c478bd9Sstevel@tonic-gate if (objp->next) { 7837c478bd9Sstevel@tonic-gate pslot->sl_tobj_list = objp->next; 7847c478bd9Sstevel@tonic-gate objp->next->prev = NULL; 7857c478bd9Sstevel@tonic-gate } else { 7867c478bd9Sstevel@tonic-gate /* Object is the only one in the list. */ 7877c478bd9Sstevel@tonic-gate pslot->sl_tobj_list = NULL; 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate } else { 7907c478bd9Sstevel@tonic-gate /* Object is not the first one in the list. */ 7917c478bd9Sstevel@tonic-gate if (objp->next) { 7927c478bd9Sstevel@tonic-gate /* Object is in the middle of the list. */ 7937c478bd9Sstevel@tonic-gate objp->prev->next = objp->next; 7947c478bd9Sstevel@tonic-gate objp->next->prev = objp->prev; 7957c478bd9Sstevel@tonic-gate } else { 7967c478bd9Sstevel@tonic-gate /* Object is the last one in the list. */ 7977c478bd9Sstevel@tonic-gate objp->prev->next = NULL; 7987c478bd9Sstevel@tonic-gate } 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate } 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate /* 8037c478bd9Sstevel@tonic-gate * Delete a token object: 8047c478bd9Sstevel@tonic-gate * - Remove the object from the slot's token object list. 8057c478bd9Sstevel@tonic-gate * - Release the storage allocated to the object. 8067c478bd9Sstevel@tonic-gate * 8077c478bd9Sstevel@tonic-gate * The boolean argument slot_lock_held is used to indicate that whether 8087c478bd9Sstevel@tonic-gate * the caller holds the slot lock or not. When the caller does not hold 8097c478bd9Sstevel@tonic-gate * the slot lock, this function will acquire that lock in order to proceed, 8107c478bd9Sstevel@tonic-gate * and also release that lock before returning to caller. 8117c478bd9Sstevel@tonic-gate * 8127c478bd9Sstevel@tonic-gate * The boolean argument wrapper_only is used to indicate that whether 8137c478bd9Sstevel@tonic-gate * the caller only wants to the object wrapper from library. 8147c478bd9Sstevel@tonic-gate */ 8157c478bd9Sstevel@tonic-gate CK_RV 8167c478bd9Sstevel@tonic-gate kernel_delete_token_object(kernel_slot_t *pslot, kernel_session_t *sp, 8177c478bd9Sstevel@tonic-gate kernel_object_t *objp, boolean_t slot_lock_held, boolean_t wrapper_only) 8187c478bd9Sstevel@tonic-gate { 8197c478bd9Sstevel@tonic-gate CK_RV rv; 8207c478bd9Sstevel@tonic-gate crypto_object_destroy_t obj_destroy; 8217c478bd9Sstevel@tonic-gate int r; 8227c478bd9Sstevel@tonic-gate 8237c478bd9Sstevel@tonic-gate /* 8247c478bd9Sstevel@tonic-gate * Check to see if the caller holds the lock on the slot. 8257c478bd9Sstevel@tonic-gate * If not, we need to acquire that lock in order to proceed. 8267c478bd9Sstevel@tonic-gate */ 8277c478bd9Sstevel@tonic-gate if (!slot_lock_held) { 8287c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&pslot->sl_mutex); 8297c478bd9Sstevel@tonic-gate } 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate /* Remove the object from the slot's token object list first. */ 8327c478bd9Sstevel@tonic-gate kernel_remove_token_object_from_slot(pslot, objp); 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate /* Release the slot lock if the call doesn't hold the lock. */ 8357c478bd9Sstevel@tonic-gate if (!slot_lock_held) { 8367c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&pslot->sl_mutex); 8377c478bd9Sstevel@tonic-gate } 8387c478bd9Sstevel@tonic-gate 839*1f49a79aSZdenek Kotala kernel_delete_object_cleanup(objp, wrapper_only); 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate if (!wrapper_only) { 8427c478bd9Sstevel@tonic-gate obj_destroy.od_session = sp->k_session; 8437c478bd9Sstevel@tonic-gate obj_destroy.od_handle = objp->k_handle; 8447c478bd9Sstevel@tonic-gate 8457c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_DESTROY, 8467c478bd9Sstevel@tonic-gate &obj_destroy)) < 0) { 8477c478bd9Sstevel@tonic-gate if (errno != EINTR) 8487c478bd9Sstevel@tonic-gate break; 8497c478bd9Sstevel@tonic-gate } 8507c478bd9Sstevel@tonic-gate if (r < 0) { 8517c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 8527c478bd9Sstevel@tonic-gate } else { 8537c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number( 8547c478bd9Sstevel@tonic-gate obj_destroy.od_return_value); 8557c478bd9Sstevel@tonic-gate } 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate /* 8587c478bd9Sstevel@tonic-gate * Could not destroy an object from kernel. Write a warning 8597c478bd9Sstevel@tonic-gate * in syslog, but we still clean up the object wrapper in 8607c478bd9Sstevel@tonic-gate * the library. 8617c478bd9Sstevel@tonic-gate */ 8627c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 8637c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "pkcs11_kernel: Could not " 8647c478bd9Sstevel@tonic-gate "destroy an object in kernel."); 8657c478bd9Sstevel@tonic-gate } 8667c478bd9Sstevel@tonic-gate } 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&objp->object_mutex); 8697c478bd9Sstevel@tonic-gate /* Destroy the object lock */ 8707c478bd9Sstevel@tonic-gate (void) pthread_mutex_destroy(&objp->object_mutex); 8717c478bd9Sstevel@tonic-gate /* Free the object itself */ 87201223cbaSmcpowers kernel_object_delay_free(objp); 8737c478bd9Sstevel@tonic-gate 87401223cbaSmcpowers return (CKR_OK); 8757c478bd9Sstevel@tonic-gate } 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate /* 8787c478bd9Sstevel@tonic-gate * Clean up private object wrappers in this slot. The caller holds the slot 8797c478bd9Sstevel@tonic-gate * lock. 8807c478bd9Sstevel@tonic-gate */ 8817c478bd9Sstevel@tonic-gate void 8827c478bd9Sstevel@tonic-gate kernel_cleanup_pri_objects_in_slot(kernel_slot_t *pslot, 8837c478bd9Sstevel@tonic-gate kernel_session_t *cur_sp) 8847c478bd9Sstevel@tonic-gate { 8857c478bd9Sstevel@tonic-gate kernel_session_t *session_p; 8867c478bd9Sstevel@tonic-gate kernel_object_t *objp; 8877c478bd9Sstevel@tonic-gate kernel_object_t *objp1; 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate /* 8907c478bd9Sstevel@tonic-gate * Delete every private token object from the slot' token object list 8917c478bd9Sstevel@tonic-gate */ 8927c478bd9Sstevel@tonic-gate objp = pslot->sl_tobj_list; 8937c478bd9Sstevel@tonic-gate while (objp) { 8947c478bd9Sstevel@tonic-gate objp1 = objp->next; 8957c478bd9Sstevel@tonic-gate /* 8967c478bd9Sstevel@tonic-gate * The first TRUE boolean argument indicates that the caller 8977c478bd9Sstevel@tonic-gate * hold the slot lock. The second TRUE boolean argument 8987c478bd9Sstevel@tonic-gate * indicates that the caller just wants to clean up the object 8997c478bd9Sstevel@tonic-gate * wrapper from the library only. 9007c478bd9Sstevel@tonic-gate */ 9017c478bd9Sstevel@tonic-gate if (objp->bool_attr_mask & PRIVATE_BOOL_ON) { 9027c478bd9Sstevel@tonic-gate (void) kernel_delete_token_object(pslot, cur_sp, objp, 9037c478bd9Sstevel@tonic-gate B_TRUE, B_TRUE); 9047c478bd9Sstevel@tonic-gate } 9057c478bd9Sstevel@tonic-gate objp = objp1; 9067c478bd9Sstevel@tonic-gate } 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate /* 9097c478bd9Sstevel@tonic-gate * Walk through all the sessions in this slot and delete every 9107c478bd9Sstevel@tonic-gate * private object. 9117c478bd9Sstevel@tonic-gate */ 9127c478bd9Sstevel@tonic-gate session_p = pslot->sl_sess_list; 9137c478bd9Sstevel@tonic-gate while (session_p) { 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate /* Delete all the objects in the session. */ 9167c478bd9Sstevel@tonic-gate objp = session_p->object_list; 9177c478bd9Sstevel@tonic-gate while (objp) { 9187c478bd9Sstevel@tonic-gate objp1 = objp->next; 9197c478bd9Sstevel@tonic-gate /* 9207c478bd9Sstevel@tonic-gate * The FALSE boolean argument indicates that the 9217c478bd9Sstevel@tonic-gate * caller does not hold the session lock. The TRUE 9227c478bd9Sstevel@tonic-gate * boolean argument indicates that the caller just 9237c478bd9Sstevel@tonic-gate * want to clean upt the object wrapper from the 9247c478bd9Sstevel@tonic-gate * library only. 9257c478bd9Sstevel@tonic-gate */ 9267c478bd9Sstevel@tonic-gate if (objp->bool_attr_mask & PRIVATE_BOOL_ON) { 9277c478bd9Sstevel@tonic-gate (void) kernel_delete_session_object(session_p, 9287c478bd9Sstevel@tonic-gate objp, B_FALSE, B_TRUE); 9297c478bd9Sstevel@tonic-gate } 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate objp = objp1; 9327c478bd9Sstevel@tonic-gate } 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate session_p = session_p->next; 9357c478bd9Sstevel@tonic-gate } 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate /* 9397c478bd9Sstevel@tonic-gate * Get the object size in bytes for the objects created in the library. 9407c478bd9Sstevel@tonic-gate */ 9417c478bd9Sstevel@tonic-gate CK_RV 9427c478bd9Sstevel@tonic-gate kernel_get_object_size(kernel_object_t *obj, CK_ULONG_PTR pulSize) 9437c478bd9Sstevel@tonic-gate { 9447c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 9457c478bd9Sstevel@tonic-gate CK_ULONG obj_size; 9467c478bd9Sstevel@tonic-gate biginteger_t *big; 9477c478bd9Sstevel@tonic-gate 9487c478bd9Sstevel@tonic-gate obj_size = sizeof (kernel_object_t); 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate switch (obj->class) { 9517c478bd9Sstevel@tonic-gate case CKO_PUBLIC_KEY: 9527c478bd9Sstevel@tonic-gate if (obj->key_type == CKK_RSA) { 9537c478bd9Sstevel@tonic-gate big = OBJ_PUB_RSA_PUBEXPO(obj); 9547c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9557c478bd9Sstevel@tonic-gate big = OBJ_PUB_RSA_MOD(obj); 9567c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate } else if (obj->key_type == CKK_DSA) { 9597c478bd9Sstevel@tonic-gate big = OBJ_PUB_DSA_PRIME(obj); 9607c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9617c478bd9Sstevel@tonic-gate big = OBJ_PUB_DSA_SUBPRIME(obj); 9627c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9637c478bd9Sstevel@tonic-gate big = OBJ_PUB_DSA_BASE(obj); 9647c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9657c478bd9Sstevel@tonic-gate big = OBJ_PUB_DSA_VALUE(obj); 9667c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9677c478bd9Sstevel@tonic-gate 968034448feSmcpowers } else if (obj->key_type == CKK_EC) { 969034448feSmcpowers big = OBJ_PUB_EC_POINT(obj); 970034448feSmcpowers obj_size += big->big_value_len; 971034448feSmcpowers 9727c478bd9Sstevel@tonic-gate } else { 9737c478bd9Sstevel@tonic-gate rv = CKR_OBJECT_HANDLE_INVALID; 9747c478bd9Sstevel@tonic-gate } 9757c478bd9Sstevel@tonic-gate break; 9767c478bd9Sstevel@tonic-gate 9777c478bd9Sstevel@tonic-gate case CKO_PRIVATE_KEY: 9787c478bd9Sstevel@tonic-gate if (obj->key_type == CKK_RSA) { 9797c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_MOD(obj); 9807c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_PUBEXPO(obj); /* optional */ 9837c478bd9Sstevel@tonic-gate if (big != NULL) { 9847c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9857c478bd9Sstevel@tonic-gate } 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_PRIEXPO(obj); 9887c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_PRIME1(obj); /* optional */ 9917c478bd9Sstevel@tonic-gate if (big != NULL) { 9927c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9937c478bd9Sstevel@tonic-gate } 9947c478bd9Sstevel@tonic-gate 9957c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_PRIME2(obj); /* optional */ 9967c478bd9Sstevel@tonic-gate if (big != NULL) { 9977c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 9987c478bd9Sstevel@tonic-gate } 9997c478bd9Sstevel@tonic-gate 10007c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_EXPO1(obj); /* optional */ 10017c478bd9Sstevel@tonic-gate if (big != NULL) { 10027c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 10037c478bd9Sstevel@tonic-gate } 10047c478bd9Sstevel@tonic-gate 10057c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_EXPO2(obj); /* optional */ 10067c478bd9Sstevel@tonic-gate if (big != NULL) { 10077c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 10087c478bd9Sstevel@tonic-gate } 10097c478bd9Sstevel@tonic-gate 10107c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_COEF(obj); /* optional */ 10117c478bd9Sstevel@tonic-gate if (big != NULL) { 10127c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 10137c478bd9Sstevel@tonic-gate } 10147c478bd9Sstevel@tonic-gate 10157c478bd9Sstevel@tonic-gate } else if (obj->key_type == CKK_DSA) { 10167c478bd9Sstevel@tonic-gate big = OBJ_PRI_DSA_PRIME(obj); 10177c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 10187c478bd9Sstevel@tonic-gate big = OBJ_PRI_DSA_SUBPRIME(obj); 10197c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 10207c478bd9Sstevel@tonic-gate big = OBJ_PRI_DSA_BASE(obj); 10217c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 10227c478bd9Sstevel@tonic-gate big = OBJ_PRI_DSA_VALUE(obj); 10237c478bd9Sstevel@tonic-gate obj_size += big->big_value_len; 10247c478bd9Sstevel@tonic-gate 1025034448feSmcpowers } else if (obj->key_type == CKK_EC) { 1026034448feSmcpowers big = OBJ_PRI_EC_VALUE(obj); 1027034448feSmcpowers obj_size += big->big_value_len; 1028034448feSmcpowers 10297c478bd9Sstevel@tonic-gate } else { 10307c478bd9Sstevel@tonic-gate rv = CKR_OBJECT_HANDLE_INVALID; 10317c478bd9Sstevel@tonic-gate } 10327c478bd9Sstevel@tonic-gate break; 10337c478bd9Sstevel@tonic-gate 10347c478bd9Sstevel@tonic-gate case CKO_SECRET_KEY: 10357c478bd9Sstevel@tonic-gate obj_size += OBJ_SEC_VALUE_LEN(obj); 10367c478bd9Sstevel@tonic-gate break; 10377c478bd9Sstevel@tonic-gate 10387c478bd9Sstevel@tonic-gate default: 10397c478bd9Sstevel@tonic-gate rv = CKR_OBJECT_HANDLE_INVALID; 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 10437c478bd9Sstevel@tonic-gate *pulSize = obj_size; 10447c478bd9Sstevel@tonic-gate } 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate return (rv); 10477c478bd9Sstevel@tonic-gate } 104801223cbaSmcpowers 104901223cbaSmcpowers /* 105001223cbaSmcpowers * This function adds the to-be-freed session object to a linked list. 105101223cbaSmcpowers * When the number of objects queued in the linked list reaches the 105201223cbaSmcpowers * maximum threshold MAX_OBJ_TO_BE_FREED, it will free the first 105301223cbaSmcpowers * object (FIFO) in the list. 105401223cbaSmcpowers */ 105501223cbaSmcpowers void 105601223cbaSmcpowers kernel_object_delay_free(kernel_object_t *objp) 105701223cbaSmcpowers { 105801223cbaSmcpowers kernel_object_t *tmp; 105901223cbaSmcpowers 106001223cbaSmcpowers (void) pthread_mutex_lock(&obj_delay_freed.obj_to_be_free_mutex); 106101223cbaSmcpowers 106201223cbaSmcpowers /* Add the newly deleted object at the end of the list */ 106301223cbaSmcpowers objp->next = NULL; 106401223cbaSmcpowers if (obj_delay_freed.first == NULL) { 106501223cbaSmcpowers obj_delay_freed.last = objp; 106601223cbaSmcpowers obj_delay_freed.first = objp; 106701223cbaSmcpowers } else { 106801223cbaSmcpowers obj_delay_freed.last->next = objp; 106901223cbaSmcpowers obj_delay_freed.last = objp; 107001223cbaSmcpowers } 107101223cbaSmcpowers 107201223cbaSmcpowers if (++obj_delay_freed.count >= MAX_OBJ_TO_BE_FREED) { 107301223cbaSmcpowers /* 107401223cbaSmcpowers * Free the first object in the list only if 107501223cbaSmcpowers * the total count reaches maximum threshold. 107601223cbaSmcpowers */ 107701223cbaSmcpowers obj_delay_freed.count--; 107801223cbaSmcpowers tmp = obj_delay_freed.first->next; 107901223cbaSmcpowers free(obj_delay_freed.first); 108001223cbaSmcpowers obj_delay_freed.first = tmp; 108101223cbaSmcpowers } 108201223cbaSmcpowers (void) pthread_mutex_unlock(&obj_delay_freed.obj_to_be_free_mutex); 108301223cbaSmcpowers } 1084