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 freezero(key->ck_attrs[i].oa_value, 484 key->ck_attrs[i].oa_value_len); 485 } 486 free(key->ck_attrs); 487 } 488 } 489 490 491 /* 492 * Convert a DSA private key object into a crypto_key structure. 493 * Memory is allocated for each attribute stored in the crypto_key 494 * structure. Memory for the crypto_key structure is not 495 * allocated. Attributes can be freed by free_dsa_key_attributes(). 496 */ 497 CK_RV 498 get_dsa_private_key(kernel_object_t *object_p, crypto_key_t *key) 499 { 500 biginteger_t *big; 501 crypto_object_attribute_t *attrs, *cur_attr; 502 char *ptr; 503 504 (void) pthread_mutex_lock(&object_p->object_mutex); 505 if (object_p->key_type != CKK_DSA || 506 object_p->class != CKO_PRIVATE_KEY) { 507 (void) pthread_mutex_unlock(&object_p->object_mutex); 508 return (CKR_ATTRIBUTE_TYPE_INVALID); 509 } 510 511 attrs = calloc(1, 512 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 513 if (attrs == NULL) { 514 (void) pthread_mutex_unlock(&object_p->object_mutex); 515 return (CKR_HOST_MEMORY); 516 } 517 518 key->ck_format = CRYPTO_KEY_ATTR_LIST; 519 key->ck_count = DSA_ATTR_COUNT; 520 key->ck_attrs = attrs; 521 522 cur_attr = attrs; 523 big = OBJ_PRI_DSA_PRIME(object_p); 524 if ((ptr = malloc(big->big_value_len)) == NULL) 525 goto mem_failure; 526 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len); 527 528 big = OBJ_PRI_DSA_SUBPRIME(object_p); 529 if ((ptr = malloc(big->big_value_len)) == NULL) 530 goto mem_failure; 531 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len); 532 533 big = OBJ_PRI_DSA_BASE(object_p); 534 if ((ptr = malloc(big->big_value_len)) == NULL) 535 goto mem_failure; 536 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len); 537 538 big = OBJ_PRI_DSA_VALUE(object_p); 539 if ((ptr = malloc(big->big_value_len)) == NULL) 540 goto mem_failure; 541 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 542 543 (void) pthread_mutex_unlock(&object_p->object_mutex); 544 return (CKR_OK); 545 546 mem_failure: 547 (void) pthread_mutex_unlock(&object_p->object_mutex); 548 free_key_attributes(key); 549 return (CKR_HOST_MEMORY); 550 } 551 552 553 /* 554 * Convert a DSA public key object into a crypto_key structure. 555 * Memory is allocated for each attribute stored in the crypto_key 556 * structure. Memory for the crypto_key structure is not 557 * allocated. Attributes can be freed by free_dsa_key_attributes(). 558 */ 559 CK_RV 560 get_dsa_public_key(kernel_object_t *object_p, crypto_key_t *key) 561 { 562 biginteger_t *big; 563 crypto_object_attribute_t *attrs, *cur_attr; 564 char *ptr; 565 566 (void) pthread_mutex_lock(&object_p->object_mutex); 567 if (object_p->key_type != CKK_DSA || 568 object_p->class != CKO_PUBLIC_KEY) { 569 (void) pthread_mutex_unlock(&object_p->object_mutex); 570 return (CKR_ATTRIBUTE_TYPE_INVALID); 571 } 572 573 attrs = calloc(1, 574 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 575 if (attrs == NULL) { 576 (void) pthread_mutex_unlock(&object_p->object_mutex); 577 return (CKR_HOST_MEMORY); 578 } 579 580 key->ck_format = CRYPTO_KEY_ATTR_LIST; 581 key->ck_count = DSA_ATTR_COUNT; 582 key->ck_attrs = attrs; 583 584 cur_attr = attrs; 585 big = OBJ_PUB_DSA_PRIME(object_p); 586 if ((ptr = malloc(big->big_value_len)) == NULL) 587 goto mem_failure; 588 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len); 589 590 big = OBJ_PUB_DSA_SUBPRIME(object_p); 591 if ((ptr = malloc(big->big_value_len)) == NULL) 592 goto mem_failure; 593 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len); 594 595 big = OBJ_PUB_DSA_BASE(object_p); 596 if ((ptr = malloc(big->big_value_len)) == NULL) 597 goto mem_failure; 598 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len); 599 600 big = OBJ_PUB_DSA_VALUE(object_p); 601 if ((ptr = malloc(big->big_value_len)) == NULL) 602 goto mem_failure; 603 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 604 605 (void) pthread_mutex_unlock(&object_p->object_mutex); 606 return (CKR_OK); 607 608 mem_failure: 609 (void) pthread_mutex_unlock(&object_p->object_mutex); 610 free_key_attributes(key); 611 return (CKR_HOST_MEMORY); 612 } 613 614 615 /* 616 * Convert a EC private key object into a crypto_key structure. 617 * Memory is allocated for each attribute stored in the crypto_key 618 * structure. Memory for the crypto_key structure is not 619 * allocated. Attributes can be freed by free_ec_key_attributes(). 620 */ 621 CK_RV 622 get_ec_private_key(kernel_object_t *object_p, crypto_key_t *key) 623 { 624 biginteger_t *big; 625 crypto_object_attribute_t *attrs, *cur_attr; 626 CK_ATTRIBUTE tmp; 627 char *ptr; 628 int rv; 629 630 (void) pthread_mutex_lock(&object_p->object_mutex); 631 if (object_p->key_type != CKK_EC || 632 object_p->class != CKO_PRIVATE_KEY) { 633 (void) pthread_mutex_unlock(&object_p->object_mutex); 634 return (CKR_ATTRIBUTE_TYPE_INVALID); 635 } 636 637 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t)); 638 if (attrs == NULL) { 639 (void) pthread_mutex_unlock(&object_p->object_mutex); 640 return (CKR_HOST_MEMORY); 641 } 642 643 key->ck_format = CRYPTO_KEY_ATTR_LIST; 644 key->ck_count = EC_ATTR_COUNT; 645 key->ck_attrs = attrs; 646 647 cur_attr = attrs; 648 big = OBJ_PRI_EC_VALUE(object_p); 649 if ((ptr = malloc(big->big_value_len)) == NULL) { 650 rv = CKR_HOST_MEMORY; 651 goto fail; 652 } 653 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 654 655 tmp.type = CKA_EC_PARAMS; 656 tmp.pValue = NULL; 657 rv = kernel_get_attribute(object_p, &tmp); 658 if (rv != CKR_OK) { 659 goto fail; 660 } 661 662 tmp.pValue = malloc(tmp.ulValueLen); 663 if (tmp.pValue == NULL) { 664 rv = CKR_HOST_MEMORY; 665 goto fail; 666 } 667 668 rv = kernel_get_attribute(object_p, &tmp); 669 if (rv != CKR_OK) { 670 free(tmp.pValue); 671 goto fail; 672 } 673 674 cur_attr->oa_type = tmp.type; 675 cur_attr->oa_value = tmp.pValue; 676 cur_attr->oa_value_len = tmp.ulValueLen; 677 678 (void) pthread_mutex_unlock(&object_p->object_mutex); 679 return (CKR_OK); 680 681 fail: 682 (void) pthread_mutex_unlock(&object_p->object_mutex); 683 free_key_attributes(key); 684 return (rv); 685 } 686 687 /* 688 * Convert an EC public key object into a crypto_key structure. 689 * Memory is allocated for each attribute stored in the crypto_key 690 * structure. Memory for the crypto_key structure is not 691 * allocated. Attributes can be freed by free_ec_key_attributes(). 692 */ 693 CK_RV 694 get_ec_public_key(kernel_object_t *object_p, crypto_key_t *key) 695 { 696 biginteger_t *big; 697 crypto_object_attribute_t *attrs, *cur_attr; 698 CK_ATTRIBUTE tmp; 699 char *ptr; 700 int rv; 701 702 (void) pthread_mutex_lock(&object_p->object_mutex); 703 if (object_p->key_type != CKK_EC || 704 object_p->class != CKO_PUBLIC_KEY) { 705 (void) pthread_mutex_unlock(&object_p->object_mutex); 706 return (CKR_ATTRIBUTE_TYPE_INVALID); 707 } 708 709 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t)); 710 if (attrs == NULL) { 711 (void) pthread_mutex_unlock(&object_p->object_mutex); 712 return (CKR_HOST_MEMORY); 713 } 714 715 key->ck_format = CRYPTO_KEY_ATTR_LIST; 716 key->ck_count = EC_ATTR_COUNT; 717 key->ck_attrs = attrs; 718 719 cur_attr = attrs; 720 big = OBJ_PUB_EC_POINT(object_p); 721 if ((ptr = malloc(big->big_value_len)) == NULL) { 722 rv = CKR_HOST_MEMORY; 723 goto fail; 724 } 725 ENCODE_ATTR(CKA_EC_POINT, big->big_value, big->big_value_len); 726 727 tmp.type = CKA_EC_PARAMS; 728 tmp.pValue = NULL; 729 rv = kernel_get_attribute(object_p, &tmp); 730 if (rv != CKR_OK) { 731 goto fail; 732 } 733 734 tmp.pValue = malloc(tmp.ulValueLen); 735 if (tmp.pValue == NULL) { 736 rv = CKR_HOST_MEMORY; 737 goto fail; 738 } 739 740 rv = kernel_get_attribute(object_p, &tmp); 741 if (rv != CKR_OK) { 742 free(tmp.pValue); 743 goto fail; 744 } 745 746 cur_attr->oa_type = tmp.type; 747 cur_attr->oa_value = tmp.pValue; 748 cur_attr->oa_value_len = tmp.ulValueLen; 749 750 (void) pthread_mutex_unlock(&object_p->object_mutex); 751 return (CKR_OK); 752 753 fail: 754 (void) pthread_mutex_unlock(&object_p->object_mutex); 755 free_key_attributes(key); 756 return (rv); 757 } 758 759 /* 760 * Convert an attribute template into an obj_attrs array. 761 * Memory is allocated for each attribute stored in the obj_attrs. 762 * The memory can be freed by free_object_attributes(). 763 * 764 * If the boolean pointer is_token_obj is not NULL, the caller wants to 765 * retrieve the value of the CKA_TOKEN attribute if it is specified in the 766 * template. 767 * - When this routine is called thru C_CreateObject(), C_CopyObject(), or 768 * any key management function, is_token_obj should NOT be NULL. 769 * - When this routine is called thru C_GetAttributeValue() or 770 * C_SetAttributeValue(), "is_token_obj" should be NULL. 771 */ 772 CK_RV 773 process_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 774 caddr_t *obj_attrs, CK_BBOOL *is_token_obj) 775 { 776 crypto_object_attribute_t *attrs, *cur_attr; 777 int i, cur_i; 778 char *ptr; 779 CK_RV rv; 780 ssize_t value_len; 781 782 if (ulCount == 0) { 783 obj_attrs = NULL; 784 return (CKR_OK); 785 } 786 787 attrs = calloc(1, ulCount * sizeof (crypto_object_attribute_t)); 788 if (attrs == NULL) { 789 return (CKR_HOST_MEMORY); 790 } 791 792 cur_attr = attrs; 793 for (i = 0; i < ulCount; i++) { 794 /* 795 * The length of long attributes must be set correctly 796 * so providers can determine whether they came from 32 797 * or 64-bit applications. 798 */ 799 switch (pTemplate[i].type) { 800 case CKA_CLASS: 801 case CKA_CERTIFICATE_TYPE: 802 case CKA_KEY_TYPE: 803 case CKA_MODULUS_BITS: 804 case CKA_HW_FEATURE_TYPE: 805 value_len = sizeof (ulong_t); 806 if (pTemplate[i].pValue != NULL && 807 (pTemplate[i].ulValueLen < value_len)) { 808 rv = CKR_ATTRIBUTE_VALUE_INVALID; 809 cur_i = i; 810 goto fail_cleanup; 811 } 812 break; 813 default: 814 value_len = pTemplate[i].ulValueLen; 815 } 816 817 cur_attr->oa_type = pTemplate[i].type; 818 cur_attr->oa_value_len = value_len; 819 cur_attr->oa_value = NULL; 820 821 if ((pTemplate[i].pValue != NULL) && 822 (pTemplate[i].ulValueLen > 0)) { 823 ptr = malloc(pTemplate[i].ulValueLen); 824 if (ptr == NULL) { 825 rv = CKR_HOST_MEMORY; 826 cur_i = i; 827 goto fail_cleanup; 828 } else { 829 (void) memcpy(ptr, pTemplate[i].pValue, 830 pTemplate[i].ulValueLen); 831 cur_attr->oa_value = ptr; 832 } 833 } 834 835 if ((is_token_obj != NULL) && 836 (pTemplate[i].type == CKA_TOKEN)) { 837 /* Get the CKA_TOKEN attribute value. */ 838 if (pTemplate[i].pValue == NULL) { 839 rv = CKR_ATTRIBUTE_VALUE_INVALID; 840 cur_i = i; 841 goto fail_cleanup; 842 } else { 843 *is_token_obj = 844 *(CK_BBOOL *)pTemplate[i].pValue; 845 } 846 } 847 848 cur_attr++; 849 } 850 851 *obj_attrs = (char *)attrs; 852 return (CKR_OK); 853 854 fail_cleanup: 855 cur_attr = attrs; 856 for (i = 0; i < cur_i; i++) { 857 if (cur_attr->oa_value != NULL) { 858 (void) free(cur_attr->oa_value); 859 } 860 cur_attr++; 861 } 862 863 (void) free(attrs); 864 return (rv); 865 } 866 867 868 /* 869 * Copy the attribute values from obj_attrs to pTemplate. 870 * The obj_attrs is an image of the Template and is expected to have the 871 * same attributes in the same order and each one of the attribute pValue 872 * in obj_attr has enough space allocated for the corresponding valueLen 873 * in pTemplate. 874 */ 875 CK_RV 876 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 877 caddr_t obj_attrs) 878 { 879 crypto_object_attribute_t *cur_attr; 880 CK_RV rv = CKR_OK; 881 int i; 882 883 /* LINTED */ 884 cur_attr = (crypto_object_attribute_t *)obj_attrs; 885 for (i = 0; i < ulCount; i++) { 886 if (pTemplate[i].type != cur_attr->oa_type) { 887 /* The attribute type doesn't match, this is bad. */ 888 rv = CKR_FUNCTION_FAILED; 889 return (rv); 890 } 891 892 pTemplate[i].ulValueLen = cur_attr->oa_value_len; 893 894 if ((pTemplate[i].pValue != NULL) && 895 ((CK_LONG)pTemplate[i].ulValueLen != -1)) { 896 (void) memcpy(pTemplate[i].pValue, cur_attr->oa_value, 897 pTemplate[i].ulValueLen); 898 } 899 cur_attr++; 900 } 901 902 return (rv); 903 } 904 905 /* 906 * Free the attribute storage in a crypto_object_attribute_t structure. 907 */ 908 void 909 free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount) 910 { 911 crypto_object_attribute_t *cur_attr; 912 int i; 913 914 if ((ulCount == 0) || (obj_attrs == NULL)) { 915 return; 916 } 917 918 /* LINTED */ 919 cur_attr = (crypto_object_attribute_t *)obj_attrs; 920 for (i = 0; i < ulCount; i++) { 921 /* XXX check that oa_value > 0 */ 922 if (cur_attr->oa_value != NULL) { 923 free(cur_attr->oa_value); 924 } 925 cur_attr++; 926 } 927 928 free(obj_attrs); 929 } 930 931 /* 932 * This function is called by process_found_objects(). It will check the 933 * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then 934 * initialize all the necessary fields in the object wrapper "objp". 935 */ 936 static CK_RV 937 create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp, 938 kernel_object_t *objp, crypto_object_id_t oid) 939 { 940 CK_RV rv = CKR_OK; 941 crypto_object_get_attribute_value_t obj_ga; 942 boolean_t is_pri_obj; 943 boolean_t is_token_obj; 944 CK_BBOOL pri_value, token_value; 945 CK_ATTRIBUTE pTemplate[2]; 946 int r; 947 948 /* 949 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this 950 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN. 951 */ 952 obj_ga.og_session = sp->k_session; 953 obj_ga.og_handle = oid; 954 obj_ga.og_count = 2; 955 956 pTemplate[0].type = CKA_PRIVATE; 957 pTemplate[0].pValue = &pri_value; 958 pTemplate[0].ulValueLen = sizeof (pri_value); 959 pTemplate[1].type = CKA_TOKEN; 960 pTemplate[1].pValue = &token_value; 961 pTemplate[1].ulValueLen = sizeof (token_value); 962 rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes, 963 NULL); 964 if (rv != CKR_OK) { 965 return (rv); 966 } 967 968 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 969 &obj_ga)) < 0) { 970 if (errno != EINTR) 971 break; 972 } 973 if (r < 0) { 974 rv = CKR_FUNCTION_FAILED; 975 } else { 976 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 977 } 978 979 if (rv == CKR_OK) { 980 rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes); 981 if (rv == CKR_OK) { 982 is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue; 983 is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue; 984 } 985 } 986 987 free_object_attributes(obj_ga.og_attributes, 2); 988 if (rv != CKR_OK) { 989 return (rv); 990 } 991 992 /* Make sure it is a token object. */ 993 if (!is_token_obj) { 994 rv = CKR_ATTRIBUTE_VALUE_INVALID; 995 return (rv); 996 } 997 998 /* If it is a private object, make sure the user has logged in. */ 999 if (is_pri_obj && (pslot->sl_state != CKU_USER)) { 1000 rv = CKR_ATTRIBUTE_VALUE_INVALID; 1001 return (rv); 1002 } 1003 1004 objp->is_lib_obj = B_FALSE; 1005 objp->k_handle = oid; 1006 objp->bool_attr_mask |= TOKEN_BOOL_ON; 1007 if (is_pri_obj) { 1008 objp->bool_attr_mask |= PRIVATE_BOOL_ON; 1009 } else { 1010 objp->bool_attr_mask &= ~PRIVATE_BOOL_ON; 1011 } 1012 1013 (void) pthread_mutex_init(&objp->object_mutex, NULL); 1014 objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC; 1015 objp->session_handle = (CK_SESSION_HANDLE) sp; 1016 1017 return (CKR_OK); 1018 } 1019 1020 /* 1021 * This function processes the kernel object handles returned from the 1022 * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list 1023 * and the number of object handles to the caller - C_FindObjects(). 1024 * The caller acquires the slot lock and the session lock. 1025 */ 1026 CK_RV 1027 process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found, 1028 CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu) 1029 { 1030 CK_RV rv = CKR_OK; 1031 crypto_object_id_t *oid_p; 1032 kernel_slot_t *pslot; 1033 kernel_object_t *objp; 1034 kernel_object_t *objp1; 1035 kernel_object_t *new_tobj_list = NULL; 1036 kernel_session_t *sp; 1037 CK_ULONG num_obj_found = 0; 1038 boolean_t is_in_lib; 1039 int i; 1040 1041 if (obj_fu.fu_count == 0) { 1042 *found_obj_count = 0; 1043 return (CKR_OK); 1044 } 1045 1046 pslot = slot_table[cur_sp->ses_slotid]; 1047 1048 /* LINTED */ 1049 oid_p = (crypto_object_id_t *)obj_fu.fu_handles; 1050 for (i = 0; i < obj_fu.fu_count; i++) { 1051 is_in_lib = B_FALSE; 1052 /* 1053 * Check if this oid has an object wrapper in the library 1054 * already. First, search the slot's token object list. 1055 */ 1056 objp = pslot->sl_tobj_list; 1057 while (!is_in_lib && objp) { 1058 if (objp->k_handle == *oid_p) { 1059 is_in_lib = B_TRUE; 1060 } else { 1061 objp = objp->next; 1062 } 1063 } 1064 1065 /* 1066 * If it is not in the slot's token object list, 1067 * search it in all the sessions. 1068 */ 1069 if (!is_in_lib) { 1070 sp = pslot->sl_sess_list; 1071 while (!is_in_lib && sp) { 1072 objp = sp->object_list; 1073 while (!is_in_lib && objp) { 1074 if (objp->k_handle == *oid_p) { 1075 is_in_lib = B_TRUE; 1076 } else { 1077 objp = objp->next; 1078 } 1079 } 1080 sp = sp->next; 1081 } 1082 } 1083 1084 /* 1085 * If this object is in the library already, add its object 1086 * wrapper to the returned find object list. 1087 */ 1088 if (is_in_lib) { 1089 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 1090 } 1091 1092 /* 1093 * If we still do not find it in the library. This object 1094 * must be a token object pre-existed in the HW provider. 1095 * We need to create an object wrapper for it in the library. 1096 */ 1097 if (!is_in_lib) { 1098 objp1 = calloc(1, sizeof (kernel_object_t)); 1099 if (objp1 == NULL) { 1100 rv = CKR_HOST_MEMORY; 1101 goto failed_exit; 1102 } 1103 rv = create_new_tobj_in_lib(pslot, cur_sp, objp1, 1104 *oid_p); 1105 1106 if (rv == CKR_OK) { 1107 /* Save the new object to the new_tobj_list. */ 1108 if (new_tobj_list == NULL) { 1109 new_tobj_list = objp1; 1110 objp1->next = NULL; 1111 objp1->prev = NULL; 1112 } else { 1113 new_tobj_list->prev = objp1; 1114 objp1->next = new_tobj_list; 1115 objp1->prev = NULL; 1116 new_tobj_list = objp1; 1117 } 1118 } else { 1119 /* 1120 * If create_new_tobj_in_lib() doesn't fail 1121 * with CKR_HOST_MEMORY, the failure should be 1122 * caused by the attributes' checking. We will 1123 * just ignore this object and continue on. 1124 */ 1125 free(objp1); 1126 if (rv == CKR_HOST_MEMORY) { 1127 goto failed_exit; 1128 } 1129 } 1130 } 1131 1132 /* Process next one */ 1133 oid_p++; 1134 } 1135 1136 /* 1137 * Add the newly created token object wrappers to the found object 1138 * list and to the slot's token object list. 1139 */ 1140 if (new_tobj_list != NULL) { 1141 /* Add to the obj_found array. */ 1142 objp = new_tobj_list; 1143 while (objp) { 1144 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 1145 if (objp->next == NULL) { 1146 break; 1147 } 1148 objp = objp->next; 1149 } 1150 1151 /* Add to the beginning of the slot's token object list. */ 1152 if (pslot->sl_tobj_list != NULL) { 1153 objp->next = pslot->sl_tobj_list; 1154 pslot->sl_tobj_list->prev = objp; 1155 } 1156 pslot->sl_tobj_list = new_tobj_list; 1157 } 1158 1159 *found_obj_count = num_obj_found; 1160 return (CKR_OK); 1161 1162 failed_exit: 1163 1164 /* Free the newly created token object wrappers. */ 1165 objp = new_tobj_list; 1166 while (objp) { 1167 objp1 = objp->next; 1168 (void) pthread_mutex_destroy(&objp->object_mutex); 1169 free(objp); 1170 objp = objp1; 1171 } 1172 1173 return (rv); 1174 } 1175 1176 1177 /* 1178 * Get the value of the CKA_PRIVATE attribute for the object just returned 1179 * from the HW provider. This function will be called by any function 1180 * that creates a new object, because the CKA_PRIVATE value of an object is 1181 * token specific. The CKA_PRIVATE attribute value of the new object will be 1182 * stored in the object structure in the library, which will be used later at 1183 * C_Logout to clean up all private objects. 1184 */ 1185 CK_RV 1186 get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid, 1187 CK_BBOOL *is_pri_obj) 1188 { 1189 CK_RV rv = CKR_OK; 1190 crypto_object_get_attribute_value_t obj_ga; 1191 crypto_object_attribute_t obj_attr; 1192 CK_BBOOL pri_value; 1193 int r; 1194 1195 obj_ga.og_session = sp->k_session; 1196 obj_ga.og_handle = oid; 1197 obj_ga.og_count = 1; 1198 1199 obj_attr.oa_type = CKA_PRIVATE; 1200 obj_attr.oa_value = (char *)&pri_value; 1201 obj_attr.oa_value_len = sizeof (CK_BBOOL); 1202 obj_ga.og_attributes = (char *)&obj_attr; 1203 1204 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 1205 &obj_ga)) < 0) { 1206 if (errno != EINTR) 1207 break; 1208 } 1209 if (r < 0) { 1210 rv = CKR_FUNCTION_FAILED; 1211 } else { 1212 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 1213 } 1214 1215 if (rv == CKR_OK) { 1216 *is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value; 1217 } 1218 1219 return (rv); 1220 } 1221 1222 1223 CK_RV 1224 get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type, 1225 CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags) 1226 { 1227 crypto_get_provider_mechanism_info_t mechanism_info; 1228 const char *string; 1229 CK_FLAGS flags, mi_flags; 1230 CK_RV rv; 1231 int r; 1232 char buf[11]; /* Num chars for representing ulong in ASCII */ 1233 1234 if (type >= CKM_VENDOR_DEFINED) { 1235 /* allocate/build a string containing the mechanism number */ 1236 (void) snprintf(buf, sizeof (buf), "%#lx", type); 1237 string = buf; 1238 } else { 1239 string = pkcs11_mech2str(type); 1240 } 1241 1242 if (string == NULL) 1243 return (CKR_MECHANISM_INVALID); 1244 1245 (void) strcpy(mechanism_info.mi_mechanism_name, string); 1246 mechanism_info.mi_provider_id = pslot->sl_provider_id; 1247 1248 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO, 1249 &mechanism_info)) < 0) { 1250 if (errno != EINTR) 1251 break; 1252 } 1253 if (r < 0) { 1254 rv = CKR_FUNCTION_FAILED; 1255 } else { 1256 rv = crypto2pkcs11_error_number( 1257 mechanism_info.mi_return_value); 1258 } 1259 1260 if (rv != CKR_OK) { 1261 return (rv); 1262 } 1263 1264 /* 1265 * Atomic flags are not part of PKCS#11 so we filter 1266 * them out here. 1267 */ 1268 mi_flags = mechanism_info.mi_flags; 1269 mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC | 1270 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC | 1271 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 1272 CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1273 CRYPTO_FG_VERIFY_RECOVER_ATOMIC | 1274 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 1275 CRYPTO_FG_MAC_DECRYPT_ATOMIC); 1276 1277 if (mi_flags == 0) { 1278 return (CKR_MECHANISM_INVALID); 1279 } 1280 1281 if (rv == CKR_OK) { 1282 /* set the value of k_mi_flags first */ 1283 *k_mi_flags = mi_flags; 1284 1285 /* convert KEF flags into pkcs11 flags */ 1286 flags = CKF_HW; 1287 if (mi_flags & CRYPTO_FG_ENCRYPT) 1288 flags |= CKF_ENCRYPT; 1289 if (mi_flags & CRYPTO_FG_DECRYPT) { 1290 flags |= CKF_DECRYPT; 1291 /* 1292 * Since we'll be emulating C_UnwrapKey() for some 1293 * cases, we can go ahead and claim CKF_UNWRAP 1294 */ 1295 flags |= CKF_UNWRAP; 1296 } 1297 if (mi_flags & CRYPTO_FG_DIGEST) 1298 flags |= CKF_DIGEST; 1299 if (mi_flags & CRYPTO_FG_SIGN) 1300 flags |= CKF_SIGN; 1301 if (mi_flags & CRYPTO_FG_SIGN_RECOVER) 1302 flags |= CKF_SIGN_RECOVER; 1303 if (mi_flags & CRYPTO_FG_VERIFY) 1304 flags |= CKF_VERIFY; 1305 if (mi_flags & CRYPTO_FG_VERIFY_RECOVER) 1306 flags |= CKF_VERIFY_RECOVER; 1307 if (mi_flags & CRYPTO_FG_GENERATE) 1308 flags |= CKF_GENERATE; 1309 if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR) 1310 flags |= CKF_GENERATE_KEY_PAIR; 1311 if (mi_flags & CRYPTO_FG_WRAP) 1312 flags |= CKF_WRAP; 1313 if (mi_flags & CRYPTO_FG_UNWRAP) 1314 flags |= CKF_UNWRAP; 1315 if (mi_flags & CRYPTO_FG_DERIVE) 1316 flags |= CKF_DERIVE; 1317 1318 pInfo->ulMinKeySize = mechanism_info.mi_min_key_size; 1319 pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size; 1320 pInfo->flags = flags; 1321 1322 } 1323 1324 return (rv); 1325 }