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 2006 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 an attribute template into an obj_attrs array. 613 * Memory is allocated for each attribute stored in the obj_attrs. 614 * The memory can be freed by free_object_attributes(). 615 * 616 * If the boolean pointer is_token_obj is not NULL, the caller wants to 617 * retrieve the value of the CKA_TOKEN attribute if it is specified in the 618 * template. 619 * - When this routine is called thru C_CreateObject(), C_CopyObject(), or 620 * any key management function, is_token_obj should NOT be NULL. 621 * - When this routine is called thru C_GetAttributeValue() or 622 * C_SetAttributeValue(), "is_token_obj" should be NULL. 623 */ 624 CK_RV 625 process_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 626 caddr_t *obj_attrs, CK_BBOOL *is_token_obj) 627 { 628 crypto_object_attribute_t *attrs, *cur_attr; 629 int i, cur_i; 630 char *ptr; 631 CK_RV rv; 632 ssize_t value_len; 633 634 if (ulCount == 0) { 635 obj_attrs = NULL; 636 return (CKR_OK); 637 } 638 639 attrs = calloc(1, ulCount * sizeof (crypto_object_attribute_t)); 640 if (attrs == NULL) { 641 return (CKR_HOST_MEMORY); 642 } 643 644 cur_attr = attrs; 645 for (i = 0; i < ulCount; i++) { 646 /* 647 * The length of long attributes must be set correctly 648 * so providers can determine whether they came from 32 649 * or 64-bit applications. 650 */ 651 switch (pTemplate[i].type) { 652 case CKA_CLASS: 653 case CKA_CERTIFICATE_TYPE: 654 case CKA_KEY_TYPE: 655 case CKA_HW_FEATURE_TYPE: 656 value_len = sizeof (ulong_t); 657 if (pTemplate[i].pValue != NULL && 658 (pTemplate[i].ulValueLen < value_len)) { 659 rv = CKR_BUFFER_TOO_SMALL; 660 cur_i = i; 661 goto fail_cleanup; 662 } 663 break; 664 default: 665 value_len = pTemplate[i].ulValueLen; 666 } 667 668 cur_attr->oa_type = pTemplate[i].type; 669 cur_attr->oa_value_len = value_len; 670 cur_attr->oa_value = NULL; 671 672 if ((pTemplate[i].pValue != NULL) && 673 (pTemplate[i].ulValueLen > 0)) { 674 ptr = malloc(pTemplate[i].ulValueLen); 675 if (ptr == NULL) { 676 rv = CKR_HOST_MEMORY; 677 cur_i = i; 678 goto fail_cleanup; 679 } else { 680 (void) memcpy(ptr, pTemplate[i].pValue, 681 pTemplate[i].ulValueLen); 682 cur_attr->oa_value = ptr; 683 } 684 } 685 686 if ((is_token_obj != NULL) && 687 (pTemplate[i].type == CKA_TOKEN)) { 688 /* Get the CKA_TOKEN attribute value. */ 689 if (pTemplate[i].pValue == NULL) { 690 rv = CKR_ATTRIBUTE_VALUE_INVALID; 691 cur_i = i; 692 goto fail_cleanup; 693 } else { 694 *is_token_obj = 695 *(CK_BBOOL *)pTemplate[i].pValue; 696 } 697 } 698 699 cur_attr++; 700 } 701 702 *obj_attrs = (char *)attrs; 703 return (CKR_OK); 704 705 fail_cleanup: 706 cur_attr = attrs; 707 for (i = 0; i < cur_i; i++) { 708 if (cur_attr->oa_value != NULL) { 709 (void) free(cur_attr->oa_value); 710 } 711 cur_attr++; 712 } 713 714 (void) free(attrs); 715 return (rv); 716 } 717 718 719 /* 720 * Copy the attribute values from obj_attrs to pTemplate. 721 * The obj_attrs is an image of the Template and is expected to have the 722 * same attributes in the same order and each one of the attribute pValue 723 * in obj_attr has enough space allocated for the corresponding valueLen 724 * in pTemplate. 725 */ 726 CK_RV 727 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 728 caddr_t obj_attrs) 729 { 730 crypto_object_attribute_t *cur_attr; 731 CK_RV rv = CKR_OK; 732 int i; 733 734 /* LINTED */ 735 cur_attr = (crypto_object_attribute_t *)obj_attrs; 736 for (i = 0; i < ulCount; i++) { 737 if (pTemplate[i].type != cur_attr->oa_type) { 738 /* The attribute type doesn't match, this is bad. */ 739 rv = CKR_FUNCTION_FAILED; 740 return (rv); 741 } 742 743 pTemplate[i].ulValueLen = cur_attr->oa_value_len; 744 745 if ((pTemplate[i].pValue != NULL) && 746 ((CK_LONG)pTemplate[i].ulValueLen != -1)) { 747 (void) memcpy(pTemplate[i].pValue, cur_attr->oa_value, 748 pTemplate[i].ulValueLen); 749 } 750 cur_attr++; 751 } 752 753 return (rv); 754 } 755 756 /* 757 * Free the attribute storage in a crypto_object_attribute_t structure. 758 */ 759 void 760 free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount) 761 { 762 crypto_object_attribute_t *cur_attr; 763 int i; 764 765 if ((ulCount == 0) || (obj_attrs == NULL)) { 766 return; 767 } 768 769 /* LINTED */ 770 cur_attr = (crypto_object_attribute_t *)obj_attrs; 771 for (i = 0; i < ulCount; i++) { 772 if (cur_attr->oa_value != NULL) { 773 free(cur_attr->oa_value); 774 } 775 cur_attr++; 776 } 777 778 free(obj_attrs); 779 } 780 781 /* 782 * This function is called by process_found_objects(). It will check the 783 * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then 784 * initialize all the necessary fields in the object wrapper "objp". 785 */ 786 static CK_RV 787 create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp, 788 kernel_object_t *objp, crypto_object_id_t oid) 789 { 790 CK_RV rv = CKR_OK; 791 crypto_object_get_attribute_value_t obj_ga; 792 boolean_t is_pri_obj; 793 boolean_t is_token_obj; 794 CK_BBOOL pri_value, token_value; 795 CK_ATTRIBUTE pTemplate[2]; 796 int r; 797 798 /* 799 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this 800 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN. 801 */ 802 obj_ga.og_session = sp->k_session; 803 obj_ga.og_handle = oid; 804 obj_ga.og_count = 2; 805 806 pTemplate[0].type = CKA_PRIVATE; 807 pTemplate[0].pValue = &pri_value; 808 pTemplate[0].ulValueLen = sizeof (pri_value); 809 pTemplate[1].type = CKA_TOKEN; 810 pTemplate[1].pValue = &token_value; 811 pTemplate[1].ulValueLen = sizeof (token_value); 812 rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes, 813 NULL); 814 if (rv != CKR_OK) { 815 return (rv); 816 } 817 818 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 819 &obj_ga)) < 0) { 820 if (errno != EINTR) 821 break; 822 } 823 if (r < 0) { 824 rv = CKR_FUNCTION_FAILED; 825 } else { 826 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 827 } 828 829 if (rv == CKR_OK) { 830 rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes); 831 if (rv == CKR_OK) { 832 is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue; 833 is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue; 834 } 835 } 836 837 free_object_attributes(obj_ga.og_attributes, 2); 838 if (rv != CKR_OK) { 839 return (rv); 840 } 841 842 /* Make sure it is a token object. */ 843 if (!is_token_obj) { 844 rv = CKR_ATTRIBUTE_VALUE_INVALID; 845 return (rv); 846 } 847 848 /* If it is a private object, make sure the user has logged in. */ 849 if (is_pri_obj && (pslot->sl_state != CKU_USER)) { 850 rv = CKR_ATTRIBUTE_VALUE_INVALID; 851 return (rv); 852 } 853 854 objp->is_lib_obj = B_FALSE; 855 objp->k_handle = oid; 856 objp->bool_attr_mask |= TOKEN_BOOL_ON; 857 if (is_pri_obj) { 858 objp->bool_attr_mask |= PRIVATE_BOOL_ON; 859 } else { 860 objp->bool_attr_mask &= ~PRIVATE_BOOL_ON; 861 } 862 863 (void) pthread_mutex_init(&objp->object_mutex, NULL); 864 objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC; 865 objp->session_handle = (CK_SESSION_HANDLE) sp; 866 867 return (CKR_OK); 868 } 869 870 /* 871 * This function processes the kernel object handles returned from the 872 * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list 873 * and the number of object handles to the caller - C_FindObjects(). 874 * The caller acquires the slot lock and the session lock. 875 */ 876 CK_RV 877 process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found, 878 CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu) 879 { 880 CK_RV rv = CKR_OK; 881 crypto_object_id_t *oid_p; 882 kernel_slot_t *pslot; 883 kernel_object_t *objp; 884 kernel_object_t *objp1; 885 kernel_object_t *new_tobj_list = NULL; 886 kernel_session_t *sp; 887 CK_ULONG num_obj_found = 0; 888 boolean_t is_in_lib; 889 int i; 890 891 if (obj_fu.fu_count == 0) { 892 *found_obj_count = 0; 893 return (CKR_OK); 894 } 895 896 pslot = slot_table[cur_sp->ses_slotid]; 897 898 /* LINTED */ 899 oid_p = (crypto_object_id_t *)obj_fu.fu_handles; 900 for (i = 0; i < obj_fu.fu_count; i++) { 901 is_in_lib = B_FALSE; 902 /* 903 * Check if this oid has an object wrapper in the library 904 * already. First, search the slot's token object list. 905 */ 906 objp = pslot->sl_tobj_list; 907 while (!is_in_lib && objp) { 908 if (objp->k_handle == *oid_p) { 909 is_in_lib = B_TRUE; 910 } else { 911 objp = objp->next; 912 } 913 } 914 915 /* 916 * If it is not in the slot's token object list, 917 * search it in all the sessions. 918 */ 919 if (!is_in_lib) { 920 sp = pslot->sl_sess_list; 921 while (!is_in_lib && sp) { 922 objp = sp->object_list; 923 while (!is_in_lib && objp) { 924 if (objp->k_handle == *oid_p) { 925 is_in_lib = B_TRUE; 926 } else { 927 objp = objp->next; 928 } 929 } 930 sp = sp->next; 931 } 932 } 933 934 /* 935 * If this object is in the library already, add its object 936 * wrapper to the returned find object list. 937 */ 938 if (is_in_lib) { 939 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 940 } 941 942 /* 943 * If we still do not find it in the library. This object 944 * must be a token object pre-existed in the HW provider. 945 * We need to create an object wrapper for it in the library. 946 */ 947 if (!is_in_lib) { 948 objp1 = calloc(1, sizeof (kernel_object_t)); 949 if (objp1 == NULL) { 950 rv = CKR_HOST_MEMORY; 951 goto failed_exit; 952 } 953 rv = create_new_tobj_in_lib(pslot, cur_sp, objp1, 954 *oid_p); 955 956 if (rv == CKR_OK) { 957 /* Save the new object to the new_tobj_list. */ 958 if (new_tobj_list == NULL) { 959 new_tobj_list = objp1; 960 objp1->next = NULL; 961 objp1->prev = NULL; 962 } else { 963 new_tobj_list->prev = objp1; 964 objp1->next = new_tobj_list; 965 objp1->prev = NULL; 966 new_tobj_list = objp1; 967 } 968 } else { 969 /* 970 * If create_new_tobj_in_lib() doesn't fail 971 * with CKR_HOST_MEMORY, the failure should be 972 * caused by the attributes' checking. We will 973 * just ignore this object and continue on. 974 */ 975 free(objp1); 976 if (rv == CKR_HOST_MEMORY) { 977 goto failed_exit; 978 } 979 } 980 } 981 982 /* Process next one */ 983 oid_p++; 984 } 985 986 /* 987 * Add the newly created token object wrappers to the found object 988 * list and to the slot's token object list. 989 */ 990 if (new_tobj_list != NULL) { 991 /* Add to the obj_found array. */ 992 objp = new_tobj_list; 993 while (objp) { 994 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 995 if (objp->next == NULL) { 996 break; 997 } 998 objp = objp->next; 999 } 1000 1001 /* Add to the beginning of the slot's token object list. */ 1002 if (pslot->sl_tobj_list != NULL) { 1003 objp->next = pslot->sl_tobj_list; 1004 pslot->sl_tobj_list->prev = objp; 1005 } 1006 pslot->sl_tobj_list = new_tobj_list; 1007 } 1008 1009 *found_obj_count = num_obj_found; 1010 return (CKR_OK); 1011 1012 failed_exit: 1013 1014 /* Free the newly created token object wrappers. */ 1015 objp = new_tobj_list; 1016 while (objp) { 1017 objp1 = objp->next; 1018 (void) pthread_mutex_destroy(&objp->object_mutex); 1019 free(objp); 1020 objp = objp1; 1021 } 1022 1023 return (rv); 1024 } 1025 1026 1027 /* 1028 * Get the value of the CKA_PRIVATE attribute for the object just returned 1029 * from the HW provider. This function will be called by any function 1030 * that creates a new object, because the CKA_PRIVATE value of an object is 1031 * token sepecific. The CKA_PRIVATE attribute value of the new object will be 1032 * stored in the object structure in the library, which will be used later at 1033 * C_Logout to clean up all private objects. 1034 */ 1035 CK_RV 1036 get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid, 1037 CK_BBOOL *is_pri_obj) 1038 { 1039 CK_RV rv = CKR_OK; 1040 crypto_object_get_attribute_value_t obj_ga; 1041 crypto_object_attribute_t obj_attr; 1042 CK_BBOOL pri_value; 1043 int r; 1044 1045 obj_ga.og_session = sp->k_session; 1046 obj_ga.og_handle = oid; 1047 obj_ga.og_count = 1; 1048 1049 obj_attr.oa_type = CKA_PRIVATE; 1050 obj_attr.oa_value = (char *)&pri_value; 1051 obj_attr.oa_value_len = sizeof (CK_BBOOL); 1052 obj_ga.og_attributes = (char *)&obj_attr; 1053 1054 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 1055 &obj_ga)) < 0) { 1056 if (errno != EINTR) 1057 break; 1058 } 1059 if (r < 0) { 1060 rv = CKR_FUNCTION_FAILED; 1061 } else { 1062 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 1063 } 1064 1065 if (rv == CKR_OK) { 1066 *is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value; 1067 } 1068 1069 return (rv); 1070 } 1071 1072 1073 CK_RV 1074 get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type, 1075 CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags) 1076 { 1077 crypto_get_provider_mechanism_info_t mechanism_info; 1078 char *string; 1079 CK_FLAGS flags, mi_flags; 1080 CK_RV rv; 1081 int r; 1082 1083 string = pkcs11_mech2str(type); 1084 if (string == NULL) 1085 return (CKR_MECHANISM_INVALID); 1086 1087 (void) strcpy(mechanism_info.mi_mechanism_name, string); 1088 mechanism_info.mi_provider_id = pslot->sl_provider_id; 1089 1090 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO, 1091 &mechanism_info)) < 0) { 1092 if (errno != EINTR) 1093 break; 1094 } 1095 if (r < 0) { 1096 rv = CKR_FUNCTION_FAILED; 1097 } else { 1098 rv = crypto2pkcs11_error_number( 1099 mechanism_info.mi_return_value); 1100 } 1101 1102 if (rv != CKR_OK) { 1103 goto out; 1104 } 1105 1106 /* 1107 * Atomic flags are not part of PKCS#11 so we filter 1108 * them out here. 1109 */ 1110 mi_flags = mechanism_info.mi_flags; 1111 mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC | 1112 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC | 1113 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 1114 CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1115 CRYPTO_FG_VERIFY_RECOVER_ATOMIC | 1116 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 1117 CRYPTO_FG_MAC_DECRYPT_ATOMIC); 1118 1119 if (mi_flags == 0) { 1120 rv = CKR_MECHANISM_INVALID; 1121 goto out; 1122 } 1123 1124 if (rv == CKR_OK) { 1125 /* set the value of k_mi_flags first */ 1126 *k_mi_flags = mi_flags; 1127 1128 /* convert KEF flags into pkcs11 flags */ 1129 flags = CKF_HW; 1130 if (mi_flags & CRYPTO_FG_ENCRYPT) 1131 flags |= CKF_ENCRYPT; 1132 if (mi_flags & CRYPTO_FG_DECRYPT) { 1133 flags |= CKF_DECRYPT; 1134 /* 1135 * Since we'll be emulating C_UnwrapKey() for some 1136 * cases, we can go ahead and claim CKF_UNWRAP 1137 */ 1138 flags |= CKF_UNWRAP; 1139 } 1140 if (mi_flags & CRYPTO_FG_DIGEST) 1141 flags |= CKF_DIGEST; 1142 if (mi_flags & CRYPTO_FG_SIGN) 1143 flags |= CKF_SIGN; 1144 if (mi_flags & CRYPTO_FG_SIGN_RECOVER) 1145 flags |= CKF_SIGN_RECOVER; 1146 if (mi_flags & CRYPTO_FG_VERIFY) 1147 flags |= CKF_VERIFY; 1148 if (mi_flags & CRYPTO_FG_VERIFY_RECOVER) 1149 flags |= CKF_VERIFY_RECOVER; 1150 if (mi_flags & CRYPTO_FG_GENERATE) 1151 flags |= CKF_GENERATE; 1152 if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR) 1153 flags |= CKF_GENERATE_KEY_PAIR; 1154 if (mi_flags & CRYPTO_FG_WRAP) 1155 flags |= CKF_WRAP; 1156 if (mi_flags & CRYPTO_FG_UNWRAP) 1157 flags |= CKF_UNWRAP; 1158 if (mi_flags & CRYPTO_FG_DERIVE) 1159 flags |= CKF_DERIVE; 1160 1161 pInfo->ulMinKeySize = mechanism_info.mi_min_key_size; 1162 pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size; 1163 pInfo->flags = flags; 1164 1165 } 1166 1167 out: 1168 free(string); 1169 return (rv); 1170 } 1171