10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <pthread.h>
300Sstevel@tonic-gate #include <stdlib.h>
310Sstevel@tonic-gate #include <errno.h>
320Sstevel@tonic-gate #include <security/cryptoki.h>
330Sstevel@tonic-gate #include "kernelGlobal.h"
340Sstevel@tonic-gate #include "kernelObject.h"
350Sstevel@tonic-gate #include "kernelSession.h"
360Sstevel@tonic-gate #include <errno.h>
370Sstevel@tonic-gate #include <string.h>
380Sstevel@tonic-gate #include <cryptoutil.h>
390Sstevel@tonic-gate
400Sstevel@tonic-gate CK_RV
C_CreateObject(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phObject)410Sstevel@tonic-gate C_CreateObject(CK_SESSION_HANDLE hSession,
420Sstevel@tonic-gate CK_ATTRIBUTE_PTR pTemplate,
430Sstevel@tonic-gate CK_ULONG ulCount,
440Sstevel@tonic-gate CK_OBJECT_HANDLE_PTR phObject)
450Sstevel@tonic-gate {
460Sstevel@tonic-gate
470Sstevel@tonic-gate CK_RV rv;
480Sstevel@tonic-gate kernel_session_t *session_p;
490Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
500Sstevel@tonic-gate
510Sstevel@tonic-gate if (!kernel_initialized)
520Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
530Sstevel@tonic-gate
540Sstevel@tonic-gate if ((pTemplate == NULL) || (ulCount == 0) ||
550Sstevel@tonic-gate (phObject == NULL)) {
560Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
570Sstevel@tonic-gate }
580Sstevel@tonic-gate
590Sstevel@tonic-gate /*
600Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
610Sstevel@tonic-gate * reference count.
620Sstevel@tonic-gate */
630Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
640Sstevel@tonic-gate if (rv != CKR_OK)
650Sstevel@tonic-gate return (rv);
660Sstevel@tonic-gate
670Sstevel@tonic-gate /* Create a new object. */
680Sstevel@tonic-gate rv = kernel_add_object(pTemplate, ulCount, phObject, session_p);
690Sstevel@tonic-gate
700Sstevel@tonic-gate /*
710Sstevel@tonic-gate * Decrement the session reference count.
720Sstevel@tonic-gate * We do not hold the session lock.
730Sstevel@tonic-gate */
740Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
750Sstevel@tonic-gate
760Sstevel@tonic-gate return (rv);
770Sstevel@tonic-gate }
780Sstevel@tonic-gate
790Sstevel@tonic-gate
800Sstevel@tonic-gate CK_RV
C_CopyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phNewObject)810Sstevel@tonic-gate C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
820Sstevel@tonic-gate CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
830Sstevel@tonic-gate CK_OBJECT_HANDLE_PTR phNewObject)
840Sstevel@tonic-gate {
850Sstevel@tonic-gate
860Sstevel@tonic-gate CK_RV rv;
870Sstevel@tonic-gate kernel_session_t *session_p;
880Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
890Sstevel@tonic-gate kernel_object_t *old_object;
900Sstevel@tonic-gate kernel_object_t *new_object = NULL;
910Sstevel@tonic-gate crypto_object_copy_t object_copy;
920Sstevel@tonic-gate CK_BBOOL is_pri_obj = FALSE;
930Sstevel@tonic-gate CK_BBOOL is_token_obj = FALSE;
940Sstevel@tonic-gate kernel_slot_t *pslot;
950Sstevel@tonic-gate int i, r;
960Sstevel@tonic-gate
970Sstevel@tonic-gate if (!kernel_initialized)
980Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
990Sstevel@tonic-gate
1000Sstevel@tonic-gate /* Check arguments */
1010Sstevel@tonic-gate if (((ulCount > 0) && (pTemplate == NULL)) ||
1020Sstevel@tonic-gate (phNewObject == NULL)) {
1030Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
1040Sstevel@tonic-gate }
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate /*
1070Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
1080Sstevel@tonic-gate * reference count.
1090Sstevel@tonic-gate */
1100Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
1110Sstevel@tonic-gate if (rv != CKR_OK)
1120Sstevel@tonic-gate return (rv);
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate /* Obtain the object pointer. */
1150Sstevel@tonic-gate HANDLE2OBJECT(hObject, old_object, rv);
1160Sstevel@tonic-gate if (rv != CKR_OK) {
1170Sstevel@tonic-gate /*
1180Sstevel@tonic-gate * Decrement the session reference count.
1190Sstevel@tonic-gate * We do not hold the session lock.
1200Sstevel@tonic-gate */
1210Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
1220Sstevel@tonic-gate return (rv);
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate (void) pthread_mutex_lock(&old_object->object_mutex);
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate if (old_object->is_lib_obj) {
1280Sstevel@tonic-gate /*
1290Sstevel@tonic-gate * Copy the old object to a new object.
1300Sstevel@tonic-gate * The 3rd argument with TRUE value indicates that
1310Sstevel@tonic-gate * everything in the object will be duplicated.
1320Sstevel@tonic-gate */
1330Sstevel@tonic-gate rv = kernel_copy_object(old_object, &new_object, B_TRUE,
1340Sstevel@tonic-gate session_p);
135*214Smcpowers (void) pthread_mutex_unlock(&old_object->object_mutex);
1360Sstevel@tonic-gate if ((rv != CKR_OK) || (new_object == NULL)) {
1370Sstevel@tonic-gate /*
138*214Smcpowers * Most likely we ran out of space.
1390Sstevel@tonic-gate * Decrement the session reference count.
1400Sstevel@tonic-gate * We do not hold the session lock.
1410Sstevel@tonic-gate */
142*214Smcpowers OBJ_REFRELE(old_object);
1430Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
1440Sstevel@tonic-gate return (rv);
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate new_object->is_lib_obj = B_TRUE;
1480Sstevel@tonic-gate
1490Sstevel@tonic-gate /* Modify the object attribute if requested */
1500Sstevel@tonic-gate for (i = 0; i < ulCount; i++) {
1510Sstevel@tonic-gate /* Set the requested attribute into the new object. */
1520Sstevel@tonic-gate rv = kernel_set_attribute(new_object, &pTemplate[i],
1530Sstevel@tonic-gate B_TRUE, session_p);
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate if (rv != CKR_OK) {
1560Sstevel@tonic-gate kernel_cleanup_object(new_object);
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate /*
1590Sstevel@tonic-gate * Decrement the session reference count.
1600Sstevel@tonic-gate * We do not hold the session lock.
1610Sstevel@tonic-gate */
162*214Smcpowers OBJ_REFRELE(old_object);
1630Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
1640Sstevel@tonic-gate return (rv);
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate /* Insert the new object into this session's object list. */
1690Sstevel@tonic-gate kernel_add_object_to_session(new_object, session_p);
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate /*
1720Sstevel@tonic-gate * Decrement the session reference count.
1730Sstevel@tonic-gate * We do not hold the session lock.
1740Sstevel@tonic-gate */
175*214Smcpowers OBJ_REFRELE(old_object);
1760Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate /* set handle of the new object */
1790Sstevel@tonic-gate *phNewObject = (CK_ULONG)new_object;
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate } else {
1820Sstevel@tonic-gate /*
1830Sstevel@tonic-gate * The old object was created in the HW provider.
1840Sstevel@tonic-gate * First, create an object wrapper in library.
1850Sstevel@tonic-gate */
1860Sstevel@tonic-gate new_object = calloc(1, sizeof (kernel_object_t));
1870Sstevel@tonic-gate if (new_object == NULL) {
188*214Smcpowers (void) pthread_mutex_unlock(&old_object->object_mutex);
189*214Smcpowers OBJ_REFRELE(old_object);
190*214Smcpowers REFRELE(session_p, ses_lock_held);
191*214Smcpowers return (CKR_HOST_MEMORY);
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate /* Call CRYPTO_OBJECT_COPY ioctl to get a new object. */
1950Sstevel@tonic-gate object_copy.oc_session = session_p->k_session;
1960Sstevel@tonic-gate object_copy.oc_handle = old_object->k_handle;
197*214Smcpowers (void) pthread_mutex_unlock(&old_object->object_mutex);
1980Sstevel@tonic-gate object_copy.oc_count = ulCount;
1990Sstevel@tonic-gate object_copy.oc_new_attributes = NULL;
2000Sstevel@tonic-gate if (ulCount > 0) {
2010Sstevel@tonic-gate rv = process_object_attributes(pTemplate, ulCount,
2020Sstevel@tonic-gate &object_copy.oc_new_attributes, &is_token_obj);
2030Sstevel@tonic-gate if (rv != CKR_OK) {
2040Sstevel@tonic-gate goto failed_cleanup;
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate }
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_COPY,
2090Sstevel@tonic-gate &object_copy)) < 0) {
2100Sstevel@tonic-gate if (errno != EINTR)
2110Sstevel@tonic-gate break;
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate if (r < 0) {
2140Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
2150Sstevel@tonic-gate } else {
2160Sstevel@tonic-gate rv = crypto2pkcs11_error_number(
2170Sstevel@tonic-gate object_copy.oc_return_value);
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate /* Free the attributes' space allocated for ioctl */
2210Sstevel@tonic-gate free_object_attributes(object_copy.oc_new_attributes, ulCount);
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate if (rv != CKR_OK) {
2240Sstevel@tonic-gate goto failed_cleanup;
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate
2270Sstevel@tonic-gate /*
2280Sstevel@tonic-gate * Store the kernel object handle in the object wrapper and
2290Sstevel@tonic-gate * get the CKA_PRIVATE value of the new object.
2300Sstevel@tonic-gate */
2310Sstevel@tonic-gate new_object->k_handle = object_copy.oc_new_handle;
2320Sstevel@tonic-gate rv = get_cka_private_value(session_p, new_object->k_handle,
2330Sstevel@tonic-gate &is_pri_obj);
2340Sstevel@tonic-gate if (rv != CKR_OK) {
2350Sstevel@tonic-gate goto failed_cleanup;
2360Sstevel@tonic-gate }
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate /*
2390Sstevel@tonic-gate * Initialize other field of the object wrapper.
2400Sstevel@tonic-gate */
2410Sstevel@tonic-gate new_object->is_lib_obj = B_FALSE;
2420Sstevel@tonic-gate new_object->magic_marker = KERNELTOKEN_OBJECT_MAGIC;
2430Sstevel@tonic-gate new_object->session_handle = (CK_SESSION_HANDLE)session_p;
2440Sstevel@tonic-gate (void) pthread_mutex_init(&new_object->object_mutex, NULL);
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate if (is_pri_obj)
2470Sstevel@tonic-gate new_object->bool_attr_mask |= PRIVATE_BOOL_ON;
2480Sstevel@tonic-gate else
2490Sstevel@tonic-gate new_object->bool_attr_mask &= ~PRIVATE_BOOL_ON;
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate if (is_token_obj)
2520Sstevel@tonic-gate new_object->bool_attr_mask |= TOKEN_BOOL_ON;
2530Sstevel@tonic-gate else
2540Sstevel@tonic-gate new_object->bool_attr_mask &= ~TOKEN_BOOL_ON;
2550Sstevel@tonic-gate
2560Sstevel@tonic-gate /*
2570Sstevel@tonic-gate * Add the new copied object into the slot's token list
2580Sstevel@tonic-gate * or the session list. We don't hold the slot lock.
2590Sstevel@tonic-gate */
2600Sstevel@tonic-gate if (is_token_obj) {
2610Sstevel@tonic-gate pslot = slot_table[session_p->ses_slotid];
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate /*
2640Sstevel@tonic-gate * Decrement the session reference count.
2650Sstevel@tonic-gate * We do not hold the session lock.
2660Sstevel@tonic-gate */
267*214Smcpowers OBJ_REFRELE(old_object);
2680Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate /* Add into the slot token object list. */
2710Sstevel@tonic-gate kernel_add_token_object_to_slot(new_object, pslot);
2720Sstevel@tonic-gate } else {
2730Sstevel@tonic-gate kernel_add_object_to_session(new_object, session_p);
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate /*
2760Sstevel@tonic-gate * Decrement the session reference count.
2770Sstevel@tonic-gate * We do not hold the session lock.
2780Sstevel@tonic-gate */
279*214Smcpowers OBJ_REFRELE(old_object);
2800Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
2810Sstevel@tonic-gate }
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate /* set handle of the new object */
2840Sstevel@tonic-gate *phNewObject = (CK_ULONG)new_object;
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate return (rv);
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate failed_cleanup:
2900Sstevel@tonic-gate if (new_object != NULL) {
2910Sstevel@tonic-gate (void) free(new_object);
2920Sstevel@tonic-gate }
2930Sstevel@tonic-gate
294*214Smcpowers OBJ_REFRELE(old_object);
2950Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
2960Sstevel@tonic-gate return (rv);
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate
2990Sstevel@tonic-gate
3000Sstevel@tonic-gate CK_RV
C_DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)3010Sstevel@tonic-gate C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
3020Sstevel@tonic-gate {
3030Sstevel@tonic-gate CK_RV rv;
3040Sstevel@tonic-gate kernel_object_t *object_p;
305*214Smcpowers kernel_session_t *session_p = (kernel_session_t *)(hSession);
3060Sstevel@tonic-gate kernel_slot_t *pslot;
3070Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
3080Sstevel@tonic-gate CK_SESSION_HANDLE creating_session;
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate if (!kernel_initialized)
3110Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
3120Sstevel@tonic-gate
313*214Smcpowers /*
314*214Smcpowers * The reason that we don't call handle2session is because
315*214Smcpowers * the argument hSession may not be the creating_session of
316*214Smcpowers * the object to be destroyed, and we want to avoid the lock
317*214Smcpowers * contention. The handle2session will be called later for
318*214Smcpowers * the creating_session.
319*214Smcpowers */
320*214Smcpowers if ((session_p == NULL) ||
321*214Smcpowers (session_p->magic_marker != KERNELTOKEN_SESSION_MAGIC)) {
322*214Smcpowers return (CKR_SESSION_HANDLE_INVALID);
323*214Smcpowers }
3240Sstevel@tonic-gate
325*214Smcpowers /* Obtain the object pointer without incrementing reference count. */
326*214Smcpowers HANDLE2OBJECT_DESTROY(hObject, object_p, rv);
3270Sstevel@tonic-gate if (rv != CKR_OK) {
328*214Smcpowers return (rv);
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate /* Only session objects can be destroyed at a read-only session. */
3320Sstevel@tonic-gate if ((session_p->ses_RO) &&
3330Sstevel@tonic-gate (object_p->bool_attr_mask & TOKEN_BOOL_ON)) {
334*214Smcpowers return (CKR_SESSION_READ_ONLY);
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate
3370Sstevel@tonic-gate /*
3380Sstevel@tonic-gate * If the object is a session object, obtain the session handle
3390Sstevel@tonic-gate * which object belongs to. For a token object, we will use the
3400Sstevel@tonic-gate * session handle from the caller, because the session used to
3410Sstevel@tonic-gate * create the token object may no longer exist.
3420Sstevel@tonic-gate */
343*214Smcpowers if (!(object_p->bool_attr_mask & TOKEN_BOOL_ON))
3440Sstevel@tonic-gate creating_session = object_p->session_handle;
345*214Smcpowers else
346*214Smcpowers creating_session = hSession;
347*214Smcpowers
348*214Smcpowers rv = handle2session(creating_session, &session_p);
349*214Smcpowers if (rv != CKR_OK) {
350*214Smcpowers return (rv);
3510Sstevel@tonic-gate }
3520Sstevel@tonic-gate
353*214Smcpowers /*
354*214Smcpowers * Set OBJECT_IS_DELETING flag so any access to this
355*214Smcpowers * object will be rejected.
356*214Smcpowers */
357*214Smcpowers (void) pthread_mutex_lock(&object_p->object_mutex);
358*214Smcpowers if (object_p->obj_delete_sync & OBJECT_IS_DELETING) {
359*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
360*214Smcpowers REFRELE(session_p, ses_lock_held);
361*214Smcpowers return (CKR_OBJECT_HANDLE_INVALID);
362*214Smcpowers }
363*214Smcpowers object_p->obj_delete_sync |= OBJECT_IS_DELETING;
364*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
365*214Smcpowers
3660Sstevel@tonic-gate if (object_p->bool_attr_mask & TOKEN_BOOL_ON) {
3670Sstevel@tonic-gate /*
3680Sstevel@tonic-gate * The first FALSE boolean argument indicates that the caller
3690Sstevel@tonic-gate * does not hold the slot lock. The second FALSE boolean
3700Sstevel@tonic-gate * argument indicates that the caller wants to clean up the
3710Sstevel@tonic-gate * object in the HW provider also.
3720Sstevel@tonic-gate */
3730Sstevel@tonic-gate pslot = slot_table[session_p->ses_slotid];
3740Sstevel@tonic-gate rv = kernel_delete_token_object(pslot, session_p, object_p,
3750Sstevel@tonic-gate B_FALSE, B_FALSE);
3760Sstevel@tonic-gate } else {
3770Sstevel@tonic-gate /*
3780Sstevel@tonic-gate * The first FALSE boolean argument indicates that the caller
3790Sstevel@tonic-gate * does not hold the session lock. The second FALSE boolean
3800Sstevel@tonic-gate * argument indicates that the caller wants to clean the object
3810Sstevel@tonic-gate * in the HW provider also.
3820Sstevel@tonic-gate */
3830Sstevel@tonic-gate rv = kernel_delete_session_object(session_p, object_p, B_FALSE,
3840Sstevel@tonic-gate B_FALSE);
3850Sstevel@tonic-gate }
3860Sstevel@tonic-gate /*
3870Sstevel@tonic-gate * Decrement the session reference count.
3880Sstevel@tonic-gate * We do not hold the session lock.
3890Sstevel@tonic-gate */
3900Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
3910Sstevel@tonic-gate return (rv);
3920Sstevel@tonic-gate }
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate CK_RV
C_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)3960Sstevel@tonic-gate C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
3970Sstevel@tonic-gate CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
3980Sstevel@tonic-gate {
3990Sstevel@tonic-gate
4000Sstevel@tonic-gate CK_RV rv = CKR_OK, rv1 = CKR_OK;
4010Sstevel@tonic-gate kernel_object_t *object_p;
4020Sstevel@tonic-gate kernel_session_t *session_p;
4030Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
4040Sstevel@tonic-gate crypto_object_get_attribute_value_t obj_get_attr;
4050Sstevel@tonic-gate int i, r;
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate if (!kernel_initialized)
4080Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
4090Sstevel@tonic-gate
4100Sstevel@tonic-gate if ((pTemplate == NULL) || (ulCount == 0))
4110Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
4120Sstevel@tonic-gate
4130Sstevel@tonic-gate /*
4140Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
4150Sstevel@tonic-gate * reference count.
4160Sstevel@tonic-gate */
4170Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
4180Sstevel@tonic-gate if (rv != CKR_OK)
4190Sstevel@tonic-gate return (rv);
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate /* Obtain the object pointer. */
4220Sstevel@tonic-gate HANDLE2OBJECT(hObject, object_p, rv);
4230Sstevel@tonic-gate if (rv != CKR_OK) {
4240Sstevel@tonic-gate /*
4250Sstevel@tonic-gate * Decrement the session reference count.
4260Sstevel@tonic-gate * We do not hold the session lock.
4270Sstevel@tonic-gate */
4280Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
4290Sstevel@tonic-gate return (rv);
4300Sstevel@tonic-gate }
4310Sstevel@tonic-gate
4320Sstevel@tonic-gate /* Acquire the lock on the object. */
4330Sstevel@tonic-gate (void) pthread_mutex_lock(&object_p->object_mutex);
4340Sstevel@tonic-gate
4350Sstevel@tonic-gate if (object_p->is_lib_obj) {
4360Sstevel@tonic-gate /*
4370Sstevel@tonic-gate * The object was created in the library. The library
4380Sstevel@tonic-gate * contains the value information of each attribute.
4390Sstevel@tonic-gate */
4400Sstevel@tonic-gate for (i = 0; i < ulCount; i++) {
4410Sstevel@tonic-gate /*
4420Sstevel@tonic-gate * Get the value of each attribute in the template.
4430Sstevel@tonic-gate * (We must process EVERY attribute in the template.)
4440Sstevel@tonic-gate */
4450Sstevel@tonic-gate rv = kernel_get_attribute(object_p, &pTemplate[i]);
4460Sstevel@tonic-gate if (rv != CKR_OK)
4470Sstevel@tonic-gate /* At least we catch some type of error. */
4480Sstevel@tonic-gate rv1 = rv;
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate rv = rv1;
451*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
4520Sstevel@tonic-gate } else {
4530Sstevel@tonic-gate /*
4540Sstevel@tonic-gate * The object was created in HW provider, call ioctl to get
4550Sstevel@tonic-gate * the values of attributes.
4560Sstevel@tonic-gate */
4570Sstevel@tonic-gate obj_get_attr.og_session = session_p->k_session;
4580Sstevel@tonic-gate obj_get_attr.og_handle = object_p->k_handle;
459*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
4600Sstevel@tonic-gate obj_get_attr.og_count = ulCount;
4610Sstevel@tonic-gate
4620Sstevel@tonic-gate rv = process_object_attributes(pTemplate, ulCount,
4630Sstevel@tonic-gate &obj_get_attr.og_attributes, NULL);
4640Sstevel@tonic-gate if (rv != CKR_OK) {
4650Sstevel@tonic-gate goto clean_exit;
4660Sstevel@tonic-gate }
4670Sstevel@tonic-gate
4680Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE,
4690Sstevel@tonic-gate &obj_get_attr)) < 0) {
4700Sstevel@tonic-gate if (errno != EINTR)
4710Sstevel@tonic-gate break;
4720Sstevel@tonic-gate }
4730Sstevel@tonic-gate if (r < 0) {
4740Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
4750Sstevel@tonic-gate } else {
4760Sstevel@tonic-gate rv = crypto2pkcs11_error_number(
4770Sstevel@tonic-gate obj_get_attr.og_return_value);
4780Sstevel@tonic-gate }
4790Sstevel@tonic-gate
4800Sstevel@tonic-gate /*
4810Sstevel@tonic-gate * The error codes CKR_ATTRIBUTE_SENSITIVE,
4820Sstevel@tonic-gate * CKR_ATTRIBUTE_TYPE_INVALID, and CKR_BUFFER_TOO_SMALL
4830Sstevel@tonic-gate * do not denote true errors for this function. If a call
4840Sstevel@tonic-gate * returns any of these three values, then the call must
4850Sstevel@tonic-gate * nonetheless have processed every attribute in the
4860Sstevel@tonic-gate * template. Every attribute in the template whose value
4870Sstevel@tonic-gate * can be returned will be returned.
4880Sstevel@tonic-gate */
4890Sstevel@tonic-gate if ((rv == CKR_OK) ||
4900Sstevel@tonic-gate (rv == CKR_ATTRIBUTE_SENSITIVE) ||
4910Sstevel@tonic-gate (rv == CKR_ATTRIBUTE_TYPE_INVALID) ||
4920Sstevel@tonic-gate (rv == CKR_BUFFER_TOO_SMALL)) {
4930Sstevel@tonic-gate rv1 = get_object_attributes(pTemplate, ulCount,
4940Sstevel@tonic-gate obj_get_attr.og_attributes);
4950Sstevel@tonic-gate if (rv1 != CKR_OK) {
4960Sstevel@tonic-gate rv = rv1;
4970Sstevel@tonic-gate }
4980Sstevel@tonic-gate }
4990Sstevel@tonic-gate
5000Sstevel@tonic-gate /* Free the attributes' allocated for the ioctl call. */
5010Sstevel@tonic-gate free_object_attributes(obj_get_attr.og_attributes, ulCount);
5020Sstevel@tonic-gate }
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate clean_exit:
5050Sstevel@tonic-gate /*
5060Sstevel@tonic-gate * Decrement the session reference count.
5070Sstevel@tonic-gate * We do not hold the session lock.
5080Sstevel@tonic-gate */
509*214Smcpowers OBJ_REFRELE(object_p);
5100Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
5110Sstevel@tonic-gate return (rv);
5120Sstevel@tonic-gate }
5130Sstevel@tonic-gate
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate CK_RV
C_SetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)5160Sstevel@tonic-gate C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
5170Sstevel@tonic-gate CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
5180Sstevel@tonic-gate {
5190Sstevel@tonic-gate CK_RV rv = CKR_OK;
5200Sstevel@tonic-gate kernel_object_t *object_p;
5210Sstevel@tonic-gate kernel_object_t *new_object = NULL;
5220Sstevel@tonic-gate kernel_session_t *session_p;
5230Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
5240Sstevel@tonic-gate crypto_object_set_attribute_value_t obj_set_attr;
5250Sstevel@tonic-gate int i, r;
5260Sstevel@tonic-gate
5270Sstevel@tonic-gate if (!kernel_initialized)
5280Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
5290Sstevel@tonic-gate
5300Sstevel@tonic-gate if ((pTemplate == NULL) || (ulCount == 0))
5310Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate /*
5340Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
5350Sstevel@tonic-gate * reference count.
5360Sstevel@tonic-gate */
5370Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
5380Sstevel@tonic-gate if (rv != CKR_OK)
5390Sstevel@tonic-gate return (rv);
5400Sstevel@tonic-gate
5410Sstevel@tonic-gate /* Obtain the object pointer. */
5420Sstevel@tonic-gate HANDLE2OBJECT(hObject, object_p, rv);
5430Sstevel@tonic-gate if (rv != CKR_OK) {
5440Sstevel@tonic-gate /*
5450Sstevel@tonic-gate * Decrement the session reference count.
5460Sstevel@tonic-gate * We do not hold the session lock.
5470Sstevel@tonic-gate */
5480Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
5490Sstevel@tonic-gate return (rv);
5500Sstevel@tonic-gate }
5510Sstevel@tonic-gate
5520Sstevel@tonic-gate /* lock the object */
5530Sstevel@tonic-gate (void) pthread_mutex_lock(&object_p->object_mutex);
5540Sstevel@tonic-gate
5550Sstevel@tonic-gate /*
5560Sstevel@tonic-gate * If the object was created in the HW provider, changing its
5570Sstevel@tonic-gate * attributes' values need to be done in the provider too.
5580Sstevel@tonic-gate */
5590Sstevel@tonic-gate if (!object_p->is_lib_obj) {
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate /* Cannot modify a token object with a READ-ONLY session */
5620Sstevel@tonic-gate if (session_p->ses_RO &&
5630Sstevel@tonic-gate (object_p->bool_attr_mask & TOKEN_BOOL_ON)) {
564*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
5650Sstevel@tonic-gate rv = CKR_SESSION_READ_ONLY;
566*214Smcpowers goto clean_exit;
5670Sstevel@tonic-gate }
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate obj_set_attr.sa_session = session_p->k_session;
5700Sstevel@tonic-gate obj_set_attr.sa_handle = object_p->k_handle;
571*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
5720Sstevel@tonic-gate obj_set_attr.sa_count = ulCount;
5730Sstevel@tonic-gate rv = process_object_attributes(pTemplate, ulCount,
5740Sstevel@tonic-gate &obj_set_attr.sa_attributes, NULL);
5750Sstevel@tonic-gate if (rv != CKR_OK) {
576*214Smcpowers goto clean_exit;
5770Sstevel@tonic-gate }
5780Sstevel@tonic-gate
5790Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_SET_ATTRIBUTE_VALUE,
5800Sstevel@tonic-gate &obj_set_attr)) < 0) {
5810Sstevel@tonic-gate if (errno != EINTR)
5820Sstevel@tonic-gate break;
5830Sstevel@tonic-gate }
5840Sstevel@tonic-gate if (r < 0) {
5850Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
5860Sstevel@tonic-gate } else {
5870Sstevel@tonic-gate rv = crypto2pkcs11_error_number(
5880Sstevel@tonic-gate obj_set_attr.sa_return_value);
5890Sstevel@tonic-gate }
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate /* Free the attributes' space allocated for the ioctl call. */
5920Sstevel@tonic-gate free_object_attributes(obj_set_attr.sa_attributes, ulCount);
593*214Smcpowers goto clean_exit;
5940Sstevel@tonic-gate }
5950Sstevel@tonic-gate
5960Sstevel@tonic-gate /*
5970Sstevel@tonic-gate * if we come here, the object must have been created in the
5980Sstevel@tonic-gate * library. The work will be done completely in the library.
5990Sstevel@tonic-gate *
6000Sstevel@tonic-gate * Copy the old object to a new object. We work on the copied
6010Sstevel@tonic-gate * version because in case of error we still keep the old one
6020Sstevel@tonic-gate * intact.
6030Sstevel@tonic-gate */
6040Sstevel@tonic-gate rv = kernel_copy_object(object_p, &new_object, B_FALSE, NULL);
605*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
6060Sstevel@tonic-gate if ((rv != CKR_OK) || (new_object == NULL)) {
6070Sstevel@tonic-gate /*
608*214Smcpowers * Most likely we ran out of space.
6090Sstevel@tonic-gate * Decrement the session reference count.
6100Sstevel@tonic-gate * We do not hold the session lock.
6110Sstevel@tonic-gate */
612*214Smcpowers goto clean_exit;
6130Sstevel@tonic-gate }
6140Sstevel@tonic-gate
6150Sstevel@tonic-gate for (i = 0; i < ulCount; i++) {
6160Sstevel@tonic-gate /* Set the requested attribute into the new object. */
6170Sstevel@tonic-gate rv = kernel_set_attribute(new_object, &pTemplate[i], B_FALSE,
6180Sstevel@tonic-gate session_p);
6190Sstevel@tonic-gate
6200Sstevel@tonic-gate if (rv != CKR_OK) {
6210Sstevel@tonic-gate kernel_cleanup_object(new_object);
622*214Smcpowers goto clean_exit;
6230Sstevel@tonic-gate }
6240Sstevel@tonic-gate }
6250Sstevel@tonic-gate
6260Sstevel@tonic-gate /*
6270Sstevel@tonic-gate * We've successfully set all the requested attributes.
6280Sstevel@tonic-gate * Merge the new object with the old object, then destory
6290Sstevel@tonic-gate * the new one. The reason to do the merging is because we
6300Sstevel@tonic-gate * have to keep the original object handle (address of object).
6310Sstevel@tonic-gate */
6320Sstevel@tonic-gate (void) pthread_mutex_lock(&object_p->object_mutex);
6330Sstevel@tonic-gate kernel_merge_object(object_p, new_object);
634*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
6350Sstevel@tonic-gate
636*214Smcpowers clean_exit:
637*214Smcpowers if (new_object != NULL)
638*214Smcpowers (void) free(new_object);
6390Sstevel@tonic-gate
6400Sstevel@tonic-gate /*
6410Sstevel@tonic-gate * Decrement the session reference count.
6420Sstevel@tonic-gate * We do not hold the session lock.
6430Sstevel@tonic-gate */
644*214Smcpowers OBJ_REFRELE(object_p);
6450Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
6460Sstevel@tonic-gate
6470Sstevel@tonic-gate return (rv);
6480Sstevel@tonic-gate }
6490Sstevel@tonic-gate
6500Sstevel@tonic-gate
6510Sstevel@tonic-gate CK_RV
C_GetObjectSize(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize)6520Sstevel@tonic-gate C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
6530Sstevel@tonic-gate CK_ULONG_PTR pulSize)
6540Sstevel@tonic-gate {
6550Sstevel@tonic-gate
6560Sstevel@tonic-gate CK_RV rv = CKR_OK;
6570Sstevel@tonic-gate kernel_object_t *object_p;
6580Sstevel@tonic-gate kernel_session_t *session_p;
6590Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
6600Sstevel@tonic-gate crypto_object_get_size_t obj_gs;
6610Sstevel@tonic-gate int r;
6620Sstevel@tonic-gate
6630Sstevel@tonic-gate if (!kernel_initialized)
6640Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
6650Sstevel@tonic-gate
6660Sstevel@tonic-gate /* Check if pulSize is valid */
6670Sstevel@tonic-gate if (pulSize == NULL) {
6680Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
6690Sstevel@tonic-gate }
6700Sstevel@tonic-gate
6710Sstevel@tonic-gate /*
6720Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
6730Sstevel@tonic-gate * reference count.
6740Sstevel@tonic-gate */
6750Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
6760Sstevel@tonic-gate if (rv != CKR_OK)
6770Sstevel@tonic-gate return (rv);
6780Sstevel@tonic-gate
6790Sstevel@tonic-gate /* Obtain the object pointer. */
6800Sstevel@tonic-gate HANDLE2OBJECT(hObject, object_p, rv);
6810Sstevel@tonic-gate if (rv != CKR_OK) {
6820Sstevel@tonic-gate /*
6830Sstevel@tonic-gate * Decrement the session reference count.
6840Sstevel@tonic-gate * We do not hold the session lock.
6850Sstevel@tonic-gate */
6860Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
6870Sstevel@tonic-gate return (rv);
6880Sstevel@tonic-gate }
6890Sstevel@tonic-gate
6900Sstevel@tonic-gate /* Acquire the lock on the object. */
6910Sstevel@tonic-gate (void) pthread_mutex_lock(&object_p->object_mutex);
6920Sstevel@tonic-gate
6930Sstevel@tonic-gate if (!object_p->is_lib_obj) {
6940Sstevel@tonic-gate /*
6950Sstevel@tonic-gate * The object was created in HW provider, call the
6960Sstevel@tonic-gate * CRYPTO_OBJECT_GET_SIZE ioctl.
6970Sstevel@tonic-gate */
6980Sstevel@tonic-gate obj_gs.gs_session = session_p->k_session;
6990Sstevel@tonic-gate obj_gs.gs_handle = object_p->k_handle;
700*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
7010Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_SIZE,
7020Sstevel@tonic-gate &obj_gs)) < 0) {
7030Sstevel@tonic-gate if (errno != EINTR)
7040Sstevel@tonic-gate break;
7050Sstevel@tonic-gate }
7060Sstevel@tonic-gate if (r < 0) {
7070Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
7080Sstevel@tonic-gate } else {
7090Sstevel@tonic-gate rv = crypto2pkcs11_error_number(
7100Sstevel@tonic-gate obj_gs.gs_return_value);
7110Sstevel@tonic-gate }
7120Sstevel@tonic-gate
7130Sstevel@tonic-gate if (rv == CKR_OK) {
7140Sstevel@tonic-gate *pulSize = obj_gs.gs_size;
7150Sstevel@tonic-gate }
7160Sstevel@tonic-gate
7170Sstevel@tonic-gate } else {
7180Sstevel@tonic-gate rv = kernel_get_object_size(object_p, pulSize);
719*214Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex);
7200Sstevel@tonic-gate }
7210Sstevel@tonic-gate
7220Sstevel@tonic-gate /*
7230Sstevel@tonic-gate * Decrement the session reference count.
7240Sstevel@tonic-gate * We do not hold the session lock.
7250Sstevel@tonic-gate */
726*214Smcpowers OBJ_REFRELE(object_p);
7270Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
7280Sstevel@tonic-gate return (rv);
7290Sstevel@tonic-gate }
7300Sstevel@tonic-gate
7310Sstevel@tonic-gate
7320Sstevel@tonic-gate CK_RV
C_FindObjectsInit(CK_SESSION_HANDLE sh,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)7330Sstevel@tonic-gate C_FindObjectsInit(CK_SESSION_HANDLE sh, CK_ATTRIBUTE_PTR pTemplate,
7340Sstevel@tonic-gate CK_ULONG ulCount)
7350Sstevel@tonic-gate {
7360Sstevel@tonic-gate CK_RV rv;
7370Sstevel@tonic-gate kernel_session_t *session_p;
7380Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
7390Sstevel@tonic-gate kernel_slot_t *pslot;
7400Sstevel@tonic-gate crypto_object_find_init_t obj_fi;
7410Sstevel@tonic-gate int r;
7420Sstevel@tonic-gate
7430Sstevel@tonic-gate if (!kernel_initialized)
7440Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
7450Sstevel@tonic-gate
7460Sstevel@tonic-gate /* Check the arguments */
7470Sstevel@tonic-gate if ((ulCount > 0) && (pTemplate == NULL)) {
7480Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
7490Sstevel@tonic-gate }
7500Sstevel@tonic-gate
7510Sstevel@tonic-gate /*
7520Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
7530Sstevel@tonic-gate * reference count.
7540Sstevel@tonic-gate */
7550Sstevel@tonic-gate rv = handle2session(sh, &session_p);
7560Sstevel@tonic-gate if (rv != CKR_OK)
7570Sstevel@tonic-gate return (rv);
7580Sstevel@tonic-gate
7590Sstevel@tonic-gate /* Acquire the session lock */
7600Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
7610Sstevel@tonic-gate ses_lock_held = B_TRUE;
7620Sstevel@tonic-gate
7630Sstevel@tonic-gate /* Check to see if find operation is already active */
7640Sstevel@tonic-gate if (session_p->find_objects.flags & CRYPTO_OPERATION_ACTIVE) {
7650Sstevel@tonic-gate /* decrement the session count, and unlock the mutex */
7660Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
7670Sstevel@tonic-gate return (CKR_OPERATION_ACTIVE);
7680Sstevel@tonic-gate } else {
7690Sstevel@tonic-gate /*
7700Sstevel@tonic-gate * This active flag will remain ON until application calls
7710Sstevel@tonic-gate * C_FindObjectsFinal.
7720Sstevel@tonic-gate */
7730Sstevel@tonic-gate session_p->find_objects.flags = CRYPTO_OPERATION_ACTIVE;
7740Sstevel@tonic-gate }
7750Sstevel@tonic-gate
7760Sstevel@tonic-gate
7770Sstevel@tonic-gate /*
7780Sstevel@tonic-gate * If the HW provider supports object creation, we call the
7790Sstevel@tonic-gate * CRYPTO_OBJECT_FIND_INIT ioctl to initialize object finding.
7800Sstevel@tonic-gate * Otherwise, all the objects are created in the library and we
7810Sstevel@tonic-gate * do the find objects solely in the library.
7820Sstevel@tonic-gate */
7830Sstevel@tonic-gate pslot = slot_table[session_p->ses_slotid];
7840Sstevel@tonic-gate if (pslot->sl_func_list.fl_object_create) {
7850Sstevel@tonic-gate obj_fi.fi_session = session_p->k_session;
7860Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
7870Sstevel@tonic-gate ses_lock_held = B_FALSE;
7880Sstevel@tonic-gate obj_fi.fi_count = ulCount;
7890Sstevel@tonic-gate rv = process_object_attributes(pTemplate, ulCount,
7900Sstevel@tonic-gate &obj_fi.fi_attributes, NULL);
7910Sstevel@tonic-gate if (rv == CKR_OK) {
7920Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_FIND_INIT,
7930Sstevel@tonic-gate &obj_fi)) < 0) {
7940Sstevel@tonic-gate if (errno != EINTR)
7950Sstevel@tonic-gate break;
7960Sstevel@tonic-gate }
7970Sstevel@tonic-gate if (r < 0) {
7980Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
7990Sstevel@tonic-gate } else {
8000Sstevel@tonic-gate rv = crypto2pkcs11_error_number(
8010Sstevel@tonic-gate obj_fi.fi_return_value);
8020Sstevel@tonic-gate }
8030Sstevel@tonic-gate }
8040Sstevel@tonic-gate
8050Sstevel@tonic-gate /* Free the attributes' space allocated for the ioctl call. */
8060Sstevel@tonic-gate free_object_attributes(obj_fi.fi_attributes, ulCount);
8070Sstevel@tonic-gate
8080Sstevel@tonic-gate } else {
8090Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
8100Sstevel@tonic-gate ses_lock_held = B_FALSE;
8110Sstevel@tonic-gate rv = kernel_find_objects_init(session_p, pTemplate, ulCount);
8120Sstevel@tonic-gate }
8130Sstevel@tonic-gate
8140Sstevel@tonic-gate if (rv != CKR_OK) {
8150Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
8160Sstevel@tonic-gate session_p->find_objects.flags = 0;
8170Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
8180Sstevel@tonic-gate }
8190Sstevel@tonic-gate
8200Sstevel@tonic-gate /* decrement the session count, and unlock the mutex */
8210Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
8220Sstevel@tonic-gate return (rv);
8230Sstevel@tonic-gate
8240Sstevel@tonic-gate }
8250Sstevel@tonic-gate
8260Sstevel@tonic-gate CK_RV
C_FindObjects(CK_SESSION_HANDLE sh,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount)8270Sstevel@tonic-gate C_FindObjects(CK_SESSION_HANDLE sh, CK_OBJECT_HANDLE_PTR phObject,
8280Sstevel@tonic-gate CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
8290Sstevel@tonic-gate {
8300Sstevel@tonic-gate CK_RV rv = CKR_OK;
8310Sstevel@tonic-gate kernel_slot_t *pslot;
8320Sstevel@tonic-gate kernel_session_t *session_p;
8330Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
8340Sstevel@tonic-gate crypto_object_find_update_t obj_fu;
8350Sstevel@tonic-gate int r;
8360Sstevel@tonic-gate
8370Sstevel@tonic-gate if (!kernel_initialized)
8380Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
8390Sstevel@tonic-gate
8400Sstevel@tonic-gate /* check for invalid arguments */
8410Sstevel@tonic-gate if (((phObject == NULL) && (ulMaxObjectCount != 0)) ||
8420Sstevel@tonic-gate (pulObjectCount == NULL)) {
8430Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
8440Sstevel@tonic-gate }
8450Sstevel@tonic-gate
8460Sstevel@tonic-gate if (ulMaxObjectCount == 0) {
8470Sstevel@tonic-gate /* don't need to do anything, just return */
8480Sstevel@tonic-gate *pulObjectCount = 0;
8490Sstevel@tonic-gate return (CKR_OK);
8500Sstevel@tonic-gate }
8510Sstevel@tonic-gate
8520Sstevel@tonic-gate /*
8530Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
8540Sstevel@tonic-gate * reference count.
8550Sstevel@tonic-gate */
8560Sstevel@tonic-gate rv = handle2session(sh, &session_p);
8570Sstevel@tonic-gate if (rv != CKR_OK)
8580Sstevel@tonic-gate return (rv);
8590Sstevel@tonic-gate
8600Sstevel@tonic-gate /* Acquire the slot lock */
8610Sstevel@tonic-gate pslot = slot_table[session_p->ses_slotid];
8620Sstevel@tonic-gate (void) pthread_mutex_lock(&pslot->sl_mutex);
8630Sstevel@tonic-gate
8640Sstevel@tonic-gate /* Acquire the session lock */
8650Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
8660Sstevel@tonic-gate ses_lock_held = B_TRUE;
8670Sstevel@tonic-gate
8680Sstevel@tonic-gate /* Check to see if find operation is active */
8690Sstevel@tonic-gate if (!(session_p->find_objects.flags & CRYPTO_OPERATION_ACTIVE)) {
8700Sstevel@tonic-gate rv = CKR_OPERATION_NOT_INITIALIZED;
8710Sstevel@tonic-gate goto clean_exit;
8720Sstevel@tonic-gate }
8730Sstevel@tonic-gate
8740Sstevel@tonic-gate /*
8750Sstevel@tonic-gate * Similar to C_FindObjectInit(), if the HW provider supports object
8760Sstevel@tonic-gate * creation, we call the respective ioctl to find objects.
8770Sstevel@tonic-gate * Otherwise, all the objects are created in the library and we do
8780Sstevel@tonic-gate * the find objects solely in the library.
8790Sstevel@tonic-gate */
8800Sstevel@tonic-gate if (pslot->sl_func_list.fl_object_create) {
8810Sstevel@tonic-gate obj_fu.fu_session = session_p->k_session;
8820Sstevel@tonic-gate obj_fu.fu_max_count = ulMaxObjectCount;
8830Sstevel@tonic-gate obj_fu.fu_handles = (char *)calloc(1,
8840Sstevel@tonic-gate ulMaxObjectCount * sizeof (crypto_object_id_t));
8850Sstevel@tonic-gate if (obj_fu.fu_handles == NULL) {
8860Sstevel@tonic-gate rv = CKR_HOST_MEMORY;
8870Sstevel@tonic-gate goto clean_exit;
8880Sstevel@tonic-gate }
8890Sstevel@tonic-gate
8900Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_FIND_UPDATE,
8910Sstevel@tonic-gate &obj_fu)) < 0) {
8920Sstevel@tonic-gate if (errno != EINTR)
8930Sstevel@tonic-gate break;
8940Sstevel@tonic-gate }
8950Sstevel@tonic-gate if (r < 0) {
8960Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
8970Sstevel@tonic-gate } else {
8980Sstevel@tonic-gate rv = crypto2pkcs11_error_number(
8990Sstevel@tonic-gate obj_fu.fu_return_value);
9000Sstevel@tonic-gate }
9010Sstevel@tonic-gate
9020Sstevel@tonic-gate if (rv == CKR_OK) {
9030Sstevel@tonic-gate rv = process_found_objects(session_p, phObject,
9040Sstevel@tonic-gate pulObjectCount, obj_fu);
9050Sstevel@tonic-gate }
9060Sstevel@tonic-gate free(obj_fu.fu_handles);
9070Sstevel@tonic-gate
9080Sstevel@tonic-gate } else {
9090Sstevel@tonic-gate
9100Sstevel@tonic-gate kernel_find_objects(session_p, phObject, ulMaxObjectCount,
9110Sstevel@tonic-gate pulObjectCount);
9120Sstevel@tonic-gate rv = CKR_OK;
9130Sstevel@tonic-gate }
9140Sstevel@tonic-gate
9150Sstevel@tonic-gate clean_exit:
9160Sstevel@tonic-gate /* decrement the session count, and release the session lock */
9170Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
9180Sstevel@tonic-gate
9190Sstevel@tonic-gate /* release the slot lock */
9200Sstevel@tonic-gate (void) pthread_mutex_unlock(&pslot->sl_mutex);
9210Sstevel@tonic-gate
9220Sstevel@tonic-gate return (rv);
9230Sstevel@tonic-gate }
9240Sstevel@tonic-gate
9250Sstevel@tonic-gate
9260Sstevel@tonic-gate CK_RV
C_FindObjectsFinal(CK_SESSION_HANDLE sh)9270Sstevel@tonic-gate C_FindObjectsFinal(CK_SESSION_HANDLE sh)
9280Sstevel@tonic-gate {
9290Sstevel@tonic-gate
9300Sstevel@tonic-gate kernel_session_t *session_p;
9310Sstevel@tonic-gate CK_RV rv;
9320Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
9330Sstevel@tonic-gate kernel_slot_t *pslot;
9340Sstevel@tonic-gate crypto_object_find_final_t obj_ff;
9350Sstevel@tonic-gate int r;
9360Sstevel@tonic-gate
9370Sstevel@tonic-gate if (!kernel_initialized)
9380Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
9390Sstevel@tonic-gate
9400Sstevel@tonic-gate /*
9410Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
9420Sstevel@tonic-gate * reference count.
9430Sstevel@tonic-gate */
9440Sstevel@tonic-gate rv = handle2session(sh, &session_p);
9450Sstevel@tonic-gate if (rv != CKR_OK)
9460Sstevel@tonic-gate return (rv);
9470Sstevel@tonic-gate
9480Sstevel@tonic-gate /* Acquire the session lock */
9490Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
9500Sstevel@tonic-gate ses_lock_held = B_TRUE;
9510Sstevel@tonic-gate
9520Sstevel@tonic-gate /* Check to see if find operation is active */
9530Sstevel@tonic-gate if (!(session_p->find_objects.flags & CRYPTO_OPERATION_ACTIVE)) {
9540Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
9550Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED);
9560Sstevel@tonic-gate }
9570Sstevel@tonic-gate
9580Sstevel@tonic-gate /*
9590Sstevel@tonic-gate * Similar to C_FindObjectInit(), if the HW provider supports object
9600Sstevel@tonic-gate * creation, we need to call the CRYPTO_OBJECT_FIND_FINAL ioctl.
9610Sstevel@tonic-gate */
9620Sstevel@tonic-gate pslot = slot_table[session_p->ses_slotid];
9630Sstevel@tonic-gate if (pslot->sl_func_list.fl_object_create) {
9640Sstevel@tonic-gate obj_ff.ff_session = session_p->k_session;
9650Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_FIND_FINAL,
9660Sstevel@tonic-gate &obj_ff)) < 0) {
9670Sstevel@tonic-gate if (errno != EINTR)
9680Sstevel@tonic-gate break;
9690Sstevel@tonic-gate }
9700Sstevel@tonic-gate if (r < 0) {
9710Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
9720Sstevel@tonic-gate } else {
9730Sstevel@tonic-gate rv = crypto2pkcs11_error_number(
9740Sstevel@tonic-gate obj_ff.ff_return_value);
9750Sstevel@tonic-gate }
9760Sstevel@tonic-gate
9770Sstevel@tonic-gate /* only need to reset find_objects.flags */
9780Sstevel@tonic-gate if (rv == CKR_OK) {
9790Sstevel@tonic-gate session_p->find_objects.flags = 0;
9800Sstevel@tonic-gate }
9810Sstevel@tonic-gate
9820Sstevel@tonic-gate } else {
9830Sstevel@tonic-gate /*
9840Sstevel@tonic-gate * The find object operations were done in the library, we
9850Sstevel@tonic-gate * need to cleanup find_objects context.
9860Sstevel@tonic-gate */
9870Sstevel@tonic-gate kernel_find_objects_final(session_p);
9880Sstevel@tonic-gate rv = CKR_OK;
9890Sstevel@tonic-gate }
9900Sstevel@tonic-gate
9910Sstevel@tonic-gate /* decrement the session count, and release the lock */
9920Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
9930Sstevel@tonic-gate return (rv);
9940Sstevel@tonic-gate }
995