1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include <stdlib.h>
30*0Sstevel@tonic-gate #include <strings.h>
31*0Sstevel@tonic-gate #include <security/cryptoki.h>
32*0Sstevel@tonic-gate #include <cryptoutil.h>
33*0Sstevel@tonic-gate #include <errno.h>
34*0Sstevel@tonic-gate #include <sys/crypto/api.h>
35*0Sstevel@tonic-gate #include <sys/crypto/common.h>
36*0Sstevel@tonic-gate #include <sys/crypto/ioctl.h>
37*0Sstevel@tonic-gate #include <sys/crypto/spi.h>
38*0Sstevel@tonic-gate #include "kernelGlobal.h"
39*0Sstevel@tonic-gate #include "kernelSlot.h"
40*0Sstevel@tonic-gate
41*0Sstevel@tonic-gate
42*0Sstevel@tonic-gate /* ARGSUSED */
43*0Sstevel@tonic-gate CK_RV
C_GetSlotList(CK_BBOOL tokenPresent,CK_SLOT_ID_PTR pSlotList,CK_ULONG_PTR pulCount)44*0Sstevel@tonic-gate C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
45*0Sstevel@tonic-gate CK_ULONG_PTR pulCount)
46*0Sstevel@tonic-gate {
47*0Sstevel@tonic-gate int i;
48*0Sstevel@tonic-gate
49*0Sstevel@tonic-gate if (!kernel_initialized)
50*0Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
51*0Sstevel@tonic-gate
52*0Sstevel@tonic-gate if (pulCount == NULL) {
53*0Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
54*0Sstevel@tonic-gate }
55*0Sstevel@tonic-gate
56*0Sstevel@tonic-gate if (pSlotList == NULL) {
57*0Sstevel@tonic-gate *pulCount = slot_count;
58*0Sstevel@tonic-gate return (CKR_OK);
59*0Sstevel@tonic-gate }
60*0Sstevel@tonic-gate
61*0Sstevel@tonic-gate if (*pulCount < slot_count) {
62*0Sstevel@tonic-gate *pulCount = slot_count;
63*0Sstevel@tonic-gate return (CKR_BUFFER_TOO_SMALL);
64*0Sstevel@tonic-gate }
65*0Sstevel@tonic-gate
66*0Sstevel@tonic-gate *pulCount = slot_count;
67*0Sstevel@tonic-gate
68*0Sstevel@tonic-gate /*
69*0Sstevel@tonic-gate * The slotID returned to an application will be the index to
70*0Sstevel@tonic-gate * the slot_table. The library will map to the provider_id when
71*0Sstevel@tonic-gate * making any ioctl call.
72*0Sstevel@tonic-gate */
73*0Sstevel@tonic-gate for (i = 0; i < slot_count; i++) {
74*0Sstevel@tonic-gate pSlotList[i] = i;
75*0Sstevel@tonic-gate }
76*0Sstevel@tonic-gate
77*0Sstevel@tonic-gate return (CKR_OK);
78*0Sstevel@tonic-gate }
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gate
81*0Sstevel@tonic-gate CK_RV
C_GetSlotInfo(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR pInfo)82*0Sstevel@tonic-gate C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
83*0Sstevel@tonic-gate {
84*0Sstevel@tonic-gate CK_RV rv;
85*0Sstevel@tonic-gate crypto_get_provider_info_t gi;
86*0Sstevel@tonic-gate int r;
87*0Sstevel@tonic-gate
88*0Sstevel@tonic-gate if (!kernel_initialized)
89*0Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
90*0Sstevel@tonic-gate
91*0Sstevel@tonic-gate if (slotID >= slot_count) {
92*0Sstevel@tonic-gate return (CKR_SLOT_ID_INVALID);
93*0Sstevel@tonic-gate }
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gate if (pInfo == NULL)
96*0Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
97*0Sstevel@tonic-gate
98*0Sstevel@tonic-gate /* kernel provider numbers start with 0 */
99*0Sstevel@tonic-gate gi.gi_provider_id = slot_table[slotID]->sl_provider_id;
100*0Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_INFO, &gi)) < 0) {
101*0Sstevel@tonic-gate if (errno != EINTR)
102*0Sstevel@tonic-gate break;
103*0Sstevel@tonic-gate }
104*0Sstevel@tonic-gate if (r < 0) {
105*0Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
106*0Sstevel@tonic-gate } else {
107*0Sstevel@tonic-gate if (gi.gi_return_value != CRYPTO_SUCCESS) {
108*0Sstevel@tonic-gate rv = crypto2pkcs11_error_number(
109*0Sstevel@tonic-gate gi.gi_return_value);
110*0Sstevel@tonic-gate } else {
111*0Sstevel@tonic-gate rv = CKR_OK;
112*0Sstevel@tonic-gate }
113*0Sstevel@tonic-gate }
114*0Sstevel@tonic-gate
115*0Sstevel@tonic-gate if (rv == CKR_OK) {
116*0Sstevel@tonic-gate bcopy(gi.gi_provider_data.pd_prov_desc,
117*0Sstevel@tonic-gate pInfo->slotDescription, CRYPTO_PROVIDER_DESCR_MAX_LEN);
118*0Sstevel@tonic-gate bcopy(gi.gi_provider_data.pd_manufacturerID,
119*0Sstevel@tonic-gate pInfo->manufacturerID, CRYPTO_EXT_SIZE_MANUF);
120*0Sstevel@tonic-gate pInfo->flags = CKF_TOKEN_PRESENT | CKF_HW_SLOT;
121*0Sstevel@tonic-gate pInfo->hardwareVersion.major =
122*0Sstevel@tonic-gate gi.gi_provider_data.pd_hardware_version.cv_major;
123*0Sstevel@tonic-gate pInfo->hardwareVersion.minor =
124*0Sstevel@tonic-gate gi.gi_provider_data.pd_hardware_version.cv_minor;
125*0Sstevel@tonic-gate pInfo->firmwareVersion.major =
126*0Sstevel@tonic-gate gi.gi_provider_data.pd_firmware_version.cv_major;
127*0Sstevel@tonic-gate pInfo->firmwareVersion.minor =
128*0Sstevel@tonic-gate gi.gi_provider_data.pd_firmware_version.cv_minor;
129*0Sstevel@tonic-gate }
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gate return (rv);
132*0Sstevel@tonic-gate }
133*0Sstevel@tonic-gate
134*0Sstevel@tonic-gate
135*0Sstevel@tonic-gate CK_RV
C_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)136*0Sstevel@tonic-gate C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
137*0Sstevel@tonic-gate {
138*0Sstevel@tonic-gate CK_RV rv;
139*0Sstevel@tonic-gate crypto_get_provider_info_t gi;
140*0Sstevel@tonic-gate int r;
141*0Sstevel@tonic-gate
142*0Sstevel@tonic-gate if (!kernel_initialized)
143*0Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
144*0Sstevel@tonic-gate
145*0Sstevel@tonic-gate if (slotID >= slot_count)
146*0Sstevel@tonic-gate return (CKR_SLOT_ID_INVALID);
147*0Sstevel@tonic-gate
148*0Sstevel@tonic-gate if (pInfo == NULL)
149*0Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
150*0Sstevel@tonic-gate
151*0Sstevel@tonic-gate gi.gi_provider_id = slot_table[slotID]->sl_provider_id;
152*0Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_INFO, &gi)) < 0) {
153*0Sstevel@tonic-gate if (errno != EINTR)
154*0Sstevel@tonic-gate break;
155*0Sstevel@tonic-gate }
156*0Sstevel@tonic-gate if (r < 0) {
157*0Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
158*0Sstevel@tonic-gate } else {
159*0Sstevel@tonic-gate rv = crypto2pkcs11_error_number(gi.gi_return_value);
160*0Sstevel@tonic-gate }
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate if (rv == CKR_OK) {
163*0Sstevel@tonic-gate bcopy(gi.gi_provider_data.pd_label, pInfo->label,
164*0Sstevel@tonic-gate CRYPTO_EXT_SIZE_LABEL);
165*0Sstevel@tonic-gate bcopy(gi.gi_provider_data.pd_manufacturerID,
166*0Sstevel@tonic-gate pInfo->manufacturerID, CRYPTO_EXT_SIZE_MANUF);
167*0Sstevel@tonic-gate bcopy(gi.gi_provider_data.pd_model, pInfo->model,
168*0Sstevel@tonic-gate CRYPTO_EXT_SIZE_MODEL);
169*0Sstevel@tonic-gate bcopy(gi.gi_provider_data.pd_serial_number,
170*0Sstevel@tonic-gate pInfo->serialNumber, CRYPTO_EXT_SIZE_SERIAL);
171*0Sstevel@tonic-gate pInfo->flags = gi.gi_provider_data.pd_flags;
172*0Sstevel@tonic-gate pInfo->ulMaxSessionCount =
173*0Sstevel@tonic-gate gi.gi_provider_data.pd_max_session_count;
174*0Sstevel@tonic-gate pInfo->ulSessionCount =
175*0Sstevel@tonic-gate gi.gi_provider_data.pd_session_count;
176*0Sstevel@tonic-gate pInfo->ulMaxRwSessionCount =
177*0Sstevel@tonic-gate gi.gi_provider_data.pd_max_rw_session_count;
178*0Sstevel@tonic-gate pInfo->ulRwSessionCount =
179*0Sstevel@tonic-gate gi.gi_provider_data.pd_rw_session_count;
180*0Sstevel@tonic-gate pInfo->ulMaxPinLen =
181*0Sstevel@tonic-gate gi.gi_provider_data.pd_max_pin_len;
182*0Sstevel@tonic-gate pInfo->ulMinPinLen =
183*0Sstevel@tonic-gate gi.gi_provider_data.pd_min_pin_len;
184*0Sstevel@tonic-gate pInfo->ulTotalPublicMemory =
185*0Sstevel@tonic-gate gi.gi_provider_data.pd_total_public_memory;
186*0Sstevel@tonic-gate pInfo->ulFreePublicMemory =
187*0Sstevel@tonic-gate gi.gi_provider_data.pd_free_public_memory;
188*0Sstevel@tonic-gate pInfo->ulTotalPrivateMemory =
189*0Sstevel@tonic-gate gi.gi_provider_data.pd_total_private_memory;
190*0Sstevel@tonic-gate pInfo->ulFreePrivateMemory =
191*0Sstevel@tonic-gate gi.gi_provider_data.pd_free_private_memory;
192*0Sstevel@tonic-gate pInfo->hardwareVersion.major =
193*0Sstevel@tonic-gate gi.gi_provider_data.pd_hardware_version.cv_major;
194*0Sstevel@tonic-gate pInfo->hardwareVersion.minor =
195*0Sstevel@tonic-gate gi.gi_provider_data.pd_hardware_version.cv_minor;
196*0Sstevel@tonic-gate pInfo->firmwareVersion.major =
197*0Sstevel@tonic-gate gi.gi_provider_data.pd_firmware_version.cv_major;
198*0Sstevel@tonic-gate pInfo->firmwareVersion.minor =
199*0Sstevel@tonic-gate gi.gi_provider_data.pd_firmware_version.cv_minor;
200*0Sstevel@tonic-gate (void) strncpy((char *)pInfo->utcTime,
201*0Sstevel@tonic-gate (const char *)gi.gi_provider_data.pd_time,
202*0Sstevel@tonic-gate CRYPTO_EXT_SIZE_TIME);
203*0Sstevel@tonic-gate
204*0Sstevel@tonic-gate }
205*0Sstevel@tonic-gate
206*0Sstevel@tonic-gate return (rv);
207*0Sstevel@tonic-gate
208*0Sstevel@tonic-gate
209*0Sstevel@tonic-gate }
210*0Sstevel@tonic-gate
211*0Sstevel@tonic-gate /*ARGSUSED*/
212*0Sstevel@tonic-gate CK_RV
C_WaitForSlotEvent(CK_FLAGS flags,CK_SLOT_ID_PTR pSlot,CK_VOID_PTR pReserved)213*0Sstevel@tonic-gate C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
214*0Sstevel@tonic-gate {
215*0Sstevel@tonic-gate if (!kernel_initialized)
216*0Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
217*0Sstevel@tonic-gate
218*0Sstevel@tonic-gate return (CKR_FUNCTION_NOT_SUPPORTED);
219*0Sstevel@tonic-gate }
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate
222*0Sstevel@tonic-gate CK_RV
C_GetMechanismList(CK_SLOT_ID slotID,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)223*0Sstevel@tonic-gate C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
224*0Sstevel@tonic-gate CK_ULONG_PTR pulCount)
225*0Sstevel@tonic-gate {
226*0Sstevel@tonic-gate CK_MECHANISM_TYPE type;
227*0Sstevel@tonic-gate CK_RV rv;
228*0Sstevel@tonic-gate CK_FLAGS flags;
229*0Sstevel@tonic-gate CK_ULONG specified_count, count = 0;
230*0Sstevel@tonic-gate crypto_get_provider_mechanisms_t *pm, tmp;
231*0Sstevel@tonic-gate crypto_get_provider_mechanism_info_t mechanism_info;
232*0Sstevel@tonic-gate crypto_provider_id_t provider_id;
233*0Sstevel@tonic-gate size_t alloc_bytes;
234*0Sstevel@tonic-gate int i, r;
235*0Sstevel@tonic-gate
236*0Sstevel@tonic-gate if (!kernel_initialized)
237*0Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
238*0Sstevel@tonic-gate
239*0Sstevel@tonic-gate if (slotID >= slot_count)
240*0Sstevel@tonic-gate return (CKR_SLOT_ID_INVALID);
241*0Sstevel@tonic-gate
242*0Sstevel@tonic-gate /* kernel provider numbers start with 0 */
243*0Sstevel@tonic-gate provider_id = slot_table[slotID]->sl_provider_id;
244*0Sstevel@tonic-gate
245*0Sstevel@tonic-gate if (pMechanismList != NULL) {
246*0Sstevel@tonic-gate if (pulCount == NULL) {
247*0Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
248*0Sstevel@tonic-gate } else if (*pulCount == 0) {
249*0Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
250*0Sstevel@tonic-gate }
251*0Sstevel@tonic-gate }
252*0Sstevel@tonic-gate specified_count = *pulCount;
253*0Sstevel@tonic-gate tmp.pm_provider_id = provider_id;
254*0Sstevel@tonic-gate tmp.pm_count = 0;
255*0Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISMS,
256*0Sstevel@tonic-gate &tmp)) < 0) {
257*0Sstevel@tonic-gate if (errno != EINTR)
258*0Sstevel@tonic-gate break;
259*0Sstevel@tonic-gate }
260*0Sstevel@tonic-gate if (r < 0) {
261*0Sstevel@tonic-gate return (CKR_FUNCTION_FAILED);
262*0Sstevel@tonic-gate } else {
263*0Sstevel@tonic-gate if (tmp.pm_return_value != CRYPTO_SUCCESS) {
264*0Sstevel@tonic-gate rv = crypto2pkcs11_error_number(tmp.pm_return_value);
265*0Sstevel@tonic-gate return (rv);
266*0Sstevel@tonic-gate }
267*0Sstevel@tonic-gate alloc_bytes = sizeof (crypto_get_provider_mechanisms_t) +
268*0Sstevel@tonic-gate (tmp.pm_count - 1) * sizeof (crypto_mech_name_t);
269*0Sstevel@tonic-gate }
270*0Sstevel@tonic-gate
271*0Sstevel@tonic-gate pm = malloc(alloc_bytes);
272*0Sstevel@tonic-gate if (pm == NULL)
273*0Sstevel@tonic-gate return (CKR_HOST_MEMORY);
274*0Sstevel@tonic-gate
275*0Sstevel@tonic-gate pm->pm_provider_id = provider_id;
276*0Sstevel@tonic-gate pm->pm_count = tmp.pm_count;
277*0Sstevel@tonic-gate
278*0Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISMS, pm)) < 0) {
279*0Sstevel@tonic-gate if (errno != EINTR)
280*0Sstevel@tonic-gate break;
281*0Sstevel@tonic-gate }
282*0Sstevel@tonic-gate if (r < 0) {
283*0Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
284*0Sstevel@tonic-gate } else {
285*0Sstevel@tonic-gate rv = crypto2pkcs11_error_number(pm->pm_return_value);
286*0Sstevel@tonic-gate }
287*0Sstevel@tonic-gate
288*0Sstevel@tonic-gate if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL)
289*0Sstevel@tonic-gate goto clean_exit;
290*0Sstevel@tonic-gate
291*0Sstevel@tonic-gate for (i = 0; i < pm->pm_count; i++) {
292*0Sstevel@tonic-gate mechanism_info.mi_provider_id = provider_id;
293*0Sstevel@tonic-gate bcopy(&pm->pm_list[i][0], mechanism_info.mi_mechanism_name,
294*0Sstevel@tonic-gate sizeof (crypto_mech_name_t));
295*0Sstevel@tonic-gate
296*0Sstevel@tonic-gate /*
297*0Sstevel@tonic-gate * Get each mechanism's flags.
298*0Sstevel@tonic-gate * The ioctl should not fail since the mechanism info is
299*0Sstevel@tonic-gate * already in the kernel and a call doesn't have to be made
300*0Sstevel@tonic-gate * to the provider. If it fails, nothing can be done other
301*0Sstevel@tonic-gate * than skip the mechanism.
302*0Sstevel@tonic-gate */
303*0Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO,
304*0Sstevel@tonic-gate &mechanism_info)) < 0) {
305*0Sstevel@tonic-gate if (errno != EINTR)
306*0Sstevel@tonic-gate break;
307*0Sstevel@tonic-gate }
308*0Sstevel@tonic-gate if (r < 0) {
309*0Sstevel@tonic-gate continue;
310*0Sstevel@tonic-gate }
311*0Sstevel@tonic-gate
312*0Sstevel@tonic-gate if (mechanism_info.mi_return_value != CRYPTO_SUCCESS)
313*0Sstevel@tonic-gate continue;
314*0Sstevel@tonic-gate
315*0Sstevel@tonic-gate flags = mechanism_info.mi_flags;
316*0Sstevel@tonic-gate
317*0Sstevel@tonic-gate /*
318*0Sstevel@tonic-gate * Atomic flags are not part of PKCS#11 so we filter
319*0Sstevel@tonic-gate * them out here.
320*0Sstevel@tonic-gate */
321*0Sstevel@tonic-gate flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC |
322*0Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC |
323*0Sstevel@tonic-gate CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
324*0Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER_ATOMIC |
325*0Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER_ATOMIC |
326*0Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
327*0Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC);
328*0Sstevel@tonic-gate
329*0Sstevel@tonic-gate /* mechanism has no PKCS#11 flags, so don't report it */
330*0Sstevel@tonic-gate if (flags == 0)
331*0Sstevel@tonic-gate continue;
332*0Sstevel@tonic-gate
333*0Sstevel@tonic-gate /*
334*0Sstevel@tonic-gate * The kernel framework has a pseudo mechanism
335*0Sstevel@tonic-gate * for RNG which we remove from the list of mechanisms.
336*0Sstevel@tonic-gate */
337*0Sstevel@tonic-gate if (strcmp(&pm->pm_list[i][0], "random") != 0) {
338*0Sstevel@tonic-gate
339*0Sstevel@tonic-gate if (pkcs11_str2mech(&pm->pm_list[i][0],
340*0Sstevel@tonic-gate &type) != CKR_OK)
341*0Sstevel@tonic-gate continue;
342*0Sstevel@tonic-gate
343*0Sstevel@tonic-gate if (pMechanismList != NULL && rv == CKR_OK &&
344*0Sstevel@tonic-gate (count < specified_count))
345*0Sstevel@tonic-gate pMechanismList[count] = type;
346*0Sstevel@tonic-gate
347*0Sstevel@tonic-gate count++;
348*0Sstevel@tonic-gate }
349*0Sstevel@tonic-gate
350*0Sstevel@tonic-gate }
351*0Sstevel@tonic-gate
352*0Sstevel@tonic-gate if (pMechanismList != NULL && (count > specified_count))
353*0Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
354*0Sstevel@tonic-gate
355*0Sstevel@tonic-gate *pulCount = count;
356*0Sstevel@tonic-gate
357*0Sstevel@tonic-gate clean_exit:
358*0Sstevel@tonic-gate free(pm);
359*0Sstevel@tonic-gate return (rv);
360*0Sstevel@tonic-gate }
361*0Sstevel@tonic-gate
362*0Sstevel@tonic-gate
363*0Sstevel@tonic-gate CK_RV
C_GetMechanismInfo(CK_SLOT_ID slotID,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)364*0Sstevel@tonic-gate C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
365*0Sstevel@tonic-gate CK_MECHANISM_INFO_PTR pInfo)
366*0Sstevel@tonic-gate {
367*0Sstevel@tonic-gate uint32_t k_mi_flags;
368*0Sstevel@tonic-gate CK_RV rv;
369*0Sstevel@tonic-gate
370*0Sstevel@tonic-gate if (!kernel_initialized)
371*0Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
372*0Sstevel@tonic-gate
373*0Sstevel@tonic-gate if (slotID >= slot_count)
374*0Sstevel@tonic-gate return (CKR_SLOT_ID_INVALID);
375*0Sstevel@tonic-gate
376*0Sstevel@tonic-gate if (pInfo == NULL) {
377*0Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
378*0Sstevel@tonic-gate }
379*0Sstevel@tonic-gate
380*0Sstevel@tonic-gate rv = get_mechanism_info(slot_table[slotID], type, pInfo, &k_mi_flags);
381*0Sstevel@tonic-gate
382*0Sstevel@tonic-gate return (rv);
383*0Sstevel@tonic-gate }
384*0Sstevel@tonic-gate
385*0Sstevel@tonic-gate
386*0Sstevel@tonic-gate /*ARGSUSED*/
387*0Sstevel@tonic-gate CK_RV
C_InitToken(CK_SLOT_ID slotID,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel)388*0Sstevel@tonic-gate C_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
389*0Sstevel@tonic-gate CK_UTF8CHAR_PTR pLabel)
390*0Sstevel@tonic-gate {
391*0Sstevel@tonic-gate if (!kernel_initialized)
392*0Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
393*0Sstevel@tonic-gate
394*0Sstevel@tonic-gate return (CKR_FUNCTION_NOT_SUPPORTED);
395*0Sstevel@tonic-gate }
396*0Sstevel@tonic-gate
397*0Sstevel@tonic-gate /*ARGSUSED*/
398*0Sstevel@tonic-gate CK_RV
C_InitPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)399*0Sstevel@tonic-gate C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
400*0Sstevel@tonic-gate {
401*0Sstevel@tonic-gate if (!kernel_initialized)
402*0Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
403*0Sstevel@tonic-gate
404*0Sstevel@tonic-gate return (CKR_FUNCTION_NOT_SUPPORTED);
405*0Sstevel@tonic-gate }
406*0Sstevel@tonic-gate
407*0Sstevel@tonic-gate
408*0Sstevel@tonic-gate CK_RV
C_SetPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pOldPin,CK_ULONG ulOldLen,CK_UTF8CHAR_PTR pNewPin,CK_ULONG ulNewLen)409*0Sstevel@tonic-gate C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
410*0Sstevel@tonic-gate CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
411*0Sstevel@tonic-gate {
412*0Sstevel@tonic-gate CK_RV rv = CKR_OK;
413*0Sstevel@tonic-gate kernel_session_t *session_p;
414*0Sstevel@tonic-gate boolean_t ses_lock_held = B_FALSE;
415*0Sstevel@tonic-gate crypto_set_pin_t setpin;
416*0Sstevel@tonic-gate int r;
417*0Sstevel@tonic-gate
418*0Sstevel@tonic-gate if (!kernel_initialized)
419*0Sstevel@tonic-gate return (CKR_CRYPTOKI_NOT_INITIALIZED);
420*0Sstevel@tonic-gate
421*0Sstevel@tonic-gate /*
422*0Sstevel@tonic-gate * Obtain the session pointer. Also, increment the session
423*0Sstevel@tonic-gate * reference count.
424*0Sstevel@tonic-gate */
425*0Sstevel@tonic-gate rv = handle2session(hSession, &session_p);
426*0Sstevel@tonic-gate if (rv != CKR_OK)
427*0Sstevel@tonic-gate return (rv);
428*0Sstevel@tonic-gate
429*0Sstevel@tonic-gate /* Make sure it is a RW session. */
430*0Sstevel@tonic-gate if (session_p->ses_RO) {
431*0Sstevel@tonic-gate rv = CKR_SESSION_READ_ONLY;
432*0Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
433*0Sstevel@tonic-gate return (rv);
434*0Sstevel@tonic-gate }
435*0Sstevel@tonic-gate
436*0Sstevel@tonic-gate /* Lock the session and make the CRYPTO_SET_PIN ioctl call. */
437*0Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
438*0Sstevel@tonic-gate ses_lock_held = B_TRUE;
439*0Sstevel@tonic-gate
440*0Sstevel@tonic-gate setpin.sp_session = session_p->k_session;
441*0Sstevel@tonic-gate setpin.sp_old_pin = (char *)pOldPin;
442*0Sstevel@tonic-gate setpin.sp_old_len = ulOldLen;
443*0Sstevel@tonic-gate setpin.sp_new_pin = (char *)pNewPin;
444*0Sstevel@tonic-gate setpin.sp_new_len = ulNewLen;
445*0Sstevel@tonic-gate
446*0Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_SET_PIN, &setpin)) < 0) {
447*0Sstevel@tonic-gate if (errno != EINTR)
448*0Sstevel@tonic-gate break;
449*0Sstevel@tonic-gate }
450*0Sstevel@tonic-gate if (r < 0) {
451*0Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
452*0Sstevel@tonic-gate } else {
453*0Sstevel@tonic-gate rv = crypto2pkcs11_error_number(setpin.sp_return_value);
454*0Sstevel@tonic-gate }
455*0Sstevel@tonic-gate
456*0Sstevel@tonic-gate REFRELE(session_p, ses_lock_held);
457*0Sstevel@tonic-gate return (rv);
458*0Sstevel@tonic-gate }
459