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