Print this page
9642 PKCS#11 softtoken should use explicit_bzero
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
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
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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 */
24 24
25 25 #include <stdlib.h>
26 26 #include <string.h>
27 27 #include <strings.h>
28 28 #include <stdio.h>
29 29 #include <cryptoutil.h>
30 30 #include <errno.h>
31 31 #include <security/cryptoki.h>
32 32 #include <sys/crypto/common.h>
33 33 #include <sys/crypto/ioctl.h>
34 34 #include "kernelGlobal.h"
35 35 #include "kernelObject.h"
36 36 #include "kernelSlot.h"
37 37
38 38 #define ENCODE_ATTR(type, value, len) { \
39 39 cur_attr->oa_type = type; \
40 40 (void) memcpy(ptr, value, len); \
41 41 cur_attr->oa_value = ptr; \
42 42 cur_attr->oa_value_len = len; \
43 43 cur_attr++; \
44 44 }
45 45
46 46 /*
47 47 * In order to fit everything on one line, the 'CRYPTO_' prefix
48 48 * has been dropped from the KCF #defines, e.g.
49 49 * CRYPTO_SUCCESS becomes SUCCESS.
50 50 */
51 51
52 52 static CK_RV error_number_table[CRYPTO_LAST_ERROR+1] = {
53 53 CKR_OK, /* SUCCESS */
54 54 CKR_CANCEL, /* CANCEL */
55 55 CKR_HOST_MEMORY, /* HOST_MEMORY */
56 56 CKR_GENERAL_ERROR, /* GENERAL_ERROR */
57 57 CKR_FUNCTION_FAILED, /* FAILED */
58 58 CKR_ARGUMENTS_BAD, /* ARGUMENTS_BAD */
59 59 CKR_ATTRIBUTE_READ_ONLY, /* ATTRIBUTE_READ_ONLY */
60 60 CKR_ATTRIBUTE_SENSITIVE, /* ATTRIBUTE_SENSITIVE */
61 61 CKR_ATTRIBUTE_TYPE_INVALID, /* ATTRIBUTE_TYPE_INVALID */
62 62 CKR_ATTRIBUTE_VALUE_INVALID, /* ATTRIBUTE_VALUE_INVALID */
63 63 CKR_FUNCTION_FAILED, /* CANCELED */
64 64 CKR_DATA_INVALID, /* DATA_INVALID */
65 65 CKR_DATA_LEN_RANGE, /* DATA_LEN_RANGE */
66 66 CKR_DEVICE_ERROR, /* DEVICE_ERROR */
67 67 CKR_DEVICE_MEMORY, /* DEVICE_MEMORY */
68 68 CKR_DEVICE_REMOVED, /* DEVICE_REMOVED */
69 69 CKR_ENCRYPTED_DATA_INVALID, /* ENCRYPTED_DATA_INVALID */
70 70 CKR_ENCRYPTED_DATA_LEN_RANGE, /* ENCRYPTED_DATA_LEN_RANGE */
71 71 CKR_KEY_HANDLE_INVALID, /* KEY_HANDLE_INVALID */
72 72 CKR_KEY_SIZE_RANGE, /* KEY_SIZE_RANGE */
73 73 CKR_KEY_TYPE_INCONSISTENT, /* KEY_TYPE_INCONSISTENT */
74 74 CKR_KEY_NOT_NEEDED, /* KEY_NOT_NEEDED */
75 75 CKR_KEY_CHANGED, /* KEY_CHANGED */
76 76 CKR_KEY_NEEDED, /* KEY_NEEDED */
77 77 CKR_KEY_INDIGESTIBLE, /* KEY_INDIGESTIBLE */
78 78 CKR_KEY_FUNCTION_NOT_PERMITTED, /* KEY_FUNCTION_NOT_PERMITTED */
79 79 CKR_KEY_NOT_WRAPPABLE, /* KEY_NOT_WRAPPABLE */
80 80 CKR_KEY_UNEXTRACTABLE, /* KEY_UNEXTRACTABLE */
81 81 CKR_MECHANISM_INVALID, /* MECHANISM_INVALID */
82 82 CKR_MECHANISM_PARAM_INVALID, /* MECHANISM_PARAM_INVALID */
83 83 CKR_OBJECT_HANDLE_INVALID, /* OBJECT_HANDLE_INVALID */
84 84 CKR_OPERATION_ACTIVE, /* OPERATION_ACTIVE */
85 85 CKR_OPERATION_NOT_INITIALIZED, /* OPERATION_NOT_INITIALIZED */
86 86 CKR_PIN_INCORRECT, /* PIN_INCORRECT */
87 87 CKR_PIN_INVALID, /* PIN_INVALID */
88 88 CKR_PIN_LEN_RANGE, /* PIN_LEN_RANGE */
89 89 CKR_PIN_EXPIRED, /* PIN_EXPIRED */
90 90 CKR_PIN_LOCKED, /* PIN_LOCKED */
91 91 CKR_SESSION_CLOSED, /* SESSION_CLOSED */
92 92 CKR_SESSION_COUNT, /* SESSION_COUNT */
93 93 CKR_SESSION_HANDLE_INVALID, /* SESSION_HANDLE_INVALID */
94 94 CKR_SESSION_READ_ONLY, /* SESSION_READ_ONLY */
95 95 CKR_SESSION_EXISTS, /* SESSION_EXISTS */
96 96 CKR_SESSION_READ_ONLY_EXISTS, /* SESSION_READ_ONLY_EXISTS */
97 97 CKR_SESSION_READ_WRITE_SO_EXISTS, /* SESSION_READ_WRITE_SO_EXISTS */
98 98 CKR_SIGNATURE_INVALID, /* SIGNATURE_INVALID */
99 99 CKR_SIGNATURE_LEN_RANGE, /* SIGNATURE_LEN_RANGE */
100 100 CKR_TEMPLATE_INCOMPLETE, /* TEMPLATE_INCOMPLETE */
101 101 CKR_TEMPLATE_INCONSISTENT, /* TEMPLATE_INCONSISTENT */
102 102 CKR_UNWRAPPING_KEY_HANDLE_INVALID, /* UNWRAPPING_KEY_HANDLE_INVALID */
103 103 CKR_UNWRAPPING_KEY_SIZE_RANGE, /* UNWRAPPING_KEY_SIZE_RANGE */
104 104 CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, /* UNWRAPPING_KEY_TYPE_INCONSISTENT */
105 105 CKR_USER_ALREADY_LOGGED_IN, /* USER_ALREADY_LOGGED_IN */
106 106 CKR_USER_NOT_LOGGED_IN, /* USER_NOT_LOGGED_IN */
107 107 CKR_USER_PIN_NOT_INITIALIZED, /* USER_PIN_NOT_INITIALIZED */
108 108 CKR_USER_TYPE_INVALID, /* USER_TYPE_INVALID */
109 109 CKR_USER_ANOTHER_ALREADY_LOGGED_IN, /* USER_ANOTHER_ALREADY_LOGGED_IN */
110 110 CKR_USER_TOO_MANY_TYPES, /* USER_TOO_MANY_TYPES */
111 111 CKR_WRAPPED_KEY_INVALID, /* WRAPPED_KEY_INVALID */
112 112 CKR_WRAPPED_KEY_LEN_RANGE, /* WRAPPED_KEY_LEN_RANGE */
113 113 CKR_WRAPPING_KEY_HANDLE_INVALID, /* WRAPPING_KEY_HANDLE_INVALID */
114 114 CKR_WRAPPING_KEY_SIZE_RANGE, /* WRAPPING_KEY_SIZE_RANGE */
115 115 CKR_WRAPPING_KEY_TYPE_INCONSISTENT, /* WRAPPING_KEY_TYPE_INCONSISTENT */
116 116 CKR_RANDOM_SEED_NOT_SUPPORTED, /* RANDOM_SEED_NOT_SUPPORTED */
117 117 CKR_RANDOM_NO_RNG, /* RANDOM_NO_RNG */
118 118 CKR_DOMAIN_PARAMS_INVALID, /* DOMAIN_PARAMS_INVALID */
119 119 CKR_BUFFER_TOO_SMALL, /* BUFFER_TOO_SMALL */
120 120 CKR_INFORMATION_SENSITIVE, /* INFORMATION_SENSITIVE */
121 121 CKR_FUNCTION_NOT_SUPPORTED, /* NOT_SUPPORTED */
122 122 CKR_GENERAL_ERROR, /* QUEUED */
123 123 CKR_GENERAL_ERROR, /* BUFFER_TOO_BIG */
124 124 CKR_OPERATION_NOT_INITIALIZED, /* INVALID_CONTEXT */
125 125 CKR_GENERAL_ERROR, /* INVALID_MAC */
126 126 CKR_GENERAL_ERROR, /* MECH_NOT_SUPPORTED */
127 127 CKR_GENERAL_ERROR, /* INCONSISTENT_ATTRIBUTE */
128 128 CKR_GENERAL_ERROR, /* NO_PERMISSION */
129 129 CKR_SLOT_ID_INVALID, /* INVALID_PROVIDER_ID */
130 130 CKR_GENERAL_ERROR, /* VERSION_MISMATCH */
131 131 CKR_GENERAL_ERROR, /* BUSY */
132 132 CKR_GENERAL_ERROR, /* UNKNOWN_PROVIDER */
133 133 CKR_GENERAL_ERROR, /* MODVERIFICATION_FAILED */
134 134 CKR_GENERAL_ERROR, /* OLD_CTX_TEMPLATE */
135 135 CKR_GENERAL_ERROR, /* WEAK_KEY */
136 136 CKR_GENERAL_ERROR /* FIPS140_ERROR */
137 137 };
138 138
139 139 #if CRYPTO_LAST_ERROR != CRYPTO_FIPS140_ERROR
140 140 #error "Crypto to PKCS11 error mapping table needs to be updated!"
141 141 #endif
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 >= sizeof (error_number_table) / sizeof (error_number_table[0]))
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 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
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 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 /*
↓ open down ↓ |
472 lines elided |
↑ open up ↑ |
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 - if (key->ck_attrs[i].oa_value != NULL) {
484 - bzero(key->ck_attrs[i].oa_value,
485 - key->ck_attrs[i].oa_value_len);
486 - free(key->ck_attrs[i].oa_value);
487 - }
483 + freezero(key->ck_attrs[i].oa_value,
484 + key->ck_attrs[i].oa_value_len);
488 485 }
489 486 free(key->ck_attrs);
490 487 }
491 488 }
492 489
493 490
494 491 /*
495 492 * Convert a DSA private key object into a crypto_key structure.
496 493 * Memory is allocated for each attribute stored in the crypto_key
497 494 * structure. Memory for the crypto_key structure is not
498 495 * allocated. Attributes can be freed by free_dsa_key_attributes().
499 496 */
500 497 CK_RV
501 498 get_dsa_private_key(kernel_object_t *object_p, crypto_key_t *key)
502 499 {
503 500 biginteger_t *big;
504 501 crypto_object_attribute_t *attrs, *cur_attr;
505 502 char *ptr;
506 503
507 504 (void) pthread_mutex_lock(&object_p->object_mutex);
508 505 if (object_p->key_type != CKK_DSA ||
509 506 object_p->class != CKO_PRIVATE_KEY) {
510 507 (void) pthread_mutex_unlock(&object_p->object_mutex);
511 508 return (CKR_ATTRIBUTE_TYPE_INVALID);
512 509 }
513 510
514 511 attrs = calloc(1,
515 512 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t));
516 513 if (attrs == NULL) {
517 514 (void) pthread_mutex_unlock(&object_p->object_mutex);
518 515 return (CKR_HOST_MEMORY);
519 516 }
520 517
521 518 key->ck_format = CRYPTO_KEY_ATTR_LIST;
522 519 key->ck_count = DSA_ATTR_COUNT;
523 520 key->ck_attrs = attrs;
524 521
525 522 cur_attr = attrs;
526 523 big = OBJ_PRI_DSA_PRIME(object_p);
527 524 if ((ptr = malloc(big->big_value_len)) == NULL)
528 525 goto mem_failure;
529 526 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len);
530 527
531 528 big = OBJ_PRI_DSA_SUBPRIME(object_p);
532 529 if ((ptr = malloc(big->big_value_len)) == NULL)
533 530 goto mem_failure;
534 531 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len);
535 532
536 533 big = OBJ_PRI_DSA_BASE(object_p);
537 534 if ((ptr = malloc(big->big_value_len)) == NULL)
538 535 goto mem_failure;
539 536 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len);
540 537
541 538 big = OBJ_PRI_DSA_VALUE(object_p);
542 539 if ((ptr = malloc(big->big_value_len)) == NULL)
543 540 goto mem_failure;
544 541 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
545 542
546 543 (void) pthread_mutex_unlock(&object_p->object_mutex);
547 544 return (CKR_OK);
548 545
549 546 mem_failure:
550 547 (void) pthread_mutex_unlock(&object_p->object_mutex);
551 548 free_key_attributes(key);
552 549 return (CKR_HOST_MEMORY);
553 550 }
554 551
555 552
556 553 /*
557 554 * Convert a DSA public key object into a crypto_key structure.
558 555 * Memory is allocated for each attribute stored in the crypto_key
559 556 * structure. Memory for the crypto_key structure is not
560 557 * allocated. Attributes can be freed by free_dsa_key_attributes().
561 558 */
562 559 CK_RV
563 560 get_dsa_public_key(kernel_object_t *object_p, crypto_key_t *key)
564 561 {
565 562 biginteger_t *big;
566 563 crypto_object_attribute_t *attrs, *cur_attr;
567 564 char *ptr;
568 565
569 566 (void) pthread_mutex_lock(&object_p->object_mutex);
570 567 if (object_p->key_type != CKK_DSA ||
571 568 object_p->class != CKO_PUBLIC_KEY) {
572 569 (void) pthread_mutex_unlock(&object_p->object_mutex);
573 570 return (CKR_ATTRIBUTE_TYPE_INVALID);
574 571 }
575 572
576 573 attrs = calloc(1,
577 574 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t));
578 575 if (attrs == NULL) {
579 576 (void) pthread_mutex_unlock(&object_p->object_mutex);
580 577 return (CKR_HOST_MEMORY);
581 578 }
582 579
583 580 key->ck_format = CRYPTO_KEY_ATTR_LIST;
584 581 key->ck_count = DSA_ATTR_COUNT;
585 582 key->ck_attrs = attrs;
586 583
587 584 cur_attr = attrs;
588 585 big = OBJ_PUB_DSA_PRIME(object_p);
589 586 if ((ptr = malloc(big->big_value_len)) == NULL)
590 587 goto mem_failure;
591 588 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len);
592 589
593 590 big = OBJ_PUB_DSA_SUBPRIME(object_p);
594 591 if ((ptr = malloc(big->big_value_len)) == NULL)
595 592 goto mem_failure;
596 593 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len);
597 594
598 595 big = OBJ_PUB_DSA_BASE(object_p);
599 596 if ((ptr = malloc(big->big_value_len)) == NULL)
600 597 goto mem_failure;
601 598 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len);
602 599
603 600 big = OBJ_PUB_DSA_VALUE(object_p);
604 601 if ((ptr = malloc(big->big_value_len)) == NULL)
605 602 goto mem_failure;
606 603 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
607 604
608 605 (void) pthread_mutex_unlock(&object_p->object_mutex);
609 606 return (CKR_OK);
610 607
611 608 mem_failure:
612 609 (void) pthread_mutex_unlock(&object_p->object_mutex);
613 610 free_key_attributes(key);
614 611 return (CKR_HOST_MEMORY);
615 612 }
616 613
617 614
618 615 /*
619 616 * Convert a EC private key object into a crypto_key structure.
620 617 * Memory is allocated for each attribute stored in the crypto_key
621 618 * structure. Memory for the crypto_key structure is not
622 619 * allocated. Attributes can be freed by free_ec_key_attributes().
623 620 */
624 621 CK_RV
625 622 get_ec_private_key(kernel_object_t *object_p, crypto_key_t *key)
626 623 {
627 624 biginteger_t *big;
628 625 crypto_object_attribute_t *attrs, *cur_attr;
629 626 CK_ATTRIBUTE tmp;
630 627 char *ptr;
631 628 int rv;
632 629
633 630 (void) pthread_mutex_lock(&object_p->object_mutex);
634 631 if (object_p->key_type != CKK_EC ||
635 632 object_p->class != CKO_PRIVATE_KEY) {
636 633 (void) pthread_mutex_unlock(&object_p->object_mutex);
637 634 return (CKR_ATTRIBUTE_TYPE_INVALID);
638 635 }
639 636
640 637 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t));
641 638 if (attrs == NULL) {
642 639 (void) pthread_mutex_unlock(&object_p->object_mutex);
643 640 return (CKR_HOST_MEMORY);
644 641 }
645 642
646 643 key->ck_format = CRYPTO_KEY_ATTR_LIST;
647 644 key->ck_count = EC_ATTR_COUNT;
648 645 key->ck_attrs = attrs;
649 646
650 647 cur_attr = attrs;
651 648 big = OBJ_PRI_EC_VALUE(object_p);
652 649 if ((ptr = malloc(big->big_value_len)) == NULL) {
653 650 rv = CKR_HOST_MEMORY;
654 651 goto fail;
655 652 }
656 653 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
657 654
658 655 tmp.type = CKA_EC_PARAMS;
659 656 tmp.pValue = NULL;
660 657 rv = kernel_get_attribute(object_p, &tmp);
661 658 if (rv != CKR_OK) {
662 659 goto fail;
663 660 }
664 661
665 662 tmp.pValue = malloc(tmp.ulValueLen);
666 663 if (tmp.pValue == NULL) {
667 664 rv = CKR_HOST_MEMORY;
668 665 goto fail;
669 666 }
670 667
671 668 rv = kernel_get_attribute(object_p, &tmp);
672 669 if (rv != CKR_OK) {
673 670 free(tmp.pValue);
674 671 goto fail;
675 672 }
676 673
677 674 cur_attr->oa_type = tmp.type;
678 675 cur_attr->oa_value = tmp.pValue;
679 676 cur_attr->oa_value_len = tmp.ulValueLen;
680 677
681 678 (void) pthread_mutex_unlock(&object_p->object_mutex);
682 679 return (CKR_OK);
683 680
684 681 fail:
685 682 (void) pthread_mutex_unlock(&object_p->object_mutex);
686 683 free_key_attributes(key);
687 684 return (rv);
688 685 }
689 686
690 687 /*
691 688 * Convert an EC public key object into a crypto_key structure.
692 689 * Memory is allocated for each attribute stored in the crypto_key
693 690 * structure. Memory for the crypto_key structure is not
694 691 * allocated. Attributes can be freed by free_ec_key_attributes().
695 692 */
696 693 CK_RV
697 694 get_ec_public_key(kernel_object_t *object_p, crypto_key_t *key)
698 695 {
699 696 biginteger_t *big;
700 697 crypto_object_attribute_t *attrs, *cur_attr;
701 698 CK_ATTRIBUTE tmp;
702 699 char *ptr;
703 700 int rv;
704 701
705 702 (void) pthread_mutex_lock(&object_p->object_mutex);
706 703 if (object_p->key_type != CKK_EC ||
707 704 object_p->class != CKO_PUBLIC_KEY) {
708 705 (void) pthread_mutex_unlock(&object_p->object_mutex);
709 706 return (CKR_ATTRIBUTE_TYPE_INVALID);
710 707 }
711 708
712 709 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t));
713 710 if (attrs == NULL) {
714 711 (void) pthread_mutex_unlock(&object_p->object_mutex);
715 712 return (CKR_HOST_MEMORY);
716 713 }
717 714
718 715 key->ck_format = CRYPTO_KEY_ATTR_LIST;
719 716 key->ck_count = EC_ATTR_COUNT;
720 717 key->ck_attrs = attrs;
721 718
722 719 cur_attr = attrs;
723 720 big = OBJ_PUB_EC_POINT(object_p);
724 721 if ((ptr = malloc(big->big_value_len)) == NULL) {
725 722 rv = CKR_HOST_MEMORY;
726 723 goto fail;
727 724 }
728 725 ENCODE_ATTR(CKA_EC_POINT, big->big_value, big->big_value_len);
729 726
730 727 tmp.type = CKA_EC_PARAMS;
731 728 tmp.pValue = NULL;
732 729 rv = kernel_get_attribute(object_p, &tmp);
733 730 if (rv != CKR_OK) {
734 731 goto fail;
735 732 }
736 733
737 734 tmp.pValue = malloc(tmp.ulValueLen);
738 735 if (tmp.pValue == NULL) {
739 736 rv = CKR_HOST_MEMORY;
740 737 goto fail;
741 738 }
742 739
743 740 rv = kernel_get_attribute(object_p, &tmp);
744 741 if (rv != CKR_OK) {
745 742 free(tmp.pValue);
746 743 goto fail;
747 744 }
748 745
749 746 cur_attr->oa_type = tmp.type;
750 747 cur_attr->oa_value = tmp.pValue;
751 748 cur_attr->oa_value_len = tmp.ulValueLen;
752 749
753 750 (void) pthread_mutex_unlock(&object_p->object_mutex);
754 751 return (CKR_OK);
755 752
756 753 fail:
757 754 (void) pthread_mutex_unlock(&object_p->object_mutex);
758 755 free_key_attributes(key);
759 756 return (rv);
760 757 }
761 758
762 759 /*
763 760 * Convert an attribute template into an obj_attrs array.
764 761 * Memory is allocated for each attribute stored in the obj_attrs.
765 762 * The memory can be freed by free_object_attributes().
766 763 *
767 764 * If the boolean pointer is_token_obj is not NULL, the caller wants to
768 765 * retrieve the value of the CKA_TOKEN attribute if it is specified in the
769 766 * template.
770 767 * - When this routine is called thru C_CreateObject(), C_CopyObject(), or
771 768 * any key management function, is_token_obj should NOT be NULL.
772 769 * - When this routine is called thru C_GetAttributeValue() or
773 770 * C_SetAttributeValue(), "is_token_obj" should be NULL.
774 771 */
775 772 CK_RV
776 773 process_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
777 774 caddr_t *obj_attrs, CK_BBOOL *is_token_obj)
778 775 {
779 776 crypto_object_attribute_t *attrs, *cur_attr;
780 777 int i, cur_i;
781 778 char *ptr;
782 779 CK_RV rv;
783 780 ssize_t value_len;
784 781
785 782 if (ulCount == 0) {
786 783 obj_attrs = NULL;
787 784 return (CKR_OK);
788 785 }
789 786
790 787 attrs = calloc(1, ulCount * sizeof (crypto_object_attribute_t));
791 788 if (attrs == NULL) {
792 789 return (CKR_HOST_MEMORY);
793 790 }
794 791
795 792 cur_attr = attrs;
796 793 for (i = 0; i < ulCount; i++) {
797 794 /*
798 795 * The length of long attributes must be set correctly
799 796 * so providers can determine whether they came from 32
800 797 * or 64-bit applications.
801 798 */
802 799 switch (pTemplate[i].type) {
803 800 case CKA_CLASS:
804 801 case CKA_CERTIFICATE_TYPE:
805 802 case CKA_KEY_TYPE:
806 803 case CKA_MODULUS_BITS:
807 804 case CKA_HW_FEATURE_TYPE:
808 805 value_len = sizeof (ulong_t);
809 806 if (pTemplate[i].pValue != NULL &&
810 807 (pTemplate[i].ulValueLen < value_len)) {
811 808 rv = CKR_ATTRIBUTE_VALUE_INVALID;
812 809 cur_i = i;
813 810 goto fail_cleanup;
814 811 }
815 812 break;
816 813 default:
817 814 value_len = pTemplate[i].ulValueLen;
818 815 }
819 816
820 817 cur_attr->oa_type = pTemplate[i].type;
821 818 cur_attr->oa_value_len = value_len;
822 819 cur_attr->oa_value = NULL;
823 820
824 821 if ((pTemplate[i].pValue != NULL) &&
825 822 (pTemplate[i].ulValueLen > 0)) {
826 823 ptr = malloc(pTemplate[i].ulValueLen);
827 824 if (ptr == NULL) {
828 825 rv = CKR_HOST_MEMORY;
829 826 cur_i = i;
830 827 goto fail_cleanup;
831 828 } else {
832 829 (void) memcpy(ptr, pTemplate[i].pValue,
833 830 pTemplate[i].ulValueLen);
834 831 cur_attr->oa_value = ptr;
835 832 }
836 833 }
837 834
838 835 if ((is_token_obj != NULL) &&
839 836 (pTemplate[i].type == CKA_TOKEN)) {
840 837 /* Get the CKA_TOKEN attribute value. */
841 838 if (pTemplate[i].pValue == NULL) {
842 839 rv = CKR_ATTRIBUTE_VALUE_INVALID;
843 840 cur_i = i;
844 841 goto fail_cleanup;
845 842 } else {
846 843 *is_token_obj =
847 844 *(CK_BBOOL *)pTemplate[i].pValue;
848 845 }
849 846 }
850 847
851 848 cur_attr++;
852 849 }
853 850
854 851 *obj_attrs = (char *)attrs;
855 852 return (CKR_OK);
856 853
857 854 fail_cleanup:
858 855 cur_attr = attrs;
859 856 for (i = 0; i < cur_i; i++) {
860 857 if (cur_attr->oa_value != NULL) {
861 858 (void) free(cur_attr->oa_value);
862 859 }
863 860 cur_attr++;
864 861 }
865 862
866 863 (void) free(attrs);
867 864 return (rv);
868 865 }
869 866
870 867
871 868 /*
872 869 * Copy the attribute values from obj_attrs to pTemplate.
873 870 * The obj_attrs is an image of the Template and is expected to have the
874 871 * same attributes in the same order and each one of the attribute pValue
875 872 * in obj_attr has enough space allocated for the corresponding valueLen
876 873 * in pTemplate.
877 874 */
878 875 CK_RV
879 876 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
880 877 caddr_t obj_attrs)
881 878 {
882 879 crypto_object_attribute_t *cur_attr;
883 880 CK_RV rv = CKR_OK;
884 881 int i;
885 882
886 883 /* LINTED */
887 884 cur_attr = (crypto_object_attribute_t *)obj_attrs;
888 885 for (i = 0; i < ulCount; i++) {
889 886 if (pTemplate[i].type != cur_attr->oa_type) {
890 887 /* The attribute type doesn't match, this is bad. */
891 888 rv = CKR_FUNCTION_FAILED;
892 889 return (rv);
893 890 }
894 891
895 892 pTemplate[i].ulValueLen = cur_attr->oa_value_len;
896 893
897 894 if ((pTemplate[i].pValue != NULL) &&
898 895 ((CK_LONG)pTemplate[i].ulValueLen != -1)) {
899 896 (void) memcpy(pTemplate[i].pValue, cur_attr->oa_value,
900 897 pTemplate[i].ulValueLen);
901 898 }
902 899 cur_attr++;
903 900 }
904 901
905 902 return (rv);
906 903 }
907 904
908 905 /*
909 906 * Free the attribute storage in a crypto_object_attribute_t structure.
910 907 */
911 908 void
912 909 free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount)
913 910 {
914 911 crypto_object_attribute_t *cur_attr;
915 912 int i;
916 913
917 914 if ((ulCount == 0) || (obj_attrs == NULL)) {
918 915 return;
919 916 }
920 917
921 918 /* LINTED */
922 919 cur_attr = (crypto_object_attribute_t *)obj_attrs;
923 920 for (i = 0; i < ulCount; i++) {
924 921 /* XXX check that oa_value > 0 */
925 922 if (cur_attr->oa_value != NULL) {
926 923 free(cur_attr->oa_value);
927 924 }
928 925 cur_attr++;
929 926 }
930 927
931 928 free(obj_attrs);
932 929 }
933 930
934 931 /*
935 932 * This function is called by process_found_objects(). It will check the
936 933 * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then
937 934 * initialize all the necessary fields in the object wrapper "objp".
938 935 */
939 936 static CK_RV
940 937 create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp,
941 938 kernel_object_t *objp, crypto_object_id_t oid)
942 939 {
943 940 CK_RV rv = CKR_OK;
944 941 crypto_object_get_attribute_value_t obj_ga;
945 942 boolean_t is_pri_obj;
946 943 boolean_t is_token_obj;
947 944 CK_BBOOL pri_value, token_value;
948 945 CK_ATTRIBUTE pTemplate[2];
949 946 int r;
950 947
951 948 /*
952 949 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this
953 950 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN.
954 951 */
955 952 obj_ga.og_session = sp->k_session;
956 953 obj_ga.og_handle = oid;
957 954 obj_ga.og_count = 2;
958 955
959 956 pTemplate[0].type = CKA_PRIVATE;
960 957 pTemplate[0].pValue = &pri_value;
961 958 pTemplate[0].ulValueLen = sizeof (pri_value);
962 959 pTemplate[1].type = CKA_TOKEN;
963 960 pTemplate[1].pValue = &token_value;
964 961 pTemplate[1].ulValueLen = sizeof (token_value);
965 962 rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes,
966 963 NULL);
967 964 if (rv != CKR_OK) {
968 965 return (rv);
969 966 }
970 967
971 968 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE,
972 969 &obj_ga)) < 0) {
973 970 if (errno != EINTR)
974 971 break;
975 972 }
976 973 if (r < 0) {
977 974 rv = CKR_FUNCTION_FAILED;
978 975 } else {
979 976 rv = crypto2pkcs11_error_number(obj_ga.og_return_value);
980 977 }
981 978
982 979 if (rv == CKR_OK) {
983 980 rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes);
984 981 if (rv == CKR_OK) {
985 982 is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue;
986 983 is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue;
987 984 }
988 985 }
989 986
990 987 free_object_attributes(obj_ga.og_attributes, 2);
991 988 if (rv != CKR_OK) {
992 989 return (rv);
993 990 }
994 991
995 992 /* Make sure it is a token object. */
996 993 if (!is_token_obj) {
997 994 rv = CKR_ATTRIBUTE_VALUE_INVALID;
998 995 return (rv);
999 996 }
1000 997
1001 998 /* If it is a private object, make sure the user has logged in. */
1002 999 if (is_pri_obj && (pslot->sl_state != CKU_USER)) {
1003 1000 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1004 1001 return (rv);
1005 1002 }
1006 1003
1007 1004 objp->is_lib_obj = B_FALSE;
1008 1005 objp->k_handle = oid;
1009 1006 objp->bool_attr_mask |= TOKEN_BOOL_ON;
1010 1007 if (is_pri_obj) {
1011 1008 objp->bool_attr_mask |= PRIVATE_BOOL_ON;
1012 1009 } else {
1013 1010 objp->bool_attr_mask &= ~PRIVATE_BOOL_ON;
1014 1011 }
1015 1012
1016 1013 (void) pthread_mutex_init(&objp->object_mutex, NULL);
1017 1014 objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC;
1018 1015 objp->session_handle = (CK_SESSION_HANDLE) sp;
1019 1016
1020 1017 return (CKR_OK);
1021 1018 }
1022 1019
1023 1020 /*
1024 1021 * This function processes the kernel object handles returned from the
1025 1022 * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list
1026 1023 * and the number of object handles to the caller - C_FindObjects().
1027 1024 * The caller acquires the slot lock and the session lock.
1028 1025 */
1029 1026 CK_RV
1030 1027 process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found,
1031 1028 CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu)
1032 1029 {
1033 1030 CK_RV rv = CKR_OK;
1034 1031 crypto_object_id_t *oid_p;
1035 1032 kernel_slot_t *pslot;
1036 1033 kernel_object_t *objp;
1037 1034 kernel_object_t *objp1;
1038 1035 kernel_object_t *new_tobj_list = NULL;
1039 1036 kernel_session_t *sp;
1040 1037 CK_ULONG num_obj_found = 0;
1041 1038 boolean_t is_in_lib;
1042 1039 int i;
1043 1040
1044 1041 if (obj_fu.fu_count == 0) {
1045 1042 *found_obj_count = 0;
1046 1043 return (CKR_OK);
1047 1044 }
1048 1045
1049 1046 pslot = slot_table[cur_sp->ses_slotid];
1050 1047
1051 1048 /* LINTED */
1052 1049 oid_p = (crypto_object_id_t *)obj_fu.fu_handles;
1053 1050 for (i = 0; i < obj_fu.fu_count; i++) {
1054 1051 is_in_lib = B_FALSE;
1055 1052 /*
1056 1053 * Check if this oid has an object wrapper in the library
1057 1054 * already. First, search the slot's token object list.
1058 1055 */
1059 1056 objp = pslot->sl_tobj_list;
1060 1057 while (!is_in_lib && objp) {
1061 1058 if (objp->k_handle == *oid_p) {
1062 1059 is_in_lib = B_TRUE;
1063 1060 } else {
1064 1061 objp = objp->next;
1065 1062 }
1066 1063 }
1067 1064
1068 1065 /*
1069 1066 * If it is not in the slot's token object list,
1070 1067 * search it in all the sessions.
1071 1068 */
1072 1069 if (!is_in_lib) {
1073 1070 sp = pslot->sl_sess_list;
1074 1071 while (!is_in_lib && sp) {
1075 1072 objp = sp->object_list;
1076 1073 while (!is_in_lib && objp) {
1077 1074 if (objp->k_handle == *oid_p) {
1078 1075 is_in_lib = B_TRUE;
1079 1076 } else {
1080 1077 objp = objp->next;
1081 1078 }
1082 1079 }
1083 1080 sp = sp->next;
1084 1081 }
1085 1082 }
1086 1083
1087 1084 /*
1088 1085 * If this object is in the library already, add its object
1089 1086 * wrapper to the returned find object list.
1090 1087 */
1091 1088 if (is_in_lib) {
1092 1089 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp;
1093 1090 }
1094 1091
1095 1092 /*
1096 1093 * If we still do not find it in the library. This object
1097 1094 * must be a token object pre-existed in the HW provider.
1098 1095 * We need to create an object wrapper for it in the library.
1099 1096 */
1100 1097 if (!is_in_lib) {
1101 1098 objp1 = calloc(1, sizeof (kernel_object_t));
1102 1099 if (objp1 == NULL) {
1103 1100 rv = CKR_HOST_MEMORY;
1104 1101 goto failed_exit;
1105 1102 }
1106 1103 rv = create_new_tobj_in_lib(pslot, cur_sp, objp1,
1107 1104 *oid_p);
1108 1105
1109 1106 if (rv == CKR_OK) {
1110 1107 /* Save the new object to the new_tobj_list. */
1111 1108 if (new_tobj_list == NULL) {
1112 1109 new_tobj_list = objp1;
1113 1110 objp1->next = NULL;
1114 1111 objp1->prev = NULL;
1115 1112 } else {
1116 1113 new_tobj_list->prev = objp1;
1117 1114 objp1->next = new_tobj_list;
1118 1115 objp1->prev = NULL;
1119 1116 new_tobj_list = objp1;
1120 1117 }
1121 1118 } else {
1122 1119 /*
1123 1120 * If create_new_tobj_in_lib() doesn't fail
1124 1121 * with CKR_HOST_MEMORY, the failure should be
1125 1122 * caused by the attributes' checking. We will
1126 1123 * just ignore this object and continue on.
1127 1124 */
1128 1125 free(objp1);
1129 1126 if (rv == CKR_HOST_MEMORY) {
1130 1127 goto failed_exit;
1131 1128 }
1132 1129 }
1133 1130 }
1134 1131
1135 1132 /* Process next one */
1136 1133 oid_p++;
1137 1134 }
1138 1135
1139 1136 /*
1140 1137 * Add the newly created token object wrappers to the found object
1141 1138 * list and to the slot's token object list.
1142 1139 */
1143 1140 if (new_tobj_list != NULL) {
1144 1141 /* Add to the obj_found array. */
1145 1142 objp = new_tobj_list;
1146 1143 while (objp) {
1147 1144 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp;
1148 1145 if (objp->next == NULL) {
1149 1146 break;
1150 1147 }
1151 1148 objp = objp->next;
1152 1149 }
1153 1150
1154 1151 /* Add to the beginning of the slot's token object list. */
1155 1152 if (pslot->sl_tobj_list != NULL) {
1156 1153 objp->next = pslot->sl_tobj_list;
1157 1154 pslot->sl_tobj_list->prev = objp;
1158 1155 }
1159 1156 pslot->sl_tobj_list = new_tobj_list;
1160 1157 }
1161 1158
1162 1159 *found_obj_count = num_obj_found;
1163 1160 return (CKR_OK);
1164 1161
1165 1162 failed_exit:
1166 1163
1167 1164 /* Free the newly created token object wrappers. */
1168 1165 objp = new_tobj_list;
1169 1166 while (objp) {
1170 1167 objp1 = objp->next;
1171 1168 (void) pthread_mutex_destroy(&objp->object_mutex);
1172 1169 free(objp);
1173 1170 objp = objp1;
1174 1171 }
1175 1172
1176 1173 return (rv);
1177 1174 }
1178 1175
1179 1176
1180 1177 /*
1181 1178 * Get the value of the CKA_PRIVATE attribute for the object just returned
1182 1179 * from the HW provider. This function will be called by any function
1183 1180 * that creates a new object, because the CKA_PRIVATE value of an object is
1184 1181 * token specific. The CKA_PRIVATE attribute value of the new object will be
1185 1182 * stored in the object structure in the library, which will be used later at
1186 1183 * C_Logout to clean up all private objects.
1187 1184 */
1188 1185 CK_RV
1189 1186 get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid,
1190 1187 CK_BBOOL *is_pri_obj)
1191 1188 {
1192 1189 CK_RV rv = CKR_OK;
1193 1190 crypto_object_get_attribute_value_t obj_ga;
1194 1191 crypto_object_attribute_t obj_attr;
1195 1192 CK_BBOOL pri_value;
1196 1193 int r;
1197 1194
1198 1195 obj_ga.og_session = sp->k_session;
1199 1196 obj_ga.og_handle = oid;
1200 1197 obj_ga.og_count = 1;
1201 1198
1202 1199 obj_attr.oa_type = CKA_PRIVATE;
1203 1200 obj_attr.oa_value = (char *)&pri_value;
1204 1201 obj_attr.oa_value_len = sizeof (CK_BBOOL);
1205 1202 obj_ga.og_attributes = (char *)&obj_attr;
1206 1203
1207 1204 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE,
1208 1205 &obj_ga)) < 0) {
1209 1206 if (errno != EINTR)
1210 1207 break;
1211 1208 }
1212 1209 if (r < 0) {
1213 1210 rv = CKR_FUNCTION_FAILED;
1214 1211 } else {
1215 1212 rv = crypto2pkcs11_error_number(obj_ga.og_return_value);
1216 1213 }
1217 1214
1218 1215 if (rv == CKR_OK) {
1219 1216 *is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value;
1220 1217 }
1221 1218
1222 1219 return (rv);
1223 1220 }
1224 1221
1225 1222
1226 1223 CK_RV
1227 1224 get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type,
1228 1225 CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags)
1229 1226 {
1230 1227 crypto_get_provider_mechanism_info_t mechanism_info;
1231 1228 const char *string;
1232 1229 CK_FLAGS flags, mi_flags;
1233 1230 CK_RV rv;
1234 1231 int r;
1235 1232 char buf[11]; /* Num chars for representing ulong in ASCII */
1236 1233
1237 1234 if (type >= CKM_VENDOR_DEFINED) {
1238 1235 /* allocate/build a string containing the mechanism number */
1239 1236 (void) snprintf(buf, sizeof (buf), "%#lx", type);
1240 1237 string = buf;
1241 1238 } else {
1242 1239 string = pkcs11_mech2str(type);
1243 1240 }
1244 1241
1245 1242 if (string == NULL)
1246 1243 return (CKR_MECHANISM_INVALID);
1247 1244
1248 1245 (void) strcpy(mechanism_info.mi_mechanism_name, string);
1249 1246 mechanism_info.mi_provider_id = pslot->sl_provider_id;
1250 1247
1251 1248 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO,
1252 1249 &mechanism_info)) < 0) {
1253 1250 if (errno != EINTR)
1254 1251 break;
1255 1252 }
1256 1253 if (r < 0) {
1257 1254 rv = CKR_FUNCTION_FAILED;
1258 1255 } else {
1259 1256 rv = crypto2pkcs11_error_number(
1260 1257 mechanism_info.mi_return_value);
1261 1258 }
1262 1259
1263 1260 if (rv != CKR_OK) {
1264 1261 return (rv);
1265 1262 }
1266 1263
1267 1264 /*
1268 1265 * Atomic flags are not part of PKCS#11 so we filter
1269 1266 * them out here.
1270 1267 */
1271 1268 mi_flags = mechanism_info.mi_flags;
1272 1269 mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC |
1273 1270 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC |
1274 1271 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
1275 1272 CRYPTO_FG_SIGN_RECOVER_ATOMIC |
1276 1273 CRYPTO_FG_VERIFY_RECOVER_ATOMIC |
1277 1274 CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
1278 1275 CRYPTO_FG_MAC_DECRYPT_ATOMIC);
1279 1276
1280 1277 if (mi_flags == 0) {
1281 1278 return (CKR_MECHANISM_INVALID);
1282 1279 }
1283 1280
1284 1281 if (rv == CKR_OK) {
1285 1282 /* set the value of k_mi_flags first */
1286 1283 *k_mi_flags = mi_flags;
1287 1284
1288 1285 /* convert KEF flags into pkcs11 flags */
1289 1286 flags = CKF_HW;
1290 1287 if (mi_flags & CRYPTO_FG_ENCRYPT)
1291 1288 flags |= CKF_ENCRYPT;
1292 1289 if (mi_flags & CRYPTO_FG_DECRYPT) {
1293 1290 flags |= CKF_DECRYPT;
1294 1291 /*
1295 1292 * Since we'll be emulating C_UnwrapKey() for some
1296 1293 * cases, we can go ahead and claim CKF_UNWRAP
1297 1294 */
1298 1295 flags |= CKF_UNWRAP;
1299 1296 }
1300 1297 if (mi_flags & CRYPTO_FG_DIGEST)
1301 1298 flags |= CKF_DIGEST;
1302 1299 if (mi_flags & CRYPTO_FG_SIGN)
1303 1300 flags |= CKF_SIGN;
1304 1301 if (mi_flags & CRYPTO_FG_SIGN_RECOVER)
1305 1302 flags |= CKF_SIGN_RECOVER;
1306 1303 if (mi_flags & CRYPTO_FG_VERIFY)
1307 1304 flags |= CKF_VERIFY;
1308 1305 if (mi_flags & CRYPTO_FG_VERIFY_RECOVER)
1309 1306 flags |= CKF_VERIFY_RECOVER;
1310 1307 if (mi_flags & CRYPTO_FG_GENERATE)
1311 1308 flags |= CKF_GENERATE;
1312 1309 if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR)
1313 1310 flags |= CKF_GENERATE_KEY_PAIR;
1314 1311 if (mi_flags & CRYPTO_FG_WRAP)
1315 1312 flags |= CKF_WRAP;
1316 1313 if (mi_flags & CRYPTO_FG_UNWRAP)
1317 1314 flags |= CKF_UNWRAP;
1318 1315 if (mi_flags & CRYPTO_FG_DERIVE)
1319 1316 flags |= CKF_DERIVE;
1320 1317
1321 1318 pInfo->ulMinKeySize = mechanism_info.mi_min_key_size;
1322 1319 pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size;
1323 1320 pInfo->flags = flags;
1324 1321
1325 1322 }
1326 1323
1327 1324 return (rv);
1328 1325 }
↓ open down ↓ |
831 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX