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