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