1 /*
2 * Copyright Copyright 2003 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms specified in the COPYING file
4 * distributed with the Net-SNMP package.
5 */
6
7 /*
8 * pkcs.c
9 */
10
11 #include <net-snmp/net-snmp-config.h>
12 #ifdef NETSNMP_USE_PKCS11
13 #include <net-snmp/types.h>
14 #include <net-snmp/output_api.h>
15 #include <net-snmp/config_api.h>
16 #include <net-snmp/library/snmp_api.h>
17 #include <net-snmp/library/tools.h>
18 #include <net-snmp/library/keytools.h>
19 #include <net-snmp/library/scapi.h>
20 #include <net-snmp/library/callback.h>
21 #include <security/cryptoki.h>
22
23 typedef struct netsnmp_pkcs_slot_session_s {
24 CK_SLOT_ID sid;
25 CK_SESSION_HANDLE hdl;
26 } netsnmp_pkcs_slot_session;
27
28 typedef struct netsnmp_pkcs_slot_info_s {
29 int count;
30 netsnmp_pkcs_slot_session *pSession;
31 } netsnmp_pkcs_slot_info;
32
33 static CK_RV get_session_handle(CK_MECHANISM_TYPE, CK_FLAGS,\
34 CK_SESSION_HANDLE_PTR);
35 static CK_RV get_slot_session_handle(netsnmp_pkcs_slot_session *,\
36 CK_SESSION_HANDLE_PTR);
37 static char *pkcserr_string(CK_RV);
38 static int free_slots(int, int, void *, void *);
39
40 static netsnmp_pkcs_slot_info *pSlot = NULL;
41
42 /*
43 * initialize the Cryptoki library.
44 */
45 int
pkcs_init(void)46 pkcs_init(void)
47 {
48 CK_RV rv;
49 CK_ULONG slotcount;
50 CK_SLOT_ID_PTR pSlotList = NULL;
51 netsnmp_pkcs_slot_session *tmp;
52 int i, rval = SNMPERR_SUCCESS;
53 /* Initialize pkcs */
54 if ((rv = C_Initialize(NULL)) != CKR_OK) {
55 DEBUGMSGTL(("pkcs_init", "C_Initialize failed: %s",
56 pkcserr_string(rv)));
57 return SNMPERR_SC_NOT_CONFIGURED;
58 }
59
60 /* Get slot count */
61 rv = C_GetSlotList(1, NULL_PTR, &slotcount);
62 if (rv != CKR_OK || slotcount == 0) {
63 DEBUGMSGTL(("pkcs_init", "C_GetSlotList failed: %s",
64 pkcserr_string(rv)));
65 QUITFUN(SNMPERR_GENERR, pkcs_init_quit);
66 }
67
68 /* Found at least one slot, allocate memory for slot list */
69 pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID));
70 pSlot = malloc(sizeof (netsnmp_pkcs_slot_info));
71 pSlot->pSession = malloc(slotcount * sizeof (netsnmp_pkcs_slot_session));
72
73 if (pSlotList == NULL_PTR ||
74 pSlot == NULL_PTR ||
75 pSlot->pSession == NULL_PTR) {
76 DEBUGMSGTL(("pkcs_init","malloc failed."));
77 QUITFUN(SNMPERR_GENERR, pkcs_init_quit);
78 }
79
80 /* Get the list of slots */
81 if ((rv = C_GetSlotList(1, pSlotList, &slotcount)) != CKR_OK) {
82 DEBUGMSGTL(("pkcs_init", "C_GetSlotList failed: %s",
83 pkcserr_string(rv)));
84 QUITFUN(SNMPERR_GENERR, pkcs_init_quit);
85 }
86
87 /* initialize Slots structure */
88 pSlot->count = slotcount;
89 for (i = 0, tmp = pSlot->pSession; i < slotcount; i++, tmp++) {
90 tmp->sid = pSlotList[i];
91 tmp->hdl = NULL;
92 }
93
94 snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
95 free_slots, NULL);
96
97 pkcs_init_quit:
98 SNMP_FREE(pSlotList);
99 return rval;
100 }
101
102 /*
103 * close all the opened sessions when finished with Cryptoki library.
104 */
105 static int
free_slots(int majorID,int minorID,void * serverarg,void * clientarg)106 free_slots(int majorID, int minorID, void *serverarg, void *clientarg)
107 {
108 int slotcount, i;
109
110 if (pSlot != NULL) {
111 slotcount = pSlot->count;
112 for (i = 0; i < slotcount; i++) {
113 if (pSlot->pSession->hdl != NULL) {
114 free(pSlot->pSession->hdl);
115 }
116 }
117 free(pSlot);
118 }
119
120 (void) C_Finalize(NULL);
121 return 0;
122 }
123
124 /*
125 * generate random data
126 */
127 int
pkcs_random(u_char * buf,size_t buflen)128 pkcs_random(u_char * buf, size_t buflen)
129 {
130 CK_SESSION_HANDLE hSession;
131
132 if (pSlot != NULL &&
133 get_slot_session_handle(pSlot->pSession, &hSession) == CKR_OK &&
134 C_GenerateRandom(hSession, buf, buflen) == CKR_OK) {
135 return SNMPERR_SUCCESS;
136 }
137
138 return SNMPERR_GENERR;
139 }
140
141 /*
142 * retrieve the session handle from the first slot that supports the specified
143 * mechanism.
144 */
145 static CK_RV
get_session_handle(CK_MECHANISM_TYPE mech_type,CK_FLAGS flag,CK_SESSION_HANDLE_PTR sess)146 get_session_handle(CK_MECHANISM_TYPE mech_type, CK_FLAGS flag,
147 CK_SESSION_HANDLE_PTR sess)
148 {
149 CK_RV rv = CKR_OK;
150 CK_MECHANISM_INFO info;
151 netsnmp_pkcs_slot_session *p = NULL;
152 int i, slotcount = 0;
153
154 if (pSlot) {
155 slotcount = pSlot->count;
156 p = pSlot->pSession;
157 }
158
159 /* Find a slot with matching mechanism */
160 for (i = 0; i < slotcount; i++, p++) {
161 rv = C_GetMechanismInfo(p->sid, mech_type, &info);
162
163 if (rv != CKR_OK) {
164 continue; /* to the next slot */
165 } else {
166 if (info.flags & flag) {
167 rv = get_slot_session_handle(p, sess);
168 break; /* found */
169 }
170 }
171 }
172
173 /* Show error if no matching mechanism found */
174 if (i == slotcount) {
175 DEBUGMSGTL(("pkcs_init","No cryptographic provider for %s",
176 mech_type));
177 return CKR_SESSION_HANDLE_INVALID;
178 }
179
180 return rv;
181 }
182
183 /*
184 * retrieve the session handle from the specified slot.
185 */
186 static CK_RV
get_slot_session_handle(netsnmp_pkcs_slot_session * p,CK_SESSION_HANDLE_PTR sess)187 get_slot_session_handle(netsnmp_pkcs_slot_session *p,
188 CK_SESSION_HANDLE_PTR sess)
189 {
190 CK_RV rv = CKR_OK;
191 if (p == NULL) {
192 *sess = NULL;
193 return CKR_SESSION_HANDLE_INVALID;
194 }
195
196 if (p->hdl == NULL) {
197 /* Open a session */
198 rv = C_OpenSession(p->sid, CKF_SERIAL_SESSION,
199 NULL_PTR, NULL, &p->hdl);
200
201 if (rv != CKR_OK) {
202 DEBUGMSGTL(("get_slot_session_handle","can not open PKCS #11 session: %s",
203 pkcserr_string(rv)));
204 }
205 }
206 *sess = p->hdl;
207
208 return rv;
209 }
210
211 /*
212 * perform a signature operation to generate MAC.
213 */
214 int
pkcs_sign(CK_MECHANISM_TYPE mech_type,u_char * key,u_int keylen,u_char * msg,u_int msglen,u_char * mac,size_t * maclen)215 pkcs_sign(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen,
216 u_char * msg, u_int msglen, u_char * mac, size_t * maclen)
217 {
218 /*
219 * Key template
220 */
221 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
222 CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
223 CK_BBOOL truevalue = TRUE;
224 CK_BBOOL falsevalue= FALSE;
225 CK_ATTRIBUTE template[] = {
226 {CKA_CLASS, &class, sizeof (class)},
227 {CKA_KEY_TYPE, &keytype, sizeof (keytype)},
228 {CKA_SIGN, &truevalue, sizeof (truevalue)},
229 {CKA_TOKEN, &falsevalue, sizeof (falsevalue)},
230 {CKA_VALUE, key, keylen}
231 };
232 CK_SESSION_HANDLE hSession;
233 CK_MECHANISM mech;
234 CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0;
235 int rval = SNMPERR_SUCCESS;
236 if (get_session_handle(mech_type, CKF_SIGN, &hSession) != CKR_OK ||
237 hSession == NULL) {
238 QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
239 }
240
241 /* create a key object */
242 if (C_CreateObject(hSession, template,
243 (sizeof (template) / sizeof (CK_ATTRIBUTE)), &hkey) != CKR_OK) {
244 QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
245 }
246
247 mech.mechanism = mech_type;
248 mech.pParameter = NULL_PTR;
249 mech.ulParameterLen = 0;
250
251 /* initialize a signature operation */
252 if (C_SignInit(hSession, &mech, hkey) != CKR_OK ) {
253 QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
254 }
255 /* continue a multiple-part signature operation */
256 if (C_SignUpdate(hSession, msg, msglen) != CKR_OK) {
257 QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
258 }
259 /* finish a multiple-part signature operation */
260 if (C_SignFinal(hSession, mac, maclen) != CKR_OK) {
261 QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
262 }
263
264 pkcs_sign_quit:
265
266 if (key != (CK_OBJECT_HANDLE) 0) {
267 (void) C_DestroyObject(hSession, hkey);
268 }
269 return rval;
270 }
271
272 /*
273 * perform a message-digesting operation.
274 */
275 int
pkcs_digest(CK_MECHANISM_TYPE mech_type,u_char * msg,u_int msglen,u_char * digest,size_t * digestlen)276 pkcs_digest(CK_MECHANISM_TYPE mech_type, u_char * msg, u_int msglen,
277 u_char * digest, size_t * digestlen)
278 {
279 int rval = SNMPERR_SUCCESS;
280 CK_SESSION_HANDLE hSession;
281 CK_MECHANISM mech;
282 if (get_session_handle(mech_type, CKF_DIGEST, &hSession) != CKR_OK ||
283 hSession == NULL) {
284 QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
285 }
286
287 mech.mechanism = mech_type;
288 mech.pParameter = NULL_PTR;
289 mech.ulParameterLen = 0;
290
291 /* initialize a message-digesting operation */
292 if (C_DigestInit(hSession, &mech)!= CKR_OK ) {
293 QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
294 }
295 /* continue a multiple-part message-digesting operation */
296 if (C_DigestUpdate(hSession, msg, msglen) != CKR_OK ) {
297 QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
298 }
299 /* finish a multiple-part message-digesting operation */
300 if (C_DigestFinal(hSession, digest, digestlen) != CKR_OK) {
301 QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
302 }
303
304 pkcs_digest_quit:
305 return rval;
306 }
307
308 /*
309 * encrypt plaintext into ciphertext using key and iv.
310 */
311 int
pkcs_encrpyt(CK_MECHANISM_TYPE mech_type,u_char * key,u_int keylen,u_char * iv,u_int ivlen,u_char * plaintext,u_int ptlen,u_char * ciphertext,size_t * ctlen)312 pkcs_encrpyt(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen,
313 u_char * iv, u_int ivlen,
314 u_char * plaintext, u_int ptlen,
315 u_char * ciphertext, size_t * ctlen)
316 {
317 int rval = SNMPERR_SUCCESS;
318 int pad_size, offset;
319 /*
320 * Key template
321 */
322 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
323 CK_KEY_TYPE keytype = CKK_DES;
324 /* CK_KEY_TYPE AESkeytype = CKK_AES; */
325 CK_BBOOL truevalue = TRUE;
326 CK_BBOOL falsevalue = FALSE;
327
328 CK_ATTRIBUTE template[] = {
329 {CKA_CLASS, &class, sizeof (class)},
330 {CKA_KEY_TYPE, &keytype, sizeof (keytype)},
331 {CKA_ENCRYPT, &truevalue, sizeof (truevalue)},
332 {CKA_TOKEN, &falsevalue, sizeof (falsevalue)},
333 {CKA_VALUE, key, keylen}
334 };
335
336 CK_SESSION_HANDLE hSession;
337 CK_MECHANISM mech;
338 CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0;
339
340 if (get_session_handle(mech_type, CKF_ENCRYPT,
341 &hSession) != CKR_OK ||
342 hSession == NULL) {
343 QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
344 }
345
346 if (C_CreateObject(hSession, template,
347 (sizeof (template) / sizeof (CK_ATTRIBUTE)),
348 &hkey) != CKR_OK) {
349 QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
350 }
351
352 mech.mechanism = mech_type;
353 mech.pParameter = iv;
354 mech.ulParameterLen = ivlen;
355
356 /* initialize an encryption operation */
357 if (C_EncryptInit(hSession, &mech, hkey) != CKR_OK ) {
358 QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
359 }
360
361 /* for DES */
362 pad_size = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
363
364 if (ptlen + pad_size - ptlen % pad_size > *ctlen) {
365 QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
366 }
367
368 for (offset = 0; offset < ptlen; offset += pad_size) {
369 /* continue a multiple-part encryption operation */
370 if (C_EncryptUpdate(hSession, plaintext + offset, pad_size,
371 ciphertext + offset, ctlen) != CKR_OK) {
372 QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
373 }
374 }
375
376 /* finish a multiple-part encryption operation */
377 if (C_EncryptFinal(hSession, ciphertext + offset, ctlen) != CKR_OK) {
378 QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
379 }
380 *ctlen = offset;
381
382 pkcs_encrypt_quit:
383 if (key != (CK_OBJECT_HANDLE) 0) {
384 (void) C_DestroyObject(hSession, hkey);
385 }
386 return rval;
387 }
388
389 /*
390 * decrypt ciphertext into plaintext using key and iv.
391 */
392 int
pkcs_decrpyt(CK_MECHANISM_TYPE mech_type,u_char * key,u_int keylen,u_char * iv,u_int ivlen,u_char * ciphertext,u_int ctlen,u_char * plaintext,size_t * ptlen)393 pkcs_decrpyt(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen,
394 u_char * iv, u_int ivlen,
395 u_char * ciphertext, u_int ctlen,
396 u_char * plaintext, size_t * ptlen)
397 {
398 int rval = SNMPERR_SUCCESS;
399 /*
400 * Key template
401 */
402 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
403 CK_KEY_TYPE keytype = CKK_DES;
404 /* CK_KEY_TYPE AESkeytype = CKK_AES; */
405 CK_BBOOL truevalue = TRUE;
406 CK_BBOOL falsevalue= FALSE;
407 CK_ATTRIBUTE template[] = {
408 {CKA_CLASS, &class, sizeof (class)},
409 {CKA_KEY_TYPE, &keytype, sizeof (keytype)},
410 {CKA_DECRYPT, &truevalue, sizeof (truevalue)},
411 {CKA_TOKEN, &falsevalue, sizeof (falsevalue)},
412 {CKA_VALUE, key, keylen}
413 };
414 CK_SESSION_HANDLE hSession;
415 CK_MECHANISM mech;
416 CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0;
417
418 if (get_session_handle(mech_type, CKF_DECRYPT, &hSession) != CKR_OK ||
419 hSession == NULL) {
420 QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
421 }
422
423 if (C_CreateObject(hSession, template,
424 (sizeof (template) / sizeof (CK_ATTRIBUTE)), &hkey) != CKR_OK) {
425 QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
426 }
427
428 mech.mechanism = mech_type;
429 mech.pParameter = iv;
430 mech.ulParameterLen = ivlen;
431
432 /* initialize a decryption operation */
433 if (C_DecryptInit(hSession, &mech, hkey) != CKR_OK ) {
434 QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
435 }
436 /* continue a multiple-part decryption operation */
437 if (C_DecryptUpdate(hSession, ciphertext, ctlen, plaintext,
438 ptlen) != CKR_OK) {
439 QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
440 }
441 /* finish a multiple-part decryption operation */
442 if (C_DecryptFinal(hSession, plaintext, ptlen) != CKR_OK) {
443 QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
444 }
445
446 pkcs_decrypt_quit:
447 if (key != (CK_OBJECT_HANDLE) 0) {
448 (void) C_DestroyObject(hSession, hkey);
449 }
450 return rval;
451 }
452
453 /*
454 * Convert a passphrase into a master user key, Ku, according to the
455 * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM)
456 */
457 int
pkcs_generate_Ku(CK_MECHANISM_TYPE mech_type,u_char * passphrase,u_int pplen,u_char * Ku,size_t * kulen)458 pkcs_generate_Ku(CK_MECHANISM_TYPE mech_type, u_char * passphrase, u_int pplen,
459 u_char * Ku, size_t * kulen)
460 {
461 int rval = SNMPERR_SUCCESS, nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;
462 CK_SESSION_HANDLE hSession;
463 CK_MECHANISM mech;
464 u_int i, pindex = 0;
465 u_char buf[USM_LENGTH_KU_HASHBLOCK], *bufp;
466
467 if (get_session_handle(mech_type, CKF_DIGEST, &hSession) != CKR_OK ||
468 hSession == NULL) {
469 QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
470 }
471
472 mech.mechanism = mech_type;
473 mech.pParameter = NULL_PTR;
474 mech.ulParameterLen = 0;
475
476 /* initialize a message-digesting operation */
477 if (C_DigestInit(hSession, &mech)!= CKR_OK ) {
478 QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
479 }
480
481 while (nbytes > 0) {
482 bufp = buf;
483 for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) {
484 /*
485 * fill a buffer with the supplied passphrase. When the end
486 * of the passphrase is reachedcycle back to the beginning.
487 */
488 *bufp++ = passphrase[pindex++ % pplen];
489 }
490 /* continue a multiple-part message-digesting operation */
491 if (C_DigestUpdate(hSession, buf, USM_LENGTH_KU_HASHBLOCK) != CKR_OK ) {
492 QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
493 }
494 nbytes -= USM_LENGTH_KU_HASHBLOCK;
495 }
496 /* finish a multiple-part message-digesting operation */
497 if (C_DigestFinal(hSession, Ku, kulen) != CKR_OK) {
498 QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
499 }
500
501 pkcs_generate_Ku_quit:
502 return rval;
503 }
504
505 /*
506 * pkcserr_stringor: returns a string representation of the given
507 * return code.
508 */
509 static char *
pkcserr_string(CK_RV rv)510 pkcserr_string(CK_RV rv)
511 {
512 static char errstr[128];
513 switch (rv) {
514 case CKR_OK:
515 return ("CKR_OK");
516 break;
517 case CKR_CANCEL:
518 return ("CKR_CANCEL");
519 break;
520 case CKR_HOST_MEMORY:
521 return ("CKR_HOST_MEMORY");
522 break;
523 case CKR_SLOT_ID_INVALID:
524 return ("CKR_SLOT_ID_INVALID");
525 break;
526 case CKR_GENERAL_ERROR:
527 return ("CKR_GENERAL_ERROR");
528 break;
529 case CKR_FUNCTION_FAILED:
530 return ("CKR_FUNCTION_FAILED");
531 break;
532 case CKR_ARGUMENTS_BAD:
533 return ("CKR_ARGUMENTS_BAD");
534 break;
535 case CKR_NO_EVENT:
536 return ("CKR_NO_EVENT");
537 break;
538 case CKR_NEED_TO_CREATE_THREADS:
539 return ("CKR_NEED_TO_CREATE_THREADS");
540 break;
541 case CKR_CANT_LOCK:
542 return ("CKR_CANT_LOCK");
543 break;
544 case CKR_ATTRIBUTE_READ_ONLY:
545 return ("CKR_ATTRIBUTE_READ_ONLY");
546 break;
547 case CKR_ATTRIBUTE_SENSITIVE:
548 return ("CKR_ATTRIBUTE_SENSITIVE");
549 break;
550 case CKR_ATTRIBUTE_TYPE_INVALID:
551 return ("CKR_ATTRIBUTE_TYPE_INVALID");
552 break;
553 case CKR_ATTRIBUTE_VALUE_INVALID:
554 return ("CKR_ATTRIBUTE_VALUE_INVALID");
555 break;
556 case CKR_DATA_INVALID:
557 return ("CKR_DATA_INVALID");
558 break;
559 case CKR_DATA_LEN_RANGE:
560 return ("CKR_DATA_LEN_RANGE");
561 break;
562 case CKR_DEVICE_ERROR:
563 return ("CKR_DEVICE_ERROR");
564 break;
565 case CKR_DEVICE_MEMORY:
566 return ("CKR_DEVICE_MEMORY");
567 break;
568 case CKR_DEVICE_REMOVED:
569 return ("CKR_DEVICE_REMOVED");
570 break;
571 case CKR_ENCRYPTED_DATA_INVALID:
572 return ("CKR_ENCRYPTED_DATA_INVALID");
573 break;
574 case CKR_ENCRYPTED_DATA_LEN_RANGE:
575 return ("CKR_ENCRYPTED_DATA_LEN_RANGE");
576 break;
577 case CKR_FUNCTION_CANCELED:
578 return ("CKR_FUNCTION_CANCELED");
579 break;
580 case CKR_FUNCTION_NOT_PARALLEL:
581 return ("CKR_FUNCTION_NOT_PARALLEL");
582 break;
583 case CKR_FUNCTION_NOT_SUPPORTED:
584 return ("CKR_FUNCTION_NOT_SUPPORTED");
585 break;
586 case CKR_KEY_HANDLE_INVALID:
587 return ("CKR_KEY_HANDLE_INVALID");
588 break;
589 case CKR_KEY_SIZE_RANGE:
590 return ("CKR_KEY_SIZE_RANGE");
591 break;
592 case CKR_KEY_TYPE_INCONSISTENT:
593 return ("CKR_KEY_TYPE_INCONSISTENT");
594 break;
595 case CKR_KEY_NOT_NEEDED:
596 return ("CKR_KEY_NOT_NEEDED");
597 break;
598 case CKR_KEY_CHANGED:
599 return ("CKR_KEY_CHANGED");
600 break;
601 case CKR_KEY_NEEDED:
602 return ("CKR_KEY_NEEDED");
603 break;
604 case CKR_KEY_INDIGESTIBLE:
605 return ("CKR_KEY_INDIGESTIBLE");
606 break;
607 case CKR_KEY_FUNCTION_NOT_PERMITTED:
608 return ("CKR_KEY_FUNCTION_NOT_PERMITTED");
609 break;
610 case CKR_KEY_NOT_WRAPPABLE:
611 return ("CKR_KEY_NOT_WRAPPABLE");
612 break;
613 case CKR_KEY_UNEXTRACTABLE:
614 return ("CKR_KEY_UNEXTRACTABLE");
615 break;
616 case CKR_MECHANISM_INVALID:
617 return ("CKR_MECHANISM_INVALID");
618 break;
619 case CKR_MECHANISM_PARAM_INVALID:
620 return ("CKR_MECHANISM_PARAM_INVALID");
621 break;
622 case CKR_OBJECT_HANDLE_INVALID:
623 return ("CKR_OBJECT_HANDLE_INVALID");
624 break;
625 case CKR_OPERATION_ACTIVE:
626 return ("CKR_OPERATION_ACTIVE");
627 break;
628 case CKR_OPERATION_NOT_INITIALIZED:
629 return ("CKR_OPERATION_NOT_INITIALIZED");
630 break;
631 case CKR_PIN_INCORRECT:
632 return ("CKR_PIN_INCORRECT");
633 break;
634 case CKR_PIN_INVALID:
635 return ("CKR_PIN_INVALID");
636 break;
637 case CKR_PIN_LEN_RANGE:
638 return ("CKR_PIN_LEN_RANGE");
639 break;
640 case CKR_PIN_EXPIRED:
641 return ("CKR_PIN_EXPIRED");
642 break;
643 case CKR_PIN_LOCKED:
644 return ("CKR_PIN_LOCKED");
645 break;
646 case CKR_SESSION_CLOSED:
647 return ("CKR_SESSION_CLOSED");
648 break;
649 case CKR_SESSION_COUNT:
650 return ("CKR_SESSION_COUNT");
651 break;
652 case CKR_SESSION_HANDLE_INVALID:
653 return ("CKR_SESSION_HANDLE_INVALID");
654 break;
655 case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
656 return ("CKR_SESSION_PARALLEL_NOT_SUPPORTED");
657 break;
658 case CKR_SESSION_READ_ONLY:
659 return ("CKR_SESSION_READ_ONLY");
660 break;
661 case CKR_SESSION_EXISTS:
662 return ("CKR_SESSION_EXISTS");
663 break;
664 case CKR_SESSION_READ_ONLY_EXISTS:
665 return ("CKR_SESSION_READ_ONLY_EXISTS");
666 break;
667 case CKR_SESSION_READ_WRITE_SO_EXISTS:
668 return ("CKR_SESSION_READ_WRITE_SO_EXISTS");
669 break;
670 case CKR_SIGNATURE_INVALID:
671 return ("CKR_SIGNATURE_INVALID");
672 break;
673 case CKR_SIGNATURE_LEN_RANGE:
674 return ("CKR_SIGNATURE_LEN_RANGE");
675 break;
676 case CKR_TEMPLATE_INCOMPLETE:
677 return ("CKR_TEMPLATE_INCOMPLETE");
678 break;
679 case CKR_TEMPLATE_INCONSISTENT:
680 return ("CKR_TEMPLATE_INCONSISTENT");
681 break;
682 case CKR_TOKEN_NOT_PRESENT:
683 return ("CKR_TOKEN_NOT_PRESENT");
684 break;
685 case CKR_TOKEN_NOT_RECOGNIZED:
686 return ("CKR_TOKEN_NOT_RECOGNIZED");
687 break;
688 case CKR_TOKEN_WRITE_PROTECTED:
689 return ("CKR_TOKEN_WRITE_PROTECTED");
690 break;
691 case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
692 return ("CKR_UNWRAPPING_KEY_HANDLE_INVALID");
693 break;
694 case CKR_UNWRAPPING_KEY_SIZE_RANGE:
695 return ("CKR_UNWRAPPING_KEY_SIZE_RANGE");
696 break;
697 case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
698 return ("CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT");
699 break;
700 case CKR_USER_ALREADY_LOGGED_IN:
701 return ("CKR_USER_ALREADY_LOGGED_IN");
702 break;
703 case CKR_USER_NOT_LOGGED_IN:
704 return ("CKR_USER_NOT_LOGGED_IN");
705 break;
706 case CKR_USER_PIN_NOT_INITIALIZED:
707 return ("CKR_USER_PIN_NOT_INITIALIZED");
708 break;
709 case CKR_USER_TYPE_INVALID:
710 return ("CKR_USER_TYPE_INVALID");
711 break;
712 case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
713 return ("CKR_USER_ANOTHER_ALREADY_LOGGED_IN");
714 break;
715 case CKR_USER_TOO_MANY_TYPES:
716 return ("CKR_USER_TOO_MANY_TYPES");
717 break;
718 case CKR_WRAPPED_KEY_INVALID:
719 return ("CKR_WRAPPED_KEY_INVALID");
720 break;
721 case CKR_WRAPPED_KEY_LEN_RANGE:
722 return ("CKR_WRAPPED_KEY_LEN_RANGE");
723 break;
724 case CKR_WRAPPING_KEY_HANDLE_INVALID:
725 return ("CKR_WRAPPING_KEY_HANDLE_INVALID");
726 break;
727 case CKR_WRAPPING_KEY_SIZE_RANGE:
728 return ("CKR_WRAPPING_KEY_SIZE_RANGE");
729 break;
730 case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
731 return ("CKR_WRAPPING_KEY_TYPE_INCONSISTENT");
732 break;
733 case CKR_RANDOM_SEED_NOT_SUPPORTED:
734 return ("CKR_RANDOM_SEED_NOT_SUPPORTED");
735 break;
736 case CKR_RANDOM_NO_RNG:
737 return ("CKR_RANDOM_NO_RNG");
738 break;
739 case CKR_DOMAIN_PARAMS_INVALID:
740 return ("CKR_DOMAIN_PARAMS_INVALID");
741 break;
742 case CKR_BUFFER_TOO_SMALL:
743 return ("CKR_BUFFER_TOO_SMALL");
744 break;
745 case CKR_SAVED_STATE_INVALID:
746 return ("CKR_SAVED_STATE_INVALID");
747 break;
748 case CKR_INFORMATION_SENSITIVE:
749 return ("CKR_INFORMATION_SENSITIVE");
750 break;
751 case CKR_STATE_UNSAVEABLE:
752 return ("CKR_STATE_UNSAVEABLE");
753 break;
754 case CKR_CRYPTOKI_NOT_INITIALIZED:
755 return ("CKR_CRYPTOKI_NOT_INITIALIZED");
756 break;
757 case CKR_CRYPTOKI_ALREADY_INITIALIZED:
758 return ("CKR_CRYPTOKI_ALREADY_INITIALIZED");
759 break;
760 case CKR_MUTEX_BAD:
761 return ("CKR_MUTEX_BAD");
762 break;
763 case CKR_MUTEX_NOT_LOCKED:
764 return ("CKR_MUTEX_NOT_LOCKED");
765 break;
766 case CKR_VENDOR_DEFINED:
767 return ("CKR_VENDOR_DEFINED");
768 break;
769 default:
770 /* rv not found */
771 snprintf(errstr, sizeof (errstr),
772 "Unknown return code: 0x%x", rv);
773 return (errstr);
774 break;
775 }
776 }
777 #else
778 int pkcs_unused; /* Suppress "empty translation unit" warning */
779 #endif
780