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