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