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