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 value_len = sizeof (ulong_t); 604 if (pTemplate[i].pValue != NULL && 605 (pTemplate[i].ulValueLen < value_len)) { 606 rv = CKR_BUFFER_TOO_SMALL; 607 cur_i = i; 608 goto fail_cleanup; 609 } 610 break; 611 default: 612 value_len = pTemplate[i].ulValueLen; 613 } 614 615 cur_attr->oa_type = pTemplate[i].type; 616 cur_attr->oa_value_len = value_len; 617 cur_attr->oa_value = NULL; 618 619 if ((pTemplate[i].pValue != NULL) && 620 (pTemplate[i].ulValueLen > 0)) { 621 ptr = malloc(pTemplate[i].ulValueLen); 622 if (ptr == NULL) { 623 rv = CKR_HOST_MEMORY; 624 cur_i = i; 625 goto fail_cleanup; 626 } else { 627 (void) memcpy(ptr, pTemplate[i].pValue, 628 pTemplate[i].ulValueLen); 629 cur_attr->oa_value = ptr; 630 } 631 } 632 633 if ((is_token_obj != NULL) && 634 (pTemplate[i].type == CKA_TOKEN)) { 635 /* Get the CKA_TOKEN attribute value. */ 636 if (pTemplate[i].pValue == NULL) { 637 rv = CKR_ATTRIBUTE_VALUE_INVALID; 638 cur_i = i; 639 goto fail_cleanup; 640 } else { 641 *is_token_obj = 642 *(CK_BBOOL *)pTemplate[i].pValue; 643 } 644 } 645 646 cur_attr++; 647 } 648 649 *obj_attrs = (char *)attrs; 650 return (CKR_OK); 651 652 fail_cleanup: 653 cur_attr = attrs; 654 for (i = 0; i < cur_i; i++) { 655 if (cur_attr->oa_value != NULL) { 656 (void) free(cur_attr->oa_value); 657 } 658 cur_attr++; 659 } 660 661 (void) free(attrs); 662 return (rv); 663 } 664 665 666 /* 667 * Copy the attribute values from obj_attrs to pTemplate. 668 * The obj_attrs is an image of the Template and is expected to have the 669 * same attributes in the same order and each one of the attribute pValue 670 * in obj_attr has enough space allocated for the corresponding valueLen 671 * in pTemplate. 672 */ 673 CK_RV 674 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 675 caddr_t obj_attrs) 676 { 677 crypto_object_attribute_t *cur_attr; 678 CK_RV rv = CKR_OK; 679 int i; 680 681 /* LINTED */ 682 cur_attr = (crypto_object_attribute_t *)obj_attrs; 683 for (i = 0; i < ulCount; i++) { 684 if (pTemplate[i].type != cur_attr->oa_type) { 685 /* The attribute type doesn't match, this is bad. */ 686 rv = CKR_FUNCTION_FAILED; 687 return (rv); 688 } 689 690 pTemplate[i].ulValueLen = cur_attr->oa_value_len; 691 692 if ((pTemplate[i].pValue != NULL) && 693 ((CK_LONG)pTemplate[i].ulValueLen != -1)) { 694 (void) memcpy(pTemplate[i].pValue, cur_attr->oa_value, 695 pTemplate[i].ulValueLen); 696 } 697 cur_attr++; 698 } 699 700 return (rv); 701 } 702 703 /* 704 * Free the attribute storage in a crypto_object_attribute_t structure. 705 */ 706 void 707 free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount) 708 { 709 crypto_object_attribute_t *cur_attr; 710 int i; 711 712 if ((ulCount == 0) || (obj_attrs == NULL)) { 713 return; 714 } 715 716 /* LINTED */ 717 cur_attr = (crypto_object_attribute_t *)obj_attrs; 718 for (i = 0; i < ulCount; i++) { 719 if (cur_attr->oa_value != NULL) { 720 free(cur_attr->oa_value); 721 } 722 cur_attr++; 723 } 724 725 free(obj_attrs); 726 } 727 728 /* 729 * This function is called by process_found_objects(). It will check the 730 * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then 731 * initialize all the necessary fields in the object wrapper "objp". 732 */ 733 static CK_RV 734 create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp, 735 kernel_object_t *objp, crypto_object_id_t oid) 736 { 737 CK_RV rv = CKR_OK; 738 crypto_object_get_attribute_value_t obj_ga; 739 boolean_t is_pri_obj; 740 boolean_t is_token_obj; 741 CK_BBOOL pri_value, token_value; 742 CK_ATTRIBUTE pTemplate[2]; 743 int r; 744 745 /* 746 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this 747 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN. 748 */ 749 obj_ga.og_session = sp->k_session; 750 obj_ga.og_handle = oid; 751 obj_ga.og_count = 2; 752 753 pTemplate[0].type = CKA_PRIVATE; 754 pTemplate[0].pValue = &pri_value; 755 pTemplate[0].ulValueLen = sizeof (pri_value); 756 pTemplate[1].type = CKA_TOKEN; 757 pTemplate[1].pValue = &token_value; 758 pTemplate[1].ulValueLen = sizeof (token_value); 759 rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes, 760 NULL); 761 if (rv != CKR_OK) { 762 return (rv); 763 } 764 765 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 766 &obj_ga)) < 0) { 767 if (errno != EINTR) 768 break; 769 } 770 if (r < 0) { 771 rv = CKR_FUNCTION_FAILED; 772 } else { 773 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 774 } 775 776 if (rv == CKR_OK) { 777 rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes); 778 if (rv == CKR_OK) { 779 is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue; 780 is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue; 781 } 782 } 783 784 free_object_attributes(obj_ga.og_attributes, 2); 785 if (rv != CKR_OK) { 786 return (rv); 787 } 788 789 /* Make sure it is a token object. */ 790 if (!is_token_obj) { 791 rv = CKR_ATTRIBUTE_VALUE_INVALID; 792 return (rv); 793 } 794 795 /* If it is a private object, make sure the user has logged in. */ 796 if (is_pri_obj && (pslot->sl_state != CKU_USER)) { 797 rv = CKR_ATTRIBUTE_VALUE_INVALID; 798 return (rv); 799 } 800 801 objp->is_lib_obj = B_FALSE; 802 objp->k_handle = oid; 803 objp->bool_attr_mask |= TOKEN_BOOL_ON; 804 if (is_pri_obj) { 805 objp->bool_attr_mask |= PRIVATE_BOOL_ON; 806 } else { 807 objp->bool_attr_mask &= ~PRIVATE_BOOL_ON; 808 } 809 810 (void) pthread_mutex_init(&objp->object_mutex, NULL); 811 objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC; 812 objp->session_handle = (CK_SESSION_HANDLE) sp; 813 814 return (CKR_OK); 815 } 816 817 /* 818 * This function processes the kernel object handles returned from the 819 * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list 820 * and the number of object handles to the caller - C_FindObjects(). 821 * The caller acquires the slot lock and the session lock. 822 */ 823 CK_RV 824 process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found, 825 CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu) 826 { 827 CK_RV rv = CKR_OK; 828 crypto_object_id_t *oid_p; 829 kernel_slot_t *pslot; 830 kernel_object_t *objp; 831 kernel_object_t *objp1; 832 kernel_object_t *new_tobj_list = NULL; 833 kernel_session_t *sp; 834 CK_ULONG num_obj_found = 0; 835 boolean_t is_in_lib; 836 int i; 837 838 if (obj_fu.fu_count == 0) { 839 *found_obj_count = 0; 840 return (CKR_OK); 841 } 842 843 pslot = slot_table[cur_sp->ses_slotid]; 844 845 /* LINTED */ 846 oid_p = (crypto_object_id_t *)obj_fu.fu_handles; 847 for (i = 0; i < obj_fu.fu_count; i++) { 848 is_in_lib = B_FALSE; 849 /* 850 * Check if this oid has an object wrapper in the library 851 * already. First, search the slot's token object list. 852 */ 853 objp = pslot->sl_tobj_list; 854 while (!is_in_lib && objp) { 855 if (objp->k_handle == *oid_p) { 856 is_in_lib = B_TRUE; 857 } else { 858 objp = objp->next; 859 } 860 } 861 862 /* 863 * If it is not in the slot's token object list, 864 * search it in all the sessions. 865 */ 866 if (!is_in_lib) { 867 sp = pslot->sl_sess_list; 868 while (!is_in_lib && sp) { 869 objp = sp->object_list; 870 while (!is_in_lib && objp) { 871 if (objp->k_handle == *oid_p) { 872 is_in_lib = B_TRUE; 873 } else { 874 objp = objp->next; 875 } 876 } 877 sp = sp->next; 878 } 879 } 880 881 /* 882 * If this object is in the library already, add its object 883 * wrapper to the returned find object list. 884 */ 885 if (is_in_lib) { 886 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 887 } 888 889 /* 890 * If we still do not find it in the library. This object 891 * must be a token object pre-existed in the HW provider. 892 * We need to create an object wrapper for it in the library. 893 */ 894 if (!is_in_lib) { 895 objp1 = calloc(1, sizeof (kernel_object_t)); 896 if (objp1 == NULL) { 897 rv = CKR_HOST_MEMORY; 898 goto failed_exit; 899 } 900 rv = create_new_tobj_in_lib(pslot, cur_sp, objp1, 901 *oid_p); 902 903 if (rv == CKR_OK) { 904 /* Save the new object to the new_tobj_list. */ 905 if (new_tobj_list == NULL) { 906 new_tobj_list = objp1; 907 objp1->next = NULL; 908 objp1->prev = NULL; 909 } else { 910 new_tobj_list->prev = objp1; 911 objp1->next = new_tobj_list; 912 objp1->prev = NULL; 913 new_tobj_list = objp1; 914 } 915 } else { 916 /* 917 * If create_new_tobj_in_lib() doesn't fail 918 * with CKR_HOST_MEMORY, the failure should be 919 * caused by the attributes' checking. We will 920 * just ignore this object and continue on. 921 */ 922 free(objp1); 923 if (rv == CKR_HOST_MEMORY) { 924 goto failed_exit; 925 } 926 } 927 } 928 929 /* Process next one */ 930 oid_p++; 931 } 932 933 /* 934 * Add the newly created token object wrappers to the found object 935 * list and to the slot's token object list. 936 */ 937 if (new_tobj_list != NULL) { 938 /* Add to the obj_found array. */ 939 objp = new_tobj_list; 940 while (objp) { 941 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 942 if (objp->next == NULL) { 943 break; 944 } 945 objp = objp->next; 946 } 947 948 /* Add to the beginning of the slot's token object list. */ 949 if (pslot->sl_tobj_list != NULL) { 950 objp->next = pslot->sl_tobj_list; 951 pslot->sl_tobj_list->prev = objp; 952 } 953 pslot->sl_tobj_list = new_tobj_list; 954 } 955 956 *found_obj_count = num_obj_found; 957 return (CKR_OK); 958 959 failed_exit: 960 961 /* Free the newly created token object wrappers. */ 962 objp = new_tobj_list; 963 while (objp) { 964 objp1 = objp->next; 965 (void) pthread_mutex_destroy(&objp->object_mutex); 966 free(objp); 967 objp = objp1; 968 } 969 970 return (rv); 971 } 972 973 974 /* 975 * Get the value of the CKA_PRIVATE attribute for the object just returned 976 * from the HW provider. This function will be called by any function 977 * that creates a new object, because the CKA_PRIVATE value of an object is 978 * token sepecific. The CKA_PRIVATE attribute value of the new object will be 979 * stored in the object structure in the library, which will be used later at 980 * C_Logout to clean up all private objects. 981 */ 982 CK_RV 983 get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid, 984 CK_BBOOL *is_pri_obj) 985 { 986 CK_RV rv = CKR_OK; 987 crypto_object_get_attribute_value_t obj_ga; 988 crypto_object_attribute_t obj_attr; 989 CK_BBOOL pri_value; 990 int r; 991 992 obj_ga.og_session = sp->k_session; 993 obj_ga.og_handle = oid; 994 obj_ga.og_count = 1; 995 996 obj_attr.oa_type = CKA_PRIVATE; 997 obj_attr.oa_value = (char *)&pri_value; 998 obj_attr.oa_value_len = sizeof (CK_BBOOL); 999 obj_ga.og_attributes = (char *)&obj_attr; 1000 1001 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 1002 &obj_ga)) < 0) { 1003 if (errno != EINTR) 1004 break; 1005 } 1006 if (r < 0) { 1007 rv = CKR_FUNCTION_FAILED; 1008 } else { 1009 rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 1010 } 1011 1012 if (rv == CKR_OK) { 1013 *is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value; 1014 } 1015 1016 return (rv); 1017 } 1018 1019 1020 CK_RV 1021 get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type, 1022 CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags) 1023 { 1024 crypto_get_provider_mechanism_info_t mechanism_info; 1025 char *string; 1026 CK_FLAGS flags, mi_flags; 1027 CK_RV rv; 1028 int r; 1029 1030 string = pkcs11_mech2str(type); 1031 if (string == NULL) 1032 return (CKR_MECHANISM_INVALID); 1033 1034 (void) strcpy(mechanism_info.mi_mechanism_name, string); 1035 mechanism_info.mi_provider_id = pslot->sl_provider_id; 1036 1037 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO, 1038 &mechanism_info)) < 0) { 1039 if (errno != EINTR) 1040 break; 1041 } 1042 if (r < 0) { 1043 rv = CKR_FUNCTION_FAILED; 1044 } else { 1045 rv = crypto2pkcs11_error_number( 1046 mechanism_info.mi_return_value); 1047 } 1048 1049 if (rv != CKR_OK) { 1050 goto out; 1051 } 1052 1053 /* 1054 * Atomic flags are not part of PKCS#11 so we filter 1055 * them out here. 1056 */ 1057 mi_flags = mechanism_info.mi_flags; 1058 mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC | 1059 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC | 1060 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 1061 CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1062 CRYPTO_FG_VERIFY_RECOVER_ATOMIC | 1063 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 1064 CRYPTO_FG_MAC_DECRYPT_ATOMIC); 1065 1066 if (mi_flags == 0) { 1067 rv = CKR_MECHANISM_INVALID; 1068 goto out; 1069 } 1070 1071 if (rv == CKR_OK) { 1072 /* set the value of k_mi_flags first */ 1073 *k_mi_flags = mi_flags; 1074 1075 /* convert KEF flags into pkcs11 flags */ 1076 flags = CKF_HW; 1077 if (mi_flags & CRYPTO_FG_ENCRYPT) 1078 flags |= CKF_ENCRYPT; 1079 if (mi_flags & CRYPTO_FG_DECRYPT) { 1080 flags |= CKF_DECRYPT; 1081 /* 1082 * Since we'll be emulating C_UnwrapKey() for some 1083 * cases, we can go ahead and claim CKF_UNWRAP 1084 */ 1085 flags |= CKF_UNWRAP; 1086 } 1087 if (mi_flags & CRYPTO_FG_DIGEST) 1088 flags |= CKF_DIGEST; 1089 if (mi_flags & CRYPTO_FG_SIGN) 1090 flags |= CKF_SIGN; 1091 if (mi_flags & CRYPTO_FG_SIGN_RECOVER) 1092 flags |= CKF_SIGN_RECOVER; 1093 if (mi_flags & CRYPTO_FG_VERIFY) 1094 flags |= CKF_VERIFY; 1095 if (mi_flags & CRYPTO_FG_VERIFY_RECOVER) 1096 flags |= CKF_VERIFY_RECOVER; 1097 if (mi_flags & CRYPTO_FG_GENERATE) 1098 flags |= CKF_GENERATE; 1099 if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR) 1100 flags |= CKF_GENERATE_KEY_PAIR; 1101 if (mi_flags & CRYPTO_FG_WRAP) 1102 flags |= CKF_WRAP; 1103 if (mi_flags & CRYPTO_FG_UNWRAP) 1104 flags |= CKF_UNWRAP; 1105 if (mi_flags & CRYPTO_FG_DERIVE) 1106 flags |= CKF_DERIVE; 1107 1108 pInfo->ulMinKeySize = mechanism_info.mi_min_key_size; 1109 pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size; 1110 pInfo->flags = flags; 1111 1112 } 1113 1114 out: 1115 free(string); 1116 return (rv); 1117 } 1118