Print this page
5031131 perf: pkcs11_kernel can benefit from a more efficient pkcs11_mech2str()
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelUtil.c
+++ new/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelUtil.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
22 + * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 -#pragma ident "@(#)kernelUtil.c 1.16 07/09/11 SMI"
26 +#pragma ident "@(#)kernelUtil.c 1.17 08/06/30 SMI"
27 27
28 28 #include <stdlib.h>
29 29 #include <string.h>
30 30 #include <strings.h>
31 +#include <stdio.h>
31 32 #include <cryptoutil.h>
32 33 #include <errno.h>
33 34 #include <security/cryptoki.h>
34 35 #include <sys/crypto/common.h>
35 36 #include <sys/crypto/ioctl.h>
36 37 #include "kernelGlobal.h"
37 38 #include "kernelObject.h"
38 39 #include "kernelSlot.h"
39 40
40 41 #define ENCODE_ATTR(type, value, len) { \
41 42 cur_attr->oa_type = type; \
42 43 (void) memcpy(ptr, value, len); \
43 44 cur_attr->oa_value = ptr; \
44 45 cur_attr->oa_value_len = len; \
45 46 cur_attr++; \
46 47 }
47 48
48 49 #define CRYPTO_LAST_ERROR (CRYPTO_WEAK_KEY + 1)
49 50
50 51 /*
51 52 * In order to fit everything on one line, the 'CRYPTO_' prefix
52 53 * has been dropped from the KCF #defines, e.g.
53 54 * CRYPTO_SUCCESS becomes SUCCESS.
54 55 */
55 56
56 57 static CK_RV error_number_table[CRYPTO_LAST_ERROR] = {
57 58 CKR_OK, /* SUCCESS */
58 59 CKR_CANCEL, /* CANCEL */
59 60 CKR_HOST_MEMORY, /* HOST_MEMORY */
60 61 CKR_GENERAL_ERROR, /* GENERAL_ERROR */
61 62 CKR_FUNCTION_FAILED, /* FAILED */
62 63 CKR_ARGUMENTS_BAD, /* ARGUMENTS_BAD */
63 64 CKR_ATTRIBUTE_READ_ONLY, /* ATTRIBUTE_READ_ONLY */
64 65 CKR_ATTRIBUTE_SENSITIVE, /* ATTRIBUTE_SENSITIVE */
65 66 CKR_ATTRIBUTE_TYPE_INVALID, /* ATTRIBUTE_TYPE_INVALID */
66 67 CKR_ATTRIBUTE_VALUE_INVALID, /* ATTRIBUTE_VALUE_INVALID */
67 68 CKR_FUNCTION_FAILED, /* CANCELED */
68 69 CKR_DATA_INVALID, /* DATA_INVALID */
69 70 CKR_DATA_LEN_RANGE, /* DATA_LEN_RANGE */
70 71 CKR_DEVICE_ERROR, /* DEVICE_ERROR */
71 72 CKR_DEVICE_MEMORY, /* DEVICE_MEMORY */
72 73 CKR_DEVICE_REMOVED, /* DEVICE_REMOVED */
73 74 CKR_ENCRYPTED_DATA_INVALID, /* ENCRYPTED_DATA_INVALID */
74 75 CKR_ENCRYPTED_DATA_LEN_RANGE, /* ENCRYPTED_DATA_LEN_RANGE */
75 76 CKR_KEY_HANDLE_INVALID, /* KEY_HANDLE_INVALID */
76 77 CKR_KEY_SIZE_RANGE, /* KEY_SIZE_RANGE */
77 78 CKR_KEY_TYPE_INCONSISTENT, /* KEY_TYPE_INCONSISTENT */
78 79 CKR_KEY_NOT_NEEDED, /* KEY_NOT_NEEDED */
79 80 CKR_KEY_CHANGED, /* KEY_CHANGED */
80 81 CKR_KEY_NEEDED, /* KEY_NEEDED */
81 82 CKR_KEY_INDIGESTIBLE, /* KEY_INDIGESTIBLE */
82 83 CKR_KEY_FUNCTION_NOT_PERMITTED, /* KEY_FUNCTION_NOT_PERMITTED */
83 84 CKR_KEY_NOT_WRAPPABLE, /* KEY_NOT_WRAPPABLE */
84 85 CKR_KEY_UNEXTRACTABLE, /* KEY_UNEXTRACTABLE */
85 86 CKR_MECHANISM_INVALID, /* MECHANISM_INVALID */
86 87 CKR_MECHANISM_PARAM_INVALID, /* MECHANISM_PARAM_INVALID */
87 88 CKR_OBJECT_HANDLE_INVALID, /* OBJECT_HANDLE_INVALID */
88 89 CKR_OPERATION_ACTIVE, /* OPERATION_ACTIVE */
89 90 CKR_OPERATION_NOT_INITIALIZED, /* OPERATION_NOT_INITIALIZED */
90 91 CKR_PIN_INCORRECT, /* PIN_INCORRECT */
91 92 CKR_PIN_INVALID, /* PIN_INVALID */
92 93 CKR_PIN_LEN_RANGE, /* PIN_LEN_RANGE */
93 94 CKR_PIN_EXPIRED, /* PIN_EXPIRED */
94 95 CKR_PIN_LOCKED, /* PIN_LOCKED */
95 96 CKR_SESSION_CLOSED, /* SESSION_CLOSED */
96 97 CKR_SESSION_COUNT, /* SESSION_COUNT */
97 98 CKR_SESSION_HANDLE_INVALID, /* SESSION_HANDLE_INVALID */
98 99 CKR_SESSION_READ_ONLY, /* SESSION_READ_ONLY */
99 100 CKR_SESSION_EXISTS, /* SESSION_EXISTS */
100 101 CKR_SESSION_READ_ONLY_EXISTS, /* SESSION_READ_ONLY_EXISTS */
101 102 CKR_SESSION_READ_WRITE_SO_EXISTS, /* SESSION_READ_WRITE_SO_EXISTS */
102 103 CKR_SIGNATURE_INVALID, /* SIGNATURE_INVALID */
103 104 CKR_SIGNATURE_LEN_RANGE, /* SIGNATURE_LEN_RANGE */
104 105 CKR_TEMPLATE_INCOMPLETE, /* TEMPLATE_INCOMPLETE */
105 106 CKR_TEMPLATE_INCONSISTENT, /* TEMPLATE_INCONSISTENT */
106 107 CKR_UNWRAPPING_KEY_HANDLE_INVALID, /* UNWRAPPING_KEY_HANDLE_INVALID */
107 108 CKR_UNWRAPPING_KEY_SIZE_RANGE, /* UNWRAPPING_KEY_SIZE_RANGE */
108 109 CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, /* UNWRAPPING_KEY_TYPE_INCONSISTENT */
109 110 CKR_USER_ALREADY_LOGGED_IN, /* USER_ALREADY_LOGGED_IN */
110 111 CKR_USER_NOT_LOGGED_IN, /* USER_NOT_LOGGED_IN */
111 112 CKR_USER_PIN_NOT_INITIALIZED, /* USER_PIN_NOT_INITIALIZED */
112 113 CKR_USER_TYPE_INVALID, /* USER_TYPE_INVALID */
113 114 CKR_USER_ANOTHER_ALREADY_LOGGED_IN, /* USER_ANOTHER_ALREADY_LOGGED_IN */
114 115 CKR_USER_TOO_MANY_TYPES, /* USER_TOO_MANY_TYPES */
115 116 CKR_WRAPPED_KEY_INVALID, /* WRAPPED_KEY_INVALID */
116 117 CKR_WRAPPED_KEY_LEN_RANGE, /* WRAPPED_KEY_LEN_RANGE */
117 118 CKR_WRAPPING_KEY_HANDLE_INVALID, /* WRAPPING_KEY_HANDLE_INVALID */
118 119 CKR_WRAPPING_KEY_SIZE_RANGE, /* WRAPPING_KEY_SIZE_RANGE */
119 120 CKR_WRAPPING_KEY_TYPE_INCONSISTENT, /* WRAPPING_KEY_TYPE_INCONSISTENT */
120 121 CKR_RANDOM_SEED_NOT_SUPPORTED, /* RANDOM_SEED_NOT_SUPPORTED */
121 122 CKR_RANDOM_NO_RNG, /* RANDOM_NO_RNG */
122 123 CKR_DOMAIN_PARAMS_INVALID, /* DOMAIN_PARAMS_INVALID */
123 124 CKR_BUFFER_TOO_SMALL, /* BUFFER_TOO_SMALL */
124 125 CKR_INFORMATION_SENSITIVE, /* INFORMATION_SENSITIVE */
125 126 CKR_FUNCTION_NOT_SUPPORTED, /* NOT_SUPPORTED */
126 127 CKR_GENERAL_ERROR, /* QUEUED */
127 128 CKR_GENERAL_ERROR, /* BUFFER_TOO_BIG */
128 129 CKR_OPERATION_NOT_INITIALIZED, /* INVALID_CONTEXT */
129 130 CKR_GENERAL_ERROR, /* INVALID_MAC */
130 131 CKR_GENERAL_ERROR, /* MECH_NOT_SUPPORTED */
131 132 CKR_GENERAL_ERROR, /* INCONSISTENT_ATTRIBUTE */
132 133 CKR_GENERAL_ERROR, /* NO_PERMISSION */
133 134 CKR_SLOT_ID_INVALID, /* INVALID_PROVIDER_ID */
134 135 CKR_GENERAL_ERROR, /* VERSION_MISMATCH */
135 136 CKR_GENERAL_ERROR, /* BUSY */
136 137 CKR_GENERAL_ERROR, /* UNKNOWN_PROVIDER */
137 138 CKR_GENERAL_ERROR, /* MODVERIFICATION_FAILED */
138 139 CKR_GENERAL_ERROR, /* OLD_CTX_TEMPLATE */
139 140 CKR_GENERAL_ERROR, /* WEAK_KEY */
140 141 };
141 142
142 143 /*
143 144 * Map KCF error codes into PKCS11 error codes.
144 145 */
145 146 CK_RV
146 147 crypto2pkcs11_error_number(uint_t n)
147 148 {
148 149 if (n > CRYPTO_LAST_ERROR)
149 150 return (CKR_GENERAL_ERROR);
150 151
151 152 return (error_number_table[n]);
152 153 }
153 154
154 155 #define MECH_HASH(type) (((uintptr_t)type) % KMECH_HASHTABLE_SIZE)
155 156 /*
156 157 * Serialize writes to the hash table. We don't need a per bucket lock as
157 158 * there are only a few writes and we don't need the lock for reads.
158 159 */
159 160 static pthread_mutex_t mechhash_mutex = PTHREAD_MUTEX_INITIALIZER;
160 161
161 162 static CK_RV
162 163 kmech_hash_insert(CK_MECHANISM_TYPE type, crypto_mech_type_t kmech)
163 164 {
164 165 uint_t h;
165 166 kmh_elem_t *elem, *cur;
166 167
167 168 elem = malloc(sizeof (kmh_elem_t));
168 169 if (elem == NULL)
169 170 return (CKR_HOST_MEMORY);
170 171
171 172 h = MECH_HASH(type);
172 173 elem->type = type;
173 174 elem->kmech = kmech;
174 175
175 176 (void) pthread_mutex_lock(&mechhash_mutex);
176 177 for (cur = kernel_mechhash[h]; cur != NULL; cur = cur->knext) {
177 178 if (type == cur->type) {
178 179 /* Some other thread beat us to it. */
179 180 (void) pthread_mutex_unlock(&mechhash_mutex);
180 181 free(elem);
181 182 return (CKR_OK);
182 183 }
183 184 }
184 185 elem->knext = kernel_mechhash[h];
|
↓ open down ↓ |
144 lines elided |
↑ open up ↑ |
185 186 kernel_mechhash[h] = elem;
186 187 (void) pthread_mutex_unlock(&mechhash_mutex);
187 188
188 189 return (CKR_OK);
189 190 }
190 191
191 192 CK_RV
192 193 kernel_mech(CK_MECHANISM_TYPE type, crypto_mech_type_t *k_number)
193 194 {
194 195 crypto_get_mechanism_number_t get_number;
195 - char *string;
196 + const char *string;
196 197 CK_RV rv;
197 198 int r;
198 199 kmh_elem_t *elem;
199 200 uint_t h;
201 + char buf[11]; /* Num chars for representing ulong in ASCII */
200 202
201 203 /*
202 204 * Search for an existing entry. No need to lock since we are
203 205 * just a reader and we never free the entries in the hash table.
204 206 */
205 207 h = MECH_HASH(type);
206 208 for (elem = kernel_mechhash[h]; elem != NULL; elem = elem->knext) {
207 209 if (type == elem->type) {
208 210 *k_number = elem->kmech;
209 211 return (CKR_OK);
210 212 }
211 213 }
212 214
213 - string = pkcs11_mech2str(type);
215 + if (type > CKM_VENDOR_DEFINED) {
216 + (void) snprintf(buf, sizeof (buf), "%#lx", type);
217 + string = buf;
218 + } else {
219 + string = pkcs11_mech2str(type);
220 + }
221 +
214 222 if (string == NULL)
215 223 return (CKR_MECHANISM_INVALID);
216 224
217 - get_number.pn_mechanism_string = string;
225 + get_number.pn_mechanism_string = (char *)string;
218 226 get_number.pn_mechanism_len = strlen(string) + 1;
219 227
220 228 while ((r = ioctl(kernel_fd, CRYPTO_GET_MECHANISM_NUMBER,
221 229 &get_number)) < 0) {
222 230 if (errno != EINTR)
223 231 break;
224 232 }
225 233 if (r < 0) {
226 234 rv = CKR_MECHANISM_INVALID;
227 235 } else {
228 236 if (get_number.pn_return_value != CRYPTO_SUCCESS) {
229 237 rv = crypto2pkcs11_error_number(
230 238 get_number.pn_return_value);
231 239 } else {
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
232 240 rv = CKR_OK;
233 241 }
234 242 }
235 243
236 244 if (rv == CKR_OK) {
237 245 *k_number = get_number.pn_internal_number;
238 246 /* Add this to the hash table */
239 247 (void) kmech_hash_insert(type, *k_number);
240 248 }
241 249
242 - free(string);
243 250 return (rv);
244 251 }
245 252
246 253
247 254 /*
248 255 * Return the value of a secret key object.
249 256 * This routine allocates memory for the value.
250 257 * A null pointer is returned on error.
251 258 */
252 259 unsigned char *
253 260 get_symmetric_key_value(kernel_object_t *key_p)
254 261 {
255 262 uint8_t *cipherKey;
256 263
257 264 switch (key_p->class) {
258 265
259 266 case CKO_SECRET_KEY:
260 267
261 268 cipherKey = malloc(OBJ_SEC(key_p)->sk_value_len);
262 269 if (cipherKey == NULL)
263 270 return (NULL);
264 271
265 272 (void) memcpy(cipherKey, OBJ_SEC(key_p)->sk_value,
266 273 OBJ_SEC(key_p)->sk_value_len);
267 274
268 275 return (cipherKey);
269 276
270 277 default:
271 278 return (NULL);
272 279 }
273 280 }
274 281
275 282 /*
276 283 * Convert a RSA private key object into a crypto_key structure.
277 284 * Memory is allocated for each attribute stored in the crypto_key
278 285 * structure. Memory for the crypto_key structure is not
279 286 * allocated. Attributes can be freed by free_key_attributes().
280 287 */
281 288 CK_RV
282 289 get_rsa_private_key(kernel_object_t *object_p, crypto_key_t *key)
283 290 {
284 291 biginteger_t *big;
285 292 crypto_object_attribute_t *attrs, *cur_attr;
286 293 char *ptr;
287 294 CK_RV rv;
288 295
289 296 (void) pthread_mutex_lock(&object_p->object_mutex);
290 297 if (object_p->key_type != CKK_RSA ||
291 298 object_p->class != CKO_PRIVATE_KEY) {
292 299 (void) pthread_mutex_unlock(&object_p->object_mutex);
293 300 return (CKR_ATTRIBUTE_TYPE_INVALID);
294 301 }
295 302
296 303 attrs = calloc(1,
297 304 RSA_PRI_ATTR_COUNT * sizeof (crypto_object_attribute_t));
298 305 if (attrs == NULL) {
299 306 (void) pthread_mutex_unlock(&object_p->object_mutex);
300 307 return (CKR_HOST_MEMORY);
301 308 }
302 309
303 310 key->ck_format = CRYPTO_KEY_ATTR_LIST;
304 311 key->ck_attrs = attrs;
305 312 cur_attr = attrs;
306 313
307 314 /*
308 315 * Allocate memory for each key attribute and set up the value
309 316 * value length.
310 317 */
311 318 key->ck_count = 0;
312 319
313 320 /* CKA_MODULUS is required. */
314 321 big = OBJ_PRI_RSA_MOD(object_p);
315 322 if (big->big_value == NULL) {
316 323 rv = CKR_ATTRIBUTE_TYPE_INVALID;
317 324 goto fail_cleanup;
318 325 } else {
319 326 if ((ptr = malloc(big->big_value_len)) == NULL) {
320 327 rv = CKR_HOST_MEMORY;
321 328 goto fail_cleanup;
322 329 }
323 330 ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len);
324 331 key->ck_count++;
325 332 }
326 333
327 334 /* CKA_PRIVATE_EXPONENT is required. */
328 335 big = OBJ_PRI_RSA_PRIEXPO(object_p);
329 336 if (big->big_value == NULL) {
330 337 rv = CKR_ATTRIBUTE_TYPE_INVALID;
331 338 goto fail_cleanup;
332 339 } else {
333 340 if ((ptr = malloc(big->big_value_len)) == NULL) {
334 341 rv = CKR_HOST_MEMORY;
335 342 goto fail_cleanup;
336 343 }
337 344 ENCODE_ATTR(CKA_PRIVATE_EXPONENT, big->big_value,
338 345 big->big_value_len);
339 346 key->ck_count++;
340 347 }
341 348
342 349 /* CKA_PRIME_1 is optional. */
343 350 big = OBJ_PRI_RSA_PRIME1(object_p);
344 351 if (big->big_value != NULL) {
345 352 if ((ptr = malloc(big->big_value_len)) == NULL) {
346 353 rv = CKR_HOST_MEMORY;
347 354 goto fail_cleanup;
348 355 }
349 356 ENCODE_ATTR(CKA_PRIME_1, big->big_value, big->big_value_len);
350 357 key->ck_count++;
351 358 }
352 359
353 360 /* CKA_PRIME_2 is optional. */
354 361 big = OBJ_PRI_RSA_PRIME2(object_p);
355 362 if (big->big_value != NULL) {
356 363 if ((ptr = malloc(big->big_value_len)) == NULL) {
357 364 rv = CKR_HOST_MEMORY;
358 365 goto fail_cleanup;
359 366 }
360 367 ENCODE_ATTR(CKA_PRIME_2, big->big_value, big->big_value_len);
361 368 key->ck_count++;
362 369 }
363 370
364 371 /* CKA_EXPONENT_1 is optional. */
365 372 big = OBJ_PRI_RSA_EXPO1(object_p);
366 373 if (big->big_value != NULL) {
367 374 if ((ptr = malloc(big->big_value_len)) == NULL) {
368 375 rv = CKR_HOST_MEMORY;
369 376 goto fail_cleanup;
370 377 }
371 378 ENCODE_ATTR(CKA_EXPONENT_1, big->big_value,
372 379 big->big_value_len);
373 380 key->ck_count++;
374 381 }
375 382
376 383 /* CKA_EXPONENT_2 is optional. */
377 384 big = OBJ_PRI_RSA_EXPO2(object_p);
378 385 if (big->big_value != NULL) {
379 386 if ((ptr = malloc(big->big_value_len)) == NULL) {
380 387 rv = CKR_HOST_MEMORY;
381 388 goto fail_cleanup;
382 389 }
383 390 ENCODE_ATTR(CKA_EXPONENT_2, big->big_value,
384 391 big->big_value_len);
385 392 key->ck_count++;
386 393 }
387 394
388 395 /* CKA_COEFFICIENT is optional. */
389 396 big = OBJ_PRI_RSA_COEF(object_p);
390 397 if (big->big_value != NULL) {
391 398 if ((ptr = malloc(big->big_value_len)) == NULL) {
392 399 rv = CKR_HOST_MEMORY;
393 400 goto fail_cleanup;
394 401 }
395 402 ENCODE_ATTR(CKA_COEFFICIENT, big->big_value,
396 403 big->big_value_len);
397 404 key->ck_count++;
398 405 }
399 406
400 407 (void) pthread_mutex_unlock(&object_p->object_mutex);
401 408 return (CKR_OK);
402 409
403 410 fail_cleanup:
404 411 (void) pthread_mutex_unlock(&object_p->object_mutex);
405 412 free_key_attributes(key);
406 413 return (rv);
407 414 }
408 415
409 416 /*
410 417 * Convert a RSA public key object into a crypto_key structure.
411 418 * Memory is allocated for each attribute stored in the crypto_key
412 419 * structure. Memory for the crypto_key structure is not
413 420 * allocated. Attributes can be freed by free_key_attributes().
414 421 */
415 422 CK_RV
416 423 get_rsa_public_key(kernel_object_t *object_p, crypto_key_t *key)
417 424 {
418 425 biginteger_t *big;
419 426 crypto_object_attribute_t *attrs, *cur_attr;
420 427 char *ptr;
421 428
422 429 (void) pthread_mutex_lock(&object_p->object_mutex);
423 430 if (object_p->key_type != CKK_RSA ||
424 431 object_p->class != CKO_PUBLIC_KEY) {
425 432 (void) pthread_mutex_unlock(&object_p->object_mutex);
426 433 return (CKR_ATTRIBUTE_TYPE_INVALID);
427 434 }
428 435
429 436 attrs = calloc(1,
430 437 RSA_PUB_ATTR_COUNT * sizeof (crypto_object_attribute_t));
431 438 if (attrs == NULL) {
432 439 (void) pthread_mutex_unlock(&object_p->object_mutex);
433 440 return (CKR_HOST_MEMORY);
434 441 }
435 442
436 443 key->ck_format = CRYPTO_KEY_ATTR_LIST;
437 444 key->ck_count = RSA_PUB_ATTR_COUNT;
438 445 key->ck_attrs = attrs;
439 446
440 447 cur_attr = attrs;
441 448 big = OBJ_PUB_RSA_PUBEXPO(object_p);
442 449 if ((ptr = malloc(big->big_value_len)) == NULL)
443 450 goto mem_failure;
444 451 ENCODE_ATTR(CKA_PUBLIC_EXPONENT, big->big_value, big->big_value_len);
445 452
446 453 big = OBJ_PUB_RSA_MOD(object_p);
447 454 if ((ptr = malloc(big->big_value_len)) == NULL)
448 455 goto mem_failure;
449 456 ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len);
450 457
451 458 if ((ptr = malloc(sizeof (CK_ULONG))) == NULL)
452 459 goto mem_failure;
453 460 ENCODE_ATTR(CKA_MODULUS_BITS, &OBJ_PUB_RSA_MOD_BITS(object_p),
454 461 sizeof (CK_ULONG));
455 462
456 463 (void) pthread_mutex_unlock(&object_p->object_mutex);
457 464 return (CKR_OK);
458 465
459 466 mem_failure:
460 467 (void) pthread_mutex_unlock(&object_p->object_mutex);
461 468 free_key_attributes(key);
462 469 return (CKR_HOST_MEMORY);
463 470 }
464 471
465 472 /*
466 473 * Free attribute storage in a crypto_key structure.
467 474 */
468 475 void
469 476 free_key_attributes(crypto_key_t *key)
470 477 {
471 478 int i;
472 479
473 480 if (key->ck_format == CRYPTO_KEY_ATTR_LIST &&
474 481 (key->ck_count > 0) && key->ck_attrs != NULL) {
475 482 for (i = 0; i < key->ck_count; i++) {
476 483 if (key->ck_attrs[i].oa_value != NULL) {
477 484 bzero(key->ck_attrs[i].oa_value,
478 485 key->ck_attrs[i].oa_value_len);
479 486 free(key->ck_attrs[i].oa_value);
480 487 }
481 488 }
482 489 free(key->ck_attrs);
483 490 }
484 491 }
485 492
486 493
487 494 /*
488 495 * Convert a DSA private key object into a crypto_key structure.
489 496 * Memory is allocated for each attribute stored in the crypto_key
490 497 * structure. Memory for the crypto_key structure is not
491 498 * allocated. Attributes can be freed by free_dsa_key_attributes().
492 499 */
493 500 CK_RV
494 501 get_dsa_private_key(kernel_object_t *object_p, crypto_key_t *key)
495 502 {
496 503 biginteger_t *big;
497 504 crypto_object_attribute_t *attrs, *cur_attr;
498 505 char *ptr;
499 506
500 507 (void) pthread_mutex_lock(&object_p->object_mutex);
501 508 if (object_p->key_type != CKK_DSA ||
502 509 object_p->class != CKO_PRIVATE_KEY) {
503 510 (void) pthread_mutex_unlock(&object_p->object_mutex);
504 511 return (CKR_ATTRIBUTE_TYPE_INVALID);
505 512 }
506 513
507 514 attrs = calloc(1,
508 515 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t));
509 516 if (attrs == NULL) {
510 517 (void) pthread_mutex_unlock(&object_p->object_mutex);
511 518 return (CKR_HOST_MEMORY);
512 519 }
513 520
514 521 key->ck_format = CRYPTO_KEY_ATTR_LIST;
515 522 key->ck_count = DSA_ATTR_COUNT;
516 523 key->ck_attrs = attrs;
517 524
518 525 cur_attr = attrs;
519 526 big = OBJ_PRI_DSA_PRIME(object_p);
520 527 if ((ptr = malloc(big->big_value_len)) == NULL)
521 528 goto mem_failure;
522 529 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len);
523 530
524 531 big = OBJ_PRI_DSA_SUBPRIME(object_p);
525 532 if ((ptr = malloc(big->big_value_len)) == NULL)
526 533 goto mem_failure;
527 534 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len);
528 535
529 536 big = OBJ_PRI_DSA_BASE(object_p);
530 537 if ((ptr = malloc(big->big_value_len)) == NULL)
531 538 goto mem_failure;
532 539 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len);
533 540
534 541 big = OBJ_PRI_DSA_VALUE(object_p);
535 542 if ((ptr = malloc(big->big_value_len)) == NULL)
536 543 goto mem_failure;
537 544 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
538 545
539 546 (void) pthread_mutex_unlock(&object_p->object_mutex);
540 547 return (CKR_OK);
541 548
542 549 mem_failure:
543 550 (void) pthread_mutex_unlock(&object_p->object_mutex);
544 551 free_key_attributes(key);
545 552 return (CKR_HOST_MEMORY);
546 553 }
547 554
548 555
549 556 /*
550 557 * Convert a DSA public key object into a crypto_key structure.
551 558 * Memory is allocated for each attribute stored in the crypto_key
552 559 * structure. Memory for the crypto_key structure is not
553 560 * allocated. Attributes can be freed by free_dsa_key_attributes().
554 561 */
555 562 CK_RV
556 563 get_dsa_public_key(kernel_object_t *object_p, crypto_key_t *key)
557 564 {
558 565 biginteger_t *big;
559 566 crypto_object_attribute_t *attrs, *cur_attr;
560 567 char *ptr;
561 568
562 569 (void) pthread_mutex_lock(&object_p->object_mutex);
563 570 if (object_p->key_type != CKK_DSA ||
564 571 object_p->class != CKO_PUBLIC_KEY) {
565 572 (void) pthread_mutex_unlock(&object_p->object_mutex);
566 573 return (CKR_ATTRIBUTE_TYPE_INVALID);
567 574 }
568 575
569 576 attrs = calloc(1,
570 577 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t));
571 578 if (attrs == NULL) {
572 579 (void) pthread_mutex_unlock(&object_p->object_mutex);
573 580 return (CKR_HOST_MEMORY);
574 581 }
575 582
576 583 key->ck_format = CRYPTO_KEY_ATTR_LIST;
577 584 key->ck_count = DSA_ATTR_COUNT;
578 585 key->ck_attrs = attrs;
579 586
580 587 cur_attr = attrs;
581 588 big = OBJ_PUB_DSA_PRIME(object_p);
582 589 if ((ptr = malloc(big->big_value_len)) == NULL)
583 590 goto mem_failure;
584 591 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len);
585 592
586 593 big = OBJ_PUB_DSA_SUBPRIME(object_p);
587 594 if ((ptr = malloc(big->big_value_len)) == NULL)
588 595 goto mem_failure;
589 596 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len);
590 597
591 598 big = OBJ_PUB_DSA_BASE(object_p);
592 599 if ((ptr = malloc(big->big_value_len)) == NULL)
593 600 goto mem_failure;
594 601 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len);
595 602
596 603 big = OBJ_PUB_DSA_VALUE(object_p);
597 604 if ((ptr = malloc(big->big_value_len)) == NULL)
598 605 goto mem_failure;
599 606 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
600 607
601 608 (void) pthread_mutex_unlock(&object_p->object_mutex);
602 609 return (CKR_OK);
603 610
604 611 mem_failure:
605 612 (void) pthread_mutex_unlock(&object_p->object_mutex);
606 613 free_key_attributes(key);
607 614 return (CKR_HOST_MEMORY);
608 615 }
609 616
610 617
611 618 /*
612 619 * Convert a EC private key object into a crypto_key structure.
613 620 * Memory is allocated for each attribute stored in the crypto_key
614 621 * structure. Memory for the crypto_key structure is not
615 622 * allocated. Attributes can be freed by free_ec_key_attributes().
616 623 */
617 624 CK_RV
618 625 get_ec_private_key(kernel_object_t *object_p, crypto_key_t *key)
619 626 {
620 627 biginteger_t *big;
621 628 crypto_object_attribute_t *attrs, *cur_attr;
622 629 CK_ATTRIBUTE tmp;
623 630 char *ptr;
624 631 int rv;
625 632
626 633 (void) pthread_mutex_lock(&object_p->object_mutex);
627 634 if (object_p->key_type != CKK_EC ||
628 635 object_p->class != CKO_PRIVATE_KEY) {
629 636 (void) pthread_mutex_unlock(&object_p->object_mutex);
630 637 return (CKR_ATTRIBUTE_TYPE_INVALID);
631 638 }
632 639
633 640 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t));
634 641 if (attrs == NULL) {
635 642 (void) pthread_mutex_unlock(&object_p->object_mutex);
636 643 return (CKR_HOST_MEMORY);
637 644 }
638 645
639 646 key->ck_format = CRYPTO_KEY_ATTR_LIST;
640 647 key->ck_count = EC_ATTR_COUNT;
641 648 key->ck_attrs = attrs;
642 649
643 650 cur_attr = attrs;
644 651 big = OBJ_PRI_EC_VALUE(object_p);
645 652 if ((ptr = malloc(big->big_value_len)) == NULL) {
646 653 rv = CKR_HOST_MEMORY;
647 654 goto fail;
648 655 }
649 656 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
650 657
651 658 tmp.type = CKA_EC_PARAMS;
652 659 tmp.pValue = NULL;
653 660 rv = kernel_get_attribute(object_p, &tmp);
654 661 if (rv != CKR_OK) {
655 662 goto fail;
656 663 }
657 664
658 665 tmp.pValue = malloc(tmp.ulValueLen);
659 666 if (tmp.pValue == NULL) {
660 667 rv = CKR_HOST_MEMORY;
661 668 goto fail;
662 669 }
663 670
664 671 rv = kernel_get_attribute(object_p, &tmp);
665 672 if (rv != CKR_OK) {
666 673 free(tmp.pValue);
667 674 goto fail;
668 675 }
669 676
670 677 cur_attr->oa_type = tmp.type;
671 678 cur_attr->oa_value = tmp.pValue;
672 679 cur_attr->oa_value_len = tmp.ulValueLen;
673 680
674 681 (void) pthread_mutex_unlock(&object_p->object_mutex);
675 682 return (CKR_OK);
676 683
677 684 fail:
678 685 (void) pthread_mutex_unlock(&object_p->object_mutex);
679 686 free_key_attributes(key);
680 687 return (rv);
681 688 }
682 689
683 690 /*
684 691 * Convert an EC public key object into a crypto_key structure.
685 692 * Memory is allocated for each attribute stored in the crypto_key
686 693 * structure. Memory for the crypto_key structure is not
687 694 * allocated. Attributes can be freed by free_ec_key_attributes().
688 695 */
689 696 CK_RV
690 697 get_ec_public_key(kernel_object_t *object_p, crypto_key_t *key)
691 698 {
692 699 biginteger_t *big;
693 700 crypto_object_attribute_t *attrs, *cur_attr;
694 701 CK_ATTRIBUTE tmp;
695 702 char *ptr;
696 703 int rv;
697 704
698 705 (void) pthread_mutex_lock(&object_p->object_mutex);
699 706 if (object_p->key_type != CKK_EC ||
700 707 object_p->class != CKO_PUBLIC_KEY) {
701 708 (void) pthread_mutex_unlock(&object_p->object_mutex);
702 709 return (CKR_ATTRIBUTE_TYPE_INVALID);
703 710 }
704 711
705 712 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t));
706 713 if (attrs == NULL) {
707 714 (void) pthread_mutex_unlock(&object_p->object_mutex);
708 715 return (CKR_HOST_MEMORY);
709 716 }
710 717
711 718 key->ck_format = CRYPTO_KEY_ATTR_LIST;
712 719 key->ck_count = EC_ATTR_COUNT;
713 720 key->ck_attrs = attrs;
714 721
715 722 cur_attr = attrs;
716 723 big = OBJ_PUB_EC_POINT(object_p);
717 724 if ((ptr = malloc(big->big_value_len)) == NULL) {
718 725 rv = CKR_HOST_MEMORY;
719 726 goto fail;
720 727 }
721 728 ENCODE_ATTR(CKA_EC_POINT, big->big_value, big->big_value_len);
722 729
723 730 tmp.type = CKA_EC_PARAMS;
724 731 tmp.pValue = NULL;
725 732 rv = kernel_get_attribute(object_p, &tmp);
726 733 if (rv != CKR_OK) {
727 734 goto fail;
728 735 }
729 736
730 737 tmp.pValue = malloc(tmp.ulValueLen);
731 738 if (tmp.pValue == NULL) {
732 739 rv = CKR_HOST_MEMORY;
733 740 goto fail;
734 741 }
735 742
736 743 rv = kernel_get_attribute(object_p, &tmp);
737 744 if (rv != CKR_OK) {
738 745 free(tmp.pValue);
739 746 goto fail;
740 747 }
741 748
742 749 cur_attr->oa_type = tmp.type;
743 750 cur_attr->oa_value = tmp.pValue;
744 751 cur_attr->oa_value_len = tmp.ulValueLen;
745 752
746 753 (void) pthread_mutex_unlock(&object_p->object_mutex);
747 754 return (CKR_OK);
748 755
749 756 fail:
750 757 (void) pthread_mutex_unlock(&object_p->object_mutex);
751 758 free_key_attributes(key);
752 759 return (rv);
753 760 }
754 761
755 762 /*
756 763 * Convert an attribute template into an obj_attrs array.
757 764 * Memory is allocated for each attribute stored in the obj_attrs.
758 765 * The memory can be freed by free_object_attributes().
759 766 *
760 767 * If the boolean pointer is_token_obj is not NULL, the caller wants to
761 768 * retrieve the value of the CKA_TOKEN attribute if it is specified in the
762 769 * template.
763 770 * - When this routine is called thru C_CreateObject(), C_CopyObject(), or
764 771 * any key management function, is_token_obj should NOT be NULL.
765 772 * - When this routine is called thru C_GetAttributeValue() or
766 773 * C_SetAttributeValue(), "is_token_obj" should be NULL.
767 774 */
768 775 CK_RV
769 776 process_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
770 777 caddr_t *obj_attrs, CK_BBOOL *is_token_obj)
771 778 {
772 779 crypto_object_attribute_t *attrs, *cur_attr;
773 780 int i, cur_i;
774 781 char *ptr;
775 782 CK_RV rv;
776 783 ssize_t value_len;
777 784
778 785 if (ulCount == 0) {
779 786 obj_attrs = NULL;
780 787 return (CKR_OK);
781 788 }
782 789
783 790 attrs = calloc(1, ulCount * sizeof (crypto_object_attribute_t));
784 791 if (attrs == NULL) {
785 792 return (CKR_HOST_MEMORY);
786 793 }
787 794
788 795 cur_attr = attrs;
789 796 for (i = 0; i < ulCount; i++) {
790 797 /*
791 798 * The length of long attributes must be set correctly
792 799 * so providers can determine whether they came from 32
793 800 * or 64-bit applications.
794 801 */
795 802 switch (pTemplate[i].type) {
796 803 case CKA_CLASS:
797 804 case CKA_CERTIFICATE_TYPE:
798 805 case CKA_KEY_TYPE:
799 806 case CKA_MODULUS_BITS:
800 807 case CKA_HW_FEATURE_TYPE:
801 808 value_len = sizeof (ulong_t);
802 809 if (pTemplate[i].pValue != NULL &&
803 810 (pTemplate[i].ulValueLen < value_len)) {
804 811 rv = CKR_BUFFER_TOO_SMALL;
805 812 cur_i = i;
806 813 goto fail_cleanup;
807 814 }
808 815 break;
809 816 default:
810 817 value_len = pTemplate[i].ulValueLen;
811 818 }
812 819
813 820 cur_attr->oa_type = pTemplate[i].type;
814 821 cur_attr->oa_value_len = value_len;
815 822 cur_attr->oa_value = NULL;
816 823
817 824 if ((pTemplate[i].pValue != NULL) &&
818 825 (pTemplate[i].ulValueLen > 0)) {
819 826 ptr = malloc(pTemplate[i].ulValueLen);
820 827 if (ptr == NULL) {
821 828 rv = CKR_HOST_MEMORY;
822 829 cur_i = i;
823 830 goto fail_cleanup;
824 831 } else {
825 832 (void) memcpy(ptr, pTemplate[i].pValue,
826 833 pTemplate[i].ulValueLen);
827 834 cur_attr->oa_value = ptr;
828 835 }
829 836 }
830 837
831 838 if ((is_token_obj != NULL) &&
832 839 (pTemplate[i].type == CKA_TOKEN)) {
833 840 /* Get the CKA_TOKEN attribute value. */
834 841 if (pTemplate[i].pValue == NULL) {
835 842 rv = CKR_ATTRIBUTE_VALUE_INVALID;
836 843 cur_i = i;
837 844 goto fail_cleanup;
838 845 } else {
839 846 *is_token_obj =
840 847 *(CK_BBOOL *)pTemplate[i].pValue;
841 848 }
842 849 }
843 850
844 851 cur_attr++;
845 852 }
846 853
847 854 *obj_attrs = (char *)attrs;
848 855 return (CKR_OK);
849 856
850 857 fail_cleanup:
851 858 cur_attr = attrs;
852 859 for (i = 0; i < cur_i; i++) {
853 860 if (cur_attr->oa_value != NULL) {
854 861 (void) free(cur_attr->oa_value);
855 862 }
856 863 cur_attr++;
857 864 }
858 865
859 866 (void) free(attrs);
860 867 return (rv);
861 868 }
862 869
863 870
864 871 /*
865 872 * Copy the attribute values from obj_attrs to pTemplate.
866 873 * The obj_attrs is an image of the Template and is expected to have the
867 874 * same attributes in the same order and each one of the attribute pValue
868 875 * in obj_attr has enough space allocated for the corresponding valueLen
869 876 * in pTemplate.
870 877 */
871 878 CK_RV
872 879 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
873 880 caddr_t obj_attrs)
874 881 {
875 882 crypto_object_attribute_t *cur_attr;
876 883 CK_RV rv = CKR_OK;
877 884 int i;
878 885
879 886 /* LINTED */
880 887 cur_attr = (crypto_object_attribute_t *)obj_attrs;
881 888 for (i = 0; i < ulCount; i++) {
882 889 if (pTemplate[i].type != cur_attr->oa_type) {
883 890 /* The attribute type doesn't match, this is bad. */
884 891 rv = CKR_FUNCTION_FAILED;
885 892 return (rv);
886 893 }
887 894
888 895 pTemplate[i].ulValueLen = cur_attr->oa_value_len;
889 896
890 897 if ((pTemplate[i].pValue != NULL) &&
891 898 ((CK_LONG)pTemplate[i].ulValueLen != -1)) {
892 899 (void) memcpy(pTemplate[i].pValue, cur_attr->oa_value,
893 900 pTemplate[i].ulValueLen);
894 901 }
895 902 cur_attr++;
896 903 }
897 904
898 905 return (rv);
899 906 }
900 907
901 908 /*
902 909 * Free the attribute storage in a crypto_object_attribute_t structure.
903 910 */
904 911 void
905 912 free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount)
906 913 {
907 914 crypto_object_attribute_t *cur_attr;
908 915 int i;
909 916
910 917 if ((ulCount == 0) || (obj_attrs == NULL)) {
911 918 return;
912 919 }
913 920
914 921 /* LINTED */
915 922 cur_attr = (crypto_object_attribute_t *)obj_attrs;
916 923 for (i = 0; i < ulCount; i++) {
917 924 /* XXX check that oa_value > 0 */
918 925 if (cur_attr->oa_value != NULL) {
919 926 free(cur_attr->oa_value);
920 927 }
921 928 cur_attr++;
922 929 }
923 930
924 931 free(obj_attrs);
925 932 }
926 933
927 934 /*
928 935 * This function is called by process_found_objects(). It will check the
929 936 * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then
930 937 * initialize all the necessary fields in the object wrapper "objp".
931 938 */
932 939 static CK_RV
933 940 create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp,
934 941 kernel_object_t *objp, crypto_object_id_t oid)
935 942 {
936 943 CK_RV rv = CKR_OK;
937 944 crypto_object_get_attribute_value_t obj_ga;
938 945 boolean_t is_pri_obj;
939 946 boolean_t is_token_obj;
940 947 CK_BBOOL pri_value, token_value;
941 948 CK_ATTRIBUTE pTemplate[2];
942 949 int r;
943 950
944 951 /*
945 952 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this
946 953 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN.
947 954 */
948 955 obj_ga.og_session = sp->k_session;
949 956 obj_ga.og_handle = oid;
950 957 obj_ga.og_count = 2;
951 958
952 959 pTemplate[0].type = CKA_PRIVATE;
953 960 pTemplate[0].pValue = &pri_value;
954 961 pTemplate[0].ulValueLen = sizeof (pri_value);
955 962 pTemplate[1].type = CKA_TOKEN;
956 963 pTemplate[1].pValue = &token_value;
957 964 pTemplate[1].ulValueLen = sizeof (token_value);
958 965 rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes,
959 966 NULL);
960 967 if (rv != CKR_OK) {
961 968 return (rv);
962 969 }
963 970
964 971 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE,
965 972 &obj_ga)) < 0) {
966 973 if (errno != EINTR)
967 974 break;
968 975 }
969 976 if (r < 0) {
970 977 rv = CKR_FUNCTION_FAILED;
971 978 } else {
972 979 rv = crypto2pkcs11_error_number(obj_ga.og_return_value);
973 980 }
974 981
975 982 if (rv == CKR_OK) {
976 983 rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes);
977 984 if (rv == CKR_OK) {
978 985 is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue;
979 986 is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue;
980 987 }
981 988 }
982 989
983 990 free_object_attributes(obj_ga.og_attributes, 2);
984 991 if (rv != CKR_OK) {
985 992 return (rv);
986 993 }
987 994
988 995 /* Make sure it is a token object. */
989 996 if (!is_token_obj) {
990 997 rv = CKR_ATTRIBUTE_VALUE_INVALID;
991 998 return (rv);
992 999 }
993 1000
994 1001 /* If it is a private object, make sure the user has logged in. */
995 1002 if (is_pri_obj && (pslot->sl_state != CKU_USER)) {
996 1003 rv = CKR_ATTRIBUTE_VALUE_INVALID;
997 1004 return (rv);
998 1005 }
999 1006
1000 1007 objp->is_lib_obj = B_FALSE;
1001 1008 objp->k_handle = oid;
1002 1009 objp->bool_attr_mask |= TOKEN_BOOL_ON;
1003 1010 if (is_pri_obj) {
1004 1011 objp->bool_attr_mask |= PRIVATE_BOOL_ON;
1005 1012 } else {
1006 1013 objp->bool_attr_mask &= ~PRIVATE_BOOL_ON;
1007 1014 }
1008 1015
1009 1016 (void) pthread_mutex_init(&objp->object_mutex, NULL);
1010 1017 objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC;
1011 1018 objp->session_handle = (CK_SESSION_HANDLE) sp;
1012 1019
1013 1020 return (CKR_OK);
1014 1021 }
1015 1022
1016 1023 /*
1017 1024 * This function processes the kernel object handles returned from the
1018 1025 * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list
1019 1026 * and the number of object handles to the caller - C_FindObjects().
1020 1027 * The caller acquires the slot lock and the session lock.
1021 1028 */
1022 1029 CK_RV
1023 1030 process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found,
1024 1031 CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu)
1025 1032 {
1026 1033 CK_RV rv = CKR_OK;
1027 1034 crypto_object_id_t *oid_p;
1028 1035 kernel_slot_t *pslot;
1029 1036 kernel_object_t *objp;
1030 1037 kernel_object_t *objp1;
1031 1038 kernel_object_t *new_tobj_list = NULL;
1032 1039 kernel_session_t *sp;
1033 1040 CK_ULONG num_obj_found = 0;
1034 1041 boolean_t is_in_lib;
1035 1042 int i;
1036 1043
1037 1044 if (obj_fu.fu_count == 0) {
1038 1045 *found_obj_count = 0;
1039 1046 return (CKR_OK);
1040 1047 }
1041 1048
1042 1049 pslot = slot_table[cur_sp->ses_slotid];
1043 1050
1044 1051 /* LINTED */
1045 1052 oid_p = (crypto_object_id_t *)obj_fu.fu_handles;
1046 1053 for (i = 0; i < obj_fu.fu_count; i++) {
1047 1054 is_in_lib = B_FALSE;
1048 1055 /*
1049 1056 * Check if this oid has an object wrapper in the library
1050 1057 * already. First, search the slot's token object list.
1051 1058 */
1052 1059 objp = pslot->sl_tobj_list;
1053 1060 while (!is_in_lib && objp) {
1054 1061 if (objp->k_handle == *oid_p) {
1055 1062 is_in_lib = B_TRUE;
1056 1063 } else {
1057 1064 objp = objp->next;
1058 1065 }
1059 1066 }
1060 1067
1061 1068 /*
1062 1069 * If it is not in the slot's token object list,
1063 1070 * search it in all the sessions.
1064 1071 */
1065 1072 if (!is_in_lib) {
1066 1073 sp = pslot->sl_sess_list;
1067 1074 while (!is_in_lib && sp) {
1068 1075 objp = sp->object_list;
1069 1076 while (!is_in_lib && objp) {
1070 1077 if (objp->k_handle == *oid_p) {
1071 1078 is_in_lib = B_TRUE;
1072 1079 } else {
1073 1080 objp = objp->next;
1074 1081 }
1075 1082 }
1076 1083 sp = sp->next;
1077 1084 }
1078 1085 }
1079 1086
1080 1087 /*
1081 1088 * If this object is in the library already, add its object
1082 1089 * wrapper to the returned find object list.
1083 1090 */
1084 1091 if (is_in_lib) {
1085 1092 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp;
1086 1093 }
1087 1094
1088 1095 /*
1089 1096 * If we still do not find it in the library. This object
1090 1097 * must be a token object pre-existed in the HW provider.
1091 1098 * We need to create an object wrapper for it in the library.
1092 1099 */
1093 1100 if (!is_in_lib) {
1094 1101 objp1 = calloc(1, sizeof (kernel_object_t));
1095 1102 if (objp1 == NULL) {
1096 1103 rv = CKR_HOST_MEMORY;
1097 1104 goto failed_exit;
1098 1105 }
1099 1106 rv = create_new_tobj_in_lib(pslot, cur_sp, objp1,
1100 1107 *oid_p);
1101 1108
1102 1109 if (rv == CKR_OK) {
1103 1110 /* Save the new object to the new_tobj_list. */
1104 1111 if (new_tobj_list == NULL) {
1105 1112 new_tobj_list = objp1;
1106 1113 objp1->next = NULL;
1107 1114 objp1->prev = NULL;
1108 1115 } else {
1109 1116 new_tobj_list->prev = objp1;
1110 1117 objp1->next = new_tobj_list;
1111 1118 objp1->prev = NULL;
1112 1119 new_tobj_list = objp1;
1113 1120 }
1114 1121 } else {
1115 1122 /*
1116 1123 * If create_new_tobj_in_lib() doesn't fail
1117 1124 * with CKR_HOST_MEMORY, the failure should be
1118 1125 * caused by the attributes' checking. We will
1119 1126 * just ignore this object and continue on.
1120 1127 */
1121 1128 free(objp1);
1122 1129 if (rv == CKR_HOST_MEMORY) {
1123 1130 goto failed_exit;
1124 1131 }
1125 1132 }
1126 1133 }
1127 1134
1128 1135 /* Process next one */
1129 1136 oid_p++;
1130 1137 }
1131 1138
1132 1139 /*
1133 1140 * Add the newly created token object wrappers to the found object
1134 1141 * list and to the slot's token object list.
1135 1142 */
1136 1143 if (new_tobj_list != NULL) {
1137 1144 /* Add to the obj_found array. */
1138 1145 objp = new_tobj_list;
1139 1146 while (objp) {
1140 1147 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp;
1141 1148 if (objp->next == NULL) {
1142 1149 break;
1143 1150 }
1144 1151 objp = objp->next;
1145 1152 }
1146 1153
1147 1154 /* Add to the beginning of the slot's token object list. */
1148 1155 if (pslot->sl_tobj_list != NULL) {
1149 1156 objp->next = pslot->sl_tobj_list;
1150 1157 pslot->sl_tobj_list->prev = objp;
1151 1158 }
1152 1159 pslot->sl_tobj_list = new_tobj_list;
1153 1160 }
1154 1161
1155 1162 *found_obj_count = num_obj_found;
1156 1163 return (CKR_OK);
1157 1164
1158 1165 failed_exit:
1159 1166
1160 1167 /* Free the newly created token object wrappers. */
1161 1168 objp = new_tobj_list;
1162 1169 while (objp) {
1163 1170 objp1 = objp->next;
1164 1171 (void) pthread_mutex_destroy(&objp->object_mutex);
1165 1172 free(objp);
1166 1173 objp = objp1;
|
↓ open down ↓ |
914 lines elided |
↑ open up ↑ |
1167 1174 }
1168 1175
1169 1176 return (rv);
1170 1177 }
1171 1178
1172 1179
1173 1180 /*
1174 1181 * Get the value of the CKA_PRIVATE attribute for the object just returned
1175 1182 * from the HW provider. This function will be called by any function
1176 1183 * that creates a new object, because the CKA_PRIVATE value of an object is
1177 - * token sepecific. The CKA_PRIVATE attribute value of the new object will be
1184 + * token specific. The CKA_PRIVATE attribute value of the new object will be
1178 1185 * stored in the object structure in the library, which will be used later at
1179 1186 * C_Logout to clean up all private objects.
1180 1187 */
1181 1188 CK_RV
1182 1189 get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid,
1183 1190 CK_BBOOL *is_pri_obj)
1184 1191 {
1185 1192 CK_RV rv = CKR_OK;
1186 1193 crypto_object_get_attribute_value_t obj_ga;
1187 1194 crypto_object_attribute_t obj_attr;
1188 1195 CK_BBOOL pri_value;
1189 1196 int r;
1190 1197
1191 1198 obj_ga.og_session = sp->k_session;
1192 1199 obj_ga.og_handle = oid;
1193 1200 obj_ga.og_count = 1;
1194 1201
1195 1202 obj_attr.oa_type = CKA_PRIVATE;
1196 1203 obj_attr.oa_value = (char *)&pri_value;
1197 1204 obj_attr.oa_value_len = sizeof (CK_BBOOL);
1198 1205 obj_ga.og_attributes = (char *)&obj_attr;
1199 1206
1200 1207 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE,
1201 1208 &obj_ga)) < 0) {
1202 1209 if (errno != EINTR)
1203 1210 break;
1204 1211 }
1205 1212 if (r < 0) {
1206 1213 rv = CKR_FUNCTION_FAILED;
1207 1214 } else {
1208 1215 rv = crypto2pkcs11_error_number(obj_ga.og_return_value);
1209 1216 }
1210 1217
1211 1218 if (rv == CKR_OK) {
1212 1219 *is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value;
1213 1220 }
|
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
1214 1221
1215 1222 return (rv);
1216 1223 }
1217 1224
1218 1225
1219 1226 CK_RV
1220 1227 get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type,
1221 1228 CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags)
1222 1229 {
1223 1230 crypto_get_provider_mechanism_info_t mechanism_info;
1224 - char *string;
1231 + const char *string;
1225 1232 CK_FLAGS flags, mi_flags;
1226 1233 CK_RV rv;
1227 1234 int r;
1235 + char buf[11]; /* Num chars for representing ulong in ASCII */
1228 1236
1229 - string = pkcs11_mech2str(type);
1237 + if (type > CKM_VENDOR_DEFINED) {
1238 + /* allocate/build a string containing the mechanism number */
1239 + (void) snprintf(buf, sizeof (buf), "%#lx", type);
1240 + string = buf;
1241 + } else {
1242 + string = pkcs11_mech2str(type);
1243 + }
1244 +
1230 1245 if (string == NULL)
1231 1246 return (CKR_MECHANISM_INVALID);
1232 1247
1233 1248 (void) strcpy(mechanism_info.mi_mechanism_name, string);
1234 1249 mechanism_info.mi_provider_id = pslot->sl_provider_id;
1235 1250
1236 1251 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO,
1237 1252 &mechanism_info)) < 0) {
1238 1253 if (errno != EINTR)
1239 1254 break;
1240 1255 }
1241 1256 if (r < 0) {
1242 1257 rv = CKR_FUNCTION_FAILED;
1243 1258 } else {
1244 1259 rv = crypto2pkcs11_error_number(
1245 1260 mechanism_info.mi_return_value);
1246 1261 }
1247 1262
1248 1263 if (rv != CKR_OK) {
1249 - goto out;
1264 + return (rv);
1250 1265 }
1251 1266
1252 1267 /*
1253 1268 * Atomic flags are not part of PKCS#11 so we filter
1254 1269 * them out here.
1255 1270 */
1256 1271 mi_flags = mechanism_info.mi_flags;
1257 1272 mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC |
1258 1273 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC |
1259 1274 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
1260 1275 CRYPTO_FG_SIGN_RECOVER_ATOMIC |
1261 1276 CRYPTO_FG_VERIFY_RECOVER_ATOMIC |
1262 1277 CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
1263 1278 CRYPTO_FG_MAC_DECRYPT_ATOMIC);
1264 1279
1265 1280 if (mi_flags == 0) {
1266 - rv = CKR_MECHANISM_INVALID;
1267 - goto out;
1281 + return (CKR_MECHANISM_INVALID);
1268 1282 }
1269 1283
1270 1284 if (rv == CKR_OK) {
1271 1285 /* set the value of k_mi_flags first */
1272 1286 *k_mi_flags = mi_flags;
1273 1287
1274 1288 /* convert KEF flags into pkcs11 flags */
1275 1289 flags = CKF_HW;
1276 1290 if (mi_flags & CRYPTO_FG_ENCRYPT)
1277 1291 flags |= CKF_ENCRYPT;
1278 1292 if (mi_flags & CRYPTO_FG_DECRYPT) {
1279 1293 flags |= CKF_DECRYPT;
1280 1294 /*
1281 1295 * Since we'll be emulating C_UnwrapKey() for some
1282 1296 * cases, we can go ahead and claim CKF_UNWRAP
1283 1297 */
1284 1298 flags |= CKF_UNWRAP;
1285 1299 }
1286 1300 if (mi_flags & CRYPTO_FG_DIGEST)
1287 1301 flags |= CKF_DIGEST;
1288 1302 if (mi_flags & CRYPTO_FG_SIGN)
1289 1303 flags |= CKF_SIGN;
1290 1304 if (mi_flags & CRYPTO_FG_SIGN_RECOVER)
1291 1305 flags |= CKF_SIGN_RECOVER;
1292 1306 if (mi_flags & CRYPTO_FG_VERIFY)
1293 1307 flags |= CKF_VERIFY;
1294 1308 if (mi_flags & CRYPTO_FG_VERIFY_RECOVER)
1295 1309 flags |= CKF_VERIFY_RECOVER;
1296 1310 if (mi_flags & CRYPTO_FG_GENERATE)
1297 1311 flags |= CKF_GENERATE;
1298 1312 if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR)
1299 1313 flags |= CKF_GENERATE_KEY_PAIR;
1300 1314 if (mi_flags & CRYPTO_FG_WRAP)
1301 1315 flags |= CKF_WRAP;
1302 1316 if (mi_flags & CRYPTO_FG_UNWRAP)
|
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
1303 1317 flags |= CKF_UNWRAP;
1304 1318 if (mi_flags & CRYPTO_FG_DERIVE)
1305 1319 flags |= CKF_DERIVE;
1306 1320
1307 1321 pInfo->ulMinKeySize = mechanism_info.mi_min_key_size;
1308 1322 pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size;
1309 1323 pInfo->flags = flags;
1310 1324
1311 1325 }
1312 1326
1313 -out:
1314 - free(string);
1315 1327 return (rv);
1316 1328 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX