4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <security/cryptoki.h>
28 #include <sys/crypto/ioctl.h>
29 #include "kernelGlobal.h"
30 #include "kernelSlot.h"
32 CK_ULONG slot_count
= 0;
33 kernel_slot_t
**slot_table
;
36 kernel_get_slot_number()
39 crypto_get_provider_list_t
*pl
;
42 pl
= malloc(sizeof (crypto_get_provider_list_t
));
44 return (CKR_HOST_MEMORY
);
47 while ((r
= ioctl(kernel_fd
, CRYPTO_GET_PROVIDER_LIST
, pl
)) < 0) {
52 rv
= CKR_FUNCTION_FAILED
;
54 if (pl
->pl_return_value
!= CRYPTO_SUCCESS
) {
55 rv
= crypto2pkcs11_error_number(pl
->pl_return_value
);
62 slot_count
= pl
->pl_count
;
70 * This function will be used by metaslot to get the kernel
71 * provider's threshold value for the supported mechanisms.
74 _SUNW_GetThreshold(void *thresholdp
)
77 cipher_mechs_threshold_t
*tp
= (cipher_mechs_threshold_t
*)thresholdp
;
82 * We alway use the 1st slot in the kernel to
83 * get the threshold because all the kernel
84 * slots will have the same threshold value
85 * with the same mechanism.
87 pslot
= slot_table
[0];
89 for (i
= 0; i
< pslot
->total_threshold_count
; i
++) {
91 pslot
->sl_mechs_threshold
[i
].mech_type
;
92 tp
[i
].mech_threshold
=
93 pslot
->sl_mechs_threshold
[i
].mech_threshold
;
98 * To retrieve the crypto_function_list structure with boolean entries
99 * indicating which functions are supported by the hardware provider which
100 * is specified by the slot ID.
103 kernel_get_func_list(kernel_slot_t
*pslot
)
106 crypto_get_function_list_t fl
;
110 (void) memset(&fl
, 0, sizeof (fl
));
111 fl
.fl_provider_id
= pslot
->sl_provider_id
;
113 while ((r
= ioctl(kernel_fd
, CRYPTO_GET_FUNCTION_LIST
, &fl
)) < 0) {
118 rv
= CKR_FUNCTION_FAILED
;
120 if (fl
.fl_return_value
== 0) {
123 rv
= crypto2pkcs11_error_number(fl
.fl_return_value
);
131 /* copy data structure received from kernel */
132 pslot
->sl_func_list
= fl
.fl_list
;
135 if (fl
.fl_list
.prov_is_hash_limited
) {
136 pslot
->sl_flags
|= CRYPTO_LIMITED_HASH_SUPPORT
;
137 pslot
->sl_hash_max_inlen
= fl
.fl_list
.prov_hash_limit
;
140 if (fl
.fl_list
.prov_is_hmac_limited
) {
141 pslot
->sl_flags
|= CRYPTO_LIMITED_HMAC_SUPPORT
;
142 pslot
->sl_hmac_max_inlen
= fl
.fl_list
.prov_hmac_limit
;
145 if (fl
.fl_list
.prov_is_hash_limited
| fl
.fl_list
.prov_is_hmac_limited
) {
146 pslot
->sl_threshold
= fl
.fl_list
.prov_hash_threshold
;
149 pslot
->total_threshold_count
= fl
.fl_list
.total_threshold_count
;
151 for (i
= 0; i
< pslot
->total_threshold_count
; i
++) {
152 pslot
->sl_mechs_threshold
[i
].mech_type
=
153 fl
.fl_list
.fl_threshold
[i
].mech_type
;
154 pslot
->sl_mechs_threshold
[i
].mech_threshold
=
155 fl
.fl_list
.fl_threshold
[i
].mech_threshold
;
162 * Initialize the slot table.
164 * This function is called from C_Initialize() only. Since C_Initialize()
165 * holds the global mutex lock, there is no need to acquire another lock
166 * in this routine to protect the slot table.
169 kernel_slottable_init()
171 int i
, cur_slot_num
= 0;
173 crypto_get_provider_list_t
*pl
= NULL
;
177 * Find out how many slots are presented from kernel hardware
178 * providers. If there is no slot presented, just return.
180 rv
= kernel_get_slot_number();
181 if (rv
!= CKR_OK
|| slot_count
== 0) {
185 /* Allocate space for the slot table */
186 slot_table
= malloc(sizeof (kernel_slot_t
*) * slot_count
);
187 if (slot_table
== NULL
) {
188 return (CKR_HOST_MEMORY
);
191 /* For each slot, allocate space and initialize the slot's mutex. */
192 for (i
= 0; i
< slot_count
; i
++) {
193 slot_table
[i
] = malloc(sizeof (kernel_slot_t
));
194 if (slot_table
[i
] == NULL
) {
195 rv
= CKR_HOST_MEMORY
;
199 slot_table
[i
]->sl_sess_list
= NULL
;
200 slot_table
[i
]->sl_tobj_list
= NULL
;
201 slot_table
[i
]->sl_state
= CKU_PUBLIC
;
203 /* Initialize this slot's mutex */
204 if (pthread_mutex_init(&slot_table
[i
]->sl_mutex
, NULL
) != 0) {
205 rv
= CKR_FUNCTION_FAILED
;
206 (void) free(slot_table
[i
]);
214 * Get the provider ID for each slot from kernel and save it in the
217 pl
= malloc(slot_count
* sizeof (crypto_get_provider_list_t
));
219 rv
= CKR_HOST_MEMORY
;
223 pl
->pl_count
= slot_count
;
224 while ((r
= ioctl(kernel_fd
, CRYPTO_GET_PROVIDER_LIST
, pl
)) < 0) {
229 rv
= CKR_FUNCTION_FAILED
;
232 if (pl
->pl_return_value
!= CRYPTO_SUCCESS
) {
233 rv
= crypto2pkcs11_error_number(pl
->pl_return_value
);
240 for (i
= 0; i
< slot_count
; i
++) {
241 slot_table
[i
]->sl_provider_id
= pl
->pl_list
[i
].pe_provider_id
;
245 * Get the function list for each slot from kernel and save it in
248 for (i
= 0; i
< slot_count
; i
++) {
249 rv
= kernel_get_func_list(slot_table
[i
]);
259 for (i
= 0; i
< cur_slot_num
; i
++) {
260 (void) pthread_mutex_destroy(&slot_table
[i
]->sl_mutex
);
261 (void) free(slot_table
[i
]);
264 (void) free(slot_table
);