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