1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2018, Joyent, Inc. 24 */ 25 26 #include <stdlib.h> 27 #include <string.h> 28 #include <strings.h> 29 #include <stdio.h> 30 #include <cryptoutil.h> 31 #include <errno.h> 32 #include <security/cryptoki.h> 33 #include <sys/crypto/common.h> 34 #include <sys/crypto/ioctl.h> 35 #include "kernelGlobal.h" 36 #include "kernelObject.h" 37 #include "kernelSlot.h" 38 39 #define ENCODE_ATTR(type, value, len) { \ 40 cur_attr->oa_type = type; \ 41 (void) memcpy(ptr, value, len); \ 42 cur_attr->oa_value = ptr; \ 43 cur_attr->oa_value_len = len; \ 44 cur_attr++; \ 45 } 46 47 #define MECH_HASH(type) (((uintptr_t)type) % KMECH_HASHTABLE_SIZE) 48 /* 49 * Serialize writes to the hash table. We don't need a per bucket lock as 50 * there are only a few writes and we don't need the lock for reads. 51 */ 52 pthread_mutex_t mechhash_mutex = PTHREAD_MUTEX_INITIALIZER; 53 54 static CK_RV 55 kmech_hash_insert(CK_MECHANISM_TYPE type, crypto_mech_type_t kmech) 56 { 57 uint_t h; 58 kmh_elem_t *elem, *cur; 59 60 elem = malloc(sizeof (kmh_elem_t)); 61 if (elem == NULL) 62 return (CKR_HOST_MEMORY); 63 64 h = MECH_HASH(type); 65 elem->type = type; 66 elem->kmech = kmech; 67 68 (void) pthread_mutex_lock(&mechhash_mutex); 69 for (cur = kernel_mechhash[h]; cur != NULL; cur = cur->knext) { 70 if (type == cur->type) { 71 /* Some other thread beat us to it. */ 72 (void) pthread_mutex_unlock(&mechhash_mutex); 73 free(elem); 74 return (CKR_OK); 75 } 76 } 77 elem->knext = kernel_mechhash[h]; 78 kernel_mechhash[h] = elem; 79 (void) pthread_mutex_unlock(&mechhash_mutex); 80 81 return (CKR_OK); 82 } 83 84 CK_RV 85 kernel_mech(CK_MECHANISM_TYPE type, crypto_mech_type_t *k_number) 86 { 87 crypto_get_mechanism_number_t get_number; 88 const char *string; 89 CK_RV rv; 90 int r; 91 kmh_elem_t *elem; 92 uint_t h; 93 char buf[11]; /* Num chars for representing ulong in ASCII */ 94 95 /* 96 * Search for an existing entry. No need to lock since we are 97 * just a reader and we never free the entries in the hash table. 98 */ 99 h = MECH_HASH(type); 100 for (elem = kernel_mechhash[h]; elem != NULL; elem = elem->knext) { 101 if (type == elem->type) { 102 *k_number = elem->kmech; 103 return (CKR_OK); 104 } 105 } 106 107 if (type >= CKM_VENDOR_DEFINED) { 108 (void) snprintf(buf, sizeof (buf), "%#lx", type); 109 string = buf; 110 } else { 111 string = pkcs11_mech2str(type); 112 } 113 114 if (string == NULL) 115 return (CKR_MECHANISM_INVALID); 116 117 get_number.pn_mechanism_string = (char *)string; 118 get_number.pn_mechanism_len = strlen(string) + 1; 119 120 while ((r = ioctl(kernel_fd, CRYPTO_GET_MECHANISM_NUMBER, 121 &get_number)) < 0) { 122 if (errno != EINTR) 123 break; 124 } 125 if (r < 0) { 126 rv = CKR_MECHANISM_INVALID; 127 } else { 128 if (get_number.pn_return_value != CRYPTO_SUCCESS) { 129 rv = crypto2pkcs11_error_number( 130 get_number.pn_return_value); 131 } else { 132 rv = CKR_OK; 133 } 134 } 135 136 if (rv == CKR_OK) { 137 *k_number = get_number.pn_internal_number; 138 /* Add this to the hash table */ 139 (void) kmech_hash_insert(type, *k_number); 140 } 141 142 return (rv); 143 } 144 145 146 /* 147 * Return the value of a secret key object. 148 * This routine allocates memory for the value. 149 * A null pointer is returned on error. 150 */ 151 unsigned char * 152 get_symmetric_key_value(kernel_object_t *key_p) 153 { 154 uint8_t *cipherKey; 155 156 switch (key_p->class) { 157 158 case CKO_SECRET_KEY: 159 160 cipherKey = malloc(OBJ_SEC(key_p)->sk_value_len); 161 if (cipherKey == NULL) 162 return (NULL); 163 164 (void) memcpy(cipherKey, OBJ_SEC(key_p)->sk_value, 165 OBJ_SEC(key_p)->sk_value_len); 166 167 return (cipherKey); 168 169 default: 170 return (NULL); 171 } 172 } 173 174 /* 175 * Convert a RSA private key object into a crypto_key structure. 176 * Memory is allocated for each attribute stored in the crypto_key 177 * structure. Memory for the crypto_key structure is not 178 * allocated. Attributes can be freed by free_key_attributes(). 179 */ 180 CK_RV 181 get_rsa_private_key(kernel_object_t *object_p, crypto_key_t *key) 182 { 183 biginteger_t *big; 184 crypto_object_attribute_t *attrs, *cur_attr; 185 char *ptr; 186 CK_RV rv; 187 188 (void) pthread_mutex_lock(&object_p->object_mutex); 189 if (object_p->key_type != CKK_RSA || 190 object_p->class != CKO_PRIVATE_KEY) { 191 (void) pthread_mutex_unlock(&object_p->object_mutex); 192 return (CKR_ATTRIBUTE_TYPE_INVALID); 193 } 194 195 attrs = calloc(1, 196 RSA_PRI_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 197 if (attrs == NULL) { 198 (void) pthread_mutex_unlock(&object_p->object_mutex); 199 return (CKR_HOST_MEMORY); 200 } 201 202 key->ck_format = CRYPTO_KEY_ATTR_LIST; 203 key->ck_attrs = attrs; 204 cur_attr = attrs; 205 206 /* 207 * Allocate memory for each key attribute and set up the value 208 * value length. 209 */ 210 key->ck_count = 0; 211 212 /* CKA_MODULUS is required. */ 213 big = OBJ_PRI_RSA_MOD(object_p); 214 if (big->big_value == NULL) { 215 rv = CKR_ATTRIBUTE_TYPE_INVALID; 216 goto fail_cleanup; 217 } else { 218 if ((ptr = malloc(big->big_value_len)) == NULL) { 219 rv = CKR_HOST_MEMORY; 220 goto fail_cleanup; 221 } 222 ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len); 223 key->ck_count++; 224 } 225 226 /* CKA_PRIVATE_EXPONENT is required. */ 227 big = OBJ_PRI_RSA_PRIEXPO(object_p); 228 if (big->big_value == NULL) { 229 rv = CKR_ATTRIBUTE_TYPE_INVALID; 230 goto fail_cleanup; 231 } else { 232 if ((ptr = malloc(big->big_value_len)) == NULL) { 233 rv = CKR_HOST_MEMORY; 234 goto fail_cleanup; 235 } 236 ENCODE_ATTR(CKA_PRIVATE_EXPONENT, big->big_value, 237 big->big_value_len); 238 key->ck_count++; 239 } 240 241 /* CKA_PRIME_1 is optional. */ 242 big = OBJ_PRI_RSA_PRIME1(object_p); 243 if (big->big_value != NULL) { 244 if ((ptr = malloc(big->big_value_len)) == NULL) { 245 rv = CKR_HOST_MEMORY; 246 goto fail_cleanup; 247 } 248 ENCODE_ATTR(CKA_PRIME_1, big->big_value, big->big_value_len); 249 key->ck_count++; 250 } 251 252 /* CKA_PRIME_2 is optional. */ 253 big = OBJ_PRI_RSA_PRIME2(object_p); 254 if (big->big_value != NULL) { 255 if ((ptr = malloc(big->big_value_len)) == NULL) { 256 rv = CKR_HOST_MEMORY; 257 goto fail_cleanup; 258 } 259 ENCODE_ATTR(CKA_PRIME_2, big->big_value, big->big_value_len); 260 key->ck_count++; 261 } 262 263 /* CKA_EXPONENT_1 is optional. */ 264 big = OBJ_PRI_RSA_EXPO1(object_p); 265 if (big->big_value != NULL) { 266 if ((ptr = malloc(big->big_value_len)) == NULL) { 267 rv = CKR_HOST_MEMORY; 268 goto fail_cleanup; 269 } 270 ENCODE_ATTR(CKA_EXPONENT_1, big->big_value, 271 big->big_value_len); 272 key->ck_count++; 273 } 274 275 /* CKA_EXPONENT_2 is optional. */ 276 big = OBJ_PRI_RSA_EXPO2(object_p); 277 if (big->big_value != NULL) { 278 if ((ptr = malloc(big->big_value_len)) == NULL) { 279 rv = CKR_HOST_MEMORY; 280 goto fail_cleanup; 281 } 282 ENCODE_ATTR(CKA_EXPONENT_2, big->big_value, 283 big->big_value_len); 284 key->ck_count++; 285 } 286 287 /* CKA_COEFFICIENT is optional. */ 288 big = OBJ_PRI_RSA_COEF(object_p); 289 if (big->big_value != NULL) { 290 if ((ptr = malloc(big->big_value_len)) == NULL) { 291 rv = CKR_HOST_MEMORY; 292 goto fail_cleanup; 293 } 294 ENCODE_ATTR(CKA_COEFFICIENT, big->big_value, 295 big->big_value_len); 296 key->ck_count++; 297 } 298 299 (void) pthread_mutex_unlock(&object_p->object_mutex); 300 return (CKR_OK); 301 302 fail_cleanup: 303 (void) pthread_mutex_unlock(&object_p->object_mutex); 304 free_key_attributes(key); 305 return (rv); 306 } 307 308 /* 309 * Convert a RSA public key object into a crypto_key structure. 310 * Memory is allocated for each attribute stored in the crypto_key 311 * structure. Memory for the crypto_key structure is not 312 * allocated. Attributes can be freed by free_key_attributes(). 313 */ 314 CK_RV 315 get_rsa_public_key(kernel_object_t *object_p, crypto_key_t *key) 316 { 317 biginteger_t *big; 318 crypto_object_attribute_t *attrs, *cur_attr; 319 char *ptr; 320 321 (void) pthread_mutex_lock(&object_p->object_mutex); 322 if (object_p->key_type != CKK_RSA || 323 object_p->class != CKO_PUBLIC_KEY) { 324 (void) pthread_mutex_unlock(&object_p->object_mutex); 325 return (CKR_ATTRIBUTE_TYPE_INVALID); 326 } 327 328 attrs = calloc(1, 329 RSA_PUB_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 330 if (attrs == NULL) { 331 (void) pthread_mutex_unlock(&object_p->object_mutex); 332 return (CKR_HOST_MEMORY); 333 } 334 335 key->ck_format = CRYPTO_KEY_ATTR_LIST; 336 key->ck_count = RSA_PUB_ATTR_COUNT; 337 key->ck_attrs = attrs; 338 339 cur_attr = attrs; 340 big = OBJ_PUB_RSA_PUBEXPO(object_p); 341 if ((ptr = malloc(big->big_value_len)) == NULL) 342 goto mem_failure; 343 ENCODE_ATTR(CKA_PUBLIC_EXPONENT, big->big_value, big->big_value_len); 344 345 big = OBJ_PUB_RSA_MOD(object_p); 346 if ((ptr = malloc(big->big_value_len)) == NULL) 347 goto mem_failure; 348 ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len); 349 350 if ((ptr = malloc(sizeof (CK_ULONG))) == NULL) 351 goto mem_failure; 352 ENCODE_ATTR(CKA_MODULUS_BITS, &OBJ_PUB_RSA_MOD_BITS(object_p), 353 sizeof (CK_ULONG)); 354 355 (void) pthread_mutex_unlock(&object_p->object_mutex); 356 return (CKR_OK); 357 358 mem_failure: 359 (void) pthread_mutex_unlock(&object_p->object_mutex); 360 free_key_attributes(key); 361 return (CKR_HOST_MEMORY); 362 } 363 364 /* 365 * Free attribute storage in a crypto_key structure. 366 */ 367 void 368 free_key_attributes(crypto_key_t *key) 369 { 370 int i; 371 372 if (key->ck_format == CRYPTO_KEY_ATTR_LIST && 373 (key->ck_count > 0) && key->ck_attrs != NULL) { 374 for (i = 0; i < key->ck_count; i++) { 375 freezero(key->ck_attrs[i].oa_value, 376 key->ck_attrs[i].oa_value_len); 377 } 378 free(key->ck_attrs); 379 } 380 } 381 382 383 /* 384 * Convert a DSA private key object into a crypto_key structure. 385 * Memory is allocated for each attribute stored in the crypto_key 386 * structure. Memory for the crypto_key structure is not 387 * allocated. Attributes can be freed by free_dsa_key_attributes(). 388 */ 389 CK_RV 390 get_dsa_private_key(kernel_object_t *object_p, crypto_key_t *key) 391 { 392 biginteger_t *big; 393 crypto_object_attribute_t *attrs, *cur_attr; 394 char *ptr; 395 396 (void) pthread_mutex_lock(&object_p->object_mutex); 397 if (object_p->key_type != CKK_DSA || 398 object_p->class != CKO_PRIVATE_KEY) { 399 (void) pthread_mutex_unlock(&object_p->object_mutex); 400 return (CKR_ATTRIBUTE_TYPE_INVALID); 401 } 402 403 attrs = calloc(1, 404 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 405 if (attrs == NULL) { 406 (void) pthread_mutex_unlock(&object_p->object_mutex); 407 return (CKR_HOST_MEMORY); 408 } 409 410 key->ck_format = CRYPTO_KEY_ATTR_LIST; 411 key->ck_count = DSA_ATTR_COUNT; 412 key->ck_attrs = attrs; 413 414 cur_attr = attrs; 415 big = OBJ_PRI_DSA_PRIME(object_p); 416 if ((ptr = malloc(big->big_value_len)) == NULL) 417 goto mem_failure; 418 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len); 419 420 big = OBJ_PRI_DSA_SUBPRIME(object_p); 421 if ((ptr = malloc(big->big_value_len)) == NULL) 422 goto mem_failure; 423 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len); 424 425 big = OBJ_PRI_DSA_BASE(object_p); 426 if ((ptr = malloc(big->big_value_len)) == NULL) 427 goto mem_failure; 428 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len); 429 430 big = OBJ_PRI_DSA_VALUE(object_p); 431 if ((ptr = malloc(big->big_value_len)) == NULL) 432 goto mem_failure; 433 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 434 435 (void) pthread_mutex_unlock(&object_p->object_mutex); 436 return (CKR_OK); 437 438 mem_failure: 439 (void) pthread_mutex_unlock(&object_p->object_mutex); 440 free_key_attributes(key); 441 return (CKR_HOST_MEMORY); 442 } 443 444 445 /* 446 * Convert a DSA public key object into a crypto_key structure. 447 * Memory is allocated for each attribute stored in the crypto_key 448 * structure. Memory for the crypto_key structure is not 449 * allocated. Attributes can be freed by free_dsa_key_attributes(). 450 */ 451 CK_RV 452 get_dsa_public_key(kernel_object_t *object_p, crypto_key_t *key) 453 { 454 biginteger_t *big; 455 crypto_object_attribute_t *attrs, *cur_attr; 456 char *ptr; 457 458 (void) pthread_mutex_lock(&object_p->object_mutex); 459 if (object_p->key_type != CKK_DSA || 460 object_p->class != CKO_PUBLIC_KEY) { 461 (void) pthread_mutex_unlock(&object_p->object_mutex); 462 return (CKR_ATTRIBUTE_TYPE_INVALID); 463 } 464 465 attrs = calloc(1, 466 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 467 if (attrs == NULL) { 468 (void) pthread_mutex_unlock(&object_p->object_mutex); 469 return (CKR_HOST_MEMORY); 470 } 471 472 key->ck_format = CRYPTO_KEY_ATTR_LIST; 473 key->ck_count = DSA_ATTR_COUNT; 474 key->ck_attrs = attrs; 475 476 cur_attr = attrs; 477 big = OBJ_PUB_DSA_PRIME(object_p); 478 if ((ptr = malloc(big->big_value_len)) == NULL) 479 goto mem_failure; 480 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len); 481 482 big = OBJ_PUB_DSA_SUBPRIME(object_p); 483 if ((ptr = malloc(big->big_value_len)) == NULL) 484 goto mem_failure; 485 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len); 486 487 big = OBJ_PUB_DSA_BASE(object_p); 488 if ((ptr = malloc(big->big_value_len)) == NULL) 489 goto mem_failure; 490 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len); 491 492 big = OBJ_PUB_DSA_VALUE(object_p); 493 if ((ptr = malloc(big->big_value_len)) == NULL) 494 goto mem_failure; 495 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 496 497 (void) pthread_mutex_unlock(&object_p->object_mutex); 498 return (CKR_OK); 499 500 mem_failure: 501 (void) pthread_mutex_unlock(&object_p->object_mutex); 502 free_key_attributes(key); 503 return (CKR_HOST_MEMORY); 504 } 505 506 507 /* 508 * Convert a EC private key object into a crypto_key structure. 509 * Memory is allocated for each attribute stored in the crypto_key 510 * structure. Memory for the crypto_key structure is not 511 * allocated. Attributes can be freed by free_ec_key_attributes(). 512 */ 513 CK_RV 514 get_ec_private_key(kernel_object_t *object_p, crypto_key_t *key) 515 { 516 biginteger_t *big; 517 crypto_object_attribute_t *attrs, *cur_attr; 518 CK_ATTRIBUTE tmp; 519 char *ptr; 520 int rv; 521 522 (void) pthread_mutex_lock(&object_p->object_mutex); 523 if (object_p->key_type != CKK_EC || 524 object_p->class != CKO_PRIVATE_KEY) { 525 (void) pthread_mutex_unlock(&object_p->object_mutex); 526 return (CKR_ATTRIBUTE_TYPE_INVALID); 527 } 528 529 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t)); 530 if (attrs == NULL) { 531 (void) pthread_mutex_unlock(&object_p->object_mutex); 532 return (CKR_HOST_MEMORY); 533 } 534 535 key->ck_format = CRYPTO_KEY_ATTR_LIST; 536 key->ck_count = EC_ATTR_COUNT; 537 key->ck_attrs = attrs; 538 539 cur_attr = attrs; 540 big = OBJ_PRI_EC_VALUE(object_p); 541 if ((ptr = malloc(big->big_value_len)) == NULL) { 542 rv = CKR_HOST_MEMORY; 543 goto fail; 544 } 545 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 546 547 tmp.type = CKA_EC_PARAMS; 548 tmp.pValue = NULL; 549 rv = kernel_get_attribute(object_p, &tmp); 550 if (rv != CKR_OK) { 551 goto fail; 552 } 553 554 tmp.pValue = malloc(tmp.ulValueLen); 555 if (tmp.pValue == NULL) { 556 rv = CKR_HOST_MEMORY; 557 goto fail; 558 } 559 560 rv = kernel_get_attribute(object_p, &tmp); 561 if (rv != CKR_OK) { 562 free(tmp.pValue); 563 goto fail; 564 } 565 566 cur_attr->oa_type = tmp.type; 567 cur_attr->oa_value = tmp.pValue; 568 cur_attr->oa_value_len = tmp.ulValueLen; 569 570 (void) pthread_mutex_unlock(&object_p->object_mutex); 571 return (CKR_OK); 572 573 fail: 574 (void) pthread_mutex_unlock(&object_p->object_mutex); 575 free_key_attributes(key); 576 return (rv); 577 } 578 579 /* 580 * Convert an EC public key object into a crypto_key structure. 581 * Memory is allocated for each attribute stored in the crypto_key 582 * structure. Memory for the crypto_key structure is not 583 * allocated. Attributes can be freed by free_ec_key_attributes(). 584 */ 585 CK_RV 586 get_ec_public_key(kernel_object_t *object_p, crypto_key_t *key) 587 { 588 biginteger_t *big; 589 crypto_object_attribute_t *attrs, *cur_attr; 590 CK_ATTRIBUTE tmp; 591 char *ptr; 592 int rv; 593 594 (void) pthread_mutex_lock(&object_p->object_mutex); 595 if (object_p->key_type != CKK_EC || 596 object_p->class != CKO_PUBLIC_KEY) { 597 (void) pthread_mutex_unlock(&object_p->object_mutex); 598 return (CKR_ATTRIBUTE_TYPE_INVALID); 599 } 600 601 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t)); 602 if (attrs == NULL) { 603 (void) pthread_mutex_unlock(&object_p->object_mutex); 604 return (CKR_HOST_MEMORY); 605 } 606 607 key->ck_format = CRYPTO_KEY_ATTR_LIST; 608 key->ck_count = EC_ATTR_COUNT; 609 key->ck_attrs = attrs; 610 611 cur_attr = attrs; 612 big = OBJ_PUB_EC_POINT(object_p); 613 if ((ptr = malloc(big->big_value_len)) == NULL) { 614 rv = CKR_HOST_MEMORY; 615 goto fail; 616 } 617 ENCODE_ATTR(CKA_EC_POINT, big->big_value, big->big_value_len); 618 619 tmp.type = CKA_EC_PARAMS; 620 tmp.pValue = NULL; 621 rv = kernel_get_attribute(object_p, &tmp); 622 if (rv != CKR_OK) { 623 goto fail; 624 } 625 626 tmp.pValue = malloc(tmp.ulValueLen); 627 if (tmp.pValue == NULL) { 628 rv = CKR_HOST_MEMORY; 629 goto fail; 630 } 631 632 rv = kernel_get_attribute(object_p, &tmp); 633 if (rv != CKR_OK) { 634 free(tmp.pValue); 635 goto fail; 636 } 637 638 cur_attr->oa_type = tmp.type; 639 cur_attr->oa_value = tmp.pValue; 640 cur_attr->oa_value_len = tmp.ulValueLen; 641 642 (void) pthread_mutex_unlock(&object_p->object_mutex); 643 return (CKR_OK); 644 645 fail: 646 (void) pthread_mutex_unlock(&object_p->object_mutex); 647 free_key_attributes(key); 648 return (rv); 649 } 650 651 /* 652 * Convert an attribute template into an obj_attrs array. 653 * Memory is allocated for each attribute stored in the obj_attrs. 654 * The memory can be freed by free_object_attributes(). 655 * 656 * If the boolean pointer is_token_obj is not NULL, the caller wants to 657 * retrieve the value of the CKA_TOKEN attribute if it is specified in the 658 * template. 659 * - When this routine is called thru C_CreateObject(), C_CopyObject(), or 660 * any key management function, is_token_obj should NOT be NULL. 661 * - When this routine is called thru C_GetAttributeValue() or 662 * C_SetAttributeValue(), "is_token_obj" should be NULL. 663 */ 664 CK_RV 665 process_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 666 caddr_t *obj_attrs, CK_BBOOL *is_token_obj) 667 { 668 crypto_object_attribute_t *attrs, *cur_attr; 669 int i, cur_i; 670 char *ptr; 671 CK_RV rv; 672 ssize_t value_len; 673 674 if (ulCount == 0) { 675 obj_attrs = NULL; 676 return (CKR_OK); 677 } 678 679 attrs = calloc(1, ulCount * sizeof (crypto_object_attribute_t)); 680 if (attrs == NULL) { 681 return (CKR_HOST_MEMORY); 682 } 683 684 cur_attr = attrs; 685 for (i = 0; i < ulCount; i++) { 686 /* 687 * The length of long attributes must be set correctly 688 * so providers can determine whether they came from 32 689 * or 64-bit applications. 690 */ 691 switch (pTemplate[i].type) { 692 case CKA_CLASS: 693 case CKA_CERTIFICATE_TYPE: 694 case CKA_KEY_TYPE: 695 case CKA_MODULUS_BITS: 696 case CKA_HW_FEATURE_TYPE: 697 value_len = sizeof (ulong_t); 698 if (pTemplate[i].pValue != NULL && 699 (pTemplate[i].ulValueLen < value_len)) { 700 rv = CKR_ATTRIBUTE_VALUE_INVALID; 701 cur_i = i; 702 goto fail_cleanup; 703 } 704 break; 705 default: 706 value_len = pTemplate[i].ulValueLen; 707 } 708 709 cur_attr->oa_type = pTemplate[i].type; 710 cur_attr->oa_value_len = value_len; 711 cur_attr->oa_value = NULL; 712 713 if ((pTemplate[i].pValue != NULL) && 714 (pTemplate[i].ulValueLen > 0)) { 715 ptr = malloc(pTemplate[i].ulValueLen); 716 if (ptr == NULL) { 717 rv = CKR_HOST_MEMORY; 718 cur_i = i; 719 goto fail_cleanup; 720 } else { 721 (void) memcpy(ptr, pTemplate[i].pValue, 722 pTemplate[i].ulValueLen); 723 cur_attr->oa_value = ptr; 724 } 725 } 726 727 if ((is_token_obj != NULL) && 728 (pTemplate[i].type == CKA_TOKEN)) { 729 /* Get the CKA_TOKEN attribute value. */ 730 if (pTemplate[i].pValue == NULL) { 731 rv = CKR_ATTRIBUTE_VALUE_INVALID; 732 cur_i = i; 733 goto fail_cleanup; 734 } else { 735 *is_token_obj = 736 *(CK_BBOOL *)pTemplate[i].pValue; 737 } 738 } 739 740 cur_attr++; 741 } 742 743 *obj_attrs = (char *)attrs; 744 return (CKR_OK); 745 746 fail_cleanup: 747 cur_attr = attrs; 748 for (i = 0; i < cur_i; i++) { 749 if (cur_attr->oa_value != NULL) { 750 (void) free(cur_attr->oa_value); 751 } 752 cur_attr++; 753 } 754 755 (void) free(attrs); 756 return (rv); 757 } 758 759 760 /* 761 * Copy the attribute values from obj_attrs to pTemplate. 762 * The obj_attrs is an image of the Template and is expected to have the 763 * same attributes in the same order and each one of the attribute pValue 764 * in obj_attr has enough space allocated for the corresponding valueLen 765 * in pTemplate. 766 */ 767 CK_RV 768 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 769 caddr_t obj_attrs) 770 { 771 crypto_object_attribute_t *cur_attr; 772 CK_RV rv = CKR_OK; 773 int i; 774 775 /* LINTED */ 776 cur_attr = (crypto_object_attribute_t *)obj_attrs; 777 for (i = 0; i < ulCount; i++) { 778 if (pTemplate[i].type != cur_attr->oa_type) { 779 /* The attribute type doesn't match, this is bad. */ 780 rv = CKR_FUNCTION_FAILED; 781 return (rv); 782 } 783 784 pTemplate[i].ulValueLen = cur_attr->oa_value_len; 785 786 if ((pTemplate[i].pValue != NULL) && 787 ((CK_LONG)pTemplate[i].ulValueLen != -1)) { 788 (void) memcpy(pTemplate[i].pValue, cur_attr->oa_value, 789 pTemplate[i].ulValueLen); 790 } 791 cur_attr++; 792 } 793 794 return (rv); 795 } 796 797 /* 798 * Free the attribute storage in a crypto_object_attribute_t structure. 799 */ 800 void 801 free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount) 802 { 803 crypto_object_attribute_t *cur_attr; 804 int i; 805 806 if ((ulCount == 0) || (obj_attrs == NULL)) { 807 return; 808 } 809 810 /* LINTED */ 811 cur_attr = (crypto_object_attribute_t *)obj_attrs; 812 for (i = 0; i < ulCount; i++) { 813 /* XXX check that oa_value > 0 */ 814 if (cur_attr->oa_value != NULL) { 815 free(cur_attr->oa_value); 816 } 817 cur_attr++; 818 } 819 820 free(obj_attrs); 821 } 822 823 /* 824 * This function is called by process_found_objects(). It will check the 825 * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then 826 * initialize all the necessary fields in the object wrapper "objp". 827 */ 828 static CK_RV 829 create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp, 830 kernel_object_t *objp, crypto_object_id_t oid) 831 { 832 CK_RV rv = CKR_OK; 833 crypto_object_get_attribute_value_t obj_ga; 834 boolean_t is_pri_obj; 835 boolean_t is_token_obj; 836 CK_BBOOL pri_value, token_value; 837 CK_ATTRIBUTE pTemplate[2]; 838 int r; 839 840 /* 841 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this 842 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN. 843 */ 844 obj_ga.og_session = sp->k_session; 845 obj_ga.og_handle = oid; 846 obj_ga.og_count = 2; 847 848 pTemplate[0].type = CKA_PRIVATE; 849 pTemplate[0].pValue = &pri_value; 850 pTemplate[0].ulValueLen = sizeof (pri_value); 851 pTemplate[1].type = CKA_TOKEN; 852 pTemplate[1].pValue = &token_value; 853 pTemplate[1].ulValueLen = sizeof (token_value); 854 rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes, 855 NULL); 856 if (rv != CKR_OK) { 857 return (rv); 858 } 859 860 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 861 &obj_ga)) < 0) { 862 if (errno != EINTR) 863 break; 864 } 865 if (r < 0) { 866 rv = CKR_FUNCTION_FAILED; 867 } else { 868 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 869 } 870 871 if (rv == CKR_OK) { 872 rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes); 873 if (rv == CKR_OK) { 874 is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue; 875 is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue; 876 } 877 } 878 879 free_object_attributes(obj_ga.og_attributes, 2); 880 if (rv != CKR_OK) { 881 return (rv); 882 } 883 884 /* Make sure it is a token object. */ 885 if (!is_token_obj) { 886 rv = CKR_ATTRIBUTE_VALUE_INVALID; 887 return (rv); 888 } 889 890 /* If it is a private object, make sure the user has logged in. */ 891 if (is_pri_obj && (pslot->sl_state != CKU_USER)) { 892 rv = CKR_ATTRIBUTE_VALUE_INVALID; 893 return (rv); 894 } 895 896 objp->is_lib_obj = B_FALSE; 897 objp->k_handle = oid; 898 objp->bool_attr_mask |= TOKEN_BOOL_ON; 899 if (is_pri_obj) { 900 objp->bool_attr_mask |= PRIVATE_BOOL_ON; 901 } else { 902 objp->bool_attr_mask &= ~PRIVATE_BOOL_ON; 903 } 904 905 (void) pthread_mutex_init(&objp->object_mutex, NULL); 906 objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC; 907 objp->session_handle = (CK_SESSION_HANDLE) sp; 908 909 return (CKR_OK); 910 } 911 912 /* 913 * This function processes the kernel object handles returned from the 914 * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list 915 * and the number of object handles to the caller - C_FindObjects(). 916 * The caller acquires the slot lock and the session lock. 917 */ 918 CK_RV 919 process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found, 920 CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu) 921 { 922 CK_RV rv = CKR_OK; 923 crypto_object_id_t *oid_p; 924 kernel_slot_t *pslot; 925 kernel_object_t *objp; 926 kernel_object_t *objp1; 927 kernel_object_t *new_tobj_list = NULL; 928 kernel_session_t *sp; 929 CK_ULONG num_obj_found = 0; 930 boolean_t is_in_lib; 931 int i; 932 933 if (obj_fu.fu_count == 0) { 934 *found_obj_count = 0; 935 return (CKR_OK); 936 } 937 938 pslot = slot_table[cur_sp->ses_slotid]; 939 940 /* LINTED */ 941 oid_p = (crypto_object_id_t *)obj_fu.fu_handles; 942 for (i = 0; i < obj_fu.fu_count; i++) { 943 is_in_lib = B_FALSE; 944 /* 945 * Check if this oid has an object wrapper in the library 946 * already. First, search the slot's token object list. 947 */ 948 objp = pslot->sl_tobj_list; 949 while (!is_in_lib && objp) { 950 if (objp->k_handle == *oid_p) { 951 is_in_lib = B_TRUE; 952 } else { 953 objp = objp->next; 954 } 955 } 956 957 /* 958 * If it is not in the slot's token object list, 959 * search it in all the sessions. 960 */ 961 if (!is_in_lib) { 962 sp = pslot->sl_sess_list; 963 while (!is_in_lib && sp) { 964 objp = sp->object_list; 965 while (!is_in_lib && objp) { 966 if (objp->k_handle == *oid_p) { 967 is_in_lib = B_TRUE; 968 } else { 969 objp = objp->next; 970 } 971 } 972 sp = sp->next; 973 } 974 } 975 976 /* 977 * If this object is in the library already, add its object 978 * wrapper to the returned find object list. 979 */ 980 if (is_in_lib) { 981 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 982 } 983 984 /* 985 * If we still do not find it in the library. This object 986 * must be a token object pre-existed in the HW provider. 987 * We need to create an object wrapper for it in the library. 988 */ 989 if (!is_in_lib) { 990 objp1 = calloc(1, sizeof (kernel_object_t)); 991 if (objp1 == NULL) { 992 rv = CKR_HOST_MEMORY; 993 goto failed_exit; 994 } 995 rv = create_new_tobj_in_lib(pslot, cur_sp, objp1, 996 *oid_p); 997 998 if (rv == CKR_OK) { 999 /* Save the new object to the new_tobj_list. */ 1000 if (new_tobj_list == NULL) { 1001 new_tobj_list = objp1; 1002 objp1->next = NULL; 1003 objp1->prev = NULL; 1004 } else { 1005 new_tobj_list->prev = objp1; 1006 objp1->next = new_tobj_list; 1007 objp1->prev = NULL; 1008 new_tobj_list = objp1; 1009 } 1010 } else { 1011 /* 1012 * If create_new_tobj_in_lib() doesn't fail 1013 * with CKR_HOST_MEMORY, the failure should be 1014 * caused by the attributes' checking. We will 1015 * just ignore this object and continue on. 1016 */ 1017 free(objp1); 1018 if (rv == CKR_HOST_MEMORY) { 1019 goto failed_exit; 1020 } 1021 } 1022 } 1023 1024 /* Process next one */ 1025 oid_p++; 1026 } 1027 1028 /* 1029 * Add the newly created token object wrappers to the found object 1030 * list and to the slot's token object list. 1031 */ 1032 if (new_tobj_list != NULL) { 1033 /* Add to the obj_found array. */ 1034 objp = new_tobj_list; 1035 while (objp) { 1036 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 1037 if (objp->next == NULL) { 1038 break; 1039 } 1040 objp = objp->next; 1041 } 1042 1043 /* Add to the beginning of the slot's token object list. */ 1044 if (pslot->sl_tobj_list != NULL) { 1045 objp->next = pslot->sl_tobj_list; 1046 pslot->sl_tobj_list->prev = objp; 1047 } 1048 pslot->sl_tobj_list = new_tobj_list; 1049 } 1050 1051 *found_obj_count = num_obj_found; 1052 return (CKR_OK); 1053 1054 failed_exit: 1055 1056 /* Free the newly created token object wrappers. */ 1057 objp = new_tobj_list; 1058 while (objp) { 1059 objp1 = objp->next; 1060 (void) pthread_mutex_destroy(&objp->object_mutex); 1061 free(objp); 1062 objp = objp1; 1063 } 1064 1065 return (rv); 1066 } 1067 1068 1069 /* 1070 * Get the value of the CKA_PRIVATE attribute for the object just returned 1071 * from the HW provider. This function will be called by any function 1072 * that creates a new object, because the CKA_PRIVATE value of an object is 1073 * token specific. The CKA_PRIVATE attribute value of the new object will be 1074 * stored in the object structure in the library, which will be used later at 1075 * C_Logout to clean up all private objects. 1076 */ 1077 CK_RV 1078 get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid, 1079 CK_BBOOL *is_pri_obj) 1080 { 1081 CK_RV rv = CKR_OK; 1082 crypto_object_get_attribute_value_t obj_ga; 1083 crypto_object_attribute_t obj_attr; 1084 CK_BBOOL pri_value; 1085 int r; 1086 1087 obj_ga.og_session = sp->k_session; 1088 obj_ga.og_handle = oid; 1089 obj_ga.og_count = 1; 1090 1091 obj_attr.oa_type = CKA_PRIVATE; 1092 obj_attr.oa_value = (char *)&pri_value; 1093 obj_attr.oa_value_len = sizeof (CK_BBOOL); 1094 obj_ga.og_attributes = (char *)&obj_attr; 1095 1096 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 1097 &obj_ga)) < 0) { 1098 if (errno != EINTR) 1099 break; 1100 } 1101 if (r < 0) { 1102 rv = CKR_FUNCTION_FAILED; 1103 } else { 1104 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 1105 } 1106 1107 if (rv == CKR_OK) { 1108 *is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value; 1109 } 1110 1111 return (rv); 1112 } 1113 1114 1115 CK_RV 1116 get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type, 1117 CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags) 1118 { 1119 crypto_get_provider_mechanism_info_t mechanism_info; 1120 const char *string; 1121 CK_FLAGS flags, mi_flags; 1122 CK_RV rv; 1123 int r; 1124 char buf[11]; /* Num chars for representing ulong in ASCII */ 1125 1126 if (type >= CKM_VENDOR_DEFINED) { 1127 /* allocate/build a string containing the mechanism number */ 1128 (void) snprintf(buf, sizeof (buf), "%#lx", type); 1129 string = buf; 1130 } else { 1131 string = pkcs11_mech2str(type); 1132 } 1133 1134 if (string == NULL) 1135 return (CKR_MECHANISM_INVALID); 1136 1137 (void) strcpy(mechanism_info.mi_mechanism_name, string); 1138 mechanism_info.mi_provider_id = pslot->sl_provider_id; 1139 1140 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO, 1141 &mechanism_info)) < 0) { 1142 if (errno != EINTR) 1143 break; 1144 } 1145 if (r < 0) { 1146 rv = CKR_FUNCTION_FAILED; 1147 } else { 1148 rv = crypto2pkcs11_error_number( 1149 mechanism_info.mi_return_value); 1150 } 1151 1152 if (rv != CKR_OK) { 1153 return (rv); 1154 } 1155 1156 /* 1157 * Atomic flags are not part of PKCS#11 so we filter 1158 * them out here. 1159 */ 1160 mi_flags = mechanism_info.mi_flags; 1161 mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC | 1162 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC | 1163 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 1164 CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1165 CRYPTO_FG_VERIFY_RECOVER_ATOMIC | 1166 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 1167 CRYPTO_FG_MAC_DECRYPT_ATOMIC); 1168 1169 if (mi_flags == 0) { 1170 return (CKR_MECHANISM_INVALID); 1171 } 1172 1173 if (rv == CKR_OK) { 1174 /* set the value of k_mi_flags first */ 1175 *k_mi_flags = mi_flags; 1176 1177 /* convert KEF flags into pkcs11 flags */ 1178 flags = CKF_HW; 1179 if (mi_flags & CRYPTO_FG_ENCRYPT) 1180 flags |= CKF_ENCRYPT; 1181 if (mi_flags & CRYPTO_FG_DECRYPT) { 1182 flags |= CKF_DECRYPT; 1183 /* 1184 * Since we'll be emulating C_UnwrapKey() for some 1185 * cases, we can go ahead and claim CKF_UNWRAP 1186 */ 1187 flags |= CKF_UNWRAP; 1188 } 1189 if (mi_flags & CRYPTO_FG_DIGEST) 1190 flags |= CKF_DIGEST; 1191 if (mi_flags & CRYPTO_FG_SIGN) 1192 flags |= CKF_SIGN; 1193 if (mi_flags & CRYPTO_FG_SIGN_RECOVER) 1194 flags |= CKF_SIGN_RECOVER; 1195 if (mi_flags & CRYPTO_FG_VERIFY) 1196 flags |= CKF_VERIFY; 1197 if (mi_flags & CRYPTO_FG_VERIFY_RECOVER) 1198 flags |= CKF_VERIFY_RECOVER; 1199 if (mi_flags & CRYPTO_FG_GENERATE) 1200 flags |= CKF_GENERATE; 1201 if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR) 1202 flags |= CKF_GENERATE_KEY_PAIR; 1203 if (mi_flags & CRYPTO_FG_WRAP) 1204 flags |= CKF_WRAP; 1205 if (mi_flags & CRYPTO_FG_UNWRAP) 1206 flags |= CKF_UNWRAP; 1207 if (mi_flags & CRYPTO_FG_DERIVE) 1208 flags |= CKF_DERIVE; 1209 1210 pInfo->ulMinKeySize = mechanism_info.mi_min_key_size; 1211 pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size; 1212 pInfo->flags = flags; 1213 1214 } 1215 1216 return (rv); 1217 } 1218 1219 /* 1220 * Unfortunately the kernel and PKCS#11 use a slightly different struct to 1221 * specify CCM parameters. 1222 */ 1223 void 1224 p11_to_kernel_ccm_params(const CK_CCM_PARAMS *in, CK_AES_CCM_PARAMS *out) 1225 { 1226 out->ulMACSize = in->ulMACLen; 1227 out->ulNonceSize = in->ulNonceLen; 1228 out->ulAuthDataSize = in->ulAADLen; 1229 out->ulDataSize = in->ulDataLen; 1230 out->nonce = in->pNonce; 1231 out->authData = in->pAAD; 1232 } 1233