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