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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdlib.h> 29 #include <string.h> 30 #include <strings.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 char *string; 196 CK_RV rv; 197 int r; 198 kmh_elem_t *elem; 199 uint_t h; 200 201 /* 202 * Search for an existing entry. No need to lock since we are 203 * just a reader and we never free the entries in the hash table. 204 */ 205 h = MECH_HASH(type); 206 for (elem = kernel_mechhash[h]; elem != NULL; elem = elem->knext) { 207 if (type == elem->type) { 208 *k_number = elem->kmech; 209 return (CKR_OK); 210 } 211 } 212 213 string = pkcs11_mech2str(type); 214 if (string == NULL) 215 return (CKR_MECHANISM_INVALID); 216 217 get_number.pn_mechanism_string = string; 218 get_number.pn_mechanism_len = strlen(string) + 1; 219 220 while ((r = ioctl(kernel_fd, CRYPTO_GET_MECHANISM_NUMBER, 221 &get_number)) < 0) { 222 if (errno != EINTR) 223 break; 224 } 225 if (r < 0) { 226 rv = CKR_MECHANISM_INVALID; 227 } else { 228 if (get_number.pn_return_value != CRYPTO_SUCCESS) { 229 rv = crypto2pkcs11_error_number( 230 get_number.pn_return_value); 231 } else { 232 rv = CKR_OK; 233 } 234 } 235 236 if (rv == CKR_OK) { 237 *k_number = get_number.pn_internal_number; 238 /* Add this to the hash table */ 239 (void) kmech_hash_insert(type, *k_number); 240 } 241 242 free(string); 243 return (rv); 244 } 245 246 247 /* 248 * Return the value of a secret key object. 249 * This routine allocates memory for the value. 250 * A null pointer is returned on error. 251 */ 252 unsigned char * 253 get_symmetric_key_value(kernel_object_t *key_p) 254 { 255 uint8_t *cipherKey; 256 257 switch (key_p->class) { 258 259 case CKO_SECRET_KEY: 260 261 cipherKey = malloc(OBJ_SEC(key_p)->sk_value_len); 262 if (cipherKey == NULL) 263 return (NULL); 264 265 (void) memcpy(cipherKey, OBJ_SEC(key_p)->sk_value, 266 OBJ_SEC(key_p)->sk_value_len); 267 268 return (cipherKey); 269 270 default: 271 return (NULL); 272 } 273 } 274 275 /* 276 * Convert a RSA private key object into a crypto_key structure. 277 * Memory is allocated for each attribute stored in the crypto_key 278 * structure. Memory for the crypto_key structure is not 279 * allocated. Attributes can be freed by free_key_attributes(). 280 */ 281 CK_RV 282 get_rsa_private_key(kernel_object_t *object_p, crypto_key_t *key) 283 { 284 biginteger_t *big; 285 crypto_object_attribute_t *attrs, *cur_attr; 286 char *ptr; 287 CK_RV rv; 288 289 (void) pthread_mutex_lock(&object_p->object_mutex); 290 if (object_p->key_type != CKK_RSA || 291 object_p->class != CKO_PRIVATE_KEY) { 292 (void) pthread_mutex_unlock(&object_p->object_mutex); 293 return (CKR_ATTRIBUTE_TYPE_INVALID); 294 } 295 296 attrs = calloc(1, 297 RSA_PRI_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 298 if (attrs == NULL) { 299 (void) pthread_mutex_unlock(&object_p->object_mutex); 300 return (CKR_HOST_MEMORY); 301 } 302 303 key->ck_format = CRYPTO_KEY_ATTR_LIST; 304 key->ck_attrs = attrs; 305 cur_attr = attrs; 306 307 /* 308 * Allocate memory for each key attribute and set up the value 309 * value length. 310 */ 311 key->ck_count = 0; 312 313 /* CKA_MODULUS is required. */ 314 big = OBJ_PRI_RSA_MOD(object_p); 315 if (big->big_value == NULL) { 316 rv = CKR_ATTRIBUTE_TYPE_INVALID; 317 goto fail_cleanup; 318 } else { 319 if ((ptr = malloc(big->big_value_len)) == NULL) { 320 rv = CKR_HOST_MEMORY; 321 goto fail_cleanup; 322 } 323 ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len); 324 key->ck_count++; 325 } 326 327 /* CKA_PRIVATE_EXPONENT is required. */ 328 big = OBJ_PRI_RSA_PRIEXPO(object_p); 329 if (big->big_value == NULL) { 330 rv = CKR_ATTRIBUTE_TYPE_INVALID; 331 goto fail_cleanup; 332 } else { 333 if ((ptr = malloc(big->big_value_len)) == NULL) { 334 rv = CKR_HOST_MEMORY; 335 goto fail_cleanup; 336 } 337 ENCODE_ATTR(CKA_PRIVATE_EXPONENT, big->big_value, 338 big->big_value_len); 339 key->ck_count++; 340 } 341 342 /* CKA_PRIME_1 is optional. */ 343 big = OBJ_PRI_RSA_PRIME1(object_p); 344 if (big->big_value != NULL) { 345 if ((ptr = malloc(big->big_value_len)) == NULL) { 346 rv = CKR_HOST_MEMORY; 347 goto fail_cleanup; 348 } 349 ENCODE_ATTR(CKA_PRIME_1, big->big_value, big->big_value_len); 350 key->ck_count++; 351 } 352 353 /* CKA_PRIME_2 is optional. */ 354 big = OBJ_PRI_RSA_PRIME2(object_p); 355 if (big->big_value != NULL) { 356 if ((ptr = malloc(big->big_value_len)) == NULL) { 357 rv = CKR_HOST_MEMORY; 358 goto fail_cleanup; 359 } 360 ENCODE_ATTR(CKA_PRIME_2, big->big_value, big->big_value_len); 361 key->ck_count++; 362 } 363 364 /* CKA_EXPONENT_1 is optional. */ 365 big = OBJ_PRI_RSA_EXPO1(object_p); 366 if (big->big_value != NULL) { 367 if ((ptr = malloc(big->big_value_len)) == NULL) { 368 rv = CKR_HOST_MEMORY; 369 goto fail_cleanup; 370 } 371 ENCODE_ATTR(CKA_EXPONENT_1, big->big_value, 372 big->big_value_len); 373 key->ck_count++; 374 } 375 376 /* CKA_EXPONENT_2 is optional. */ 377 big = OBJ_PRI_RSA_EXPO2(object_p); 378 if (big->big_value != NULL) { 379 if ((ptr = malloc(big->big_value_len)) == NULL) { 380 rv = CKR_HOST_MEMORY; 381 goto fail_cleanup; 382 } 383 ENCODE_ATTR(CKA_EXPONENT_2, big->big_value, 384 big->big_value_len); 385 key->ck_count++; 386 } 387 388 /* CKA_COEFFICIENT is optional. */ 389 big = OBJ_PRI_RSA_COEF(object_p); 390 if (big->big_value != NULL) { 391 if ((ptr = malloc(big->big_value_len)) == NULL) { 392 rv = CKR_HOST_MEMORY; 393 goto fail_cleanup; 394 } 395 ENCODE_ATTR(CKA_COEFFICIENT, big->big_value, 396 big->big_value_len); 397 key->ck_count++; 398 } 399 400 (void) pthread_mutex_unlock(&object_p->object_mutex); 401 return (CKR_OK); 402 403 fail_cleanup: 404 (void) pthread_mutex_unlock(&object_p->object_mutex); 405 free_key_attributes(key); 406 return (rv); 407 } 408 409 /* 410 * Convert a RSA public key object into a crypto_key structure. 411 * Memory is allocated for each attribute stored in the crypto_key 412 * structure. Memory for the crypto_key structure is not 413 * allocated. Attributes can be freed by free_key_attributes(). 414 */ 415 CK_RV 416 get_rsa_public_key(kernel_object_t *object_p, crypto_key_t *key) 417 { 418 biginteger_t *big; 419 crypto_object_attribute_t *attrs, *cur_attr; 420 char *ptr; 421 422 (void) pthread_mutex_lock(&object_p->object_mutex); 423 if (object_p->key_type != CKK_RSA || 424 object_p->class != CKO_PUBLIC_KEY) { 425 (void) pthread_mutex_unlock(&object_p->object_mutex); 426 return (CKR_ATTRIBUTE_TYPE_INVALID); 427 } 428 429 attrs = calloc(1, 430 RSA_PUB_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 431 if (attrs == NULL) { 432 (void) pthread_mutex_unlock(&object_p->object_mutex); 433 return (CKR_HOST_MEMORY); 434 } 435 436 key->ck_format = CRYPTO_KEY_ATTR_LIST; 437 key->ck_count = RSA_PUB_ATTR_COUNT; 438 key->ck_attrs = attrs; 439 440 cur_attr = attrs; 441 big = OBJ_PUB_RSA_PUBEXPO(object_p); 442 if ((ptr = malloc(big->big_value_len)) == NULL) 443 goto mem_failure; 444 ENCODE_ATTR(CKA_PUBLIC_EXPONENT, big->big_value, big->big_value_len); 445 446 big = OBJ_PUB_RSA_MOD(object_p); 447 if ((ptr = malloc(big->big_value_len)) == NULL) 448 goto mem_failure; 449 ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len); 450 451 if ((ptr = malloc(sizeof (CK_ULONG))) == NULL) 452 goto mem_failure; 453 ENCODE_ATTR(CKA_MODULUS_BITS, &OBJ_PUB_RSA_MOD_BITS(object_p), 454 sizeof (CK_ULONG)); 455 456 (void) pthread_mutex_unlock(&object_p->object_mutex); 457 return (CKR_OK); 458 459 mem_failure: 460 (void) pthread_mutex_unlock(&object_p->object_mutex); 461 free_key_attributes(key); 462 return (CKR_HOST_MEMORY); 463 } 464 465 /* 466 * Free attribute storage in a crypto_key structure. 467 */ 468 void 469 free_key_attributes(crypto_key_t *key) 470 { 471 int i; 472 473 if (key->ck_format == CRYPTO_KEY_ATTR_LIST && 474 (key->ck_count > 0) && key->ck_attrs != NULL) { 475 for (i = 0; i < key->ck_count; i++) { 476 if (key->ck_attrs[i].oa_value != NULL) { 477 bzero(key->ck_attrs[i].oa_value, 478 key->ck_attrs[i].oa_value_len); 479 free(key->ck_attrs[i].oa_value); 480 } 481 } 482 free(key->ck_attrs); 483 } 484 } 485 486 487 /* 488 * Convert a DSA private key object into a crypto_key structure. 489 * Memory is allocated for each attribute stored in the crypto_key 490 * structure. Memory for the crypto_key structure is not 491 * allocated. Attributes can be freed by free_dsa_key_attributes(). 492 */ 493 CK_RV 494 get_dsa_private_key(kernel_object_t *object_p, crypto_key_t *key) 495 { 496 biginteger_t *big; 497 crypto_object_attribute_t *attrs, *cur_attr; 498 char *ptr; 499 500 (void) pthread_mutex_lock(&object_p->object_mutex); 501 if (object_p->key_type != CKK_DSA || 502 object_p->class != CKO_PRIVATE_KEY) { 503 (void) pthread_mutex_unlock(&object_p->object_mutex); 504 return (CKR_ATTRIBUTE_TYPE_INVALID); 505 } 506 507 attrs = calloc(1, 508 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 509 if (attrs == NULL) { 510 (void) pthread_mutex_unlock(&object_p->object_mutex); 511 return (CKR_HOST_MEMORY); 512 } 513 514 key->ck_format = CRYPTO_KEY_ATTR_LIST; 515 key->ck_count = DSA_ATTR_COUNT; 516 key->ck_attrs = attrs; 517 518 cur_attr = attrs; 519 big = OBJ_PRI_DSA_PRIME(object_p); 520 if ((ptr = malloc(big->big_value_len)) == NULL) 521 goto mem_failure; 522 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len); 523 524 big = OBJ_PRI_DSA_SUBPRIME(object_p); 525 if ((ptr = malloc(big->big_value_len)) == NULL) 526 goto mem_failure; 527 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len); 528 529 big = OBJ_PRI_DSA_BASE(object_p); 530 if ((ptr = malloc(big->big_value_len)) == NULL) 531 goto mem_failure; 532 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len); 533 534 big = OBJ_PRI_DSA_VALUE(object_p); 535 if ((ptr = malloc(big->big_value_len)) == NULL) 536 goto mem_failure; 537 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 538 539 (void) pthread_mutex_unlock(&object_p->object_mutex); 540 return (CKR_OK); 541 542 mem_failure: 543 (void) pthread_mutex_unlock(&object_p->object_mutex); 544 free_key_attributes(key); 545 return (CKR_HOST_MEMORY); 546 } 547 548 549 /* 550 * Convert a DSA public key object into a crypto_key structure. 551 * Memory is allocated for each attribute stored in the crypto_key 552 * structure. Memory for the crypto_key structure is not 553 * allocated. Attributes can be freed by free_dsa_key_attributes(). 554 */ 555 CK_RV 556 get_dsa_public_key(kernel_object_t *object_p, crypto_key_t *key) 557 { 558 biginteger_t *big; 559 crypto_object_attribute_t *attrs, *cur_attr; 560 char *ptr; 561 562 (void) pthread_mutex_lock(&object_p->object_mutex); 563 if (object_p->key_type != CKK_DSA || 564 object_p->class != CKO_PUBLIC_KEY) { 565 (void) pthread_mutex_unlock(&object_p->object_mutex); 566 return (CKR_ATTRIBUTE_TYPE_INVALID); 567 } 568 569 attrs = calloc(1, 570 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 571 if (attrs == NULL) { 572 (void) pthread_mutex_unlock(&object_p->object_mutex); 573 return (CKR_HOST_MEMORY); 574 } 575 576 key->ck_format = CRYPTO_KEY_ATTR_LIST; 577 key->ck_count = DSA_ATTR_COUNT; 578 key->ck_attrs = attrs; 579 580 cur_attr = attrs; 581 big = OBJ_PUB_DSA_PRIME(object_p); 582 if ((ptr = malloc(big->big_value_len)) == NULL) 583 goto mem_failure; 584 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len); 585 586 big = OBJ_PUB_DSA_SUBPRIME(object_p); 587 if ((ptr = malloc(big->big_value_len)) == NULL) 588 goto mem_failure; 589 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len); 590 591 big = OBJ_PUB_DSA_BASE(object_p); 592 if ((ptr = malloc(big->big_value_len)) == NULL) 593 goto mem_failure; 594 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len); 595 596 big = OBJ_PUB_DSA_VALUE(object_p); 597 if ((ptr = malloc(big->big_value_len)) == NULL) 598 goto mem_failure; 599 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 600 601 (void) pthread_mutex_unlock(&object_p->object_mutex); 602 return (CKR_OK); 603 604 mem_failure: 605 (void) pthread_mutex_unlock(&object_p->object_mutex); 606 free_key_attributes(key); 607 return (CKR_HOST_MEMORY); 608 } 609 610 611 /* 612 * Convert a EC private key object into a crypto_key structure. 613 * Memory is allocated for each attribute stored in the crypto_key 614 * structure. Memory for the crypto_key structure is not 615 * allocated. Attributes can be freed by free_ec_key_attributes(). 616 */ 617 CK_RV 618 get_ec_private_key(kernel_object_t *object_p, crypto_key_t *key) 619 { 620 biginteger_t *big; 621 crypto_object_attribute_t *attrs, *cur_attr; 622 CK_ATTRIBUTE tmp; 623 char *ptr; 624 int rv; 625 626 (void) pthread_mutex_lock(&object_p->object_mutex); 627 if (object_p->key_type != CKK_EC || 628 object_p->class != CKO_PRIVATE_KEY) { 629 (void) pthread_mutex_unlock(&object_p->object_mutex); 630 return (CKR_ATTRIBUTE_TYPE_INVALID); 631 } 632 633 attrs = calloc(1, 634 (EC_ATTR_COUNT + 1) * sizeof (crypto_object_attribute_t)); 635 if (attrs == NULL) { 636 (void) pthread_mutex_unlock(&object_p->object_mutex); 637 return (CKR_HOST_MEMORY); 638 } 639 640 key->ck_format = CRYPTO_KEY_ATTR_LIST; 641 key->ck_count = EC_ATTR_COUNT + 1; 642 key->ck_attrs = attrs; 643 644 cur_attr = attrs; 645 big = OBJ_PRI_EC_VALUE(object_p); 646 if ((ptr = malloc(big->big_value_len)) == NULL) { 647 rv = CKR_HOST_MEMORY; 648 goto fail; 649 } 650 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 651 652 tmp.type = CKA_EC_PARAMS; 653 tmp.pValue = NULL; 654 rv = kernel_get_attribute(object_p, &tmp); 655 if (rv != CKR_OK) { 656 goto fail; 657 } 658 659 tmp.pValue = malloc(tmp.ulValueLen); 660 if (tmp.pValue == NULL) { 661 rv = CKR_HOST_MEMORY; 662 goto fail; 663 } 664 665 rv = kernel_get_attribute(object_p, &tmp); 666 if (rv != CKR_OK) { 667 free(tmp.pValue); 668 goto fail; 669 } 670 671 cur_attr->oa_type = tmp.type; 672 cur_attr->oa_value = tmp.pValue; 673 cur_attr->oa_value_len = tmp.ulValueLen; 674 675 (void) pthread_mutex_unlock(&object_p->object_mutex); 676 return (CKR_OK); 677 678 fail: 679 (void) pthread_mutex_unlock(&object_p->object_mutex); 680 free_key_attributes(key); 681 return (rv); 682 } 683 684 /* 685 * Convert an EC public key object into a crypto_key structure. 686 * Memory is allocated for each attribute stored in the crypto_key 687 * structure. Memory for the crypto_key structure is not 688 * allocated. Attributes can be freed by free_ec_key_attributes(). 689 */ 690 CK_RV 691 get_ec_public_key(kernel_object_t *object_p, crypto_key_t *key) 692 { 693 biginteger_t *big; 694 crypto_object_attribute_t *attrs, *cur_attr; 695 char *ptr; 696 697 (void) pthread_mutex_lock(&object_p->object_mutex); 698 if (object_p->key_type != CKK_EC || 699 object_p->class != CKO_PUBLIC_KEY) { 700 (void) pthread_mutex_unlock(&object_p->object_mutex); 701 return (CKR_ATTRIBUTE_TYPE_INVALID); 702 } 703 704 attrs = calloc(1, EC_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 705 if (attrs == NULL) { 706 (void) pthread_mutex_unlock(&object_p->object_mutex); 707 return (CKR_HOST_MEMORY); 708 } 709 710 key->ck_format = CRYPTO_KEY_ATTR_LIST; 711 key->ck_count = EC_ATTR_COUNT; 712 key->ck_attrs = attrs; 713 714 cur_attr = attrs; 715 big = OBJ_PUB_EC_POINT(object_p); 716 if ((ptr = malloc(big->big_value_len)) == NULL) { 717 (void) pthread_mutex_unlock(&object_p->object_mutex); 718 free_key_attributes(key); 719 return (CKR_HOST_MEMORY); 720 } 721 ENCODE_ATTR(CKA_EC_POINT, big->big_value, big->big_value_len); 722 723 (void) pthread_mutex_unlock(&object_p->object_mutex); 724 return (CKR_OK); 725 } 726 727 /* 728 * Convert an attribute template into an obj_attrs array. 729 * Memory is allocated for each attribute stored in the obj_attrs. 730 * The memory can be freed by free_object_attributes(). 731 * 732 * If the boolean pointer is_token_obj is not NULL, the caller wants to 733 * retrieve the value of the CKA_TOKEN attribute if it is specified in the 734 * template. 735 * - When this routine is called thru C_CreateObject(), C_CopyObject(), or 736 * any key management function, is_token_obj should NOT be NULL. 737 * - When this routine is called thru C_GetAttributeValue() or 738 * C_SetAttributeValue(), "is_token_obj" should be NULL. 739 */ 740 CK_RV 741 process_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 742 caddr_t *obj_attrs, CK_BBOOL *is_token_obj) 743 { 744 crypto_object_attribute_t *attrs, *cur_attr; 745 int i, cur_i; 746 char *ptr; 747 CK_RV rv; 748 ssize_t value_len; 749 750 if (ulCount == 0) { 751 obj_attrs = NULL; 752 return (CKR_OK); 753 } 754 755 attrs = calloc(1, ulCount * sizeof (crypto_object_attribute_t)); 756 if (attrs == NULL) { 757 return (CKR_HOST_MEMORY); 758 } 759 760 cur_attr = attrs; 761 for (i = 0; i < ulCount; i++) { 762 /* 763 * The length of long attributes must be set correctly 764 * so providers can determine whether they came from 32 765 * or 64-bit applications. 766 */ 767 switch (pTemplate[i].type) { 768 case CKA_CLASS: 769 case CKA_CERTIFICATE_TYPE: 770 case CKA_KEY_TYPE: 771 case CKA_MODULUS_BITS: 772 case CKA_HW_FEATURE_TYPE: 773 value_len = sizeof (ulong_t); 774 if (pTemplate[i].pValue != NULL && 775 (pTemplate[i].ulValueLen < value_len)) { 776 rv = CKR_BUFFER_TOO_SMALL; 777 cur_i = i; 778 goto fail_cleanup; 779 } 780 break; 781 default: 782 value_len = pTemplate[i].ulValueLen; 783 } 784 785 cur_attr->oa_type = pTemplate[i].type; 786 cur_attr->oa_value_len = value_len; 787 cur_attr->oa_value = NULL; 788 789 if ((pTemplate[i].pValue != NULL) && 790 (pTemplate[i].ulValueLen > 0)) { 791 ptr = malloc(pTemplate[i].ulValueLen); 792 if (ptr == NULL) { 793 rv = CKR_HOST_MEMORY; 794 cur_i = i; 795 goto fail_cleanup; 796 } else { 797 (void) memcpy(ptr, pTemplate[i].pValue, 798 pTemplate[i].ulValueLen); 799 cur_attr->oa_value = ptr; 800 } 801 } 802 803 if ((is_token_obj != NULL) && 804 (pTemplate[i].type == CKA_TOKEN)) { 805 /* Get the CKA_TOKEN attribute value. */ 806 if (pTemplate[i].pValue == NULL) { 807 rv = CKR_ATTRIBUTE_VALUE_INVALID; 808 cur_i = i; 809 goto fail_cleanup; 810 } else { 811 *is_token_obj = 812 *(CK_BBOOL *)pTemplate[i].pValue; 813 } 814 } 815 816 cur_attr++; 817 } 818 819 *obj_attrs = (char *)attrs; 820 return (CKR_OK); 821 822 fail_cleanup: 823 cur_attr = attrs; 824 for (i = 0; i < cur_i; i++) { 825 if (cur_attr->oa_value != NULL) { 826 (void) free(cur_attr->oa_value); 827 } 828 cur_attr++; 829 } 830 831 (void) free(attrs); 832 return (rv); 833 } 834 835 836 /* 837 * Copy the attribute values from obj_attrs to pTemplate. 838 * The obj_attrs is an image of the Template and is expected to have the 839 * same attributes in the same order and each one of the attribute pValue 840 * in obj_attr has enough space allocated for the corresponding valueLen 841 * in pTemplate. 842 */ 843 CK_RV 844 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 845 caddr_t obj_attrs) 846 { 847 crypto_object_attribute_t *cur_attr; 848 CK_RV rv = CKR_OK; 849 int i; 850 851 /* LINTED */ 852 cur_attr = (crypto_object_attribute_t *)obj_attrs; 853 for (i = 0; i < ulCount; i++) { 854 if (pTemplate[i].type != cur_attr->oa_type) { 855 /* The attribute type doesn't match, this is bad. */ 856 rv = CKR_FUNCTION_FAILED; 857 return (rv); 858 } 859 860 pTemplate[i].ulValueLen = cur_attr->oa_value_len; 861 862 if ((pTemplate[i].pValue != NULL) && 863 ((CK_LONG)pTemplate[i].ulValueLen != -1)) { 864 (void) memcpy(pTemplate[i].pValue, cur_attr->oa_value, 865 pTemplate[i].ulValueLen); 866 } 867 cur_attr++; 868 } 869 870 return (rv); 871 } 872 873 /* 874 * Free the attribute storage in a crypto_object_attribute_t structure. 875 */ 876 void 877 free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount) 878 { 879 crypto_object_attribute_t *cur_attr; 880 int i; 881 882 if ((ulCount == 0) || (obj_attrs == NULL)) { 883 return; 884 } 885 886 /* LINTED */ 887 cur_attr = (crypto_object_attribute_t *)obj_attrs; 888 for (i = 0; i < ulCount; i++) { 889 /* XXX check that oa_value > 0 */ 890 if (cur_attr->oa_value != NULL) { 891 free(cur_attr->oa_value); 892 } 893 cur_attr++; 894 } 895 896 free(obj_attrs); 897 } 898 899 /* 900 * This function is called by process_found_objects(). It will check the 901 * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then 902 * initialize all the necessary fields in the object wrapper "objp". 903 */ 904 static CK_RV 905 create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp, 906 kernel_object_t *objp, crypto_object_id_t oid) 907 { 908 CK_RV rv = CKR_OK; 909 crypto_object_get_attribute_value_t obj_ga; 910 boolean_t is_pri_obj; 911 boolean_t is_token_obj; 912 CK_BBOOL pri_value, token_value; 913 CK_ATTRIBUTE pTemplate[2]; 914 int r; 915 916 /* 917 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this 918 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN. 919 */ 920 obj_ga.og_session = sp->k_session; 921 obj_ga.og_handle = oid; 922 obj_ga.og_count = 2; 923 924 pTemplate[0].type = CKA_PRIVATE; 925 pTemplate[0].pValue = &pri_value; 926 pTemplate[0].ulValueLen = sizeof (pri_value); 927 pTemplate[1].type = CKA_TOKEN; 928 pTemplate[1].pValue = &token_value; 929 pTemplate[1].ulValueLen = sizeof (token_value); 930 rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes, 931 NULL); 932 if (rv != CKR_OK) { 933 return (rv); 934 } 935 936 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 937 &obj_ga)) < 0) { 938 if (errno != EINTR) 939 break; 940 } 941 if (r < 0) { 942 rv = CKR_FUNCTION_FAILED; 943 } else { 944 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 945 } 946 947 if (rv == CKR_OK) { 948 rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes); 949 if (rv == CKR_OK) { 950 is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue; 951 is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue; 952 } 953 } 954 955 free_object_attributes(obj_ga.og_attributes, 2); 956 if (rv != CKR_OK) { 957 return (rv); 958 } 959 960 /* Make sure it is a token object. */ 961 if (!is_token_obj) { 962 rv = CKR_ATTRIBUTE_VALUE_INVALID; 963 return (rv); 964 } 965 966 /* If it is a private object, make sure the user has logged in. */ 967 if (is_pri_obj && (pslot->sl_state != CKU_USER)) { 968 rv = CKR_ATTRIBUTE_VALUE_INVALID; 969 return (rv); 970 } 971 972 objp->is_lib_obj = B_FALSE; 973 objp->k_handle = oid; 974 objp->bool_attr_mask |= TOKEN_BOOL_ON; 975 if (is_pri_obj) { 976 objp->bool_attr_mask |= PRIVATE_BOOL_ON; 977 } else { 978 objp->bool_attr_mask &= ~PRIVATE_BOOL_ON; 979 } 980 981 (void) pthread_mutex_init(&objp->object_mutex, NULL); 982 objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC; 983 objp->session_handle = (CK_SESSION_HANDLE) sp; 984 985 return (CKR_OK); 986 } 987 988 /* 989 * This function processes the kernel object handles returned from the 990 * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list 991 * and the number of object handles to the caller - C_FindObjects(). 992 * The caller acquires the slot lock and the session lock. 993 */ 994 CK_RV 995 process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found, 996 CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu) 997 { 998 CK_RV rv = CKR_OK; 999 crypto_object_id_t *oid_p; 1000 kernel_slot_t *pslot; 1001 kernel_object_t *objp; 1002 kernel_object_t *objp1; 1003 kernel_object_t *new_tobj_list = NULL; 1004 kernel_session_t *sp; 1005 CK_ULONG num_obj_found = 0; 1006 boolean_t is_in_lib; 1007 int i; 1008 1009 if (obj_fu.fu_count == 0) { 1010 *found_obj_count = 0; 1011 return (CKR_OK); 1012 } 1013 1014 pslot = slot_table[cur_sp->ses_slotid]; 1015 1016 /* LINTED */ 1017 oid_p = (crypto_object_id_t *)obj_fu.fu_handles; 1018 for (i = 0; i < obj_fu.fu_count; i++) { 1019 is_in_lib = B_FALSE; 1020 /* 1021 * Check if this oid has an object wrapper in the library 1022 * already. First, search the slot's token object list. 1023 */ 1024 objp = pslot->sl_tobj_list; 1025 while (!is_in_lib && objp) { 1026 if (objp->k_handle == *oid_p) { 1027 is_in_lib = B_TRUE; 1028 } else { 1029 objp = objp->next; 1030 } 1031 } 1032 1033 /* 1034 * If it is not in the slot's token object list, 1035 * search it in all the sessions. 1036 */ 1037 if (!is_in_lib) { 1038 sp = pslot->sl_sess_list; 1039 while (!is_in_lib && sp) { 1040 objp = sp->object_list; 1041 while (!is_in_lib && objp) { 1042 if (objp->k_handle == *oid_p) { 1043 is_in_lib = B_TRUE; 1044 } else { 1045 objp = objp->next; 1046 } 1047 } 1048 sp = sp->next; 1049 } 1050 } 1051 1052 /* 1053 * If this object is in the library already, add its object 1054 * wrapper to the returned find object list. 1055 */ 1056 if (is_in_lib) { 1057 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 1058 } 1059 1060 /* 1061 * If we still do not find it in the library. This object 1062 * must be a token object pre-existed in the HW provider. 1063 * We need to create an object wrapper for it in the library. 1064 */ 1065 if (!is_in_lib) { 1066 objp1 = calloc(1, sizeof (kernel_object_t)); 1067 if (objp1 == NULL) { 1068 rv = CKR_HOST_MEMORY; 1069 goto failed_exit; 1070 } 1071 rv = create_new_tobj_in_lib(pslot, cur_sp, objp1, 1072 *oid_p); 1073 1074 if (rv == CKR_OK) { 1075 /* Save the new object to the new_tobj_list. */ 1076 if (new_tobj_list == NULL) { 1077 new_tobj_list = objp1; 1078 objp1->next = NULL; 1079 objp1->prev = NULL; 1080 } else { 1081 new_tobj_list->prev = objp1; 1082 objp1->next = new_tobj_list; 1083 objp1->prev = NULL; 1084 new_tobj_list = objp1; 1085 } 1086 } else { 1087 /* 1088 * If create_new_tobj_in_lib() doesn't fail 1089 * with CKR_HOST_MEMORY, the failure should be 1090 * caused by the attributes' checking. We will 1091 * just ignore this object and continue on. 1092 */ 1093 free(objp1); 1094 if (rv == CKR_HOST_MEMORY) { 1095 goto failed_exit; 1096 } 1097 } 1098 } 1099 1100 /* Process next one */ 1101 oid_p++; 1102 } 1103 1104 /* 1105 * Add the newly created token object wrappers to the found object 1106 * list and to the slot's token object list. 1107 */ 1108 if (new_tobj_list != NULL) { 1109 /* Add to the obj_found array. */ 1110 objp = new_tobj_list; 1111 while (objp) { 1112 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 1113 if (objp->next == NULL) { 1114 break; 1115 } 1116 objp = objp->next; 1117 } 1118 1119 /* Add to the beginning of the slot's token object list. */ 1120 if (pslot->sl_tobj_list != NULL) { 1121 objp->next = pslot->sl_tobj_list; 1122 pslot->sl_tobj_list->prev = objp; 1123 } 1124 pslot->sl_tobj_list = new_tobj_list; 1125 } 1126 1127 *found_obj_count = num_obj_found; 1128 return (CKR_OK); 1129 1130 failed_exit: 1131 1132 /* Free the newly created token object wrappers. */ 1133 objp = new_tobj_list; 1134 while (objp) { 1135 objp1 = objp->next; 1136 (void) pthread_mutex_destroy(&objp->object_mutex); 1137 free(objp); 1138 objp = objp1; 1139 } 1140 1141 return (rv); 1142 } 1143 1144 1145 /* 1146 * Get the value of the CKA_PRIVATE attribute for the object just returned 1147 * from the HW provider. This function will be called by any function 1148 * that creates a new object, because the CKA_PRIVATE value of an object is 1149 * token sepecific. The CKA_PRIVATE attribute value of the new object will be 1150 * stored in the object structure in the library, which will be used later at 1151 * C_Logout to clean up all private objects. 1152 */ 1153 CK_RV 1154 get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid, 1155 CK_BBOOL *is_pri_obj) 1156 { 1157 CK_RV rv = CKR_OK; 1158 crypto_object_get_attribute_value_t obj_ga; 1159 crypto_object_attribute_t obj_attr; 1160 CK_BBOOL pri_value; 1161 int r; 1162 1163 obj_ga.og_session = sp->k_session; 1164 obj_ga.og_handle = oid; 1165 obj_ga.og_count = 1; 1166 1167 obj_attr.oa_type = CKA_PRIVATE; 1168 obj_attr.oa_value = (char *)&pri_value; 1169 obj_attr.oa_value_len = sizeof (CK_BBOOL); 1170 obj_ga.og_attributes = (char *)&obj_attr; 1171 1172 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 1173 &obj_ga)) < 0) { 1174 if (errno != EINTR) 1175 break; 1176 } 1177 if (r < 0) { 1178 rv = CKR_FUNCTION_FAILED; 1179 } else { 1180 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 1181 } 1182 1183 if (rv == CKR_OK) { 1184 *is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value; 1185 } 1186 1187 return (rv); 1188 } 1189 1190 1191 CK_RV 1192 get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type, 1193 CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags) 1194 { 1195 crypto_get_provider_mechanism_info_t mechanism_info; 1196 char *string; 1197 CK_FLAGS flags, mi_flags; 1198 CK_RV rv; 1199 int r; 1200 1201 string = pkcs11_mech2str(type); 1202 if (string == NULL) 1203 return (CKR_MECHANISM_INVALID); 1204 1205 (void) strcpy(mechanism_info.mi_mechanism_name, string); 1206 mechanism_info.mi_provider_id = pslot->sl_provider_id; 1207 1208 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO, 1209 &mechanism_info)) < 0) { 1210 if (errno != EINTR) 1211 break; 1212 } 1213 if (r < 0) { 1214 rv = CKR_FUNCTION_FAILED; 1215 } else { 1216 rv = crypto2pkcs11_error_number( 1217 mechanism_info.mi_return_value); 1218 } 1219 1220 if (rv != CKR_OK) { 1221 goto out; 1222 } 1223 1224 /* 1225 * Atomic flags are not part of PKCS#11 so we filter 1226 * them out here. 1227 */ 1228 mi_flags = mechanism_info.mi_flags; 1229 mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC | 1230 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC | 1231 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 1232 CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1233 CRYPTO_FG_VERIFY_RECOVER_ATOMIC | 1234 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 1235 CRYPTO_FG_MAC_DECRYPT_ATOMIC); 1236 1237 if (mi_flags == 0) { 1238 rv = CKR_MECHANISM_INVALID; 1239 goto out; 1240 } 1241 1242 if (rv == CKR_OK) { 1243 /* set the value of k_mi_flags first */ 1244 *k_mi_flags = mi_flags; 1245 1246 /* convert KEF flags into pkcs11 flags */ 1247 flags = CKF_HW; 1248 if (mi_flags & CRYPTO_FG_ENCRYPT) 1249 flags |= CKF_ENCRYPT; 1250 if (mi_flags & CRYPTO_FG_DECRYPT) { 1251 flags |= CKF_DECRYPT; 1252 /* 1253 * Since we'll be emulating C_UnwrapKey() for some 1254 * cases, we can go ahead and claim CKF_UNWRAP 1255 */ 1256 flags |= CKF_UNWRAP; 1257 } 1258 if (mi_flags & CRYPTO_FG_DIGEST) 1259 flags |= CKF_DIGEST; 1260 if (mi_flags & CRYPTO_FG_SIGN) 1261 flags |= CKF_SIGN; 1262 if (mi_flags & CRYPTO_FG_SIGN_RECOVER) 1263 flags |= CKF_SIGN_RECOVER; 1264 if (mi_flags & CRYPTO_FG_VERIFY) 1265 flags |= CKF_VERIFY; 1266 if (mi_flags & CRYPTO_FG_VERIFY_RECOVER) 1267 flags |= CKF_VERIFY_RECOVER; 1268 if (mi_flags & CRYPTO_FG_GENERATE) 1269 flags |= CKF_GENERATE; 1270 if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR) 1271 flags |= CKF_GENERATE_KEY_PAIR; 1272 if (mi_flags & CRYPTO_FG_WRAP) 1273 flags |= CKF_WRAP; 1274 if (mi_flags & CRYPTO_FG_UNWRAP) 1275 flags |= CKF_UNWRAP; 1276 if (mi_flags & CRYPTO_FG_DERIVE) 1277 flags |= CKF_DERIVE; 1278 1279 pInfo->ulMinKeySize = mechanism_info.mi_min_key_size; 1280 pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size; 1281 pInfo->flags = flags; 1282 1283 } 1284 1285 out: 1286 free(string); 1287 return (rv); 1288 } 1289