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