dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_kernel / common / kernelSlottable.c
blob1cada4b315c13dfb02941875a8cf08e0e52824b8
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <errno.h>
26 #include <security/cryptoki.h>
27 #include <strings.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;
35 static CK_RV
36 kernel_get_slot_number()
38 CK_RV rv;
39 crypto_get_provider_list_t *pl;
40 int r;
42 pl = malloc(sizeof (crypto_get_provider_list_t));
43 if (pl == NULL)
44 return (CKR_HOST_MEMORY);
46 pl->pl_count = 0;
47 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_LIST, pl)) < 0) {
48 if (errno != EINTR)
49 break;
51 if (r < 0) {
52 rv = CKR_FUNCTION_FAILED;
53 } else {
54 if (pl->pl_return_value != CRYPTO_SUCCESS) {
55 rv = crypto2pkcs11_error_number(pl->pl_return_value);
56 } else {
57 rv = CKR_OK;
61 if (rv == CKR_OK) {
62 slot_count = pl->pl_count;
65 (void) free(pl);
66 return (rv);
70 * This function will be used by metaslot to get the kernel
71 * provider's threshold value for the supported mechanisms.
73 void
74 _SUNW_GetThreshold(void *thresholdp)
77 cipher_mechs_threshold_t *tp = (cipher_mechs_threshold_t *)thresholdp;
78 kernel_slot_t *pslot;
79 int i;
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++) {
90 tp[i].mech_type =
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.
102 static CK_RV
103 kernel_get_func_list(kernel_slot_t *pslot)
105 CK_RV rv = CKR_OK;
106 crypto_get_function_list_t fl;
107 int r;
108 int i;
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) {
114 if (errno != EINTR)
115 break;
117 if (r < 0) {
118 rv = CKR_FUNCTION_FAILED;
119 } else {
120 if (fl.fl_return_value == 0) {
121 rv = CKR_OK;
122 } else {
123 rv = crypto2pkcs11_error_number(fl.fl_return_value);
127 if (rv != CKR_OK) {
128 return (rv);
131 /* copy data structure received from kernel */
132 pslot->sl_func_list = fl.fl_list;
134 pslot->sl_flags = 0;
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;
158 return (CKR_OK);
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.
168 CK_RV
169 kernel_slottable_init()
171 int i, cur_slot_num = 0;
172 CK_RV rv = CKR_OK;
173 crypto_get_provider_list_t *pl = NULL;
174 int r;
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) {
182 return (rv);
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;
196 goto failed;
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]);
207 goto failed;
210 cur_slot_num = i;
214 * Get the provider ID for each slot from kernel and save it in the
215 * slot table.
217 pl = malloc(slot_count * sizeof (crypto_get_provider_list_t));
218 if (pl == NULL) {
219 rv = CKR_HOST_MEMORY;
220 goto failed;
223 pl->pl_count = slot_count;
224 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_LIST, pl)) < 0) {
225 if (errno != EINTR)
226 break;
228 if (r < 0) {
229 rv = CKR_FUNCTION_FAILED;
230 goto failed;
231 } else {
232 if (pl->pl_return_value != CRYPTO_SUCCESS) {
233 rv = crypto2pkcs11_error_number(pl->pl_return_value);
234 goto failed;
235 } else {
236 rv = CKR_OK;
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
246 * the slot table.
248 for (i = 0; i < slot_count; i++) {
249 rv = kernel_get_func_list(slot_table[i]);
250 if (rv != CKR_OK) {
251 goto failed;
255 (void) free(pl);
256 return (CKR_OK);
258 failed:
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);
265 (void) free(pl);
266 return (rv);