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