1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <stdlib.h> 27 #include <string.h> 28 #include <security/cryptoki.h> 29 #include <sys/crypto/common.h> 30 #include <aes_impl.h> 31 #include <blowfish_impl.h> 32 #include <arcfour.h> 33 #include <des_impl.h> 34 #include "kernelGlobal.h" 35 #include "kernelObject.h" 36 #include "kernelSession.h" 37 #include "kernelSlot.h" 38 39 40 /* 41 * This attribute table is used by the kernel_lookup_attr() 42 * to validate the attributes. 43 */ 44 CK_ATTRIBUTE_TYPE attr_map[] = { 45 CKA_PRIVATE, 46 CKA_LABEL, 47 CKA_APPLICATION, 48 CKA_OBJECT_ID, 49 CKA_CERTIFICATE_TYPE, 50 CKA_ISSUER, 51 CKA_SERIAL_NUMBER, 52 CKA_AC_ISSUER, 53 CKA_OWNER, 54 CKA_ATTR_TYPES, 55 CKA_SUBJECT, 56 CKA_ID, 57 CKA_SENSITIVE, 58 CKA_START_DATE, 59 CKA_END_DATE, 60 CKA_MODULUS, 61 CKA_MODULUS_BITS, 62 CKA_PUBLIC_EXPONENT, 63 CKA_PRIVATE_EXPONENT, 64 CKA_PRIME_1, 65 CKA_PRIME_2, 66 CKA_EXPONENT_1, 67 CKA_EXPONENT_2, 68 CKA_COEFFICIENT, 69 CKA_PRIME, 70 CKA_SUBPRIME, 71 CKA_BASE, 72 CKA_EXTRACTABLE, 73 CKA_LOCAL, 74 CKA_NEVER_EXTRACTABLE, 75 CKA_ALWAYS_SENSITIVE, 76 CKA_MODIFIABLE, 77 CKA_ECDSA_PARAMS, 78 CKA_EC_POINT, 79 CKA_SECONDARY_AUTH, 80 CKA_AUTH_PIN_FLAGS, 81 CKA_HW_FEATURE_TYPE, 82 CKA_RESET_ON_INIT, 83 CKA_HAS_RESET 84 }; 85 86 /* 87 * attributes that exists only in public key objects 88 * Note: some attributes may also exist in one or two 89 * other object classes, but they are also listed 90 * because not all object have them. 91 */ 92 CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] = 93 { 94 CKA_SUBJECT, 95 CKA_ENCRYPT, 96 CKA_WRAP, 97 CKA_VERIFY, 98 CKA_VERIFY_RECOVER, 99 CKA_MODULUS, 100 CKA_MODULUS_BITS, 101 CKA_PUBLIC_EXPONENT, 102 CKA_PRIME, 103 CKA_SUBPRIME, 104 CKA_BASE, 105 CKA_TRUSTED, 106 CKA_ECDSA_PARAMS, 107 CKA_EC_PARAMS, 108 CKA_EC_POINT 109 }; 110 111 /* 112 * attributes that exists only in private key objects 113 * Note: some attributes may also exist in one or two 114 * other object classes, but they are also listed 115 * because not all object have them. 116 */ 117 CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] = 118 { 119 CKA_DECRYPT, 120 CKA_UNWRAP, 121 CKA_SIGN, 122 CKA_SIGN_RECOVER, 123 CKA_MODULUS, 124 CKA_PUBLIC_EXPONENT, 125 CKA_PRIVATE_EXPONENT, 126 CKA_PRIME, 127 CKA_SUBPRIME, 128 CKA_BASE, 129 CKA_PRIME_1, 130 CKA_PRIME_2, 131 CKA_EXPONENT_1, 132 CKA_EXPONENT_2, 133 CKA_COEFFICIENT, 134 CKA_VALUE_BITS, 135 CKA_SUBJECT, 136 CKA_SENSITIVE, 137 CKA_EXTRACTABLE, 138 CKA_NEVER_EXTRACTABLE, 139 CKA_ALWAYS_SENSITIVE, 140 CKA_ECDSA_PARAMS, 141 CKA_EC_PARAMS 142 }; 143 144 /* 145 * attributes that exists only in secret key objects 146 * Note: some attributes may also exist in one or two 147 * other object classes, but they are also listed 148 * because not all object have them. 149 */ 150 CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] = 151 { 152 CKA_VALUE_LEN, 153 CKA_ENCRYPT, 154 CKA_DECRYPT, 155 CKA_WRAP, 156 CKA_UNWRAP, 157 CKA_SIGN, 158 CKA_VERIFY, 159 CKA_SENSITIVE, 160 CKA_EXTRACTABLE, 161 CKA_NEVER_EXTRACTABLE, 162 CKA_ALWAYS_SENSITIVE 163 }; 164 165 /* 166 * attributes that exists only in domain parameter objects 167 * Note: some attributes may also exist in one or two 168 * other object classes, but they are also listed 169 * because not all object have them. 170 */ 171 CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] = 172 { 173 CKA_PRIME, 174 CKA_SUBPRIME, 175 CKA_BASE, 176 CKA_PRIME_BITS, 177 CKA_SUBPRIME_BITS, 178 CKA_SUB_PRIME_BITS 179 }; 180 181 /* 182 * attributes that exists only in hardware feature objects 183 */ 184 CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] = 185 { 186 CKA_HW_FEATURE_TYPE, 187 CKA_RESET_ON_INIT, 188 CKA_HAS_RESET 189 }; 190 191 /* 192 * attributes that exists only in certificate objects 193 */ 194 CK_ATTRIBUTE_TYPE CERT_ATTRS[] = 195 { 196 CKA_CERTIFICATE_TYPE, 197 CKA_SUBJECT, 198 CKA_ID, 199 CKA_ISSUER, 200 CKA_AC_ISSUER, 201 CKA_SERIAL_NUMBER, 202 CKA_OWNER, 203 CKA_ATTR_TYPES 204 }; 205 206 207 /* 208 * Validate the attribute by using binary search algorithm. 209 */ 210 CK_RV 211 kernel_lookup_attr(CK_ATTRIBUTE_TYPE type) 212 { 213 214 size_t lower, middle, upper; 215 216 lower = 0; 217 upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1; 218 219 while (lower <= upper) { 220 /* Always starts from middle. */ 221 middle = (lower + upper) / 2; 222 223 if (type > attr_map[middle]) { 224 /* Adjust the lower bound to upper half. */ 225 lower = middle + 1; 226 continue; 227 } 228 229 if (type == attr_map[middle]) { 230 /* Found it. */ 231 return (CKR_OK); 232 } 233 234 if (type < attr_map[middle]) { 235 /* Adjust the upper bound to lower half. */ 236 upper = middle - 1; 237 continue; 238 } 239 } 240 241 /* Failed to find the matching attribute from the attribute table. */ 242 return (CKR_ATTRIBUTE_TYPE_INVALID); 243 } 244 245 246 /* 247 * Validate the attribute by using the following search algorithm: 248 * 249 * 1) Search for the most frequently used attributes first. 250 * 2) If not found, search for the usage-purpose attributes - these 251 * attributes have dense set of values, therefore compiler will 252 * optimize it with a branch table and branch to the appropriate 253 * case. 254 * 3) If still not found, use binary search for the rest of the 255 * attributes in the attr_map[] table. 256 */ 257 CK_RV 258 kernel_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum, 259 CK_OBJECT_CLASS *class) 260 { 261 262 CK_ULONG i; 263 CK_RV rv = CKR_OK; 264 265 for (i = 0; i < ulAttrNum; i++) { 266 /* First tier search */ 267 switch (template[i].type) { 268 case CKA_CLASS: 269 *class = *((CK_OBJECT_CLASS*)template[i].pValue); 270 break; 271 case CKA_TOKEN: 272 break; 273 case CKA_KEY_TYPE: 274 break; 275 case CKA_VALUE: 276 break; 277 case CKA_VALUE_LEN: 278 break; 279 case CKA_VALUE_BITS: 280 break; 281 default: 282 /* Second tier search */ 283 switch (template[i].type) { 284 case CKA_ENCRYPT: 285 break; 286 case CKA_DECRYPT: 287 break; 288 case CKA_WRAP: 289 break; 290 case CKA_UNWRAP: 291 break; 292 case CKA_SIGN: 293 break; 294 case CKA_SIGN_RECOVER: 295 break; 296 case CKA_VERIFY: 297 break; 298 case CKA_VERIFY_RECOVER: 299 break; 300 case CKA_DERIVE: 301 break; 302 default: 303 /* Third tier search */ 304 rv = kernel_lookup_attr(template[i].type); 305 if (rv != CKR_OK) 306 return (rv); 307 break; 308 } 309 break; 310 } 311 } 312 return (rv); 313 } 314 315 316 /* 317 * Clean up and release all the storage in the extra attribute list 318 * of an object. 319 */ 320 void 321 kernel_cleanup_extra_attr(kernel_object_t *object_p) 322 { 323 324 CK_ATTRIBUTE_INFO_PTR extra_attr; 325 CK_ATTRIBUTE_INFO_PTR tmp; 326 327 extra_attr = object_p->extra_attrlistp; 328 while (extra_attr) { 329 tmp = extra_attr->next; 330 if (extra_attr->attr.pValue) 331 /* 332 * All extra attributes in the extra attribute 333 * list have pValue points to the value of the 334 * attribute (with simple byte array type). 335 * Free the storage for the value of the attribute. 336 */ 337 free(extra_attr->attr.pValue); 338 339 /* Free the storage for the attribute_info struct. */ 340 free(extra_attr); 341 extra_attr = tmp; 342 } 343 344 object_p->extra_attrlistp = NULL; 345 } 346 347 348 /* 349 * Create the attribute_info struct to hold the object's attribute, 350 * and add it to the extra attribute list of an object. 351 */ 352 CK_RV 353 kernel_add_extra_attr(CK_ATTRIBUTE_PTR template, kernel_object_t *object_p) 354 { 355 356 CK_ATTRIBUTE_INFO_PTR attrp; 357 358 /* Allocate the storage for the attribute_info struct. */ 359 attrp = calloc(1, sizeof (attribute_info_t)); 360 if (attrp == NULL) { 361 return (CKR_HOST_MEMORY); 362 } 363 364 /* Set up attribute_info struct. */ 365 attrp->attr.type = template->type; 366 attrp->attr.ulValueLen = template->ulValueLen; 367 368 if ((template->pValue != NULL) && 369 (template->ulValueLen > 0)) { 370 /* Allocate storage for the value of the attribute. */ 371 attrp->attr.pValue = malloc(template->ulValueLen); 372 if (attrp->attr.pValue == NULL) { 373 free(attrp); 374 return (CKR_HOST_MEMORY); 375 } 376 377 (void) memcpy(attrp->attr.pValue, template->pValue, 378 template->ulValueLen); 379 } else { 380 attrp->attr.pValue = NULL; 381 } 382 383 /* Insert the new attribute in front of extra attribute list. */ 384 if (object_p->extra_attrlistp == NULL) { 385 object_p->extra_attrlistp = attrp; 386 attrp->next = NULL; 387 } else { 388 attrp->next = object_p->extra_attrlistp; 389 object_p->extra_attrlistp = attrp; 390 } 391 392 return (CKR_OK); 393 } 394 395 396 /* 397 * Copy the attribute_info struct from the old object to a new attribute_info 398 * struct, and add that new struct to the extra attribute list of the new 399 * object. 400 */ 401 CK_RV 402 kernel_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, 403 kernel_object_t *object_p) 404 { 405 CK_ATTRIBUTE_INFO_PTR attrp; 406 407 /* Allocate attribute_info struct. */ 408 attrp = calloc(1, sizeof (attribute_info_t)); 409 if (attrp == NULL) { 410 return (CKR_HOST_MEMORY); 411 } 412 413 attrp->attr.type = old_attrp->attr.type; 414 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen; 415 416 if ((old_attrp->attr.pValue != NULL) && 417 (old_attrp->attr.ulValueLen > 0)) { 418 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen); 419 if (attrp->attr.pValue == NULL) { 420 free(attrp); 421 return (CKR_HOST_MEMORY); 422 } 423 424 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue, 425 old_attrp->attr.ulValueLen); 426 } else { 427 attrp->attr.pValue = NULL; 428 } 429 430 /* Insert the new attribute in front of extra attribute list */ 431 if (object_p->extra_attrlistp == NULL) { 432 object_p->extra_attrlistp = attrp; 433 attrp->next = NULL; 434 } else { 435 attrp->next = object_p->extra_attrlistp; 436 object_p->extra_attrlistp = attrp; 437 } 438 439 return (CKR_OK); 440 } 441 442 443 /* 444 * Get the attribute triple from the extra attribute list in the object 445 * (if the specified attribute type is found), and copy it to a template. 446 * Note the type of the attribute to be copied is specified by the template, 447 * and the storage is pre-allocated for the atrribute value in the template 448 * for doing the copy. 449 */ 450 CK_RV 451 get_extra_attr_from_object(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template) 452 { 453 454 CK_ATTRIBUTE_INFO_PTR extra_attr; 455 CK_ATTRIBUTE_TYPE type = template->type; 456 457 extra_attr = object_p->extra_attrlistp; 458 459 while (extra_attr) { 460 if (type == extra_attr->attr.type) { 461 /* Found it. */ 462 break; 463 } else { 464 /* Does not match, try next one. */ 465 extra_attr = extra_attr->next; 466 } 467 } 468 469 if (extra_attr == NULL) { 470 /* A valid but un-initialized attribute. */ 471 template->ulValueLen = 0; 472 return (CKR_OK); 473 } 474 475 /* 476 * We found the attribute in the extra attribute list. 477 */ 478 if (template->pValue == NULL) { 479 template->ulValueLen = extra_attr->attr.ulValueLen; 480 return (CKR_OK); 481 } 482 483 if (template->ulValueLen >= extra_attr->attr.ulValueLen) { 484 /* 485 * The buffer provided by the application is large 486 * enough to hold the value of the attribute. 487 */ 488 (void) memcpy(template->pValue, extra_attr->attr.pValue, 489 extra_attr->attr.ulValueLen); 490 template->ulValueLen = extra_attr->attr.ulValueLen; 491 return (CKR_OK); 492 } else { 493 /* 494 * The buffer provided by the application does 495 * not have enough space to hold the value. 496 */ 497 template->ulValueLen = (CK_ULONG)-1; 498 return (CKR_BUFFER_TOO_SMALL); 499 } 500 } 501 502 503 /* 504 * Modify the attribute triple in the extra attribute list of the object 505 * if the specified attribute type is found. Otherwise, just add it to 506 * list. 507 */ 508 CK_RV 509 set_extra_attr_to_object(kernel_object_t *object_p, CK_ATTRIBUTE_TYPE type, 510 CK_ATTRIBUTE_PTR template) 511 { 512 513 CK_ATTRIBUTE_INFO_PTR extra_attr; 514 515 extra_attr = object_p->extra_attrlistp; 516 517 while (extra_attr) { 518 if (type == extra_attr->attr.type) { 519 /* Found it. */ 520 break; 521 } else { 522 /* Does not match, try next one. */ 523 extra_attr = extra_attr->next; 524 } 525 } 526 527 if (extra_attr == NULL) { 528 /* 529 * This attribute is a new one, go ahead adding it to 530 * the extra attribute list. 531 */ 532 return (kernel_add_extra_attr(template, object_p)); 533 } 534 535 /* We found the attribute in the extra attribute list. */ 536 if ((template->pValue != NULL) && 537 (template->ulValueLen > 0)) { 538 if (template->ulValueLen > extra_attr->attr.ulValueLen) { 539 /* The old buffer is too small to hold the new value. */ 540 if (extra_attr->attr.pValue != NULL) 541 /* Free storage for the old attribute value. */ 542 free(extra_attr->attr.pValue); 543 544 /* Allocate storage for the new attribute value. */ 545 extra_attr->attr.pValue = malloc(template->ulValueLen); 546 if (extra_attr->attr.pValue == NULL) { 547 return (CKR_HOST_MEMORY); 548 } 549 } 550 551 /* Replace the attribute with new value. */ 552 extra_attr->attr.ulValueLen = template->ulValueLen; 553 (void) memcpy(extra_attr->attr.pValue, template->pValue, 554 template->ulValueLen); 555 } else { 556 extra_attr->attr.pValue = NULL; 557 } 558 559 return (CKR_OK); 560 } 561 562 563 /* 564 * Copy the big integer attribute value from template to a biginteger_t struct. 565 */ 566 CK_RV 567 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template) 568 { 569 570 if ((template->pValue != NULL) && 571 (template->ulValueLen > 0)) { 572 /* Allocate storage for the value of the attribute. */ 573 big->big_value = malloc(template->ulValueLen); 574 if (big->big_value == NULL) { 575 return (CKR_HOST_MEMORY); 576 } 577 578 (void) memcpy(big->big_value, template->pValue, 579 template->ulValueLen); 580 big->big_value_len = template->ulValueLen; 581 } else { 582 big->big_value = NULL; 583 big->big_value_len = 0; 584 } 585 586 return (CKR_OK); 587 } 588 589 590 /* 591 * Copy the big integer attribute value from a biginteger_t struct in the 592 * object to a template. 593 */ 594 CK_RV 595 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template) 596 { 597 598 if (template->pValue == NULL) { 599 template->ulValueLen = big->big_value_len; 600 return (CKR_OK); 601 } 602 603 if (big->big_value == NULL) { 604 template->ulValueLen = 0; 605 return (CKR_OK); 606 } 607 608 if (template->ulValueLen >= big->big_value_len) { 609 /* 610 * The buffer provided by the application is large 611 * enough to hold the value of the attribute. 612 */ 613 (void) memcpy(template->pValue, big->big_value, 614 big->big_value_len); 615 template->ulValueLen = big->big_value_len; 616 return (CKR_OK); 617 } else { 618 /* 619 * The buffer provided by the application does 620 * not have enough space to hold the value. 621 */ 622 template->ulValueLen = (CK_ULONG)-1; 623 return (CKR_BUFFER_TOO_SMALL); 624 } 625 } 626 627 628 /* 629 * Copy the boolean data type attribute value from an object for the 630 * specified attribute to the template. 631 */ 632 CK_RV 633 get_bool_attr_from_object(kernel_object_t *object_p, CK_ULONG bool_flag, 634 CK_ATTRIBUTE_PTR template) 635 { 636 637 if (template->pValue == NULL) { 638 template->ulValueLen = sizeof (CK_BBOOL); 639 return (CKR_OK); 640 } 641 642 if (template->ulValueLen >= sizeof (CK_BBOOL)) { 643 /* 644 * The buffer provided by the application is large 645 * enough to hold the value of the attribute. 646 */ 647 if (object_p->bool_attr_mask & bool_flag) { 648 *((CK_BBOOL *)template->pValue) = B_TRUE; 649 } else { 650 *((CK_BBOOL *)template->pValue) = B_FALSE; 651 } 652 653 template->ulValueLen = sizeof (CK_BBOOL); 654 return (CKR_OK); 655 } else { 656 /* 657 * The buffer provided by the application does 658 * not have enough space to hold the value. 659 */ 660 template->ulValueLen = (CK_ULONG)-1; 661 return (CKR_BUFFER_TOO_SMALL); 662 } 663 } 664 665 /* 666 * Set the boolean data type attribute value in the object. 667 */ 668 CK_RV 669 set_bool_attr_to_object(kernel_object_t *object_p, CK_ULONG bool_flag, 670 CK_ATTRIBUTE_PTR template) 671 { 672 673 if (*(CK_BBOOL *)template->pValue) 674 object_p->bool_attr_mask |= bool_flag; 675 else 676 object_p->bool_attr_mask &= ~bool_flag; 677 678 return (CKR_OK); 679 } 680 681 682 /* 683 * Copy the CK_ULONG data type attribute value from an object to the 684 * template. 685 */ 686 CK_RV 687 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template) 688 { 689 690 if (template->pValue == NULL) { 691 template->ulValueLen = sizeof (CK_ULONG); 692 return (CKR_OK); 693 } 694 695 if (template->ulValueLen >= sizeof (CK_ULONG)) { 696 /* 697 * The buffer provided by the application is large 698 * enough to hold the value of the attribute. 699 */ 700 *(CK_ULONG_PTR)template->pValue = value; 701 template->ulValueLen = sizeof (CK_ULONG); 702 return (CKR_OK); 703 } else { 704 /* 705 * The buffer provided by the application does 706 * not have enough space to hold the value. 707 */ 708 template->ulValueLen = (CK_ULONG)-1; 709 return (CKR_BUFFER_TOO_SMALL); 710 } 711 } 712 713 714 /* 715 * Copy the CK_ULONG data type attribute value from a template to the 716 * object. 717 */ 718 void 719 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template) 720 { 721 722 if (template->pValue != NULL) { 723 *value = *(CK_ULONG_PTR)template->pValue; 724 } else { 725 *value = 0; 726 } 727 728 } 729 730 /* 731 * Copy the big integer attribute value from source's biginteger_t to 732 * destination's biginteger_t. 733 */ 734 void 735 copy_bigint_attr(biginteger_t *src, biginteger_t *dst) 736 { 737 738 if ((src->big_value != NULL) && 739 (src->big_value_len > 0)) { 740 /* 741 * To do the copy, just have dst's big_value points 742 * to src's. 743 */ 744 dst->big_value = src->big_value; 745 dst->big_value_len = src->big_value_len; 746 747 /* 748 * After the copy, nullify the src's big_value pointer. 749 * It prevents any double freeing the value. 750 */ 751 src->big_value = NULL; 752 src->big_value_len = 0; 753 } else { 754 dst->big_value = NULL; 755 dst->big_value_len = 0; 756 } 757 758 } 759 760 761 CK_RV 762 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src) 763 { 764 if ((src->pValue != NULL) && 765 (src->ulValueLen > 0)) { 766 /* Allocate storage for the value of the attribute. */ 767 dest->pValue = malloc(src->ulValueLen); 768 if (dest->pValue == NULL) { 769 return (CKR_HOST_MEMORY); 770 } 771 772 (void) memcpy(dest->pValue, src->pValue, 773 src->ulValueLen); 774 dest->ulValueLen = src->ulValueLen; 775 dest->type = src->type; 776 } else { 777 dest->pValue = NULL; 778 dest->ulValueLen = 0; 779 dest->type = src->type; 780 } 781 782 return (CKR_OK); 783 784 } 785 786 void 787 string_attr_cleanup(CK_ATTRIBUTE_PTR template) 788 { 789 790 if (template->pValue) { 791 free(template->pValue); 792 template->pValue = NULL; 793 template->ulValueLen = 0; 794 } 795 } 796 797 /* 798 * Release the storage allocated for object attribute with big integer 799 * value. 800 */ 801 void 802 bigint_attr_cleanup(biginteger_t *big) 803 { 804 805 if (big == NULL) 806 return; 807 808 if (big->big_value) { 809 (void) memset(big->big_value, 0, big->big_value_len); 810 free(big->big_value); 811 big->big_value = NULL; 812 big->big_value_len = 0; 813 } 814 } 815 816 817 /* 818 * Clean up and release all the storage allocated to hold the big integer 819 * attributes associated with the type (i.e. class) of the object. Also, 820 * release the storage allocated to the type of the object. 821 */ 822 void 823 kernel_cleanup_object_bigint_attrs(kernel_object_t *object_p) 824 { 825 826 CK_OBJECT_CLASS class = object_p->class; 827 CK_KEY_TYPE keytype = object_p->key_type; 828 829 830 switch (class) { 831 case CKO_PUBLIC_KEY: 832 if (OBJ_PUB(object_p)) { 833 switch (keytype) { 834 case CKK_RSA: 835 bigint_attr_cleanup(OBJ_PUB_RSA_MOD( 836 object_p)); 837 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO( 838 object_p)); 839 break; 840 841 case CKK_DSA: 842 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME( 843 object_p)); 844 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME( 845 object_p)); 846 bigint_attr_cleanup(OBJ_PUB_DSA_BASE( 847 object_p)); 848 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE( 849 object_p)); 850 break; 851 852 case CKK_DH: 853 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(object_p)); 854 bigint_attr_cleanup(OBJ_PUB_DH_BASE(object_p)); 855 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(object_p)); 856 break; 857 858 case CKK_EC: 859 bigint_attr_cleanup(OBJ_PUB_EC_POINT(object_p)); 860 break; 861 } 862 863 /* Release Public Key Object struct */ 864 free(OBJ_PUB(object_p)); 865 OBJ_PUB(object_p) = NULL; 866 } 867 break; 868 869 case CKO_PRIVATE_KEY: 870 if (OBJ_PRI(object_p)) { 871 switch (keytype) { 872 case CKK_RSA: 873 bigint_attr_cleanup(OBJ_PRI_RSA_MOD( 874 object_p)); 875 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO( 876 object_p)); 877 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO( 878 object_p)); 879 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1( 880 object_p)); 881 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2( 882 object_p)); 883 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1( 884 object_p)); 885 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2( 886 object_p)); 887 bigint_attr_cleanup(OBJ_PRI_RSA_COEF( 888 object_p)); 889 break; 890 891 case CKK_DSA: 892 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME( 893 object_p)); 894 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME( 895 object_p)); 896 bigint_attr_cleanup(OBJ_PRI_DSA_BASE( 897 object_p)); 898 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE( 899 object_p)); 900 break; 901 902 case CKK_DH: 903 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(object_p)); 904 bigint_attr_cleanup(OBJ_PRI_DH_BASE(object_p)); 905 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(object_p)); 906 break; 907 908 case CKK_EC: 909 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(object_p)); 910 break; 911 } 912 913 /* Release Private Key Object struct. */ 914 free(OBJ_PRI(object_p)); 915 OBJ_PRI(object_p) = NULL; 916 } 917 break; 918 } 919 } 920 921 922 /* 923 * Parse the common attributes. Return to caller with appropriate return 924 * value to indicate if the supplied template specifies a valid attribute 925 * with a valid value. 926 */ 927 CK_RV 928 kernel_parse_common_attrs(CK_ATTRIBUTE_PTR template, kernel_session_t *sp, 929 uint64_t *attr_mask_p) 930 { 931 932 CK_RV rv = CKR_OK; 933 kernel_slot_t *pslot = slot_table[sp->ses_slotid]; 934 935 switch (template->type) { 936 case CKA_CLASS: 937 break; 938 939 /* default boolean attributes */ 940 case CKA_TOKEN: 941 if ((*(CK_BBOOL *)template->pValue) == TRUE) { 942 rv = CKR_ATTRIBUTE_VALUE_INVALID; 943 } 944 break; 945 946 case CKA_PRIVATE: 947 if ((*(CK_BBOOL *)template->pValue) == TRUE) { 948 /* 949 * Cannot create a private object if the token 950 * has a keystore and the user isn't logged in. 951 */ 952 if (pslot->sl_func_list.fl_object_create && 953 pslot->sl_state != CKU_USER) { 954 rv = CKR_ATTRIBUTE_VALUE_INVALID; 955 } else { 956 *attr_mask_p |= PRIVATE_BOOL_ON; 957 } 958 } 959 break; 960 961 case CKA_MODIFIABLE: 962 if ((*(CK_BBOOL *)template->pValue) == FALSE) { 963 *attr_mask_p &= ~MODIFIABLE_BOOL_ON; 964 } 965 break; 966 967 case CKA_LABEL: 968 break; 969 970 default: 971 rv = CKR_TEMPLATE_INCONSISTENT; 972 } 973 974 return (rv); 975 } 976 977 978 979 980 /* 981 * Build a Public Key Object. 982 * 983 * - Parse the object's template, and when an error is detected such as 984 * invalid attribute type, invalid attribute value, etc., return 985 * with appropriate return value. 986 * - Set up attribute mask field in the object for the supplied common 987 * attributes that have boolean type. 988 * - Build the attribute_info struct to hold the value of each supplied 989 * attribute that has byte array type. Link attribute_info structs 990 * together to form the extra attribute list of the object. 991 * - Allocate storage for the Public Key object. 992 * - Build the Public Key object according to the key type. Allocate 993 * storage to hold the big integer value for the supplied attributes 994 * that are required for a certain key type. 995 * 996 */ 997 CK_RV 998 kernel_build_public_key_object(CK_ATTRIBUTE_PTR template, 999 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp, 1000 uint_t mode) 1001 { 1002 1003 int i; 1004 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL; 1005 uint64_t attr_mask = PUBLIC_KEY_DEFAULT; 1006 CK_RV rv = CKR_OK; 1007 int isLabel = 0; 1008 /* Must set flags */ 1009 int isModulus = 0; 1010 int isPubExpo = 0; 1011 int isPrime = 0; 1012 int isSubprime = 0; 1013 int isBase = 0; 1014 int isValue = 0; 1015 int isPoint = 0; 1016 int isParams = 0; 1017 /* Must not set flags */ 1018 int isModulusBits = 0; 1019 CK_ULONG modulus_bits = 0; 1020 1021 biginteger_t modulus; 1022 biginteger_t pubexpo; 1023 biginteger_t prime; 1024 biginteger_t subprime; 1025 biginteger_t base; 1026 biginteger_t value; 1027 biginteger_t point; 1028 CK_ATTRIBUTE string_tmp; 1029 CK_ATTRIBUTE param_tmp; 1030 1031 public_key_obj_t *pbk; 1032 1033 /* prevent bigint_attr_cleanup from freeing invalid attr value */ 1034 (void) memset(&modulus, 0x0, sizeof (biginteger_t)); 1035 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t)); 1036 (void) memset(&prime, 0x0, sizeof (biginteger_t)); 1037 (void) memset(&subprime, 0x0, sizeof (biginteger_t)); 1038 (void) memset(&base, 0x0, sizeof (biginteger_t)); 1039 (void) memset(&value, 0x0, sizeof (biginteger_t)); 1040 (void) memset(&point, 0x0, sizeof (biginteger_t)); 1041 string_tmp.pValue = NULL; 1042 param_tmp.pValue = NULL; 1043 1044 for (i = 0; i < ulAttrNum; i++) { 1045 1046 /* Public Key Object Attributes */ 1047 switch (template[i].type) { 1048 1049 /* common key attributes */ 1050 case CKA_KEY_TYPE: 1051 keytype = *((CK_KEY_TYPE*)template[i].pValue); 1052 break; 1053 1054 case CKA_ID: 1055 case CKA_START_DATE: 1056 case CKA_END_DATE: 1057 1058 /* common public key attribute */ 1059 case CKA_SUBJECT: 1060 /* 1061 * Allocate storage to hold the attribute 1062 * value with byte array type, and add it to 1063 * the extra attribute list of the object. 1064 */ 1065 rv = kernel_add_extra_attr(&template[i], 1066 new_object); 1067 if (rv != CKR_OK) { 1068 goto fail_cleanup; 1069 } 1070 break; 1071 1072 /* 1073 * The following key related attribute types must 1074 * not be specified by C_CreateObject. 1075 */ 1076 case CKA_LOCAL: 1077 case CKA_KEY_GEN_MECHANISM: 1078 rv = CKR_TEMPLATE_INCONSISTENT; 1079 goto fail_cleanup; 1080 1081 /* Key related boolean attributes */ 1082 case CKA_DERIVE: 1083 if (*(CK_BBOOL *)template[i].pValue) 1084 attr_mask |= DERIVE_BOOL_ON; 1085 break; 1086 1087 case CKA_ENCRYPT: 1088 if (*(CK_BBOOL *)template[i].pValue) 1089 attr_mask |= ENCRYPT_BOOL_ON; 1090 else 1091 attr_mask &= ~ENCRYPT_BOOL_ON; 1092 break; 1093 1094 case CKA_VERIFY: 1095 if (*(CK_BBOOL *)template[i].pValue) 1096 attr_mask |= VERIFY_BOOL_ON; 1097 else 1098 attr_mask &= ~VERIFY_BOOL_ON; 1099 break; 1100 1101 case CKA_VERIFY_RECOVER: 1102 if (*(CK_BBOOL *)template[i].pValue) 1103 attr_mask |= VERIFY_RECOVER_BOOL_ON; 1104 else 1105 attr_mask &= ~VERIFY_RECOVER_BOOL_ON; 1106 break; 1107 1108 case CKA_WRAP: 1109 if (*(CK_BBOOL *)template[i].pValue) 1110 attr_mask |= WRAP_BOOL_ON; 1111 break; 1112 1113 case CKA_TRUSTED: 1114 if (*(CK_BBOOL *)template[i].pValue) 1115 attr_mask |= TRUSTED_BOOL_ON; 1116 break; 1117 1118 /* 1119 * The following key related attribute types must 1120 * be specified according to the key type by 1121 * C_CreateObject. 1122 */ 1123 case CKA_MODULUS: 1124 isModulus = 1; 1125 /* 1126 * Copyin big integer attribute from template 1127 * to a local variable. 1128 */ 1129 rv = get_bigint_attr_from_template(&modulus, 1130 &template[i]); 1131 if (rv != CKR_OK) 1132 goto fail_cleanup; 1133 break; 1134 1135 case CKA_PUBLIC_EXPONENT: 1136 isPubExpo = 1; 1137 rv = get_bigint_attr_from_template(&pubexpo, 1138 &template[i]); 1139 if (rv != CKR_OK) 1140 goto fail_cleanup; 1141 break; 1142 1143 case CKA_PRIME: 1144 isPrime = 1; 1145 rv = get_bigint_attr_from_template(&prime, 1146 &template[i]); 1147 if (rv != CKR_OK) 1148 goto fail_cleanup; 1149 break; 1150 1151 case CKA_SUBPRIME: 1152 isSubprime = 1; 1153 rv = get_bigint_attr_from_template(&subprime, 1154 &template[i]); 1155 if (rv != CKR_OK) 1156 goto fail_cleanup; 1157 break; 1158 1159 case CKA_BASE: 1160 isBase = 1; 1161 rv = get_bigint_attr_from_template(&base, 1162 &template[i]); 1163 if (rv != CKR_OK) 1164 goto fail_cleanup; 1165 break; 1166 1167 case CKA_VALUE: 1168 isValue = 1; 1169 rv = get_bigint_attr_from_template(&value, 1170 &template[i]); 1171 if (rv != CKR_OK) 1172 goto fail_cleanup; 1173 break; 1174 1175 case CKA_MODULUS_BITS: 1176 isModulusBits = 1; 1177 get_ulong_attr_from_template(&modulus_bits, 1178 &template[i]); 1179 break; 1180 1181 case CKA_LABEL: 1182 isLabel = 1; 1183 rv = get_string_from_template(&string_tmp, 1184 &template[i]); 1185 if (rv != CKR_OK) 1186 goto fail_cleanup; 1187 break; 1188 1189 case CKA_EC_POINT: 1190 isPoint = 1; 1191 rv = get_bigint_attr_from_template(&point, 1192 &template[i]); 1193 if (rv != CKR_OK) 1194 goto fail_cleanup; 1195 break; 1196 1197 case CKA_EC_PARAMS: 1198 isParams = 1; 1199 rv = get_string_from_template(¶m_tmp, 1200 &template[i]); 1201 if (rv != CKR_OK) 1202 goto fail_cleanup; 1203 break; 1204 1205 default: 1206 rv = kernel_parse_common_attrs(&template[i], sp, 1207 &attr_mask); 1208 if (rv != CKR_OK) 1209 goto fail_cleanup; 1210 break; 1211 } 1212 } /* For */ 1213 1214 /* Allocate storage for Public Key Object. */ 1215 pbk = calloc(1, sizeof (public_key_obj_t)); 1216 if (pbk == NULL) { 1217 rv = CKR_HOST_MEMORY; 1218 goto fail_cleanup; 1219 } 1220 1221 new_object->object_class_u.public_key = pbk; 1222 new_object->class = CKO_PUBLIC_KEY; 1223 1224 if (keytype == (CK_KEY_TYPE)~0UL) { 1225 rv = CKR_TEMPLATE_INCOMPLETE; 1226 goto fail_cleanup; 1227 } 1228 new_object->key_type = keytype; 1229 1230 /* Supported key types of the Public Key Object */ 1231 switch (keytype) { 1232 case CKK_RSA: 1233 if (mode == KERNEL_CREATE_OBJ) { 1234 if (isModulusBits || isPrime || isSubprime || 1235 isBase|| isValue) { 1236 rv = CKR_TEMPLATE_INCONSISTENT; 1237 goto fail_cleanup; 1238 } 1239 } 1240 1241 if (isModulus && isPubExpo) { 1242 /* 1243 * Copy big integer attribute value to the 1244 * designated place in the public key object. 1245 */ 1246 copy_bigint_attr(&modulus, 1247 KEY_PUB_RSA_MOD(pbk)); 1248 1249 copy_bigint_attr(&pubexpo, 1250 KEY_PUB_RSA_PUBEXPO(pbk)); 1251 } else { 1252 rv = CKR_TEMPLATE_INCOMPLETE; 1253 goto fail_cleanup; 1254 } 1255 1256 /* must be generating a RSA key pair by value */ 1257 if (isModulusBits) { 1258 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits; 1259 } 1260 break; 1261 1262 case CKK_DSA: 1263 if (isModulusBits || isModulus || isPubExpo) { 1264 rv = CKR_TEMPLATE_INCONSISTENT; 1265 goto fail_cleanup; 1266 } 1267 1268 if (!(isPrime && isSubprime && isBase && isValue)) { 1269 rv = CKR_TEMPLATE_INCOMPLETE; 1270 goto fail_cleanup; 1271 } 1272 1273 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk)); 1274 1275 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk)); 1276 1277 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk)); 1278 1279 copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk)); 1280 1281 break; 1282 1283 case CKK_DH: 1284 if (!(isPrime && isBase && isValue)) { 1285 rv = CKR_TEMPLATE_INCOMPLETE; 1286 goto fail_cleanup; 1287 } 1288 1289 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk)); 1290 1291 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk)); 1292 1293 copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk)); 1294 1295 break; 1296 1297 case CKK_EC: 1298 if (!isPoint || !isParams) { 1299 rv = CKR_TEMPLATE_INCOMPLETE; 1300 goto fail_cleanup; 1301 } 1302 1303 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk)); 1304 rv = kernel_add_extra_attr(¶m_tmp, new_object); 1305 if (rv != CKR_OK) 1306 goto fail_cleanup; 1307 string_attr_cleanup(¶m_tmp); 1308 break; 1309 default: 1310 rv = CKR_TEMPLATE_INCONSISTENT; 1311 goto fail_cleanup; 1312 } 1313 1314 /* Set up object. */ 1315 new_object->bool_attr_mask = attr_mask; 1316 if (isLabel) { 1317 rv = kernel_add_extra_attr(&string_tmp, new_object); 1318 if (rv != CKR_OK) 1319 goto fail_cleanup; 1320 string_attr_cleanup(&string_tmp); 1321 } 1322 1323 return (rv); 1324 1325 fail_cleanup: 1326 /* 1327 * cleanup the storage allocated to the local variables. 1328 */ 1329 bigint_attr_cleanup(&modulus); 1330 bigint_attr_cleanup(&pubexpo); 1331 bigint_attr_cleanup(&prime); 1332 bigint_attr_cleanup(&subprime); 1333 bigint_attr_cleanup(&base); 1334 bigint_attr_cleanup(&value); 1335 bigint_attr_cleanup(&point); 1336 string_attr_cleanup(&string_tmp); 1337 string_attr_cleanup(¶m_tmp); 1338 1339 /* 1340 * cleanup the storage allocated inside the object itself. 1341 */ 1342 kernel_cleanup_object(new_object); 1343 1344 return (rv); 1345 } 1346 1347 1348 /* 1349 * Build a Private Key Object. 1350 * 1351 * - Parse the object's template, and when an error is detected such as 1352 * invalid attribute type, invalid attribute value, etc., return 1353 * with appropriate return value. 1354 * - Set up attribute mask field in the object for the supplied common 1355 * attributes that have boolean type. 1356 * - Build the attribute_info struct to hold the value of each supplied 1357 * attribute that has byte array type. Link attribute_info structs 1358 * together to form the extra attribute list of the object. 1359 * - Allocate storage for the Private Key object. 1360 * - Build the Private Key object according to the key type. Allocate 1361 * storage to hold the big integer value for the supplied attributes 1362 * that are required for a certain key type. 1363 * 1364 */ 1365 CK_RV 1366 kernel_build_private_key_object(CK_ATTRIBUTE_PTR template, 1367 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp, 1368 uint_t mode) 1369 { 1370 ulong_t i; 1371 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL; 1372 uint64_t attr_mask = PRIVATE_KEY_DEFAULT; 1373 CK_RV rv = CKR_OK; 1374 int isLabel = 0; 1375 /* Must set flags */ 1376 int isModulus = 0; 1377 int isPriExpo = 0; 1378 int isPrime = 0; 1379 int isSubprime = 0; 1380 int isBase = 0; 1381 int isValue = 0; 1382 int isParams = 0; 1383 /* Must not set flags */ 1384 int isValueBits = 0; 1385 CK_ULONG value_bits = 0; 1386 1387 /* Private Key RSA optional */ 1388 int isPubExpo = 0; 1389 int isPrime1 = 0; 1390 int isPrime2 = 0; 1391 int isExpo1 = 0; 1392 int isExpo2 = 0; 1393 int isCoef = 0; 1394 1395 biginteger_t modulus; 1396 biginteger_t priexpo; 1397 biginteger_t prime; 1398 biginteger_t subprime; 1399 biginteger_t base; 1400 biginteger_t value; 1401 1402 biginteger_t pubexpo; 1403 biginteger_t prime1; 1404 biginteger_t prime2; 1405 biginteger_t expo1; 1406 biginteger_t expo2; 1407 biginteger_t coef; 1408 CK_ATTRIBUTE string_tmp; 1409 CK_ATTRIBUTE param_tmp; 1410 1411 private_key_obj_t *pvk; 1412 1413 /* prevent bigint_attr_cleanup from freeing invalid attr value */ 1414 (void) memset(&modulus, 0x0, sizeof (biginteger_t)); 1415 (void) memset(&priexpo, 0x0, sizeof (biginteger_t)); 1416 (void) memset(&prime, 0x0, sizeof (biginteger_t)); 1417 (void) memset(&subprime, 0x0, sizeof (biginteger_t)); 1418 (void) memset(&base, 0x0, sizeof (biginteger_t)); 1419 (void) memset(&value, 0x0, sizeof (biginteger_t)); 1420 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t)); 1421 (void) memset(&prime1, 0x0, sizeof (biginteger_t)); 1422 (void) memset(&prime2, 0x0, sizeof (biginteger_t)); 1423 (void) memset(&expo1, 0x0, sizeof (biginteger_t)); 1424 (void) memset(&expo2, 0x0, sizeof (biginteger_t)); 1425 (void) memset(&coef, 0x0, sizeof (biginteger_t)); 1426 string_tmp.pValue = NULL; 1427 param_tmp.pValue = NULL; 1428 1429 for (i = 0; i < ulAttrNum; i++) { 1430 1431 /* Private Key Object Attributes */ 1432 switch (template[i].type) { 1433 1434 /* common key attributes */ 1435 case CKA_KEY_TYPE: 1436 keytype = *((CK_KEY_TYPE*)template[i].pValue); 1437 break; 1438 1439 case CKA_ID: 1440 case CKA_START_DATE: 1441 case CKA_END_DATE: 1442 1443 /* common private key attribute */ 1444 case CKA_SUBJECT: 1445 /* 1446 * Allocate storage to hold the attribute 1447 * value with byte array type, and add it to 1448 * the extra attribute list of the object. 1449 */ 1450 rv = kernel_add_extra_attr(&template[i], 1451 new_object); 1452 if (rv != CKR_OK) { 1453 goto fail_cleanup; 1454 } 1455 break; 1456 1457 /* 1458 * The following key related attribute types must 1459 * not be specified by C_CreateObject. 1460 */ 1461 case CKA_LOCAL: 1462 case CKA_KEY_GEN_MECHANISM: 1463 case CKA_AUTH_PIN_FLAGS: 1464 case CKA_ALWAYS_SENSITIVE: 1465 case CKA_NEVER_EXTRACTABLE: 1466 rv = CKR_TEMPLATE_INCONSISTENT; 1467 goto fail_cleanup; 1468 1469 /* Key related boolean attributes */ 1470 case CKA_DERIVE: 1471 if (*(CK_BBOOL *)template[i].pValue) 1472 attr_mask |= DERIVE_BOOL_ON; 1473 break; 1474 1475 case CKA_SENSITIVE: 1476 if (*(CK_BBOOL *)template[i].pValue) 1477 attr_mask |= SENSITIVE_BOOL_ON; 1478 break; 1479 1480 case CKA_SECONDARY_AUTH: 1481 if (*(CK_BBOOL *)template[i].pValue) { 1482 rv = CKR_ATTRIBUTE_VALUE_INVALID; 1483 goto fail_cleanup; 1484 } 1485 break; 1486 1487 case CKA_DECRYPT: 1488 if (*(CK_BBOOL *)template[i].pValue) 1489 attr_mask |= DECRYPT_BOOL_ON; 1490 else 1491 attr_mask &= ~DECRYPT_BOOL_ON; 1492 break; 1493 1494 case CKA_SIGN: 1495 if (*(CK_BBOOL *)template[i].pValue) 1496 attr_mask |= SIGN_BOOL_ON; 1497 else 1498 attr_mask &= ~SIGN_BOOL_ON; 1499 break; 1500 1501 case CKA_SIGN_RECOVER: 1502 if (*(CK_BBOOL *)template[i].pValue) 1503 attr_mask |= SIGN_RECOVER_BOOL_ON; 1504 else 1505 attr_mask &= ~SIGN_RECOVER_BOOL_ON; 1506 break; 1507 1508 case CKA_UNWRAP: 1509 if (*(CK_BBOOL *)template[i].pValue) 1510 attr_mask |= UNWRAP_BOOL_ON; 1511 break; 1512 1513 case CKA_EXTRACTABLE: 1514 if (*(CK_BBOOL *)template[i].pValue) 1515 attr_mask |= EXTRACTABLE_BOOL_ON; 1516 else 1517 attr_mask &= ~EXTRACTABLE_BOOL_ON; 1518 break; 1519 1520 /* 1521 * The following key related attribute types must 1522 * be specified according to the key type by 1523 * C_CreateObject. 1524 */ 1525 case CKA_MODULUS: 1526 isModulus = 1; 1527 /* 1528 * Copyin big integer attribute from template 1529 * to a local variable. 1530 */ 1531 rv = get_bigint_attr_from_template(&modulus, 1532 &template[i]); 1533 if (rv != CKR_OK) 1534 goto fail_cleanup; 1535 break; 1536 1537 case CKA_PUBLIC_EXPONENT: 1538 isPubExpo = 1; 1539 rv = get_bigint_attr_from_template(&pubexpo, 1540 &template[i]); 1541 if (rv != CKR_OK) 1542 goto fail_cleanup; 1543 break; 1544 1545 case CKA_PRIVATE_EXPONENT: 1546 isPriExpo = 1; 1547 rv = get_bigint_attr_from_template(&priexpo, 1548 &template[i]); 1549 if (rv != CKR_OK) 1550 goto fail_cleanup; 1551 break; 1552 1553 case CKA_PRIME_1: 1554 isPrime1 = 1; 1555 rv = get_bigint_attr_from_template(&prime1, 1556 &template[i]); 1557 if (rv != CKR_OK) 1558 goto fail_cleanup; 1559 break; 1560 1561 case CKA_PRIME_2: 1562 isPrime2 = 1; 1563 rv = get_bigint_attr_from_template(&prime2, 1564 &template[i]); 1565 if (rv != CKR_OK) 1566 goto fail_cleanup; 1567 break; 1568 1569 case CKA_EXPONENT_1: 1570 isExpo1 = 1; 1571 rv = get_bigint_attr_from_template(&expo1, 1572 &template[i]); 1573 if (rv != CKR_OK) 1574 goto fail_cleanup; 1575 break; 1576 1577 case CKA_EXPONENT_2: 1578 isExpo2 = 1; 1579 rv = get_bigint_attr_from_template(&expo2, 1580 &template[i]); 1581 if (rv != CKR_OK) 1582 goto fail_cleanup; 1583 break; 1584 1585 case CKA_COEFFICIENT: 1586 isCoef = 1; 1587 rv = get_bigint_attr_from_template(&coef, 1588 &template[i]); 1589 if (rv != CKR_OK) 1590 goto fail_cleanup; 1591 break; 1592 1593 case CKA_PRIME: 1594 isPrime = 1; 1595 rv = get_bigint_attr_from_template(&prime, 1596 &template[i]); 1597 if (rv != CKR_OK) 1598 goto fail_cleanup; 1599 break; 1600 1601 case CKA_SUBPRIME: 1602 isSubprime = 1; 1603 rv = get_bigint_attr_from_template(&subprime, 1604 &template[i]); 1605 if (rv != CKR_OK) 1606 goto fail_cleanup; 1607 break; 1608 1609 case CKA_BASE: 1610 isBase = 1; 1611 rv = get_bigint_attr_from_template(&base, 1612 &template[i]); 1613 if (rv != CKR_OK) 1614 goto fail_cleanup; 1615 break; 1616 1617 case CKA_VALUE: 1618 isValue = 1; 1619 rv = get_bigint_attr_from_template(&value, 1620 &template[i]); 1621 if (rv != CKR_OK) 1622 goto fail_cleanup; 1623 break; 1624 1625 case CKA_VALUE_BITS: 1626 isValueBits = 1; 1627 get_ulong_attr_from_template(&value_bits, 1628 &template[i]); 1629 break; 1630 1631 case CKA_LABEL: 1632 isLabel = 1; 1633 rv = get_string_from_template(&string_tmp, 1634 &template[i]); 1635 if (rv != CKR_OK) 1636 goto fail_cleanup; 1637 break; 1638 1639 case CKA_EC_PARAMS: 1640 isParams = 1; 1641 rv = get_string_from_template(¶m_tmp, 1642 &template[i]); 1643 if (rv != CKR_OK) 1644 goto fail_cleanup; 1645 break; 1646 1647 default: 1648 rv = kernel_parse_common_attrs(&template[i], sp, 1649 &attr_mask); 1650 if (rv != CKR_OK) 1651 goto fail_cleanup; 1652 break; 1653 1654 } 1655 } /* For */ 1656 1657 /* Allocate storage for Private Key Object. */ 1658 pvk = calloc(1, sizeof (private_key_obj_t)); 1659 if (pvk == NULL) { 1660 rv = CKR_HOST_MEMORY; 1661 goto fail_cleanup; 1662 } 1663 1664 new_object->object_class_u.private_key = pvk; 1665 new_object->class = CKO_PRIVATE_KEY; 1666 1667 if (keytype == (CK_KEY_TYPE)~0UL) { 1668 rv = CKR_TEMPLATE_INCOMPLETE; 1669 goto fail_cleanup; 1670 } 1671 1672 new_object->key_type = keytype; 1673 1674 /* Supported key types of the Private Key Object */ 1675 switch (keytype) { 1676 case CKK_RSA: 1677 if (isPrime || isSubprime || isBase || isValue || 1678 isValueBits) { 1679 rv = CKR_TEMPLATE_INCONSISTENT; 1680 goto fail_cleanup; 1681 } 1682 1683 if (isModulus && isPriExpo) { 1684 /* 1685 * Copy big integer attribute value to the 1686 * designated place in the Private Key object. 1687 */ 1688 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk)); 1689 1690 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk)); 1691 1692 } else { 1693 rv = CKR_TEMPLATE_INCOMPLETE; 1694 goto fail_cleanup; 1695 } 1696 1697 /* The following attributes are optional. */ 1698 if (isPubExpo) { 1699 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk)); 1700 } 1701 1702 if (isPrime1) { 1703 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk)); 1704 } 1705 1706 if (isPrime2) { 1707 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk)); 1708 } 1709 1710 if (isExpo1) { 1711 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk)); 1712 } 1713 1714 if (isExpo2) { 1715 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk)); 1716 } 1717 1718 if (isCoef) { 1719 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk)); 1720 } 1721 break; 1722 1723 case CKK_DSA: 1724 if (isModulus || isPubExpo || isPriExpo || isPrime1 || 1725 isPrime2 || isExpo1 || isExpo2 || isCoef || 1726 isValueBits) { 1727 rv = CKR_TEMPLATE_INCONSISTENT; 1728 goto fail_cleanup; 1729 } 1730 1731 if (!(isPrime && isSubprime && isBase && isValue)) { 1732 rv = CKR_TEMPLATE_INCOMPLETE; 1733 goto fail_cleanup; 1734 } 1735 1736 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk)); 1737 1738 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk)); 1739 1740 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk)); 1741 1742 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk)); 1743 1744 break; 1745 1746 case CKK_DH: 1747 if (mode == KERNEL_CREATE_OBJ && isValueBits) { 1748 rv = CKR_TEMPLATE_INCONSISTENT; 1749 goto fail_cleanup; 1750 } 1751 if (!(isPrime && isBase && isValue)) { 1752 rv = CKR_TEMPLATE_INCOMPLETE; 1753 goto fail_cleanup; 1754 } 1755 1756 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk)); 1757 1758 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk)); 1759 1760 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk)); 1761 1762 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ? value_bits : 0; 1763 1764 break; 1765 1766 case CKK_EC: 1767 if (!isValue || !isParams) { 1768 rv = CKR_TEMPLATE_INCOMPLETE; 1769 goto fail_cleanup; 1770 } 1771 1772 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk)); 1773 rv = kernel_add_extra_attr(¶m_tmp, new_object); 1774 if (rv != CKR_OK) 1775 goto fail_cleanup; 1776 string_attr_cleanup(¶m_tmp); 1777 break; 1778 default: 1779 rv = CKR_TEMPLATE_INCONSISTENT; 1780 goto fail_cleanup; 1781 } 1782 1783 /* Set up object. */ 1784 new_object->bool_attr_mask = attr_mask; 1785 if (isLabel) { 1786 rv = kernel_add_extra_attr(&string_tmp, new_object); 1787 if (rv != CKR_OK) 1788 goto fail_cleanup; 1789 string_attr_cleanup(&string_tmp); 1790 } 1791 1792 return (rv); 1793 1794 fail_cleanup: 1795 /* 1796 * cleanup the storage allocated to the local variables. 1797 */ 1798 bigint_attr_cleanup(&modulus); 1799 bigint_attr_cleanup(&priexpo); 1800 bigint_attr_cleanup(&prime); 1801 bigint_attr_cleanup(&subprime); 1802 bigint_attr_cleanup(&base); 1803 bigint_attr_cleanup(&value); 1804 bigint_attr_cleanup(&pubexpo); 1805 bigint_attr_cleanup(&prime1); 1806 bigint_attr_cleanup(&prime2); 1807 bigint_attr_cleanup(&expo1); 1808 bigint_attr_cleanup(&expo2); 1809 bigint_attr_cleanup(&coef); 1810 string_attr_cleanup(&string_tmp); 1811 string_attr_cleanup(¶m_tmp); 1812 1813 /* 1814 * cleanup the storage allocated inside the object itself. 1815 */ 1816 kernel_cleanup_object(new_object); 1817 1818 return (rv); 1819 } 1820 1821 1822 /* 1823 * Build a Secret Key Object. 1824 * 1825 * - Parse the object's template, and when an error is detected such as 1826 * invalid attribute type, invalid attribute value, etc., return 1827 * with appropriate return value. 1828 * - Set up attribute mask field in the object for the supplied common 1829 * attributes that have boolean type. 1830 * - Build the attribute_info struct to hold the value of each supplied 1831 * attribute that has byte array type. Link attribute_info structs 1832 * together to form the extra attribute list of the object. 1833 * - Allocate storage for the Secret Key object. 1834 * - Build the Secret Key object. Allocate storage to hold the big integer 1835 * value for the attribute CKA_VALUE that is required for all the key 1836 * types supported by secret key object. 1837 * 1838 */ 1839 CK_RV 1840 kernel_build_secret_key_object(CK_ATTRIBUTE_PTR template, 1841 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp) 1842 { 1843 1844 int i; 1845 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL; 1846 uint64_t attr_mask = SECRET_KEY_DEFAULT; 1847 CK_RV rv = CKR_OK; 1848 int isLabel = 0; 1849 /* Must set flags */ 1850 int isValue = 0; 1851 /* Must not set flags */ 1852 int isValueLen = 0; 1853 1854 CK_ATTRIBUTE string_tmp; 1855 1856 secret_key_obj_t *sck; 1857 1858 string_tmp.pValue = NULL; 1859 1860 /* Allocate storage for Secret Key Object. */ 1861 sck = calloc(1, sizeof (secret_key_obj_t)); 1862 if (sck == NULL) { 1863 rv = CKR_HOST_MEMORY; 1864 goto fail_cleanup; 1865 } 1866 1867 new_object->object_class_u.secret_key = sck; 1868 new_object->class = CKO_SECRET_KEY; 1869 1870 for (i = 0; i < ulAttrNum; i++) { 1871 1872 /* Secret Key Object Attributes */ 1873 switch (template[i].type) { 1874 1875 /* common key attributes */ 1876 case CKA_KEY_TYPE: 1877 keytype = *((CK_KEY_TYPE*)template[i].pValue); 1878 break; 1879 1880 case CKA_ID: 1881 case CKA_START_DATE: 1882 case CKA_END_DATE: 1883 /* 1884 * Allocate storage to hold the attribute 1885 * value with byte array type, and add it to 1886 * the extra attribute list of the object. 1887 */ 1888 rv = kernel_add_extra_attr(&template[i], 1889 new_object); 1890 if (rv != CKR_OK) { 1891 goto fail_cleanup; 1892 } 1893 break; 1894 1895 /* 1896 * The following key related attribute types must 1897 * not be specified by C_CreateObject. 1898 */ 1899 case CKA_LOCAL: 1900 case CKA_KEY_GEN_MECHANISM: 1901 case CKA_ALWAYS_SENSITIVE: 1902 case CKA_NEVER_EXTRACTABLE: 1903 rv = CKR_TEMPLATE_INCONSISTENT; 1904 goto fail_cleanup; 1905 1906 /* Key related boolean attributes */ 1907 case CKA_DERIVE: 1908 if (*(CK_BBOOL *)template[i].pValue) 1909 attr_mask |= DERIVE_BOOL_ON; 1910 break; 1911 1912 case CKA_SENSITIVE: 1913 if (*(CK_BBOOL *)template[i].pValue) 1914 attr_mask |= SENSITIVE_BOOL_ON; 1915 break; 1916 1917 case CKA_ENCRYPT: 1918 if (*(CK_BBOOL *)template[i].pValue) 1919 attr_mask |= ENCRYPT_BOOL_ON; 1920 else 1921 attr_mask &= ~ENCRYPT_BOOL_ON; 1922 break; 1923 1924 case CKA_DECRYPT: 1925 if (*(CK_BBOOL *)template[i].pValue) 1926 attr_mask |= DECRYPT_BOOL_ON; 1927 else 1928 attr_mask &= ~DECRYPT_BOOL_ON; 1929 break; 1930 1931 case CKA_SIGN: 1932 if (*(CK_BBOOL *)template[i].pValue) 1933 attr_mask |= SIGN_BOOL_ON; 1934 else 1935 attr_mask &= ~SIGN_BOOL_ON; 1936 break; 1937 1938 case CKA_VERIFY: 1939 if (*(CK_BBOOL *)template[i].pValue) 1940 attr_mask |= VERIFY_BOOL_ON; 1941 else 1942 attr_mask &= ~VERIFY_BOOL_ON; 1943 break; 1944 1945 case CKA_WRAP: 1946 if (*(CK_BBOOL *)template[i].pValue) 1947 attr_mask |= WRAP_BOOL_ON; 1948 break; 1949 1950 case CKA_UNWRAP: 1951 if (*(CK_BBOOL *)template[i].pValue) 1952 attr_mask |= UNWRAP_BOOL_ON; 1953 break; 1954 1955 case CKA_EXTRACTABLE: 1956 if (*(CK_BBOOL *)template[i].pValue) 1957 attr_mask |= EXTRACTABLE_BOOL_ON; 1958 else 1959 attr_mask &= ~EXTRACTABLE_BOOL_ON; 1960 break; 1961 1962 case CKA_VALUE: 1963 isValue = 1; 1964 if ((template[i].ulValueLen == 0) || 1965 (template[i].pValue == NULL)) { 1966 rv = CKR_ATTRIBUTE_VALUE_INVALID; 1967 goto fail_cleanup; 1968 } 1969 1970 /* 1971 * Copyin attribute from template 1972 * to a local variable. 1973 */ 1974 sck->sk_value = malloc(template[i].ulValueLen); 1975 if (sck->sk_value == NULL) { 1976 rv = CKR_HOST_MEMORY; 1977 goto fail_cleanup; 1978 } 1979 (void) memcpy(sck->sk_value, template[i].pValue, 1980 template[i].ulValueLen); 1981 sck->sk_value_len = template[i].ulValueLen; 1982 break; 1983 1984 case CKA_VALUE_LEN: 1985 isValueLen = 1; 1986 break; 1987 1988 case CKA_LABEL: 1989 isLabel = 1; 1990 rv = get_string_from_template(&string_tmp, 1991 &template[i]); 1992 if (rv != CKR_OK) 1993 goto fail_cleanup; 1994 break; 1995 1996 default: 1997 rv = kernel_parse_common_attrs(&template[i], sp, 1998 &attr_mask); 1999 if (rv != CKR_OK) 2000 goto fail_cleanup; 2001 break; 2002 2003 } 2004 } /* For */ 2005 2006 if (keytype == (CK_KEY_TYPE)~0UL) { 2007 rv = CKR_TEMPLATE_INCOMPLETE; 2008 goto fail_cleanup; 2009 } 2010 2011 new_object->key_type = keytype; 2012 2013 /* Supported key types of the Secret Key Object */ 2014 switch (keytype) { 2015 case CKK_RC4: 2016 if (!isValue) { 2017 rv = CKR_TEMPLATE_INCOMPLETE; 2018 goto fail_cleanup; 2019 } 2020 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) || 2021 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) { 2022 rv = CKR_ATTRIBUTE_VALUE_INVALID; 2023 goto fail_cleanup; 2024 } 2025 break; 2026 2027 case CKK_GENERIC_SECRET: 2028 if (!isValue) { 2029 rv = CKR_TEMPLATE_INCOMPLETE; 2030 goto fail_cleanup; 2031 } 2032 break; 2033 2034 case CKK_AES: 2035 if (!isValue) { 2036 rv = CKR_TEMPLATE_INCOMPLETE; 2037 goto fail_cleanup; 2038 } 2039 if (sck->sk_value_len < AES_MIN_KEY_BYTES) { 2040 rv = CKR_ATTRIBUTE_VALUE_INVALID; 2041 goto fail_cleanup; 2042 } 2043 break; 2044 2045 case CKK_BLOWFISH: 2046 if (!isValue) { 2047 rv = CKR_TEMPLATE_INCOMPLETE; 2048 goto fail_cleanup; 2049 } 2050 if (sck->sk_value_len < BLOWFISH_MINBYTES) { 2051 rv = CKR_ATTRIBUTE_VALUE_INVALID; 2052 goto fail_cleanup; 2053 } 2054 break; 2055 2056 case CKK_DES: 2057 if (!isValue) { 2058 rv = CKR_TEMPLATE_INCOMPLETE; 2059 goto fail_cleanup; 2060 } 2061 if (sck->sk_value_len != DES_KEYSIZE) { 2062 rv = CKR_ATTRIBUTE_VALUE_INVALID; 2063 goto fail_cleanup; 2064 } 2065 break; 2066 2067 case CKK_DES2: 2068 if (!isValue) { 2069 rv = CKR_TEMPLATE_INCOMPLETE; 2070 goto fail_cleanup; 2071 } 2072 if (sck->sk_value_len != DES2_KEYSIZE) { 2073 rv = CKR_ATTRIBUTE_VALUE_INVALID; 2074 goto fail_cleanup; 2075 } 2076 break; 2077 2078 case CKK_DES3: 2079 if (!isValue) { 2080 rv = CKR_TEMPLATE_INCOMPLETE; 2081 goto fail_cleanup; 2082 } 2083 if (sck->sk_value_len != DES3_KEYSIZE) { 2084 rv = CKR_ATTRIBUTE_VALUE_INVALID; 2085 goto fail_cleanup; 2086 } 2087 break; 2088 2089 default: 2090 rv = CKR_TEMPLATE_INCONSISTENT; 2091 goto fail_cleanup; 2092 } 2093 2094 if (isValueLen) { 2095 rv = CKR_TEMPLATE_INCONSISTENT; 2096 goto fail_cleanup; 2097 } 2098 2099 /* Set up object. */ 2100 new_object->bool_attr_mask = attr_mask; 2101 if (isLabel) { 2102 rv = kernel_add_extra_attr(&string_tmp, new_object); 2103 if (rv != CKR_OK) 2104 goto fail_cleanup; 2105 string_attr_cleanup(&string_tmp); 2106 } 2107 2108 return (rv); 2109 2110 fail_cleanup: 2111 /* 2112 * cleanup the storage allocated to the local variables. 2113 */ 2114 string_attr_cleanup(&string_tmp); 2115 2116 /* 2117 * cleanup the storage allocated inside the object itself. 2118 */ 2119 kernel_cleanup_object(new_object); 2120 2121 return (rv); 2122 } 2123 2124 2125 /* 2126 * Validate the attribute types in the object's template. Then, 2127 * call the appropriate build function according to the class of 2128 * the object specified in the template. 2129 * 2130 * Note: The following classes of objects are supported: 2131 * - CKO_SECRET_KEY 2132 * - CKO_PUBLIC_KEY 2133 * - CKO_PRIVATE_KEY 2134 */ 2135 CK_RV 2136 kernel_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum, 2137 kernel_object_t *new_object, kernel_session_t *sp, uint_t mode) 2138 { 2139 2140 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL; 2141 CK_RV rv = CKR_OK; 2142 2143 if (template == NULL) { 2144 return (CKR_ARGUMENTS_BAD); 2145 } 2146 2147 /* Validate the attribute type in the template. */ 2148 rv = kernel_validate_attr(template, ulAttrNum, &class); 2149 if (rv != CKR_OK) 2150 return (rv); 2151 2152 if (class == (CK_OBJECT_CLASS)~0UL) 2153 return (CKR_TEMPLATE_INCOMPLETE); 2154 2155 /* 2156 * Call the appropriate function based on the supported class 2157 * of the object. 2158 */ 2159 switch (class) { 2160 case CKO_PUBLIC_KEY: 2161 rv = kernel_build_public_key_object(template, ulAttrNum, 2162 new_object, sp, mode); 2163 break; 2164 2165 case CKO_PRIVATE_KEY: 2166 rv = kernel_build_private_key_object(template, ulAttrNum, 2167 new_object, sp, mode); 2168 break; 2169 2170 case CKO_SECRET_KEY: 2171 rv = kernel_build_secret_key_object(template, ulAttrNum, 2172 new_object, sp); 2173 break; 2174 2175 case CKO_DOMAIN_PARAMETERS: 2176 case CKO_DATA: 2177 case CKO_CERTIFICATE: 2178 case CKO_HW_FEATURE: 2179 case CKO_VENDOR_DEFINED: 2180 default: 2181 return (CKR_ATTRIBUTE_VALUE_INVALID); 2182 } 2183 2184 return (rv); 2185 } 2186 2187 2188 /* 2189 * Get the value of a requested attribute that is common to all supported 2190 * classes (i.e. public key, private key, secret key classes). 2191 */ 2192 CK_RV 2193 kernel_get_common_attrs(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template) 2194 { 2195 2196 CK_RV rv = CKR_OK; 2197 2198 switch (template->type) { 2199 2200 case CKA_CLASS: 2201 return (get_ulong_attr_from_object(object_p->class, 2202 template)); 2203 2204 /* default boolean attributes */ 2205 case CKA_TOKEN: 2206 2207 template->ulValueLen = sizeof (CK_BBOOL); 2208 if (template->pValue == NULL) { 2209 return (CKR_OK); 2210 } 2211 2212 /* 2213 * A token object will not be created in the library, so we 2214 * return FALSE. 2215 */ 2216 *((CK_BBOOL *)template->pValue) = B_FALSE; 2217 break; 2218 2219 case CKA_PRIVATE: 2220 2221 template->ulValueLen = sizeof (CK_BBOOL); 2222 if (template->pValue == NULL) { 2223 return (CKR_OK); 2224 } 2225 if (object_p->bool_attr_mask & PRIVATE_BOOL_ON) { 2226 *((CK_BBOOL *)template->pValue) = B_TRUE; 2227 } else { 2228 *((CK_BBOOL *)template->pValue) = B_FALSE; 2229 } 2230 break; 2231 2232 case CKA_MODIFIABLE: 2233 template->ulValueLen = sizeof (CK_BBOOL); 2234 if (template->pValue == NULL) { 2235 return (CKR_OK); 2236 } 2237 if ((object_p->bool_attr_mask) & MODIFIABLE_BOOL_ON) 2238 *((CK_BBOOL *)template->pValue) = B_TRUE; 2239 else 2240 *((CK_BBOOL *)template->pValue) = B_FALSE; 2241 break; 2242 2243 case CKA_LABEL: 2244 return (get_extra_attr_from_object(object_p, 2245 template)); 2246 break; 2247 2248 default: 2249 /* 2250 * The specified attribute for the object is invalid. 2251 * (the object does not possess such an attribute.) 2252 */ 2253 template->ulValueLen = (CK_ULONG)-1; 2254 return (CKR_ATTRIBUTE_TYPE_INVALID); 2255 } 2256 2257 return (rv); 2258 } 2259 2260 /* 2261 * Get the value of a requested attribute that is common to all key objects 2262 * (i.e. public key, private key and secret key). 2263 */ 2264 CK_RV 2265 kernel_get_common_key_attrs(kernel_object_t *object_p, 2266 CK_ATTRIBUTE_PTR template) 2267 { 2268 2269 switch (template->type) { 2270 2271 case CKA_KEY_TYPE: 2272 return (get_ulong_attr_from_object(object_p->key_type, 2273 template)); 2274 2275 case CKA_ID: 2276 case CKA_START_DATE: 2277 case CKA_END_DATE: 2278 /* 2279 * The above extra attributes have byte array type. 2280 */ 2281 return (get_extra_attr_from_object(object_p, 2282 template)); 2283 2284 /* Key related boolean attributes */ 2285 case CKA_LOCAL: 2286 return (get_bool_attr_from_object(object_p, 2287 LOCAL_BOOL_ON, template)); 2288 2289 case CKA_DERIVE: 2290 return (get_bool_attr_from_object(object_p, 2291 DERIVE_BOOL_ON, template)); 2292 2293 case CKA_KEY_GEN_MECHANISM: 2294 return (get_ulong_attr_from_object(object_p->mechanism, 2295 template)); 2296 2297 default: 2298 return (CKR_ATTRIBUTE_TYPE_INVALID); 2299 } 2300 } 2301 2302 2303 /* 2304 * Get the value of a requested attribute of a Public Key Object. 2305 * 2306 * Rule: All the attributes in the public key object can be revealed. 2307 */ 2308 CK_RV 2309 kernel_get_public_key_attribute(kernel_object_t *object_p, 2310 CK_ATTRIBUTE_PTR template) 2311 { 2312 2313 CK_RV rv = CKR_OK; 2314 CK_KEY_TYPE keytype = object_p->key_type; 2315 2316 switch (template->type) { 2317 2318 case CKA_SUBJECT: 2319 case CKA_EC_PARAMS: 2320 /* 2321 * The above extra attributes have byte array type. 2322 */ 2323 return (get_extra_attr_from_object(object_p, 2324 template)); 2325 2326 /* Key related boolean attributes */ 2327 case CKA_ENCRYPT: 2328 return (get_bool_attr_from_object(object_p, 2329 ENCRYPT_BOOL_ON, template)); 2330 2331 case CKA_VERIFY: 2332 return (get_bool_attr_from_object(object_p, 2333 VERIFY_BOOL_ON, template)); 2334 2335 case CKA_VERIFY_RECOVER: 2336 return (get_bool_attr_from_object(object_p, 2337 VERIFY_RECOVER_BOOL_ON, template)); 2338 2339 case CKA_WRAP: 2340 return (get_bool_attr_from_object(object_p, 2341 WRAP_BOOL_ON, template)); 2342 2343 case CKA_TRUSTED: 2344 return (get_bool_attr_from_object(object_p, 2345 TRUSTED_BOOL_ON, template)); 2346 2347 case CKA_MODULUS: 2348 /* 2349 * This attribute is valid only for RSA public key 2350 * object. 2351 */ 2352 if (keytype == CKK_RSA) { 2353 return (get_bigint_attr_from_object( 2354 OBJ_PUB_RSA_MOD(object_p), template)); 2355 } else { 2356 template->ulValueLen = (CK_ULONG)-1; 2357 return (CKR_ATTRIBUTE_TYPE_INVALID); 2358 } 2359 2360 case CKA_PUBLIC_EXPONENT: 2361 if (keytype == CKK_RSA) { 2362 return (get_bigint_attr_from_object( 2363 OBJ_PUB_RSA_PUBEXPO(object_p), template)); 2364 } else { 2365 template->ulValueLen = (CK_ULONG)-1; 2366 return (CKR_ATTRIBUTE_TYPE_INVALID); 2367 } 2368 2369 case CKA_MODULUS_BITS: 2370 if (keytype == CKK_RSA) { 2371 return (get_ulong_attr_from_object( 2372 OBJ_PUB_RSA_MOD_BITS(object_p), template)); 2373 } else { 2374 template->ulValueLen = (CK_ULONG)-1; 2375 return (CKR_ATTRIBUTE_TYPE_INVALID); 2376 } 2377 2378 case CKA_PRIME: 2379 switch (keytype) { 2380 case CKK_DSA: 2381 return (get_bigint_attr_from_object( 2382 OBJ_PUB_DSA_PRIME(object_p), template)); 2383 case CKK_DH: 2384 return (get_bigint_attr_from_object( 2385 OBJ_PUB_DH_PRIME(object_p), template)); 2386 default: 2387 template->ulValueLen = (CK_ULONG)-1; 2388 return (CKR_ATTRIBUTE_TYPE_INVALID); 2389 } 2390 2391 case CKA_SUBPRIME: 2392 switch (keytype) { 2393 case CKK_DSA: 2394 return (get_bigint_attr_from_object( 2395 OBJ_PUB_DSA_SUBPRIME(object_p), template)); 2396 default: 2397 template->ulValueLen = (CK_ULONG)-1; 2398 return (CKR_ATTRIBUTE_TYPE_INVALID); 2399 } 2400 2401 case CKA_BASE: 2402 switch (keytype) { 2403 case CKK_DSA: 2404 return (get_bigint_attr_from_object( 2405 OBJ_PUB_DSA_BASE(object_p), template)); 2406 case CKK_DH: 2407 return (get_bigint_attr_from_object( 2408 OBJ_PUB_DH_BASE(object_p), template)); 2409 default: 2410 template->ulValueLen = (CK_ULONG)-1; 2411 return (CKR_ATTRIBUTE_TYPE_INVALID); 2412 } 2413 2414 case CKA_VALUE: 2415 switch (keytype) { 2416 case CKK_DSA: 2417 return (get_bigint_attr_from_object( 2418 OBJ_PUB_DSA_VALUE(object_p), template)); 2419 case CKK_DH: 2420 return (get_bigint_attr_from_object( 2421 OBJ_PUB_DH_VALUE(object_p), template)); 2422 default: 2423 template->ulValueLen = (CK_ULONG)-1; 2424 return (CKR_ATTRIBUTE_TYPE_INVALID); 2425 } 2426 2427 case CKA_EC_POINT: 2428 switch (keytype) { 2429 case CKK_EC: 2430 return (get_bigint_attr_from_object( 2431 OBJ_PUB_EC_POINT(object_p), template)); 2432 default: 2433 template->ulValueLen = (CK_ULONG)-1; 2434 return (CKR_ATTRIBUTE_TYPE_INVALID); 2435 } 2436 default: 2437 /* 2438 * First, get the value of the request attribute defined 2439 * in the list of common key attributes. If the request 2440 * attribute is not found in that list, then get the 2441 * attribute from the list of common attributes. 2442 */ 2443 rv = kernel_get_common_key_attrs(object_p, template); 2444 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) { 2445 rv = kernel_get_common_attrs(object_p, template); 2446 } 2447 break; 2448 } 2449 2450 return (rv); 2451 } 2452 2453 2454 /* 2455 * Get the value of a requested attribute of a Private Key Object. 2456 * 2457 * Rule: All the attributes in the private key object can be revealed 2458 * except those marked with footnote number "7" when the object 2459 * has its CKA_SENSITIVE attribute set to TRUE or its 2460 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.). 2461 */ 2462 CK_RV 2463 kernel_get_private_key_attribute(kernel_object_t *object_p, 2464 CK_ATTRIBUTE_PTR template) 2465 { 2466 2467 CK_RV rv = CKR_OK; 2468 CK_KEY_TYPE keytype = object_p->key_type; 2469 2470 2471 /* 2472 * If the following specified attributes for the private key 2473 * object cannot be revealed because the object is sensitive 2474 * or unextractable, then the ulValueLen is set to -1. 2475 */ 2476 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) || 2477 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) { 2478 2479 switch (template->type) { 2480 case CKA_PRIVATE_EXPONENT: 2481 case CKA_PRIME_1: 2482 case CKA_PRIME_2: 2483 case CKA_EXPONENT_1: 2484 case CKA_EXPONENT_2: 2485 case CKA_COEFFICIENT: 2486 case CKA_VALUE: 2487 template->ulValueLen = (CK_ULONG)-1; 2488 return (CKR_ATTRIBUTE_SENSITIVE); 2489 } 2490 } 2491 2492 switch (template->type) { 2493 2494 case CKA_SUBJECT: 2495 case CKA_EC_PARAMS: 2496 /* 2497 * The above extra attributes have byte array type. 2498 */ 2499 return (get_extra_attr_from_object(object_p, 2500 template)); 2501 2502 /* Key related boolean attributes */ 2503 case CKA_SENSITIVE: 2504 return (get_bool_attr_from_object(object_p, 2505 SENSITIVE_BOOL_ON, template)); 2506 2507 case CKA_SECONDARY_AUTH: 2508 return (get_bool_attr_from_object(object_p, 2509 SECONDARY_AUTH_BOOL_ON, template)); 2510 2511 case CKA_DECRYPT: 2512 return (get_bool_attr_from_object(object_p, 2513 DECRYPT_BOOL_ON, template)); 2514 2515 case CKA_SIGN: 2516 return (get_bool_attr_from_object(object_p, 2517 SIGN_BOOL_ON, template)); 2518 2519 case CKA_SIGN_RECOVER: 2520 return (get_bool_attr_from_object(object_p, 2521 SIGN_RECOVER_BOOL_ON, template)); 2522 2523 case CKA_UNWRAP: 2524 return (get_bool_attr_from_object(object_p, 2525 UNWRAP_BOOL_ON, template)); 2526 2527 case CKA_EXTRACTABLE: 2528 return (get_bool_attr_from_object(object_p, 2529 EXTRACTABLE_BOOL_ON, template)); 2530 2531 case CKA_ALWAYS_SENSITIVE: 2532 return (get_bool_attr_from_object(object_p, 2533 ALWAYS_SENSITIVE_BOOL_ON, template)); 2534 2535 case CKA_NEVER_EXTRACTABLE: 2536 return (get_bool_attr_from_object(object_p, 2537 NEVER_EXTRACTABLE_BOOL_ON, template)); 2538 2539 case CKA_MODULUS: 2540 if (keytype == CKK_RSA) { 2541 return (get_bigint_attr_from_object( 2542 OBJ_PRI_RSA_MOD(object_p), template)); 2543 } else { 2544 template->ulValueLen = (CK_ULONG)-1; 2545 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2546 break; 2547 } 2548 2549 case CKA_PUBLIC_EXPONENT: 2550 if (keytype == CKK_RSA) { 2551 return (get_bigint_attr_from_object( 2552 OBJ_PRI_RSA_PUBEXPO(object_p), template)); 2553 } else { 2554 template->ulValueLen = (CK_ULONG)-1; 2555 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2556 break; 2557 } 2558 2559 case CKA_PRIVATE_EXPONENT: 2560 if (keytype == CKK_RSA) { 2561 return (get_bigint_attr_from_object( 2562 OBJ_PRI_RSA_PRIEXPO(object_p), template)); 2563 } else { 2564 template->ulValueLen = (CK_ULONG)-1; 2565 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2566 break; 2567 } 2568 2569 case CKA_PRIME_1: 2570 if (keytype == CKK_RSA) { 2571 return (get_bigint_attr_from_object( 2572 OBJ_PRI_RSA_PRIME1(object_p), template)); 2573 } else { 2574 template->ulValueLen = (CK_ULONG)-1; 2575 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2576 break; 2577 } 2578 2579 case CKA_PRIME_2: 2580 if (keytype == CKK_RSA) { 2581 return (get_bigint_attr_from_object( 2582 OBJ_PRI_RSA_PRIME2(object_p), template)); 2583 } else { 2584 template->ulValueLen = (CK_ULONG)-1; 2585 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2586 break; 2587 } 2588 2589 case CKA_EXPONENT_1: 2590 if (keytype == CKK_RSA) { 2591 return (get_bigint_attr_from_object( 2592 OBJ_PRI_RSA_EXPO1(object_p), template)); 2593 } else { 2594 template->ulValueLen = (CK_ULONG)-1; 2595 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2596 break; 2597 } 2598 2599 case CKA_EXPONENT_2: 2600 if (keytype == CKK_RSA) { 2601 return (get_bigint_attr_from_object( 2602 OBJ_PRI_RSA_EXPO2(object_p), template)); 2603 } else { 2604 template->ulValueLen = (CK_ULONG)-1; 2605 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2606 break; 2607 } 2608 2609 case CKA_COEFFICIENT: 2610 if (keytype == CKK_RSA) { 2611 return (get_bigint_attr_from_object( 2612 OBJ_PRI_RSA_COEF(object_p), template)); 2613 } else { 2614 template->ulValueLen = (CK_ULONG)-1; 2615 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2616 break; 2617 } 2618 2619 case CKA_VALUE_BITS: 2620 if (keytype == CKK_DH) { 2621 return (get_ulong_attr_from_object( 2622 OBJ_PRI_DH_VAL_BITS(object_p), template)); 2623 } else { 2624 template->ulValueLen = (CK_ULONG)-1; 2625 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2626 break; 2627 } 2628 2629 case CKA_PRIME: 2630 switch (keytype) { 2631 case CKK_DSA: 2632 return (get_bigint_attr_from_object( 2633 OBJ_PRI_DSA_PRIME(object_p), template)); 2634 case CKK_DH: 2635 return (get_bigint_attr_from_object( 2636 OBJ_PRI_DH_PRIME(object_p), template)); 2637 default: 2638 template->ulValueLen = (CK_ULONG)-1; 2639 return (CKR_ATTRIBUTE_TYPE_INVALID); 2640 } 2641 2642 case CKA_SUBPRIME: 2643 switch (keytype) { 2644 case CKK_DSA: 2645 return (get_bigint_attr_from_object( 2646 OBJ_PRI_DSA_SUBPRIME(object_p), template)); 2647 default: 2648 template->ulValueLen = (CK_ULONG)-1; 2649 return (CKR_ATTRIBUTE_TYPE_INVALID); 2650 } 2651 2652 case CKA_BASE: 2653 switch (keytype) { 2654 case CKK_DSA: 2655 return (get_bigint_attr_from_object( 2656 OBJ_PRI_DSA_BASE(object_p), template)); 2657 case CKK_DH: 2658 return (get_bigint_attr_from_object( 2659 OBJ_PRI_DH_BASE(object_p), template)); 2660 default: 2661 template->ulValueLen = (CK_ULONG)-1; 2662 return (CKR_ATTRIBUTE_TYPE_INVALID); 2663 } 2664 2665 case CKA_VALUE: 2666 switch (keytype) { 2667 case CKK_DSA: 2668 return (get_bigint_attr_from_object( 2669 OBJ_PRI_DSA_VALUE(object_p), template)); 2670 case CKK_DH: 2671 return (get_bigint_attr_from_object( 2672 OBJ_PRI_DH_VALUE(object_p), template)); 2673 case CKK_EC: 2674 return (get_bigint_attr_from_object( 2675 OBJ_PRI_EC_VALUE(object_p), template)); 2676 default: 2677 template->ulValueLen = (CK_ULONG)-1; 2678 return (CKR_ATTRIBUTE_TYPE_INVALID); 2679 } 2680 2681 default: 2682 /* 2683 * First, get the value of the request attribute defined 2684 * in the list of common key attributes. If the request 2685 * attribute is not found in that list, then get the 2686 * attribute from the list of common attributes. 2687 */ 2688 rv = kernel_get_common_key_attrs(object_p, template); 2689 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) { 2690 rv = kernel_get_common_attrs(object_p, template); 2691 } 2692 break; 2693 } 2694 2695 return (rv); 2696 } 2697 2698 2699 /* 2700 * Get the value of a requested attribute of a Secret Key Object. 2701 * 2702 * Rule: All the attributes in the secret key object can be revealed 2703 * except those marked with footnote number "7" when the object 2704 * has its CKA_SENSITIVE attribute set to TRUE or its 2705 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.). 2706 */ 2707 CK_RV 2708 kernel_get_secret_key_attribute(kernel_object_t *object_p, 2709 CK_ATTRIBUTE_PTR template) 2710 { 2711 2712 CK_RV rv = CKR_OK; 2713 CK_KEY_TYPE keytype = object_p->key_type; 2714 2715 switch (template->type) { 2716 2717 /* Key related boolean attributes */ 2718 case CKA_SENSITIVE: 2719 return (get_bool_attr_from_object(object_p, 2720 SENSITIVE_BOOL_ON, template)); 2721 2722 case CKA_ENCRYPT: 2723 return (get_bool_attr_from_object(object_p, 2724 ENCRYPT_BOOL_ON, template)); 2725 2726 case CKA_DECRYPT: 2727 return (get_bool_attr_from_object(object_p, 2728 DECRYPT_BOOL_ON, template)); 2729 2730 case CKA_SIGN: 2731 return (get_bool_attr_from_object(object_p, 2732 SIGN_BOOL_ON, template)); 2733 2734 case CKA_VERIFY: 2735 return (get_bool_attr_from_object(object_p, 2736 VERIFY_BOOL_ON, template)); 2737 2738 case CKA_WRAP: 2739 return (get_bool_attr_from_object(object_p, 2740 WRAP_BOOL_ON, template)); 2741 2742 case CKA_UNWRAP: 2743 return (get_bool_attr_from_object(object_p, 2744 UNWRAP_BOOL_ON, template)); 2745 2746 case CKA_EXTRACTABLE: 2747 return (get_bool_attr_from_object(object_p, 2748 EXTRACTABLE_BOOL_ON, template)); 2749 2750 case CKA_ALWAYS_SENSITIVE: 2751 return (get_bool_attr_from_object(object_p, 2752 ALWAYS_SENSITIVE_BOOL_ON, template)); 2753 2754 case CKA_NEVER_EXTRACTABLE: 2755 return (get_bool_attr_from_object(object_p, 2756 NEVER_EXTRACTABLE_BOOL_ON, template)); 2757 2758 case CKA_VALUE: 2759 /* 2760 * If the specified attribute for the secret key object 2761 * cannot be revealed because the object is sensitive 2762 * or unextractable, then the ulValueLen is set to -1. 2763 */ 2764 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) || 2765 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) { 2766 template->ulValueLen = (CK_ULONG)-1; 2767 return (CKR_ATTRIBUTE_SENSITIVE); 2768 } 2769 2770 switch (keytype) { 2771 case CKK_RC4: 2772 case CKK_GENERIC_SECRET: 2773 case CKK_RC5: 2774 case CKK_DES: 2775 case CKK_DES2: 2776 case CKK_DES3: 2777 case CKK_CDMF: 2778 case CKK_AES: 2779 case CKK_BLOWFISH: 2780 /* 2781 * Copy secret key object attributes to template. 2782 */ 2783 if (template->pValue == NULL) { 2784 template->ulValueLen = 2785 OBJ_SEC_VALUE_LEN(object_p); 2786 return (CKR_OK); 2787 } 2788 2789 if (OBJ_SEC_VALUE(object_p) == NULL) { 2790 template->ulValueLen = 0; 2791 return (CKR_OK); 2792 } 2793 2794 if (template->ulValueLen >= 2795 OBJ_SEC_VALUE_LEN(object_p)) { 2796 (void) memcpy(template->pValue, 2797 OBJ_SEC_VALUE(object_p), 2798 OBJ_SEC_VALUE_LEN(object_p)); 2799 template->ulValueLen = 2800 OBJ_SEC_VALUE_LEN(object_p); 2801 return (CKR_OK); 2802 } else { 2803 template->ulValueLen = (CK_ULONG)-1; 2804 return (CKR_BUFFER_TOO_SMALL); 2805 } 2806 2807 default: 2808 template->ulValueLen = (CK_ULONG)-1; 2809 rv = CKR_ATTRIBUTE_TYPE_INVALID; 2810 break; 2811 } 2812 break; 2813 2814 case CKA_VALUE_LEN: 2815 return (get_ulong_attr_from_object(OBJ_SEC_VALUE_LEN(object_p), 2816 template)); 2817 2818 default: 2819 /* 2820 * First, get the value of the request attribute defined 2821 * in the list of common key attributes. If the request 2822 * attribute is not found in that list, then get the 2823 * attribute from the list of common attributes. 2824 */ 2825 rv = kernel_get_common_key_attrs(object_p, template); 2826 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) { 2827 rv = kernel_get_common_attrs(object_p, template); 2828 } 2829 break; 2830 } 2831 2832 return (rv); 2833 2834 } 2835 2836 2837 2838 2839 /* 2840 * Call the appropriate get attribute function according to the class 2841 * of object. 2842 * 2843 * The caller of this function holds the lock on the object. 2844 */ 2845 CK_RV 2846 kernel_get_attribute(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template) 2847 { 2848 2849 CK_RV rv = CKR_OK; 2850 CK_OBJECT_CLASS class = object_p->class; 2851 2852 switch (class) { 2853 2854 case CKO_PUBLIC_KEY: 2855 rv = kernel_get_public_key_attribute(object_p, template); 2856 break; 2857 2858 case CKO_PRIVATE_KEY: 2859 rv = kernel_get_private_key_attribute(object_p, template); 2860 break; 2861 2862 case CKO_SECRET_KEY: 2863 rv = kernel_get_secret_key_attribute(object_p, template); 2864 break; 2865 2866 default: 2867 /* 2868 * If the specified attribute for the object is invalid 2869 * (the object does not possess such as attribute), then 2870 * the ulValueLen is modified to hold the value -1. 2871 */ 2872 template->ulValueLen = (CK_ULONG)-1; 2873 return (CKR_ATTRIBUTE_TYPE_INVALID); 2874 } 2875 2876 return (rv); 2877 2878 } 2879 2880 /* 2881 * Set the value of an attribute that is common to all key objects 2882 * (i.e. public key, private key and secret key). 2883 */ 2884 CK_RV 2885 kernel_set_common_key_attribute(kernel_object_t *object_p, 2886 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp) 2887 { 2888 2889 kernel_slot_t *pslot = slot_table[sp->ses_slotid]; 2890 CK_RV rv = CKR_OK; 2891 2892 switch (template->type) { 2893 2894 case CKA_LABEL: 2895 /* 2896 * Only the LABEL can be modified in the common storage 2897 * object attributes after the object is created. 2898 */ 2899 return (set_extra_attr_to_object(object_p, 2900 CKA_LABEL, template)); 2901 2902 case CKA_ID: 2903 return (set_extra_attr_to_object(object_p, 2904 CKA_ID, template)); 2905 2906 case CKA_START_DATE: 2907 return (set_extra_attr_to_object(object_p, 2908 CKA_START_DATE, template)); 2909 2910 case CKA_END_DATE: 2911 return (set_extra_attr_to_object(object_p, 2912 CKA_END_DATE, template)); 2913 2914 case CKA_DERIVE: 2915 return (set_bool_attr_to_object(object_p, 2916 DERIVE_BOOL_ON, template)); 2917 2918 case CKA_CLASS: 2919 case CKA_KEY_TYPE: 2920 case CKA_LOCAL: 2921 return (CKR_ATTRIBUTE_READ_ONLY); 2922 2923 case CKA_PRIVATE: 2924 if (!copy) { 2925 /* called from C_SetAttributeValue() */ 2926 return (CKR_ATTRIBUTE_READ_ONLY); 2927 } 2928 2929 /* called from C_CopyObject() */ 2930 if ((*(CK_BBOOL *)template->pValue) != B_TRUE) { 2931 return (CKR_OK); 2932 } 2933 2934 (void) pthread_mutex_lock(&pslot->sl_mutex); 2935 /* 2936 * Cannot create a private object if the token 2937 * has a keystore and the user isn't logged in. 2938 */ 2939 if (pslot->sl_func_list.fl_object_create && 2940 pslot->sl_state != CKU_USER) { 2941 rv = CKR_USER_NOT_LOGGED_IN; 2942 } else { 2943 rv = set_bool_attr_to_object(object_p, 2944 PRIVATE_BOOL_ON, template); 2945 } 2946 (void) pthread_mutex_unlock(&pslot->sl_mutex); 2947 return (rv); 2948 2949 case CKA_MODIFIABLE: 2950 if (copy) { 2951 rv = set_bool_attr_to_object(object_p, 2952 MODIFIABLE_BOOL_ON, template); 2953 } else { 2954 rv = CKR_ATTRIBUTE_READ_ONLY; 2955 } 2956 return (rv); 2957 2958 default: 2959 return (CKR_TEMPLATE_INCONSISTENT); 2960 } 2961 2962 } 2963 2964 2965 /* 2966 * Set the value of an attribute of a Public Key Object. 2967 * 2968 * Rule: The attributes marked with footnote number "8" in the PKCS11 2969 * spec may be modified (p.88 in PKCS11 spec.). 2970 */ 2971 CK_RV 2972 kernel_set_public_key_attribute(kernel_object_t *object_p, 2973 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp) 2974 { 2975 CK_KEY_TYPE keytype = object_p->key_type; 2976 2977 switch (template->type) { 2978 2979 case CKA_SUBJECT: 2980 return (set_extra_attr_to_object(object_p, 2981 CKA_SUBJECT, template)); 2982 2983 case CKA_ENCRYPT: 2984 return (set_bool_attr_to_object(object_p, 2985 ENCRYPT_BOOL_ON, template)); 2986 2987 case CKA_VERIFY: 2988 return (set_bool_attr_to_object(object_p, 2989 VERIFY_BOOL_ON, template)); 2990 2991 case CKA_VERIFY_RECOVER: 2992 return (set_bool_attr_to_object(object_p, 2993 VERIFY_RECOVER_BOOL_ON, template)); 2994 2995 case CKA_WRAP: 2996 return (set_bool_attr_to_object(object_p, 2997 WRAP_BOOL_ON, template)); 2998 2999 case CKA_MODULUS: 3000 case CKA_MODULUS_BITS: 3001 case CKA_PUBLIC_EXPONENT: 3002 if (keytype == CKK_RSA) 3003 return (CKR_ATTRIBUTE_READ_ONLY); 3004 break; 3005 3006 case CKA_SUBPRIME: 3007 case CKA_PRIME: 3008 case CKA_BASE: 3009 case CKA_VALUE: 3010 if (keytype == CKK_DSA) 3011 return (CKR_ATTRIBUTE_READ_ONLY); 3012 break; 3013 3014 default: 3015 /* 3016 * Set the value of a common key attribute. 3017 */ 3018 return (kernel_set_common_key_attribute(object_p, 3019 template, copy, sp)); 3020 3021 } 3022 3023 /* 3024 * If we got this far, then the combination of key type 3025 * and requested attribute is invalid. 3026 */ 3027 return (CKR_ATTRIBUTE_TYPE_INVALID); 3028 } 3029 3030 3031 /* 3032 * Set the value of an attribute of a Private Key Object. 3033 * 3034 * Rule: The attributes marked with footnote number "8" in the PKCS11 3035 * spec may be modified (p.88 in PKCS11 spec.). 3036 */ 3037 CK_RV 3038 kernel_set_private_key_attribute(kernel_object_t *object_p, 3039 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp) 3040 { 3041 CK_KEY_TYPE keytype = object_p->key_type; 3042 3043 switch (template->type) { 3044 3045 case CKA_SUBJECT: 3046 return (set_extra_attr_to_object(object_p, 3047 CKA_SUBJECT, template)); 3048 3049 case CKA_SENSITIVE: 3050 /* 3051 * Cannot set SENSITIVE to FALSE if it is already ON. 3052 */ 3053 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) && 3054 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) { 3055 return (CKR_ATTRIBUTE_READ_ONLY); 3056 } 3057 3058 if (*(CK_BBOOL *)template->pValue) 3059 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON; 3060 return (CKR_OK); 3061 3062 case CKA_DECRYPT: 3063 return (set_bool_attr_to_object(object_p, 3064 DECRYPT_BOOL_ON, template)); 3065 3066 case CKA_SIGN: 3067 return (set_bool_attr_to_object(object_p, 3068 SIGN_BOOL_ON, template)); 3069 3070 case CKA_SIGN_RECOVER: 3071 return (set_bool_attr_to_object(object_p, 3072 SIGN_RECOVER_BOOL_ON, template)); 3073 3074 case CKA_UNWRAP: 3075 return (set_bool_attr_to_object(object_p, 3076 UNWRAP_BOOL_ON, template)); 3077 3078 case CKA_EXTRACTABLE: 3079 /* 3080 * Cannot set EXTRACTABLE to TRUE if it is already OFF. 3081 */ 3082 if ((*(CK_BBOOL *)template->pValue) && 3083 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) { 3084 return (CKR_ATTRIBUTE_READ_ONLY); 3085 } 3086 3087 if ((*(CK_BBOOL *)template->pValue) == B_FALSE) 3088 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON; 3089 return (CKR_OK); 3090 3091 case CKA_MODULUS: 3092 case CKA_PUBLIC_EXPONENT: 3093 case CKA_PRIVATE_EXPONENT: 3094 case CKA_PRIME_1: 3095 case CKA_PRIME_2: 3096 case CKA_EXPONENT_1: 3097 case CKA_EXPONENT_2: 3098 case CKA_COEFFICIENT: 3099 if (keytype == CKK_RSA) { 3100 return (CKR_ATTRIBUTE_READ_ONLY); 3101 } 3102 break; 3103 3104 case CKA_SUBPRIME: 3105 case CKA_PRIME: 3106 case CKA_BASE: 3107 case CKA_VALUE: 3108 if (keytype == CKK_DSA) 3109 return (CKR_ATTRIBUTE_READ_ONLY); 3110 break; 3111 3112 default: 3113 /* 3114 * Set the value of a common key attribute. 3115 */ 3116 return (kernel_set_common_key_attribute(object_p, 3117 template, copy, sp)); 3118 } 3119 3120 /* 3121 * If we got this far, then the combination of key type 3122 * and requested attribute is invalid. 3123 */ 3124 return (CKR_ATTRIBUTE_TYPE_INVALID); 3125 } 3126 3127 3128 3129 /* 3130 * Set the value of an attribute of a Secret Key Object. 3131 * 3132 * Rule: The attributes marked with footnote number "8" in the PKCS11 3133 * spec may be modified (p.88 in PKCS11 spec.). 3134 */ 3135 CK_RV 3136 kernel_set_secret_key_attribute(kernel_object_t *object_p, 3137 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp) 3138 { 3139 CK_KEY_TYPE keytype = object_p->key_type; 3140 3141 switch (template->type) { 3142 3143 case CKA_SENSITIVE: 3144 /* 3145 * Cannot set SENSITIVE to FALSE if it is already ON. 3146 */ 3147 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) && 3148 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) { 3149 return (CKR_ATTRIBUTE_READ_ONLY); 3150 } 3151 3152 if (*(CK_BBOOL *)template->pValue) 3153 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON; 3154 return (CKR_OK); 3155 3156 case CKA_ENCRYPT: 3157 return (set_bool_attr_to_object(object_p, 3158 ENCRYPT_BOOL_ON, template)); 3159 3160 case CKA_DECRYPT: 3161 return (set_bool_attr_to_object(object_p, 3162 DECRYPT_BOOL_ON, template)); 3163 3164 case CKA_SIGN: 3165 return (set_bool_attr_to_object(object_p, 3166 SIGN_BOOL_ON, template)); 3167 3168 case CKA_VERIFY: 3169 return (set_bool_attr_to_object(object_p, 3170 VERIFY_BOOL_ON, template)); 3171 3172 case CKA_WRAP: 3173 return (set_bool_attr_to_object(object_p, 3174 WRAP_BOOL_ON, template)); 3175 3176 case CKA_UNWRAP: 3177 return (set_bool_attr_to_object(object_p, 3178 UNWRAP_BOOL_ON, template)); 3179 3180 case CKA_EXTRACTABLE: 3181 /* 3182 * Cannot set EXTRACTABLE to TRUE if it is already OFF. 3183 */ 3184 if ((*(CK_BBOOL *)template->pValue) && 3185 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) { 3186 return (CKR_ATTRIBUTE_READ_ONLY); 3187 } 3188 3189 if ((*(CK_BBOOL *)template->pValue) == B_FALSE) 3190 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON; 3191 return (CKR_OK); 3192 3193 case CKA_VALUE: 3194 return (CKR_ATTRIBUTE_READ_ONLY); 3195 3196 case CKA_VALUE_LEN: 3197 if ((keytype == CKK_RC4) || 3198 (keytype == CKK_GENERIC_SECRET) || 3199 (keytype == CKK_AES) || 3200 (keytype == CKK_BLOWFISH)) 3201 return (CKR_ATTRIBUTE_READ_ONLY); 3202 break; 3203 3204 default: 3205 /* 3206 * Set the value of a common key attribute. 3207 */ 3208 return (kernel_set_common_key_attribute(object_p, 3209 template, copy, sp)); 3210 } 3211 3212 /* 3213 * If we got this far, then the combination of key type 3214 * and requested attribute is invalid. 3215 */ 3216 return (CKR_ATTRIBUTE_TYPE_INVALID); 3217 } 3218 3219 3220 /* 3221 * Call the appropriate set attribute function according to the class 3222 * of object. 3223 * 3224 * The caller of this function does not hold the lock on the original 3225 * object, since this function is setting the attribute on the new object 3226 * that is being modified. 3227 * 3228 */ 3229 CK_RV 3230 kernel_set_attribute(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template, 3231 boolean_t copy, kernel_session_t *sp) 3232 { 3233 3234 CK_RV rv = CKR_OK; 3235 CK_OBJECT_CLASS class = object_p->class; 3236 3237 switch (class) { 3238 3239 case CKO_PUBLIC_KEY: 3240 rv = kernel_set_public_key_attribute(object_p, template, 3241 copy, sp); 3242 break; 3243 3244 case CKO_PRIVATE_KEY: 3245 rv = kernel_set_private_key_attribute(object_p, template, 3246 copy, sp); 3247 break; 3248 3249 case CKO_SECRET_KEY: 3250 rv = kernel_set_secret_key_attribute(object_p, template, 3251 copy, sp); 3252 break; 3253 3254 default: 3255 /* 3256 * If the template specifies a value of an attribute 3257 * which is incompatible with other existing attributes 3258 * of the object, then fails with return code 3259 * CKR_TEMPLATE_INCONSISTENT. 3260 */ 3261 rv = CKR_TEMPLATE_INCONSISTENT; 3262 break; 3263 } 3264 3265 return (rv); 3266 } 3267 3268 3269 static CK_RV 3270 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint) 3271 { 3272 new_bigint->big_value = 3273 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len)); 3274 3275 if (new_bigint->big_value == NULL) { 3276 return (CKR_HOST_MEMORY); 3277 } 3278 3279 (void) memcpy(new_bigint->big_value, old_bigint->big_value, 3280 (sizeof (CK_BYTE) * new_bigint->big_value_len)); 3281 3282 return (CKR_OK); 3283 } 3284 3285 static void 3286 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type) 3287 { 3288 if (pbk == NULL) { 3289 return; 3290 } 3291 3292 switch (key_type) { 3293 case CKK_RSA: 3294 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk)); 3295 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk)); 3296 break; 3297 case CKK_DSA: 3298 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk)); 3299 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk)); 3300 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk)); 3301 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk)); 3302 break; 3303 default: 3304 break; 3305 } 3306 free(pbk); 3307 } 3308 3309 3310 CK_RV 3311 kernel_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p, 3312 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type) 3313 { 3314 3315 public_key_obj_t *pbk; 3316 CK_RV rv = CKR_OK; 3317 3318 pbk = calloc(1, sizeof (public_key_obj_t)); 3319 if (pbk == NULL) { 3320 return (CKR_HOST_MEMORY); 3321 } 3322 3323 switch (key_type) { 3324 case CKK_RSA: 3325 (void) memcpy(KEY_PUB_RSA(pbk), 3326 KEY_PUB_RSA(old_pub_key_obj_p), 3327 sizeof (rsa_pub_key_t)); 3328 /* copy modulus */ 3329 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk), 3330 KEY_PUB_RSA_MOD(old_pub_key_obj_p)); 3331 if (rv != CKR_OK) { 3332 free_public_key_attr(pbk, key_type); 3333 return (rv); 3334 } 3335 /* copy public exponent */ 3336 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk), 3337 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p)); 3338 if (rv != CKR_OK) { 3339 free_public_key_attr(pbk, key_type); 3340 return (rv); 3341 } 3342 break; 3343 case CKK_DSA: 3344 (void) memcpy(KEY_PUB_DSA(pbk), 3345 KEY_PUB_DSA(old_pub_key_obj_p), 3346 sizeof (dsa_pub_key_t)); 3347 3348 /* copy prime */ 3349 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk), 3350 KEY_PUB_DSA_PRIME(old_pub_key_obj_p)); 3351 if (rv != CKR_OK) { 3352 free_public_key_attr(pbk, key_type); 3353 return (rv); 3354 } 3355 3356 /* copy subprime */ 3357 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk), 3358 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p)); 3359 if (rv != CKR_OK) { 3360 free_public_key_attr(pbk, key_type); 3361 return (rv); 3362 } 3363 3364 /* copy base */ 3365 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk), 3366 KEY_PUB_DSA_BASE(old_pub_key_obj_p)); 3367 if (rv != CKR_OK) { 3368 free_public_key_attr(pbk, key_type); 3369 return (rv); 3370 } 3371 3372 /* copy value */ 3373 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk), 3374 KEY_PUB_DSA_VALUE(old_pub_key_obj_p)); 3375 if (rv != CKR_OK) { 3376 free_public_key_attr(pbk, key_type); 3377 return (rv); 3378 } 3379 break; 3380 default: 3381 break; 3382 } 3383 *new_pub_key_obj_p = pbk; 3384 return (rv); 3385 } 3386 3387 3388 static void 3389 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type) 3390 { 3391 if (pbk == NULL) { 3392 return; 3393 } 3394 3395 switch (key_type) { 3396 case CKK_RSA: 3397 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk)); 3398 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk)); 3399 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk)); 3400 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk)); 3401 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk)); 3402 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk)); 3403 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk)); 3404 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk)); 3405 break; 3406 case CKK_DSA: 3407 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk)); 3408 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk)); 3409 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk)); 3410 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk)); 3411 break; 3412 default: 3413 break; 3414 } 3415 free(pbk); 3416 } 3417 3418 CK_RV 3419 kernel_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p, 3420 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type) 3421 { 3422 CK_RV rv = CKR_OK; 3423 private_key_obj_t *pbk; 3424 3425 pbk = calloc(1, sizeof (private_key_obj_t)); 3426 if (pbk == NULL) { 3427 return (CKR_HOST_MEMORY); 3428 } 3429 3430 switch (key_type) { 3431 case CKK_RSA: 3432 (void) memcpy(KEY_PRI_RSA(pbk), 3433 KEY_PRI_RSA(old_pri_key_obj_p), 3434 sizeof (rsa_pri_key_t)); 3435 /* copy modulus */ 3436 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk), 3437 KEY_PRI_RSA_MOD(old_pri_key_obj_p)); 3438 if (rv != CKR_OK) { 3439 free_private_key_attr(pbk, key_type); 3440 return (rv); 3441 } 3442 /* copy public exponent */ 3443 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk), 3444 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p)); 3445 if (rv != CKR_OK) { 3446 free_private_key_attr(pbk, key_type); 3447 return (rv); 3448 } 3449 /* copy private exponent */ 3450 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk), 3451 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p)); 3452 if (rv != CKR_OK) { 3453 free_private_key_attr(pbk, key_type); 3454 return (rv); 3455 } 3456 /* copy prime_1 */ 3457 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk), 3458 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p)); 3459 if (rv != CKR_OK) { 3460 free_private_key_attr(pbk, key_type); 3461 return (rv); 3462 } 3463 /* copy prime_2 */ 3464 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk), 3465 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p)); 3466 if (rv != CKR_OK) { 3467 free_private_key_attr(pbk, key_type); 3468 return (rv); 3469 } 3470 /* copy exponent_1 */ 3471 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk), 3472 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p)); 3473 if (rv != CKR_OK) { 3474 free_private_key_attr(pbk, key_type); 3475 return (rv); 3476 } 3477 /* copy exponent_2 */ 3478 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk), 3479 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p)); 3480 if (rv != CKR_OK) { 3481 free_private_key_attr(pbk, key_type); 3482 return (rv); 3483 } 3484 /* copy coefficient */ 3485 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk), 3486 KEY_PRI_RSA_COEF(old_pri_key_obj_p)); 3487 if (rv != CKR_OK) { 3488 free_private_key_attr(pbk, key_type); 3489 return (rv); 3490 } 3491 break; 3492 case CKK_DSA: 3493 (void) memcpy(KEY_PRI_DSA(pbk), 3494 KEY_PRI_DSA(old_pri_key_obj_p), 3495 sizeof (dsa_pri_key_t)); 3496 3497 /* copy prime */ 3498 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk), 3499 KEY_PRI_DSA_PRIME(old_pri_key_obj_p)); 3500 if (rv != CKR_OK) { 3501 free_private_key_attr(pbk, key_type); 3502 return (rv); 3503 } 3504 3505 /* copy subprime */ 3506 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk), 3507 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p)); 3508 if (rv != CKR_OK) { 3509 free_private_key_attr(pbk, key_type); 3510 return (rv); 3511 } 3512 3513 /* copy base */ 3514 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk), 3515 KEY_PRI_DSA_BASE(old_pri_key_obj_p)); 3516 if (rv != CKR_OK) { 3517 free_private_key_attr(pbk, key_type); 3518 return (rv); 3519 } 3520 3521 /* copy value */ 3522 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk), 3523 KEY_PRI_DSA_VALUE(old_pri_key_obj_p)); 3524 if (rv != CKR_OK) { 3525 free_private_key_attr(pbk, key_type); 3526 return (rv); 3527 } 3528 break; 3529 default: 3530 break; 3531 } 3532 *new_pri_key_obj_p = pbk; 3533 return (rv); 3534 } 3535 3536 3537 CK_RV 3538 kernel_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p, 3539 secret_key_obj_t **new_secret_key_obj_p) 3540 { 3541 secret_key_obj_t *sk; 3542 3543 sk = malloc(sizeof (secret_key_obj_t)); 3544 if (sk == NULL) { 3545 return (CKR_HOST_MEMORY); 3546 } 3547 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t)); 3548 3549 /* copy the secret key value */ 3550 sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len)); 3551 if (sk->sk_value == NULL) { 3552 free(sk); 3553 return (CKR_HOST_MEMORY); 3554 } 3555 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value, 3556 (sizeof (CK_BYTE) * sk->sk_value_len)); 3557 3558 *new_secret_key_obj_p = sk; 3559 3560 return (CKR_OK); 3561 } 3562 3563 3564 3565 /* 3566 * If CKA_CLASS not given, guess CKA_CLASS using 3567 * attributes on template . 3568 * 3569 * Some attributes are specific to an object class. If one or more 3570 * of these attributes are in the template, make a list of classes 3571 * that can have these attributes. This would speed up the search later, 3572 * because we can immediately skip an object if the class of that 3573 * object can not possibly contain one of the attributes. 3574 * 3575 */ 3576 void 3577 kernel_process_find_attr(CK_OBJECT_CLASS *pclasses, 3578 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate, 3579 CK_ULONG ulCount) 3580 { 3581 ulong_t i; 3582 int j; 3583 boolean_t pub_found = B_FALSE, 3584 priv_found = B_FALSE, 3585 secret_found = B_FALSE, 3586 domain_found = B_FALSE, 3587 hardware_found = B_FALSE, 3588 cert_found = B_FALSE; 3589 int num_pub_key_attrs, num_priv_key_attrs, 3590 num_secret_key_attrs, num_domain_attrs, 3591 num_hardware_attrs, num_cert_attrs; 3592 int num_pclasses = 0; 3593 3594 for (i = 0; i < ulCount; i++) { 3595 if (pTemplate[i].type == CKA_CLASS) { 3596 /* 3597 * don't need to guess the class, it is specified. 3598 * Just record the class, and return. 3599 */ 3600 pclasses[0] = 3601 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue)); 3602 *num_result_pclasses = 1; 3603 return; 3604 } 3605 } 3606 3607 num_pub_key_attrs = 3608 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE); 3609 num_priv_key_attrs = 3610 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE); 3611 num_secret_key_attrs = 3612 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE); 3613 num_domain_attrs = 3614 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE); 3615 num_hardware_attrs = 3616 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE); 3617 num_cert_attrs = 3618 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE); 3619 3620 /* 3621 * Get the list of objects class that might contain 3622 * some attributes. 3623 */ 3624 for (i = 0; i < ulCount; i++) { 3625 /* 3626 * only check if this attribute can belong to public key object 3627 * class if public key object isn't already in the list 3628 */ 3629 if (!pub_found) { 3630 for (j = 0; j < num_pub_key_attrs; j++) { 3631 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) { 3632 pub_found = B_TRUE; 3633 pclasses[num_pclasses++] = 3634 CKO_PUBLIC_KEY; 3635 break; 3636 } 3637 } 3638 } 3639 3640 if (!priv_found) { 3641 for (j = 0; j < num_priv_key_attrs; j++) { 3642 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) { 3643 priv_found = B_TRUE; 3644 pclasses[num_pclasses++] = 3645 CKO_PRIVATE_KEY; 3646 break; 3647 } 3648 } 3649 } 3650 3651 if (!secret_found) { 3652 for (j = 0; j < num_secret_key_attrs; j++) { 3653 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) { 3654 secret_found = B_TRUE; 3655 pclasses[num_pclasses++] = 3656 CKO_SECRET_KEY; 3657 break; 3658 } 3659 } 3660 } 3661 3662 if (!domain_found) { 3663 for (j = 0; j < num_domain_attrs; j++) { 3664 if (pTemplate[i].type == DOMAIN_ATTRS[j]) { 3665 domain_found = B_TRUE; 3666 pclasses[num_pclasses++] = 3667 CKO_DOMAIN_PARAMETERS; 3668 break; 3669 } 3670 } 3671 } 3672 3673 if (!hardware_found) { 3674 for (j = 0; j < num_hardware_attrs; j++) { 3675 if (pTemplate[i].type == HARDWARE_ATTRS[j]) { 3676 hardware_found = B_TRUE; 3677 pclasses[num_pclasses++] = 3678 CKO_HW_FEATURE; 3679 break; 3680 } 3681 } 3682 } 3683 3684 if (!cert_found) { 3685 for (j = 0; j < num_cert_attrs; j++) { 3686 if (pTemplate[i].type == CERT_ATTRS[j]) { 3687 cert_found = B_TRUE; 3688 pclasses[num_pclasses++] = 3689 CKO_CERTIFICATE; 3690 break; 3691 } 3692 } 3693 } 3694 } 3695 *num_result_pclasses = num_pclasses; 3696 } 3697 3698 3699 boolean_t 3700 kernel_find_match_attrs(kernel_object_t *obj, CK_OBJECT_CLASS *pclasses, 3701 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr) 3702 { 3703 ulong_t i; 3704 CK_ATTRIBUTE *tmpl_attr, *obj_attr; 3705 uint64_t attr_mask; 3706 biginteger_t *bigint; 3707 boolean_t compare_attr, compare_bigint, compare_boolean; 3708 3709 /* 3710 * Check if the class of this object match with any 3711 * of object classes that can possibly contain the 3712 * requested attributes. 3713 */ 3714 if (num_pclasses > 0) { 3715 for (i = 0; i < num_pclasses; i++) { 3716 if (obj->class == pclasses[i]) { 3717 break; 3718 } 3719 } 3720 if (i == num_pclasses) { 3721 /* 3722 * this object can't possibly contain one or 3723 * more attributes, don't need to check this object 3724 */ 3725 return (B_FALSE); 3726 } 3727 } 3728 3729 /* need to examine everything */ 3730 for (i = 0; i < num_attr; i++) { 3731 tmpl_attr = &(template[i]); 3732 compare_attr = B_FALSE; 3733 compare_bigint = B_FALSE; 3734 compare_boolean = B_FALSE; 3735 switch (tmpl_attr->type) { 3736 /* First, check the most common attributes */ 3737 case CKA_CLASS: 3738 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) != 3739 obj->class) { 3740 return (B_FALSE); 3741 } 3742 break; 3743 case CKA_KEY_TYPE: 3744 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) != 3745 obj->key_type) { 3746 return (B_FALSE); 3747 } 3748 break; 3749 case CKA_ENCRYPT: 3750 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON; 3751 compare_boolean = B_TRUE; 3752 break; 3753 case CKA_DECRYPT: 3754 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON; 3755 compare_boolean = B_TRUE; 3756 break; 3757 case CKA_WRAP: 3758 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON; 3759 compare_boolean = B_TRUE; 3760 break; 3761 case CKA_UNWRAP: 3762 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON; 3763 compare_boolean = B_TRUE; 3764 break; 3765 case CKA_SIGN: 3766 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON; 3767 compare_boolean = B_TRUE; 3768 break; 3769 case CKA_SIGN_RECOVER: 3770 attr_mask = (obj->bool_attr_mask) & 3771 SIGN_RECOVER_BOOL_ON; 3772 compare_boolean = B_TRUE; 3773 break; 3774 case CKA_VERIFY: 3775 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON; 3776 compare_boolean = B_TRUE; 3777 break; 3778 case CKA_VERIFY_RECOVER: 3779 attr_mask = (obj->bool_attr_mask) & 3780 VERIFY_RECOVER_BOOL_ON; 3781 compare_boolean = B_TRUE; 3782 break; 3783 case CKA_DERIVE: 3784 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON; 3785 compare_boolean = B_TRUE; 3786 break; 3787 case CKA_LOCAL: 3788 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON; 3789 compare_boolean = B_TRUE; 3790 break; 3791 case CKA_SENSITIVE: 3792 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON; 3793 compare_boolean = B_TRUE; 3794 break; 3795 case CKA_SECONDARY_AUTH: 3796 attr_mask = (obj->bool_attr_mask) & 3797 SECONDARY_AUTH_BOOL_ON; 3798 compare_boolean = B_TRUE; 3799 break; 3800 case CKA_TRUSTED: 3801 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON; 3802 compare_boolean = B_TRUE; 3803 break; 3804 case CKA_EXTRACTABLE: 3805 attr_mask = (obj->bool_attr_mask) & 3806 EXTRACTABLE_BOOL_ON; 3807 compare_boolean = B_TRUE; 3808 break; 3809 case CKA_ALWAYS_SENSITIVE: 3810 attr_mask = (obj->bool_attr_mask) & 3811 ALWAYS_SENSITIVE_BOOL_ON; 3812 compare_boolean = B_TRUE; 3813 break; 3814 case CKA_NEVER_EXTRACTABLE: 3815 attr_mask = (obj->bool_attr_mask) & 3816 NEVER_EXTRACTABLE_BOOL_ON; 3817 compare_boolean = B_TRUE; 3818 break; 3819 case CKA_TOKEN: 3820 /* 3821 * CKA_TOKEN value is not applicable to an object 3822 * created in the library, it should only contain 3823 * the default value FALSE 3824 */ 3825 attr_mask = 0; 3826 compare_boolean = B_TRUE; 3827 break; 3828 case CKA_PRIVATE: 3829 attr_mask = (obj->bool_attr_mask) & PRIVATE_BOOL_ON; 3830 compare_boolean = B_TRUE; 3831 break; 3832 case CKA_MODIFIABLE: 3833 attr_mask = (obj->bool_attr_mask) & MODIFIABLE_BOOL_ON; 3834 compare_boolean = B_TRUE; 3835 break; 3836 case CKA_SUBJECT: 3837 case CKA_ID: 3838 case CKA_START_DATE: 3839 case CKA_END_DATE: 3840 case CKA_KEY_GEN_MECHANISM: 3841 case CKA_LABEL: 3842 /* find these attributes from extra_attrlistp */ 3843 obj_attr = get_extra_attr(tmpl_attr->type, obj); 3844 compare_attr = B_TRUE; 3845 break; 3846 case CKA_VALUE_LEN: 3847 /* only secret key has this attribute */ 3848 if (obj->class == CKO_SECRET_KEY) { 3849 if (*((CK_ULONG *)tmpl_attr->pValue) != 3850 OBJ_SEC_VALUE_LEN(obj)) { 3851 return (B_FALSE); 3852 } 3853 } else { 3854 return (B_FALSE); 3855 } 3856 break; 3857 case CKA_VALUE: 3858 switch (obj->class) { 3859 case CKO_SECRET_KEY: 3860 /* 3861 * secret_key_obj_t is the same as 3862 * biginteger_t 3863 */ 3864 bigint = (biginteger_t *)OBJ_SEC(obj); 3865 break; 3866 case CKO_PRIVATE_KEY: 3867 if (obj->key_type == CKK_DSA) { 3868 bigint = OBJ_PRI_DSA_VALUE(obj); 3869 } else { 3870 return (B_FALSE); 3871 } 3872 break; 3873 case CKO_PUBLIC_KEY: 3874 if (obj->key_type == CKK_DSA) { 3875 bigint = OBJ_PUB_DSA_VALUE(obj); 3876 } else { 3877 return (B_FALSE); 3878 } 3879 break; 3880 default: 3881 return (B_FALSE); 3882 } 3883 compare_bigint = B_TRUE; 3884 break; 3885 case CKA_MODULUS: 3886 /* only RSA public and private key have this attr */ 3887 if (obj->key_type == CKK_RSA) { 3888 if (obj->class == CKO_PUBLIC_KEY) { 3889 bigint = OBJ_PUB_RSA_MOD(obj); 3890 } else if (obj->class == CKO_PRIVATE_KEY) { 3891 bigint = OBJ_PRI_RSA_MOD(obj); 3892 } else { 3893 return (B_FALSE); 3894 } 3895 compare_bigint = B_TRUE; 3896 } else { 3897 return (B_FALSE); 3898 } 3899 break; 3900 case CKA_MODULUS_BITS: 3901 /* only RSA public key has this attribute */ 3902 if ((obj->key_type == CKK_RSA) && 3903 (obj->class == CKO_PUBLIC_KEY)) { 3904 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj); 3905 if (mod_bits != 3906 *((CK_ULONG *)tmpl_attr->pValue)) { 3907 return (B_FALSE); 3908 } 3909 } else { 3910 return (B_FALSE); 3911 } 3912 break; 3913 case CKA_PUBLIC_EXPONENT: 3914 /* only RSA public and private key have this attr */ 3915 if (obj->key_type == CKK_RSA) { 3916 if (obj->class == CKO_PUBLIC_KEY) { 3917 bigint = OBJ_PUB_RSA_PUBEXPO(obj); 3918 } else if (obj->class == CKO_PRIVATE_KEY) { 3919 bigint = OBJ_PRI_RSA_PUBEXPO(obj); 3920 } else { 3921 return (B_FALSE); 3922 } 3923 compare_bigint = B_TRUE; 3924 } else { 3925 return (B_FALSE); 3926 } 3927 break; 3928 case CKA_PRIVATE_EXPONENT: 3929 /* only RSA private key has this attribute */ 3930 if ((obj->key_type == CKK_RSA) && 3931 (obj->class == CKO_PRIVATE_KEY)) { 3932 bigint = OBJ_PRI_RSA_PRIEXPO(obj); 3933 compare_bigint = B_TRUE; 3934 } else { 3935 return (B_FALSE); 3936 } 3937 break; 3938 case CKA_PRIME_1: 3939 /* only RSA private key has this attribute */ 3940 if ((obj->key_type == CKK_RSA) && 3941 (obj->class == CKO_PRIVATE_KEY)) { 3942 bigint = OBJ_PRI_RSA_PRIME1(obj); 3943 compare_bigint = B_TRUE; 3944 } else { 3945 return (B_FALSE); 3946 } 3947 break; 3948 case CKA_PRIME_2: 3949 /* only RSA private key has this attribute */ 3950 if ((obj->key_type == CKK_RSA) && 3951 (obj->class == CKO_PRIVATE_KEY)) { 3952 bigint = OBJ_PRI_RSA_PRIME2(obj); 3953 compare_bigint = B_TRUE; 3954 } else { 3955 return (B_FALSE); 3956 } 3957 break; 3958 case CKA_EXPONENT_1: 3959 /* only RSA private key has this attribute */ 3960 if ((obj->key_type == CKK_RSA) && 3961 (obj->class == CKO_PRIVATE_KEY)) { 3962 bigint = OBJ_PRI_RSA_EXPO1(obj); 3963 compare_bigint = B_TRUE; 3964 } else { 3965 return (B_FALSE); 3966 } 3967 break; 3968 case CKA_EXPONENT_2: 3969 /* only RSA private key has this attribute */ 3970 if ((obj->key_type == CKK_RSA) && 3971 (obj->class == CKO_PRIVATE_KEY)) { 3972 bigint = OBJ_PRI_RSA_EXPO2(obj); 3973 compare_bigint = B_TRUE; 3974 } else { 3975 return (B_FALSE); 3976 } 3977 break; 3978 case CKA_COEFFICIENT: 3979 /* only RSA private key has this attribute */ 3980 if ((obj->key_type == CKK_RSA) && 3981 (obj->class == CKO_PRIVATE_KEY)) { 3982 bigint = OBJ_PRI_RSA_COEF(obj); 3983 compare_bigint = B_TRUE; 3984 } else { 3985 return (B_FALSE); 3986 } 3987 break; 3988 case CKA_VALUE_BITS: 3989 return (B_FALSE); 3990 case CKA_PRIME: 3991 if (obj->class == CKO_PUBLIC_KEY) { 3992 switch (obj->key_type) { 3993 case CKK_DSA: 3994 bigint = OBJ_PUB_DSA_PRIME(obj); 3995 break; 3996 default: 3997 return (B_FALSE); 3998 } 3999 } else if (obj->class == CKO_PRIVATE_KEY) { 4000 switch (obj->key_type) { 4001 case CKK_DSA: 4002 bigint = OBJ_PRI_DSA_PRIME(obj); 4003 break; 4004 default: 4005 return (B_FALSE); 4006 } 4007 } else { 4008 return (B_FALSE); 4009 } 4010 compare_bigint = B_TRUE; 4011 break; 4012 case CKA_SUBPRIME: 4013 if (obj->class == CKO_PUBLIC_KEY) { 4014 switch (obj->key_type) { 4015 case CKK_DSA: 4016 bigint = OBJ_PUB_DSA_SUBPRIME(obj); 4017 break; 4018 default: 4019 return (B_FALSE); 4020 } 4021 } else if (obj->class == CKO_PRIVATE_KEY) { 4022 switch (obj->key_type) { 4023 case CKK_DSA: 4024 bigint = OBJ_PRI_DSA_SUBPRIME(obj); 4025 break; 4026 default: 4027 return (B_FALSE); 4028 } 4029 } else { 4030 return (B_FALSE); 4031 } 4032 compare_bigint = B_TRUE; 4033 break; 4034 case CKA_BASE: 4035 if (obj->class == CKO_PUBLIC_KEY) { 4036 switch (obj->key_type) { 4037 case CKK_DSA: 4038 bigint = OBJ_PUB_DSA_BASE(obj); 4039 break; 4040 default: 4041 return (B_FALSE); 4042 } 4043 } else if (obj->class == CKO_PRIVATE_KEY) { 4044 switch (obj->key_type) { 4045 case CKK_DSA: 4046 bigint = OBJ_PRI_DSA_BASE(obj); 4047 break; 4048 default: 4049 return (B_FALSE); 4050 } 4051 } else { 4052 return (B_FALSE); 4053 } 4054 compare_bigint = B_TRUE; 4055 break; 4056 case CKA_PRIME_BITS: 4057 return (B_FALSE); 4058 case CKA_SUBPRIME_BITS: 4059 return (B_FALSE); 4060 default: 4061 /* 4062 * any other attributes are currently not supported. 4063 * so, it's not possible for them to be in the 4064 * object 4065 */ 4066 return (B_FALSE); 4067 } 4068 if (compare_boolean) { 4069 CK_BBOOL bval; 4070 4071 if (attr_mask) { 4072 bval = TRUE; 4073 } else { 4074 bval = FALSE; 4075 } 4076 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) { 4077 return (B_FALSE); 4078 } 4079 } else if (compare_bigint) { 4080 if (bigint == NULL) { 4081 return (B_FALSE); 4082 } 4083 if (tmpl_attr->ulValueLen != bigint->big_value_len) { 4084 return (B_FALSE); 4085 } 4086 if (memcmp(tmpl_attr->pValue, bigint->big_value, 4087 tmpl_attr->ulValueLen) != 0) { 4088 return (B_FALSE); 4089 } 4090 } else if (compare_attr) { 4091 if (obj_attr == NULL) { 4092 /* 4093 * The attribute type is valid, and its value 4094 * has not been initialized in the object. In 4095 * this case, it only matches the template's 4096 * attribute if the template's value length 4097 * is 0. 4098 */ 4099 if (tmpl_attr->ulValueLen != 0) 4100 return (B_FALSE); 4101 } else { 4102 if (tmpl_attr->ulValueLen != 4103 obj_attr->ulValueLen) { 4104 return (B_FALSE); 4105 } 4106 if (memcmp(tmpl_attr->pValue, obj_attr->pValue, 4107 tmpl_attr->ulValueLen) != 0) { 4108 return (B_FALSE); 4109 } 4110 } 4111 } 4112 } 4113 return (B_TRUE); 4114 } 4115 4116 CK_ATTRIBUTE_PTR 4117 get_extra_attr(CK_ATTRIBUTE_TYPE type, kernel_object_t *obj) 4118 { 4119 CK_ATTRIBUTE_INFO_PTR tmp; 4120 4121 tmp = obj->extra_attrlistp; 4122 while (tmp != NULL) { 4123 if (tmp->attr.type == type) { 4124 return (&(tmp->attr)); 4125 } 4126 tmp = tmp->next; 4127 } 4128 /* if get there, the specified attribute is not found */ 4129 return (NULL); 4130 } 4131