4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
32 #include <security/cryptoki.h>
33 #include "kernelGlobal.h"
34 #include "kernelObject.h"
35 #include "kernelSession.h"
38 #include <cryptoutil.h>
41 C_CreateObject(CK_SESSION_HANDLE hSession
,
42 CK_ATTRIBUTE_PTR pTemplate
,
44 CK_OBJECT_HANDLE_PTR phObject
)
48 kernel_session_t
*session_p
;
49 boolean_t ses_lock_held
= B_FALSE
;
51 if (!kernel_initialized
)
52 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
54 if ((pTemplate
== NULL
) || (ulCount
== 0) ||
56 return (CKR_ARGUMENTS_BAD
);
60 * Obtain the session pointer. Also, increment the session
63 rv
= handle2session(hSession
, &session_p
);
67 /* Create a new object. */
68 rv
= kernel_add_object(pTemplate
, ulCount
, phObject
, session_p
);
71 * Decrement the session reference count.
72 * We do not hold the session lock.
74 REFRELE(session_p
, ses_lock_held
);
81 C_CopyObject(CK_SESSION_HANDLE hSession
, CK_OBJECT_HANDLE hObject
,
82 CK_ATTRIBUTE_PTR pTemplate
, CK_ULONG ulCount
,
83 CK_OBJECT_HANDLE_PTR phNewObject
)
87 kernel_session_t
*session_p
;
88 boolean_t ses_lock_held
= B_FALSE
;
89 kernel_object_t
*old_object
;
90 kernel_object_t
*new_object
= NULL
;
91 crypto_object_copy_t object_copy
;
92 CK_BBOOL is_pri_obj
= FALSE
;
93 CK_BBOOL is_token_obj
= FALSE
;
97 if (!kernel_initialized
)
98 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
100 /* Check arguments */
101 if (((ulCount
> 0) && (pTemplate
== NULL
)) ||
102 (phNewObject
== NULL
)) {
103 return (CKR_ARGUMENTS_BAD
);
107 * Obtain the session pointer. Also, increment the session
110 rv
= handle2session(hSession
, &session_p
);
114 /* Obtain the object pointer. */
115 HANDLE2OBJECT(hObject
, old_object
, rv
);
118 * Decrement the session reference count.
119 * We do not hold the session lock.
121 REFRELE(session_p
, ses_lock_held
);
125 (void) pthread_mutex_lock(&old_object
->object_mutex
);
127 if (old_object
->is_lib_obj
) {
129 * Copy the old object to a new object.
130 * The 3rd argument with TRUE value indicates that
131 * everything in the object will be duplicated.
133 rv
= kernel_copy_object(old_object
, &new_object
, B_TRUE
,
135 (void) pthread_mutex_unlock(&old_object
->object_mutex
);
136 if ((rv
!= CKR_OK
) || (new_object
== NULL
)) {
138 * Most likely we ran out of space.
139 * Decrement the session reference count.
140 * We do not hold the session lock.
142 OBJ_REFRELE(old_object
);
143 REFRELE(session_p
, ses_lock_held
);
147 new_object
->is_lib_obj
= B_TRUE
;
149 /* Modify the object attribute if requested */
150 for (i
= 0; i
< ulCount
; i
++) {
151 /* Set the requested attribute into the new object. */
152 rv
= kernel_set_attribute(new_object
, &pTemplate
[i
],
156 kernel_cleanup_object(new_object
);
159 * Decrement the session reference count.
160 * We do not hold the session lock.
162 OBJ_REFRELE(old_object
);
163 REFRELE(session_p
, ses_lock_held
);
168 /* Insert the new object into this session's object list. */
169 kernel_add_object_to_session(new_object
, session_p
);
172 * Decrement the session reference count.
173 * We do not hold the session lock.
175 OBJ_REFRELE(old_object
);
176 REFRELE(session_p
, ses_lock_held
);
178 /* set handle of the new object */
179 *phNewObject
= (CK_ULONG
)new_object
;
183 * The old object was created in the HW provider.
184 * First, create an object wrapper in library.
186 new_object
= calloc(1, sizeof (kernel_object_t
));
187 if (new_object
== NULL
) {
188 (void) pthread_mutex_unlock(&old_object
->object_mutex
);
189 OBJ_REFRELE(old_object
);
190 REFRELE(session_p
, ses_lock_held
);
191 return (CKR_HOST_MEMORY
);
194 /* Call CRYPTO_OBJECT_COPY ioctl to get a new object. */
195 object_copy
.oc_session
= session_p
->k_session
;
196 object_copy
.oc_handle
= old_object
->k_handle
;
197 (void) pthread_mutex_unlock(&old_object
->object_mutex
);
198 object_copy
.oc_count
= ulCount
;
199 object_copy
.oc_new_attributes
= NULL
;
201 rv
= process_object_attributes(pTemplate
, ulCount
,
202 &object_copy
.oc_new_attributes
, &is_token_obj
);
208 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_COPY
,
209 &object_copy
)) < 0) {
214 rv
= CKR_FUNCTION_FAILED
;
216 rv
= crypto2pkcs11_error_number(
217 object_copy
.oc_return_value
);
220 /* Free the attributes' space allocated for ioctl */
221 free_object_attributes(object_copy
.oc_new_attributes
, ulCount
);
228 * Store the kernel object handle in the object wrapper and
229 * get the CKA_PRIVATE value of the new object.
231 new_object
->k_handle
= object_copy
.oc_new_handle
;
232 rv
= get_cka_private_value(session_p
, new_object
->k_handle
,
239 * Initialize other field of the object wrapper.
241 new_object
->is_lib_obj
= B_FALSE
;
242 new_object
->magic_marker
= KERNELTOKEN_OBJECT_MAGIC
;
243 new_object
->session_handle
= (CK_SESSION_HANDLE
)session_p
;
244 (void) pthread_mutex_init(&new_object
->object_mutex
, NULL
);
247 new_object
->bool_attr_mask
|= PRIVATE_BOOL_ON
;
249 new_object
->bool_attr_mask
&= ~PRIVATE_BOOL_ON
;
252 new_object
->bool_attr_mask
|= TOKEN_BOOL_ON
;
254 new_object
->bool_attr_mask
&= ~TOKEN_BOOL_ON
;
257 * Add the new copied object into the slot's token list
258 * or the session list. We don't hold the slot lock.
261 pslot
= slot_table
[session_p
->ses_slotid
];
264 * Decrement the session reference count.
265 * We do not hold the session lock.
267 OBJ_REFRELE(old_object
);
268 REFRELE(session_p
, ses_lock_held
);
270 /* Add into the slot token object list. */
271 kernel_add_token_object_to_slot(new_object
, pslot
);
273 kernel_add_object_to_session(new_object
, session_p
);
276 * Decrement the session reference count.
277 * We do not hold the session lock.
279 OBJ_REFRELE(old_object
);
280 REFRELE(session_p
, ses_lock_held
);
283 /* set handle of the new object */
284 *phNewObject
= (CK_ULONG
)new_object
;
290 if (new_object
!= NULL
) {
291 (void) free(new_object
);
294 OBJ_REFRELE(old_object
);
295 REFRELE(session_p
, ses_lock_held
);
301 C_DestroyObject(CK_SESSION_HANDLE hSession
, CK_OBJECT_HANDLE hObject
)
304 kernel_object_t
*object_p
;
305 kernel_session_t
*session_p
= (kernel_session_t
*)(hSession
);
306 kernel_slot_t
*pslot
;
307 boolean_t ses_lock_held
= B_FALSE
;
308 CK_SESSION_HANDLE creating_session
;
310 if (!kernel_initialized
)
311 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
314 * The reason that we don't call handle2session is because
315 * the argument hSession may not be the creating_session of
316 * the object to be destroyed, and we want to avoid the lock
317 * contention. The handle2session will be called later for
318 * the creating_session.
320 if ((session_p
== NULL
) ||
321 (session_p
->magic_marker
!= KERNELTOKEN_SESSION_MAGIC
)) {
322 return (CKR_SESSION_HANDLE_INVALID
);
325 /* Obtain the object pointer without incrementing reference count. */
326 HANDLE2OBJECT_DESTROY(hObject
, object_p
, rv
);
331 /* Only session objects can be destroyed at a read-only session. */
332 if ((session_p
->ses_RO
) &&
333 (object_p
->bool_attr_mask
& TOKEN_BOOL_ON
)) {
334 return (CKR_SESSION_READ_ONLY
);
338 * If the object is a session object, obtain the session handle
339 * which object belongs to. For a token object, we will use the
340 * session handle from the caller, because the session used to
341 * create the token object may no longer exist.
343 if (!(object_p
->bool_attr_mask
& TOKEN_BOOL_ON
))
344 creating_session
= object_p
->session_handle
;
346 creating_session
= hSession
;
348 rv
= handle2session(creating_session
, &session_p
);
354 * Set OBJECT_IS_DELETING flag so any access to this
355 * object will be rejected.
357 (void) pthread_mutex_lock(&object_p
->object_mutex
);
358 if (object_p
->obj_delete_sync
& OBJECT_IS_DELETING
) {
359 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
360 REFRELE(session_p
, ses_lock_held
);
361 return (CKR_OBJECT_HANDLE_INVALID
);
363 object_p
->obj_delete_sync
|= OBJECT_IS_DELETING
;
364 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
366 if (object_p
->bool_attr_mask
& TOKEN_BOOL_ON
) {
368 * The first FALSE boolean argument indicates that the caller
369 * does not hold the slot lock. The second FALSE boolean
370 * argument indicates that the caller wants to clean up the
371 * object in the HW provider also.
373 pslot
= slot_table
[session_p
->ses_slotid
];
374 rv
= kernel_delete_token_object(pslot
, session_p
, object_p
,
378 * The first FALSE boolean argument indicates that the caller
379 * does not hold the session lock. The second FALSE boolean
380 * argument indicates that the caller wants to clean the object
381 * in the HW provider also.
383 rv
= kernel_delete_session_object(session_p
, object_p
, B_FALSE
,
387 * Decrement the session reference count.
388 * We do not hold the session lock.
390 REFRELE(session_p
, ses_lock_held
);
396 C_GetAttributeValue(CK_SESSION_HANDLE hSession
, CK_OBJECT_HANDLE hObject
,
397 CK_ATTRIBUTE_PTR pTemplate
, CK_ULONG ulCount
)
400 CK_RV rv
= CKR_OK
, rv1
= CKR_OK
;
401 kernel_object_t
*object_p
;
402 kernel_session_t
*session_p
;
403 boolean_t ses_lock_held
= B_FALSE
;
404 crypto_object_get_attribute_value_t obj_get_attr
;
407 if (!kernel_initialized
)
408 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
410 if ((pTemplate
== NULL
) || (ulCount
== 0))
411 return (CKR_ARGUMENTS_BAD
);
414 * Obtain the session pointer. Also, increment the session
417 rv
= handle2session(hSession
, &session_p
);
421 /* Obtain the object pointer. */
422 HANDLE2OBJECT(hObject
, object_p
, rv
);
425 * Decrement the session reference count.
426 * We do not hold the session lock.
428 REFRELE(session_p
, ses_lock_held
);
432 /* Acquire the lock on the object. */
433 (void) pthread_mutex_lock(&object_p
->object_mutex
);
435 if (object_p
->is_lib_obj
) {
437 * The object was created in the library. The library
438 * contains the value information of each attribute.
440 for (i
= 0; i
< ulCount
; i
++) {
442 * Get the value of each attribute in the template.
443 * (We must process EVERY attribute in the template.)
445 rv
= kernel_get_attribute(object_p
, &pTemplate
[i
]);
447 /* At least we catch some type of error. */
451 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
454 * The object was created in HW provider, call ioctl to get
455 * the values of attributes.
457 obj_get_attr
.og_session
= session_p
->k_session
;
458 obj_get_attr
.og_handle
= object_p
->k_handle
;
459 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
460 obj_get_attr
.og_count
= ulCount
;
462 rv
= process_object_attributes(pTemplate
, ulCount
,
463 &obj_get_attr
.og_attributes
, NULL
);
468 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE
,
469 &obj_get_attr
)) < 0) {
474 rv
= CKR_FUNCTION_FAILED
;
476 rv
= crypto2pkcs11_error_number(
477 obj_get_attr
.og_return_value
);
481 * The error codes CKR_ATTRIBUTE_SENSITIVE,
482 * CKR_ATTRIBUTE_TYPE_INVALID, and CKR_BUFFER_TOO_SMALL
483 * do not denote true errors for this function. If a call
484 * returns any of these three values, then the call must
485 * nonetheless have processed every attribute in the
486 * template. Every attribute in the template whose value
487 * can be returned will be returned.
489 if ((rv
== CKR_OK
) ||
490 (rv
== CKR_ATTRIBUTE_SENSITIVE
) ||
491 (rv
== CKR_ATTRIBUTE_TYPE_INVALID
) ||
492 (rv
== CKR_BUFFER_TOO_SMALL
)) {
493 rv1
= get_object_attributes(pTemplate
, ulCount
,
494 obj_get_attr
.og_attributes
);
500 /* Free the attributes' allocated for the ioctl call. */
501 free_object_attributes(obj_get_attr
.og_attributes
, ulCount
);
506 * Decrement the session reference count.
507 * We do not hold the session lock.
509 OBJ_REFRELE(object_p
);
510 REFRELE(session_p
, ses_lock_held
);
516 C_SetAttributeValue(CK_SESSION_HANDLE hSession
, CK_OBJECT_HANDLE hObject
,
517 CK_ATTRIBUTE_PTR pTemplate
, CK_ULONG ulCount
)
520 kernel_object_t
*object_p
;
521 kernel_object_t
*new_object
= NULL
;
522 kernel_session_t
*session_p
;
523 boolean_t ses_lock_held
= B_FALSE
;
524 crypto_object_set_attribute_value_t obj_set_attr
;
527 if (!kernel_initialized
)
528 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
530 if ((pTemplate
== NULL
) || (ulCount
== 0))
531 return (CKR_ARGUMENTS_BAD
);
534 * Obtain the session pointer. Also, increment the session
537 rv
= handle2session(hSession
, &session_p
);
541 /* Obtain the object pointer. */
542 HANDLE2OBJECT(hObject
, object_p
, rv
);
545 * Decrement the session reference count.
546 * We do not hold the session lock.
548 REFRELE(session_p
, ses_lock_held
);
552 /* lock the object */
553 (void) pthread_mutex_lock(&object_p
->object_mutex
);
556 * If the object was created in the HW provider, changing its
557 * attributes' values need to be done in the provider too.
559 if (!object_p
->is_lib_obj
) {
561 /* Cannot modify a token object with a READ-ONLY session */
562 if (session_p
->ses_RO
&&
563 (object_p
->bool_attr_mask
& TOKEN_BOOL_ON
)) {
564 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
565 rv
= CKR_SESSION_READ_ONLY
;
569 obj_set_attr
.sa_session
= session_p
->k_session
;
570 obj_set_attr
.sa_handle
= object_p
->k_handle
;
571 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
572 obj_set_attr
.sa_count
= ulCount
;
573 rv
= process_object_attributes(pTemplate
, ulCount
,
574 &obj_set_attr
.sa_attributes
, NULL
);
579 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_SET_ATTRIBUTE_VALUE
,
580 &obj_set_attr
)) < 0) {
585 rv
= CKR_FUNCTION_FAILED
;
587 rv
= crypto2pkcs11_error_number(
588 obj_set_attr
.sa_return_value
);
591 /* Free the attributes' space allocated for the ioctl call. */
592 free_object_attributes(obj_set_attr
.sa_attributes
, ulCount
);
597 * if we come here, the object must have been created in the
598 * library. The work will be done completely in the library.
600 * Copy the old object to a new object. We work on the copied
601 * version because in case of error we still keep the old one
604 rv
= kernel_copy_object(object_p
, &new_object
, B_FALSE
, NULL
);
605 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
606 if ((rv
!= CKR_OK
) || (new_object
== NULL
)) {
608 * Most likely we ran out of space.
609 * Decrement the session reference count.
610 * We do not hold the session lock.
615 for (i
= 0; i
< ulCount
; i
++) {
616 /* Set the requested attribute into the new object. */
617 rv
= kernel_set_attribute(new_object
, &pTemplate
[i
], B_FALSE
,
621 kernel_cleanup_object(new_object
);
627 * We've successfully set all the requested attributes.
628 * Merge the new object with the old object, then destory
629 * the new one. The reason to do the merging is because we
630 * have to keep the original object handle (address of object).
632 (void) pthread_mutex_lock(&object_p
->object_mutex
);
633 kernel_merge_object(object_p
, new_object
);
634 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
637 if (new_object
!= NULL
)
638 (void) free(new_object
);
641 * Decrement the session reference count.
642 * We do not hold the session lock.
644 OBJ_REFRELE(object_p
);
645 REFRELE(session_p
, ses_lock_held
);
652 C_GetObjectSize(CK_SESSION_HANDLE hSession
, CK_OBJECT_HANDLE hObject
,
653 CK_ULONG_PTR pulSize
)
657 kernel_object_t
*object_p
;
658 kernel_session_t
*session_p
;
659 boolean_t ses_lock_held
= B_FALSE
;
660 crypto_object_get_size_t obj_gs
;
663 if (!kernel_initialized
)
664 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
666 /* Check if pulSize is valid */
667 if (pulSize
== NULL
) {
668 return (CKR_ARGUMENTS_BAD
);
672 * Obtain the session pointer. Also, increment the session
675 rv
= handle2session(hSession
, &session_p
);
679 /* Obtain the object pointer. */
680 HANDLE2OBJECT(hObject
, object_p
, rv
);
683 * Decrement the session reference count.
684 * We do not hold the session lock.
686 REFRELE(session_p
, ses_lock_held
);
690 /* Acquire the lock on the object. */
691 (void) pthread_mutex_lock(&object_p
->object_mutex
);
693 if (!object_p
->is_lib_obj
) {
695 * The object was created in HW provider, call the
696 * CRYPTO_OBJECT_GET_SIZE ioctl.
698 obj_gs
.gs_session
= session_p
->k_session
;
699 obj_gs
.gs_handle
= object_p
->k_handle
;
700 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
701 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_GET_SIZE
,
707 rv
= CKR_FUNCTION_FAILED
;
709 rv
= crypto2pkcs11_error_number(
710 obj_gs
.gs_return_value
);
714 *pulSize
= obj_gs
.gs_size
;
718 rv
= kernel_get_object_size(object_p
, pulSize
);
719 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
723 * Decrement the session reference count.
724 * We do not hold the session lock.
726 OBJ_REFRELE(object_p
);
727 REFRELE(session_p
, ses_lock_held
);
733 C_FindObjectsInit(CK_SESSION_HANDLE sh
, CK_ATTRIBUTE_PTR pTemplate
,
737 kernel_session_t
*session_p
;
738 boolean_t ses_lock_held
= B_FALSE
;
739 kernel_slot_t
*pslot
;
740 crypto_object_find_init_t obj_fi
;
743 if (!kernel_initialized
)
744 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
746 /* Check the arguments */
747 if ((ulCount
> 0) && (pTemplate
== NULL
)) {
748 return (CKR_ARGUMENTS_BAD
);
752 * Obtain the session pointer. Also, increment the session
755 rv
= handle2session(sh
, &session_p
);
759 /* Acquire the session lock */
760 (void) pthread_mutex_lock(&session_p
->session_mutex
);
761 ses_lock_held
= B_TRUE
;
763 /* Check to see if find operation is already active */
764 if (session_p
->find_objects
.flags
& CRYPTO_OPERATION_ACTIVE
) {
765 /* decrement the session count, and unlock the mutex */
766 REFRELE(session_p
, ses_lock_held
);
767 return (CKR_OPERATION_ACTIVE
);
770 * This active flag will remain ON until application calls
771 * C_FindObjectsFinal.
773 session_p
->find_objects
.flags
= CRYPTO_OPERATION_ACTIVE
;
778 * If the HW provider supports object creation, we call the
779 * CRYPTO_OBJECT_FIND_INIT ioctl to initialize object finding.
780 * Otherwise, all the objects are created in the library and we
781 * do the find objects solely in the library.
783 pslot
= slot_table
[session_p
->ses_slotid
];
784 if (pslot
->sl_func_list
.fl_object_create
) {
785 obj_fi
.fi_session
= session_p
->k_session
;
786 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
787 ses_lock_held
= B_FALSE
;
788 obj_fi
.fi_count
= ulCount
;
789 rv
= process_object_attributes(pTemplate
, ulCount
,
790 &obj_fi
.fi_attributes
, NULL
);
792 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_FIND_INIT
,
798 rv
= CKR_FUNCTION_FAILED
;
800 rv
= crypto2pkcs11_error_number(
801 obj_fi
.fi_return_value
);
805 /* Free the attributes' space allocated for the ioctl call. */
806 free_object_attributes(obj_fi
.fi_attributes
, ulCount
);
809 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
810 ses_lock_held
= B_FALSE
;
811 rv
= kernel_find_objects_init(session_p
, pTemplate
, ulCount
);
815 (void) pthread_mutex_lock(&session_p
->session_mutex
);
816 session_p
->find_objects
.flags
= 0;
817 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
820 /* decrement the session count, and unlock the mutex */
821 REFRELE(session_p
, ses_lock_held
);
827 C_FindObjects(CK_SESSION_HANDLE sh
, CK_OBJECT_HANDLE_PTR phObject
,
828 CK_ULONG ulMaxObjectCount
, CK_ULONG_PTR pulObjectCount
)
831 kernel_slot_t
*pslot
;
832 kernel_session_t
*session_p
;
833 boolean_t ses_lock_held
= B_FALSE
;
834 crypto_object_find_update_t obj_fu
;
837 if (!kernel_initialized
)
838 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
840 /* check for invalid arguments */
841 if (((phObject
== NULL
) && (ulMaxObjectCount
!= 0)) ||
842 (pulObjectCount
== NULL
)) {
843 return (CKR_ARGUMENTS_BAD
);
846 if (ulMaxObjectCount
== 0) {
847 /* don't need to do anything, just return */
853 * Obtain the session pointer. Also, increment the session
856 rv
= handle2session(sh
, &session_p
);
860 /* Acquire the slot lock */
861 pslot
= slot_table
[session_p
->ses_slotid
];
862 (void) pthread_mutex_lock(&pslot
->sl_mutex
);
864 /* Acquire the session lock */
865 (void) pthread_mutex_lock(&session_p
->session_mutex
);
866 ses_lock_held
= B_TRUE
;
868 /* Check to see if find operation is active */
869 if (!(session_p
->find_objects
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
870 rv
= CKR_OPERATION_NOT_INITIALIZED
;
875 * Similar to C_FindObjectInit(), if the HW provider supports object
876 * creation, we call the respective ioctl to find objects.
877 * Otherwise, all the objects are created in the library and we do
878 * the find objects solely in the library.
880 if (pslot
->sl_func_list
.fl_object_create
) {
881 obj_fu
.fu_session
= session_p
->k_session
;
882 obj_fu
.fu_max_count
= ulMaxObjectCount
;
883 obj_fu
.fu_handles
= (char *)calloc(1,
884 ulMaxObjectCount
* sizeof (crypto_object_id_t
));
885 if (obj_fu
.fu_handles
== NULL
) {
886 rv
= CKR_HOST_MEMORY
;
890 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_FIND_UPDATE
,
896 rv
= CKR_FUNCTION_FAILED
;
898 rv
= crypto2pkcs11_error_number(
899 obj_fu
.fu_return_value
);
903 rv
= process_found_objects(session_p
, phObject
,
904 pulObjectCount
, obj_fu
);
906 free(obj_fu
.fu_handles
);
910 kernel_find_objects(session_p
, phObject
, ulMaxObjectCount
,
916 /* decrement the session count, and release the session lock */
917 REFRELE(session_p
, ses_lock_held
);
919 /* release the slot lock */
920 (void) pthread_mutex_unlock(&pslot
->sl_mutex
);
927 C_FindObjectsFinal(CK_SESSION_HANDLE sh
)
930 kernel_session_t
*session_p
;
932 boolean_t ses_lock_held
= B_FALSE
;
933 kernel_slot_t
*pslot
;
934 crypto_object_find_final_t obj_ff
;
937 if (!kernel_initialized
)
938 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
941 * Obtain the session pointer. Also, increment the session
944 rv
= handle2session(sh
, &session_p
);
948 /* Acquire the session lock */
949 (void) pthread_mutex_lock(&session_p
->session_mutex
);
950 ses_lock_held
= B_TRUE
;
952 /* Check to see if find operation is active */
953 if (!(session_p
->find_objects
.flags
& CRYPTO_OPERATION_ACTIVE
)) {
954 REFRELE(session_p
, ses_lock_held
);
955 return (CKR_OPERATION_NOT_INITIALIZED
);
959 * Similar to C_FindObjectInit(), if the HW provider supports object
960 * creation, we need to call the CRYPTO_OBJECT_FIND_FINAL ioctl.
962 pslot
= slot_table
[session_p
->ses_slotid
];
963 if (pslot
->sl_func_list
.fl_object_create
) {
964 obj_ff
.ff_session
= session_p
->k_session
;
965 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_FIND_FINAL
,
971 rv
= CKR_FUNCTION_FAILED
;
973 rv
= crypto2pkcs11_error_number(
974 obj_ff
.ff_return_value
);
977 /* only need to reset find_objects.flags */
979 session_p
->find_objects
.flags
= 0;
984 * The find object operations were done in the library, we
985 * need to cleanup find_objects context.
987 kernel_find_objects_final(session_p
);
991 /* decrement the session count, and release the lock */
992 REFRELE(session_p
, ses_lock_held
);