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