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