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