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 /* 30 * Functions used for manipulating the keystore 31 */ 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <errno.h> 36 #include <sys/stat.h> 37 #include <fcntl.h> 38 #include <time.h> 39 #include <unistd.h> 40 #include <pwd.h> 41 #include <sys/types.h> 42 #include <dirent.h> 43 #include <limits.h> 44 #include <strings.h> 45 #include <security/cryptoki.h> 46 #include <cryptoutil.h> 47 #include "softGlobal.h" 48 #include "softObject.h" 49 #include "softKeystore.h" 50 #include "softKeystoreUtil.h" 51 52 #define MAXPATHLEN 1024 53 #define SUNW_PATH ".sunw" /* top level Sun directory */ 54 #define KEYSTORE_PATH "pkcs11_softtoken" /* keystore directory */ 55 #define PUB_OBJ_DIR "public" /* directory for public objects */ 56 #define PRI_OBJ_DIR "private" /* directory for private objects */ 57 #define DS_FILE "objstore_info" /* keystore description file */ 58 #define TMP_DS_FILE "t_info" /* temp name for keystore desc. file */ 59 #define OBJ_PREFIX "obj" /* prefix of the keystore object file names */ 60 #define TMP_OBJ_PREFIX "t_o" /* prefix of the temp object file names */ 61 62 /* 63 * KEYSTORE DESCRIPTION FILE: 64 * 65 * The following describes the content of the keystore description file 66 * 67 * The order AND data type of the fields are very important. 68 * All the code in this file assume that they are in the order specified 69 * below. If either order of the fields or their data type changed, 70 * you must make sure the ALL the pre-define values are still valid 71 * 72 * 1) PKCS#11 release number. It's 2.11 in this release (uchar_t[32]) 73 * 2) keystore version number: used for synchronizing when different 74 * processes access the keystore at the same time. It is incremented 75 * when there is a change to the keystore. (uint_32) 76 * 3) monotonic-counter: last counter value for name of token object file. 77 * used for assigning unique name to each token (uint_32) 78 * 4) salt used for generating encryption key (uint_16) 79 * 5) salt used for generating key used for doing HMAC (uint_16) 80 * 6) Length of salt used for generating hashed pin (length of salt 81 * is variable) 82 * 7) Salt used for generating hashed pin. 83 * 8) Hashed pin len (length of hashed pin could be variable, the offset of 84 * where this value lives in the file is calculated at run time) 85 * 9) Hashed pin 86 * 87 */ 88 89 /* Keystore description file pre-defined values */ 90 #define KS_PKCS11_VER "2.20" 91 #define KS_PKCS11_OFFSET 0 92 #define KS_PKCS11_VER_SIZE 32 93 94 #define KS_VER_OFFSET (KS_PKCS11_OFFSET + KS_PKCS11_VER_SIZE) 95 #define KS_VER_SIZE 4 /* size in bytes of keystore version value */ 96 97 #define KS_COUNTER_OFFSET (KS_VER_OFFSET + KS_VER_SIZE) 98 #define KS_COUNTER_SIZE 4 /* size in bytes of the monotonic counter */ 99 100 #define KS_KEY_SALT_OFFSET (KS_COUNTER_OFFSET + KS_COUNTER_SIZE) 101 #define KS_KEY_SALT_SIZE PBKD2_SALT_SIZE 102 103 #define KS_HMAC_SALT_OFFSET (KS_KEY_SALT_OFFSET + KS_KEY_SALT_SIZE) 104 #define KS_HMAC_SALT_SIZE PBKD2_SALT_SIZE 105 106 /* Salt for hashed pin */ 107 #define KS_HASHED_PIN_SALT_LEN_OFFSET (KS_HMAC_SALT_OFFSET + KS_HMAC_SALT_SIZE) 108 #define KS_HASHED_PIN_SALT_LEN_SIZE 8 /* stores length of hashed pin salt */ 109 110 #define KS_HASHED_PIN_SALT_OFFSET \ 111 (KS_HASHED_PIN_SALT_LEN_OFFSET + KS_HASHED_PIN_SALT_LEN_SIZE) 112 113 /* 114 * hashed pin 115 * 116 * hashed_pin length offset will be calculated at run time since 117 * there's the hashed pin salt size is variable. 118 * 119 * The offset will be calculated at run time by calling the 120 * function calculate_hashed_pin_offset() 121 */ 122 static off_t ks_hashed_pinlen_offset = -1; 123 #define KS_HASHED_PINLEN_SIZE 8 124 125 /* End of Keystore description file pre-defined values */ 126 127 /* 128 * Metadata for each object 129 * 130 * The order AND data type of all the fields is very important. 131 * All the code in this file assume that they are in the order specified 132 * below. If either order of the fields or their data type is changed, 133 * you must make sure the following pre-define value is still valid 134 * Each object will have the meta data at the beginning of the object file. 135 * 136 * 1) object_version: used by softtoken to see if the object 137 * has been modified since it last reads it. (uint_32) 138 * 2) iv: initialization vector for encrypted data in the object. This 139 * value will be 0 for public objects. (uchar_t[16]) 140 * 3) obj_hmac: keyed hash as verifier to detect private object 141 * being tampered this value will be 0 for public objects (uchar_t[16]) 142 */ 143 144 /* Object metadata pre-defined values */ 145 #define OBJ_VER_OFFSET 0 146 #define OBJ_VER_SIZE 4 /* size of object version in bytes */ 147 #define OBJ_IV_OFFSET (OBJ_VER_OFFSET + OBJ_VER_SIZE) 148 #define OBJ_IV_SIZE 16 149 #define OBJ_HMAC_OFFSET (OBJ_IV_OFFSET + OBJ_IV_SIZE) 150 #define OBJ_HMAC_SIZE 16 /* MD5 HMAC keyed hash */ 151 #define OBJ_DATA_OFFSET (OBJ_HMAC_OFFSET + OBJ_HMAC_SIZE) 152 /* End of object metadata pre-defined values */ 153 154 #define ALTERNATE_KEYSTORE_PATH "SOFTTOKEN_DIR" 155 156 static soft_object_t *enc_key = NULL; 157 static soft_object_t *hmac_key = NULL; 158 static char keystore_path[MAXPATHLEN]; 159 static boolean_t keystore_path_initialized = B_FALSE; 160 static int desc_fd = 0; 161 162 static char * 163 get_user_home_sunw_path(char *home_path) 164 { 165 struct passwd *user_info; 166 167 user_info = getpwuid(getuid()); 168 169 (void) snprintf(home_path, MAXPATHLEN, "%s/%s", 170 user_info ? user_info->pw_dir : "", SUNW_PATH); 171 172 return (home_path); 173 } 174 175 static char * 176 get_keystore_path() 177 { 178 char *env_val; 179 char home_path[MAXPATHLEN]; 180 181 if (!keystore_path_initialized) { 182 env_val = getenv(ALTERNATE_KEYSTORE_PATH); 183 bzero(keystore_path, sizeof (keystore_path)); 184 /* 185 * If it isn't set or is set to the empty string use the 186 * default location. We need to check for the empty string 187 * because some users "unset" environment variables by giving 188 * them no value, this isn't the same thing as removing it 189 * from the environment. 190 * 191 * We don't want that to attempt to open /.sunw/pkcs11_sofftoken 192 */ 193 if ((env_val == NULL) || (strcmp(env_val, "") == 0)) { 194 /* alternate path not specified, use user's home dir */ 195 (void) snprintf(keystore_path, MAXPATHLEN, "%s/%s", 196 get_user_home_sunw_path(home_path), KEYSTORE_PATH); 197 } else { 198 (void) snprintf(keystore_path, MAXPATHLEN, "%s/%s", 199 env_val, KEYSTORE_PATH); 200 } 201 keystore_path_initialized = B_TRUE; 202 } 203 return (keystore_path); 204 } 205 206 static char * 207 get_pub_obj_path(char *name) 208 { 209 bzero(name, sizeof (name)); 210 (void) snprintf(name, MAXPATHLEN, "%s/%s", 211 get_keystore_path(), PUB_OBJ_DIR); 212 return (name); 213 } 214 215 static char * 216 get_pri_obj_path(char *name) 217 { 218 bzero(name, sizeof (name)); 219 (void) snprintf(name, MAXPATHLEN, "%s/%s", 220 get_keystore_path(), PRI_OBJ_DIR); 221 return (name); 222 } 223 224 static char * 225 get_desc_file_path(char *name) 226 { 227 bzero(name, sizeof (name)); 228 (void) snprintf(name, MAXPATHLEN, "%s/%s", 229 get_keystore_path(), DS_FILE); 230 return (name); 231 } 232 233 static char * 234 get_tmp_desc_file_path(char *name) 235 { 236 bzero(name, sizeof (name)); 237 (void) snprintf(name, MAXPATHLEN, "%s/%s", 238 get_keystore_path(), TMP_DS_FILE); 239 return (name); 240 } 241 242 /* 243 * Calculates the offset for hashed_pin length and hashed pin 244 * 245 * Returns 0 if successful, -1 if there's any error. 246 * 247 * If successful, global variables "ks_hashed_pinlen_offset" will be set. 248 * 249 */ 250 static int 251 calculate_hashed_pin_offset(int fd) 252 { 253 uint64_t salt_length; 254 255 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET) 256 != KS_HASHED_PIN_SALT_LEN_OFFSET) { 257 return (-1); 258 } 259 260 if (looping_read(fd, (char *)&salt_length, 261 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 262 return (-1); 263 } 264 salt_length = SWAP64(salt_length); 265 266 ks_hashed_pinlen_offset = KS_HASHED_PIN_SALT_LEN_OFFSET 267 + KS_HASHED_PIN_SALT_LEN_SIZE + salt_length; 268 269 return (0); 270 271 } 272 273 /* 274 * acquire or release read/write lock on a specific file 275 * 276 * read_lock: true for read lock; false for write lock 277 * set_lock: true to set a lock; false to release a lock 278 */ 279 static int 280 lock_file(int fd, boolean_t read_lock, boolean_t set_lock) 281 { 282 283 flock_t lock_info; 284 int r; 285 286 lock_info.l_whence = SEEK_SET; 287 lock_info.l_start = 0; 288 lock_info.l_len = 0; /* l_len == 0 means until end of file */ 289 290 if (read_lock) { 291 lock_info.l_type = F_RDLCK; 292 } else { 293 lock_info.l_type = F_WRLCK; 294 } 295 296 if (set_lock) { 297 while ((r = fcntl(fd, F_SETLKW, &lock_info)) == -1) { 298 if (errno != EINTR) 299 break; 300 } 301 if (r == -1) { 302 return (-1); 303 } 304 } else { 305 lock_info.l_type = F_UNLCK; 306 while ((r = fcntl(fd, F_SETLKW, &lock_info)) == -1) { 307 if (errno != EINTR) 308 break; 309 } 310 if (r == -1) { 311 return (-1); 312 } 313 } 314 315 return (0); 316 } 317 318 static int 319 create_keystore() 320 { 321 int fd, buf; 322 uint64_t hashed_pin_len, hashed_pin_salt_len, ulong_buf; 323 uchar_t ver_buf[KS_PKCS11_VER_SIZE]; 324 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 325 ks_desc_file[MAXPATHLEN]; 326 CK_BYTE salt[KS_KEY_SALT_SIZE]; 327 char *hashed_pin = NULL, *hashed_pin_salt = NULL; 328 char *env_val; 329 330 /* keystore doesn't exist, create keystore directory */ 331 if (mkdir(get_keystore_path(), S_IRUSR|S_IWUSR|S_IXUSR) < 0) { 332 if (errno == EEXIST) { 333 return (0); 334 } 335 336 if (errno == EACCES) { 337 return (-1); 338 } 339 340 /* can't create keystore directory */ 341 if (errno == ENOENT) { /* part of the path doesn't exist */ 342 /* 343 * try to create $HOME/.sunw if it doesn't 344 * exist. If it is a alternate path provided by the 345 * user, it should have existed. Will not 346 * create for them. 347 */ 348 env_val = getenv(ALTERNATE_KEYSTORE_PATH); 349 if ((env_val == NULL) || (strcmp(env_val, "") == 0)) { 350 char sunw_path[MAXPATHLEN]; 351 352 /* create $HOME/.sunw */ 353 if (mkdir(get_user_home_sunw_path(sunw_path), 354 S_IRUSR|S_IWUSR|S_IXUSR) < 0) { 355 return (-1); 356 } 357 358 /* create $HOME/.sunw/pkcs11_softtoken */ 359 if (mkdir(get_keystore_path(), 360 S_IRUSR|S_IWUSR|S_IXUSR) < 0) { 361 return (-1); 362 } 363 } else { 364 return (-1); 365 } 366 } 367 } 368 369 /* create keystore description file */ 370 while ((fd = open(get_desc_file_path(ks_desc_file), 371 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR)) < 0) { 372 if (errno != EINTR) 373 break; 374 } 375 if (fd < 0) { 376 if (errno == EEXIST) { 377 return (0); 378 } else { 379 /* can't create keystore description file */ 380 (void) rmdir(get_keystore_path()); 381 return (-1); 382 } 383 } 384 385 /* Mark fd as "close on exec" */ 386 (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 387 388 if (lock_file(fd, B_FALSE, B_TRUE) != 0) { 389 (void) unlink(ks_desc_file); 390 (void) close(fd); 391 (void) rmdir(get_keystore_path()); 392 return (-1); 393 } 394 395 if (mkdir(get_pub_obj_path(pub_obj_path), 396 S_IRUSR|S_IWUSR|S_IXUSR) < 0) { 397 /* can't create directory for public objects */ 398 (void) lock_file(fd, B_FALSE, B_FALSE); 399 (void) unlink(ks_desc_file); 400 (void) close(fd); 401 (void) rmdir(get_keystore_path()); 402 return (-1); 403 } 404 405 if (mkdir(get_pri_obj_path(pri_obj_path), 406 S_IRUSR|S_IWUSR|S_IXUSR) < 0) { 407 /* can't create directory for private objects */ 408 (void) lock_file(fd, B_FALSE, B_FALSE); 409 (void) unlink(ks_desc_file); 410 (void) close(fd); 411 (void) rmdir(get_keystore_path()); 412 (void) rmdir(pub_obj_path); 413 return (-1); 414 } 415 416 417 /* write file format release number */ 418 bzero(ver_buf, sizeof (ver_buf)); 419 (void) strcpy((char *)ver_buf, KS_PKCS11_VER); 420 if ((looping_write(fd, (char *)ver_buf, sizeof (ver_buf))) 421 != sizeof (ver_buf)) { 422 goto cleanup; 423 } 424 425 /* write version number, version = 0 since keystore just created */ 426 buf = SWAP32(0); 427 if (looping_write(fd, (void *)&buf, KS_VER_SIZE) != KS_VER_SIZE) { 428 goto cleanup; 429 } 430 431 /* write monotonic-counter. Counter for keystore objects start at 1 */ 432 buf = SWAP32(1); 433 if (looping_write(fd, (void *)&buf, KS_COUNTER_SIZE) 434 != KS_COUNTER_SIZE) { 435 goto cleanup; 436 } 437 438 /* initial encryption key salt should be all NULL */ 439 bzero(salt, sizeof (salt)); 440 if (looping_write(fd, (void *)salt, KS_KEY_SALT_SIZE) 441 != KS_KEY_SALT_SIZE) { 442 goto cleanup; 443 } 444 445 /* initial HMAC key salt should also be all NULL */ 446 if (looping_write(fd, (void *)salt, KS_HMAC_SALT_SIZE) 447 != KS_HMAC_SALT_SIZE) { 448 goto cleanup; 449 } 450 451 /* generate the hashed pin salt, and MD5 hashed pin of default pin */ 452 if (soft_gen_hashed_pin((CK_CHAR_PTR)SOFT_DEFAULT_PIN, &hashed_pin, 453 &hashed_pin_salt) < 0) { 454 goto cleanup; 455 } 456 457 if ((hashed_pin_salt == NULL) || (hashed_pin == NULL)) { 458 goto cleanup; 459 } 460 461 hashed_pin_salt_len = (uint64_t)strlen(hashed_pin_salt); 462 hashed_pin_len = (uint64_t)strlen(hashed_pin); 463 464 /* write hashed pin salt length */ 465 ulong_buf = SWAP64(hashed_pin_salt_len); 466 if (looping_write(fd, (void *)&ulong_buf, KS_HASHED_PIN_SALT_LEN_SIZE) 467 != KS_HASHED_PIN_SALT_LEN_SIZE) { 468 goto cleanup; 469 } 470 471 if (looping_write(fd, (void *)hashed_pin_salt, 472 hashed_pin_salt_len) != hashed_pin_salt_len) { 473 goto cleanup; 474 } 475 476 /* write MD5 hashed pin of the default pin */ 477 ulong_buf = SWAP64(hashed_pin_len); 478 if (looping_write(fd, (void *)&ulong_buf, KS_HASHED_PINLEN_SIZE) 479 != KS_HASHED_PINLEN_SIZE) { 480 goto cleanup; 481 } 482 483 if (looping_write(fd, (void *)hashed_pin, hashed_pin_len) 484 != hashed_pin_len) { 485 goto cleanup; 486 } 487 488 (void) lock_file(fd, B_FALSE, B_FALSE); 489 490 (void) close(fd); 491 if (hashed_pin_salt) 492 free(hashed_pin_salt); 493 return (0); 494 495 cleanup: 496 (void) lock_file(fd, B_FALSE, B_FALSE); 497 (void) unlink(ks_desc_file); 498 (void) close(fd); 499 (void) rmdir(get_keystore_path()); 500 (void) rmdir(pub_obj_path); 501 (void) rmdir(pri_obj_path); 502 return (-1); 503 } 504 505 /* 506 * Determines if the file referenced by "fd" has the same 507 * inode as the file referenced by "fname". 508 * 509 * The argument "same" contains the result of determining 510 * if the inode is the same or not 511 * 512 * Returns 0 if there's no error. 513 * Returns 1 if there's any error with opening the file. 514 * 515 * 516 */ 517 static int 518 is_inode_same(int fd, char *fname, boolean_t *same) 519 { 520 struct stat fn_stat, fd_stat; 521 522 if (fstat(fd, &fd_stat) != 0) { 523 return (-1); 524 } 525 526 if (stat(fname, &fn_stat) != 0) { 527 return (-1); 528 } 529 530 /* It's the same file if both st_ino and st_dev match */ 531 if ((fd_stat.st_ino == fn_stat.st_ino) && 532 (fd_stat.st_dev == fn_stat.st_dev)) { 533 *same = B_TRUE; 534 } else { 535 *same = B_FALSE; 536 } 537 return (0); 538 } 539 540 static int 541 acquire_file_lock(int *fd, char *fname, mode_t mode) { 542 543 boolean_t read_lock = B_TRUE, same_inode; 544 545 if ((mode == O_RDWR) || (mode == O_WRONLY)) { 546 read_lock = B_FALSE; 547 } 548 549 if (lock_file(*fd, read_lock, B_TRUE) != 0) { 550 return (-1); 551 } 552 553 /* 554 * make sure another process did not modify the file 555 * while we were trying to get the lock 556 */ 557 if (is_inode_same(*fd, fname, &same_inode) != 0) { 558 (void) lock_file(*fd, B_TRUE, B_FALSE); /* unlock file */ 559 return (-1); 560 } 561 562 while (!same_inode) { 563 /* 564 * need to unlock file, close, re-open the file, 565 * and re-acquire the lock 566 */ 567 568 /* unlock file */ 569 if (lock_file(*fd, B_TRUE, B_FALSE) != 0) { 570 return (-1); 571 } 572 573 (void) close(*fd); 574 575 /* re-open */ 576 while ((*fd = open(fname, mode|O_NONBLOCK)) < 0) { 577 if (errno != EINTR) 578 break; 579 } 580 if (*fd < 0) { 581 return (-1); 582 } 583 584 (void) fcntl(*fd, F_SETFD, FD_CLOEXEC); 585 586 /* acquire lock again */ 587 if (lock_file(*fd, read_lock, B_TRUE) != 0) { 588 return (-1); 589 } 590 591 if (is_inode_same(*fd, fname, &same_inode) != 0) { 592 (void) lock_file(*fd, B_TRUE, B_FALSE); /* unlock */ 593 return (-1); 594 } 595 596 } 597 598 return (0); 599 } 600 601 /* 602 * Open the keystore description file in the specified mode. 603 * If the keystore doesn't exist, the "do_create_keystore" 604 * argument determines if the keystore should be created 605 */ 606 static int 607 open_and_lock_keystore_desc(mode_t mode, boolean_t do_create_keystore, 608 boolean_t lock_held) 609 { 610 611 int fd; 612 char *fname, ks_desc_file[MAXPATHLEN]; 613 614 /* open the keystore description file in requested mode */ 615 fname = get_desc_file_path(ks_desc_file); 616 while ((fd = open(fname, mode|O_NONBLOCK)) < 0) { 617 if (errno != EINTR) 618 break; 619 } 620 if (fd < 0) { 621 soft_token_present = B_FALSE; 622 if ((errno == ENOENT) && (do_create_keystore)) { 623 if (create_keystore() < 0) { 624 goto done; 625 } 626 while ((fd = open(fname, mode|O_NONBLOCK)) < 0) { 627 if (errno != EINTR) 628 break; 629 } 630 if (fd < 0) { 631 goto done; 632 } else { 633 (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 634 } 635 } else { 636 goto done; 637 } 638 } else { 639 (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 640 } 641 642 soft_token_present = B_TRUE; 643 644 if (lock_held) { 645 /* already hold the lock */ 646 return (fd); 647 } 648 649 if (acquire_file_lock(&fd, fname, mode) != 0) { 650 if (fd > 0) { 651 (void) close(fd); 652 } 653 return (-1); 654 } 655 656 done: 657 return (fd); 658 } 659 660 661 /* 662 * Set or remove read or write lock on keystore description file 663 * 664 * read_lock: true for read lock, false for write lock 665 * set_lock: true for set a lock, false to remove a lock 666 */ 667 static int 668 lock_desc_file(boolean_t read_lock, boolean_t set_lock) 669 { 670 671 char ks_desc_file[MAXPATHLEN]; 672 673 if (set_lock) { 674 int oflag; 675 676 /* 677 * make sure desc_fd is not already used. If used, it means 678 * some other lock is already set on the file 679 */ 680 if (desc_fd > 0) { 681 return (-1); 682 } 683 684 (void) get_desc_file_path(ks_desc_file); 685 686 if (read_lock) { 687 oflag = O_RDONLY; 688 } else { 689 oflag = O_WRONLY; 690 } 691 if ((desc_fd = open_and_lock_keystore_desc(oflag, 692 B_FALSE, B_FALSE)) < 0) { 693 return (-1); 694 } 695 } else { 696 /* make sure we have a valid fd */ 697 if (desc_fd <= 0) { 698 return (-1); 699 } 700 701 if (lock_file(desc_fd, read_lock, B_FALSE) == 1) { 702 return (-1); 703 } 704 705 (void) close(desc_fd); 706 desc_fd = 0; 707 708 } 709 return (0); 710 } 711 712 static int 713 open_and_lock_object_file(ks_obj_handle_t *ks_handle, int oflag, 714 boolean_t lock_held) 715 { 716 char obj_fname[MAXPATHLEN]; 717 int fd; 718 719 if (ks_handle->public) { 720 char pub_obj_path[MAXPATHLEN]; 721 (void) snprintf(obj_fname, MAXPATHLEN, "%s/%s", 722 get_pub_obj_path(pub_obj_path), ks_handle->name); 723 } else { 724 char pri_obj_path[MAXPATHLEN]; 725 (void) snprintf(obj_fname, MAXPATHLEN, "%s/%s", 726 get_pri_obj_path(pri_obj_path), ks_handle->name); 727 } 728 729 while ((fd = open(obj_fname, oflag|O_NONBLOCK)) < 0) { 730 if (errno != EINTR) 731 break; 732 } 733 if (fd < 0) { 734 return (-1); 735 } 736 737 (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 738 739 if (lock_held) { 740 /* already hold the lock */ 741 return (fd); 742 } 743 744 if (acquire_file_lock(&fd, obj_fname, oflag) != 0) { 745 if (fd > 0) { 746 (void) close(fd); 747 } 748 return (-1); 749 } 750 751 752 return (fd); 753 } 754 755 756 /* 757 * Update file version number in a temporary file that's 758 * a copy of the keystore description file. 759 * The update is NOT made to the original keystore description 760 * file. It makes the update in a tempoary file. 761 * 762 * Name of the temporary file is assumed to be provided, but 763 * the file is assumed to not exist. 764 * 765 * return 0 if creating temp file is successful, returns -1 otherwise 766 */ 767 static int 768 create_updated_keystore_version(int fd, char *tmp_fname) 769 { 770 int version, tmp_fd; 771 char buf[BUFSIZ]; 772 size_t nread; 773 774 /* first, create the tempoary file */ 775 while ((tmp_fd = open(tmp_fname, 776 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR)) < 0) { 777 if (errno != EINTR) 778 break; 779 } 780 if (tmp_fd < 0) { 781 return (-1); 782 } 783 (void) fcntl(tmp_fd, F_SETFD, FD_CLOEXEC); 784 785 /* 786 * copy everything from keystore version to temp file except 787 * the keystore version. Keystore version is updated 788 * 789 */ 790 791 /* pkcs11 version */ 792 if (looping_read(fd, buf, KS_PKCS11_VER_SIZE) != KS_PKCS11_VER_SIZE) { 793 goto cleanup; 794 } 795 796 if (looping_write(tmp_fd, buf, KS_PKCS11_VER_SIZE) 797 != KS_PKCS11_VER_SIZE) { 798 goto cleanup; 799 } 800 801 /* version number, it needs to be updated */ 802 803 /* read the current version number */ 804 if (looping_read(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) { 805 goto cleanup; 806 } 807 808 version = SWAP32(version); 809 version++; 810 version = SWAP32(version); 811 812 /* write the updated value to the tmp file */ 813 if (looping_write(tmp_fd, (void *)&version, KS_VER_SIZE) 814 != KS_VER_SIZE) { 815 goto cleanup; 816 } 817 818 /* read rest of information, nothing needs to be updated */ 819 nread = looping_read(fd, buf, BUFSIZ); 820 while (nread > 0) { 821 if (looping_write(tmp_fd, buf, nread) != nread) { 822 goto cleanup; 823 } 824 nread = looping_read(fd, buf, BUFSIZ); 825 } 826 827 (void) close(tmp_fd); 828 return (0); /* no error */ 829 830 cleanup: 831 (void) close(tmp_fd); 832 (void) remove(tmp_fname); 833 return (-1); 834 } 835 836 static CK_RV 837 get_all_objs_in_dir(DIR *dirp, ks_obj_handle_t *ks_handle, 838 ks_obj_t **result_obj_list, boolean_t lock_held) 839 { 840 struct dirent *dp; 841 ks_obj_t *obj; 842 CK_RV rv; 843 844 while ((dp = readdir(dirp)) != NULL) { 845 846 if ((strcmp(dp->d_name, ".") == 0) || 847 (strcmp(dp->d_name, "..") == 0)) { 848 continue; 849 } 850 851 (void) strcpy((char *)ks_handle->name, dp->d_name); 852 rv = soft_keystore_get_single_obj(ks_handle, &obj, lock_held); 853 if (rv != CKR_OK) { 854 return (rv); 855 } 856 if (obj != NULL) { 857 if (*result_obj_list == NULL) { 858 *result_obj_list = obj; 859 } else { 860 obj->next = *result_obj_list; 861 *result_obj_list = obj; 862 } 863 } 864 } 865 return (CKR_OK); 866 } 867 868 /* 869 * This function prepares the obj data for encryption by prepending 870 * the FULL path of the file that will be used for storing 871 * the object. Having full path of the file as part of 872 * of the data for the object will prevent an attacker from 873 * copying a "bad" object into the keystore undetected. 874 * 875 * This function will always allocate: 876 * MAXPATHLEN + buf_len 877 * amount of data. If the full path of the filename doesn't occupy 878 * the whole MAXPATHLEN, the rest of the space will just be empty. 879 * It is the caller's responsibility to free the buffer allocated here. 880 * 881 * The allocated buffer is returned in the variable "prepared_buf" 882 * if there's no error. 883 * 884 * Returns 0 if there's no error, -1 otherwise. 885 */ 886 static int 887 prepare_data_for_encrypt(char *obj_path, unsigned char *buf, CK_ULONG buf_len, 888 unsigned char **prepared_buf, CK_ULONG *prepared_len) 889 { 890 *prepared_len = MAXPATHLEN + buf_len; 891 *prepared_buf = malloc(*prepared_len); 892 if (*prepared_buf == NULL) { 893 return (-1); 894 } 895 896 /* 897 * only zero out the space for the path name. I could zero out 898 * the whole buffer, but that will be a waste of processing 899 * cycle since the rest of the buffer will be 100% filled all 900 * the time 901 */ 902 bzero(*prepared_buf, MAXPATHLEN); 903 (void) memcpy(*prepared_buf, obj_path, strlen(obj_path)); 904 (void) memcpy(*prepared_buf + MAXPATHLEN, buf, buf_len); 905 return (0); 906 } 907 908 /* 909 * retrieves the hashed pin from the keystore 910 */ 911 static CK_RV 912 get_hashed_pin(int fd, char **hashed_pin) 913 { 914 uint64_t hashed_pin_size; 915 916 if (ks_hashed_pinlen_offset == -1) { 917 if (calculate_hashed_pin_offset(fd) != 0) { 918 return (CKR_FUNCTION_FAILED); 919 } 920 } 921 922 /* first, get size of the hashed pin */ 923 if (lseek(fd, ks_hashed_pinlen_offset, SEEK_SET) 924 != ks_hashed_pinlen_offset) { 925 return (CKR_FUNCTION_FAILED); 926 } 927 928 if (looping_read(fd, (char *)&hashed_pin_size, 929 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) { 930 return (CKR_FUNCTION_FAILED); 931 } 932 933 hashed_pin_size = SWAP64(hashed_pin_size); 934 935 *hashed_pin = malloc(hashed_pin_size + 1); 936 if (*hashed_pin == NULL) { 937 return (CKR_HOST_MEMORY); 938 } 939 940 if ((looping_read(fd, *hashed_pin, hashed_pin_size)) 941 != (ssize_t)hashed_pin_size) { 942 free(*hashed_pin); 943 *hashed_pin = NULL; 944 return (CKR_FUNCTION_FAILED); 945 } 946 (*hashed_pin)[hashed_pin_size] = '\0'; 947 return (CKR_OK); 948 } 949 950 951 /* 952 * FUNCTION: soft_keystore_lock 953 * 954 * ARGUMENTS: 955 * set_lock: TRUE to set readlock on the keystore object file, 956 * FALSE to remove readlock on keystore object file. 957 * 958 * RETURN VALUE: 959 * 960 * 0: success 961 * -1: failure 962 * 963 * DESCRIPTION: 964 * 965 * set or remove readlock on the keystore description file. 966 */ 967 int 968 soft_keystore_readlock(boolean_t set_lock) 969 { 970 971 return (lock_desc_file(B_TRUE, set_lock)); 972 } 973 974 975 /* 976 * FUNCTION: soft_keystore_writelock 977 * 978 * ARGUMENTS: 979 * set_lock: TRUE to set writelock on the keystore description file 980 * FALSE to remove write lock on keystore description file. 981 * 982 * RETURN VALUE: 983 * 984 * 0: no error 985 * 1: some error occurred 986 * 987 * DESCRIPTION: 988 * set/reset writelock on the keystore description file. 989 */ 990 int 991 soft_keystore_writelock(boolean_t set_lock) 992 { 993 return (lock_desc_file(B_FALSE, set_lock)); 994 995 } 996 997 /* 998 * 999 * FUNCTION: soft_keystore_lock_object 1000 * 1001 * ARGUMENTS: 1002 * 1003 * ks_handle: handle of the keystore object file to be accessed. 1004 * read_lock: TRUE to set readlock on the keystore object file, 1005 * FALSE to set writelock on keystore object file. 1006 * 1007 * RETURN VALUE: 1008 * 1009 * If no error, file descriptor of locked file will be returned 1010 * -1: some error occurred 1011 * 1012 * DESCRIPTION: 1013 * 1014 * set readlock or writelock on the keystore object file. 1015 */ 1016 int 1017 soft_keystore_lock_object(ks_obj_handle_t *ks_handle, boolean_t read_lock) 1018 { 1019 int fd; 1020 int oflag; 1021 1022 if (read_lock) { 1023 oflag = O_RDONLY; 1024 } else { 1025 oflag = O_WRONLY; 1026 } 1027 1028 if ((fd = open_and_lock_object_file(ks_handle, oflag, B_FALSE)) < 0) { 1029 return (-1); 1030 } 1031 1032 return (fd); 1033 } 1034 1035 /* 1036 * FUNCTION: soft_keystore_unlock_object 1037 * 1038 * ARGUMENTS: 1039 * fd: file descriptor returned from soft_keystore_lock_object 1040 * 1041 * RETURN VALUE: 1042 * 0: no error 1043 * 1: some error occurred while getting the pin 1044 * 1045 * DESCRIPTION: 1046 * set/reset writelock on the keystore object file. 1047 */ 1048 int 1049 soft_keystore_unlock_object(int fd) 1050 { 1051 if (lock_file(fd, B_TRUE, B_FALSE) != 0) { 1052 return (1); 1053 } 1054 1055 (void) close(fd); 1056 return (0); 1057 } 1058 1059 1060 1061 /* 1062 * FUNCTION: soft_keystore_get_version 1063 * 1064 * ARGUMENTS: 1065 * version: pointer to caller allocated memory for storing 1066 * the version of the keystore. 1067 * lock_held: TRUE if the lock is held by caller. 1068 * 1069 * RETURN VALUE: 1070 * 1071 * 0: no error 1072 * -1: some error occurred while getting the version number 1073 * 1074 * DESCRIPTION: 1075 * get the version number of the keystore from keystore 1076 * description file. 1077 */ 1078 int 1079 soft_keystore_get_version(uint_t *version, boolean_t lock_held) 1080 { 1081 1082 int fd, ret_val = 0; 1083 uint_t buf; 1084 1085 if ((fd = open_and_lock_keystore_desc(O_RDONLY, 1086 B_TRUE, lock_held)) < 0) { 1087 return (-1); 1088 } 1089 1090 if (lseek(fd, KS_VER_OFFSET, SEEK_SET) != KS_VER_OFFSET) { 1091 ret_val = -1; 1092 goto cleanup; 1093 } 1094 1095 if (looping_read(fd, (char *)&buf, KS_VER_SIZE) != KS_VER_SIZE) { 1096 ret_val = -1; 1097 goto cleanup; 1098 } 1099 *version = SWAP32(buf); 1100 1101 cleanup: 1102 1103 if (!lock_held) { 1104 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 1105 ret_val = -1; 1106 } 1107 } 1108 1109 (void) close(fd); 1110 return (ret_val); 1111 } 1112 1113 /* 1114 * FUNCTION: soft_keystore_get_object_version 1115 * 1116 * ARGUMENTS: 1117 * 1118 * ks_handle: handle of the key store object to be accessed. 1119 * version: 1120 * pointer to caller allocated memory for storing 1121 * the version of the object. 1122 * lock_held: TRUE if the lock is held by caller. 1123 * 1124 * RETURN VALUE: 1125 * 1126 * 0: no error 1127 * -1: some error occurred while getting the pin 1128 * 1129 * DESCRIPTION: 1130 * get the version number of the specified token object. 1131 */ 1132 int 1133 soft_keystore_get_object_version(ks_obj_handle_t *ks_handle, 1134 uint_t *version, boolean_t lock_held) 1135 { 1136 int fd, ret_val = 0; 1137 uint_t tmp; 1138 1139 if ((fd = open_and_lock_object_file(ks_handle, O_RDONLY, 1140 lock_held)) < 0) { 1141 return (-1); 1142 } 1143 1144 /* 1145 * read version. Version is always first item in object file 1146 * so, no need to do lseek 1147 */ 1148 if (looping_read(fd, (char *)&tmp, OBJ_VER_SIZE) != OBJ_VER_SIZE) { 1149 ret_val = -1; 1150 goto cleanup; 1151 } 1152 1153 *version = SWAP32(tmp); 1154 1155 cleanup: 1156 if (!lock_held) { 1157 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 1158 ret_val = -1; 1159 } 1160 } 1161 1162 1163 (void) close(fd); 1164 return (ret_val); 1165 } 1166 1167 /* 1168 * FUNCTION: soft_keystore_getpin 1169 * 1170 * ARGUMENTS: 1171 * hashed_pin: pointer to caller allocated memory 1172 * for storing the pin to be returned. 1173 * lock_held: TRUE if the lock is held by caller. 1174 * 1175 * RETURN VALUE: 1176 * 1177 * 0: no error 1178 * -1: some error occurred while getting the pin 1179 * 1180 * DESCRIPTION: 1181 * 1182 * Reads the MD5 hash from the keystore description 1183 * file and return it to the caller in the provided 1184 * buffer. If there is no PIN in the description file 1185 * because the file is just created, this function 1186 * will get a MD5 digest of the string "changeme", 1187 * store it in the file, and also return this 1188 * string to the caller. 1189 */ 1190 int 1191 soft_keystore_getpin(char **hashed_pin, boolean_t lock_held) 1192 { 1193 int fd, ret_val = -1; 1194 CK_RV rv; 1195 1196 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_TRUE, 1197 lock_held)) < 0) { 1198 return (-1); 1199 } 1200 1201 rv = get_hashed_pin(fd, hashed_pin); 1202 if (rv == CKR_OK) { 1203 ret_val = 0; 1204 } 1205 1206 cleanup: 1207 if (!lock_held) { 1208 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 1209 ret_val = -1; 1210 } 1211 } 1212 1213 (void) close(fd); 1214 return (ret_val); 1215 } 1216 1217 /* 1218 * This function reads all the data until the end of the file, and 1219 * put the data into the "buf" in argument. Memory for buf will 1220 * be allocated in this function. It is the caller's responsibility 1221 * to free it. The number of bytes read will be returned 1222 * in the argument "bytes_read" 1223 * 1224 * returns CKR_OK if no error. Other CKR error codes if there's an error 1225 */ 1226 static CK_RV 1227 read_obj_data(int old_fd, char **buf, ssize_t *bytes_read) 1228 { 1229 1230 ssize_t nread, loop_count; 1231 char *buf1 = NULL; 1232 1233 *buf = malloc(BUFSIZ); 1234 if (*buf == NULL) { 1235 return (CKR_HOST_MEMORY); 1236 } 1237 1238 nread = looping_read(old_fd, *buf, BUFSIZ); 1239 if (nread < 0) { 1240 free(*buf); 1241 return (CKR_FUNCTION_FAILED); 1242 } 1243 loop_count = 1; 1244 while (nread == (loop_count * BUFSIZ)) { 1245 ssize_t nread_tmp; 1246 1247 loop_count++; 1248 /* more than BUFSIZ of data */ 1249 buf1 = realloc(*buf, loop_count * BUFSIZ); 1250 if (buf1 == NULL) { 1251 free(*buf); 1252 return (CKR_HOST_MEMORY); 1253 } 1254 *buf = buf1; 1255 nread_tmp = looping_read(old_fd, 1256 *buf + ((loop_count - 1) * BUFSIZ), BUFSIZ); 1257 if (nread_tmp < 0) { 1258 free(*buf); 1259 return (CKR_FUNCTION_FAILED); 1260 } 1261 nread += nread_tmp; 1262 } 1263 *bytes_read = nread; 1264 return (CKR_OK); 1265 } 1266 1267 /* 1268 * Re-encrypt an object using the provided new_enc_key. The new HMAC 1269 * is calculated using the new_hmac_key. The global static variables 1270 * enc_key, and hmac_key will be used for decrypting the original 1271 * object, and verifying its signature. 1272 * 1273 * The re-encrypted object will be stored in the file named 1274 * in the "new_obj_name" variable. The content of the "original" 1275 * file named in "orig_obj_name" is not disturbed. 1276 * 1277 * Returns 0 if there's no error, returns -1 otherwise. 1278 * 1279 */ 1280 static int 1281 reencrypt_obj(soft_object_t *new_enc_key, soft_object_t *new_hmac_key, 1282 char *orig_obj_name, char *new_obj_name) { 1283 1284 int old_fd, new_fd, version, ret_val = -1; 1285 CK_BYTE iv[OBJ_IV_SIZE], old_iv[OBJ_IV_SIZE]; 1286 ssize_t nread; 1287 CK_ULONG decrypted_len, encrypted_len, hmac_len; 1288 CK_BYTE hmac[OBJ_HMAC_SIZE], *decrypted_buf = NULL, *buf = NULL; 1289 1290 while ((old_fd = open(orig_obj_name, O_RDONLY|O_NONBLOCK)) < 0) { 1291 if (errno != EINTR) 1292 break; 1293 } 1294 if (old_fd < 0) { 1295 return (-1); 1296 } 1297 1298 (void) fcntl(old_fd, F_SETFD, FD_CLOEXEC); 1299 1300 if (acquire_file_lock(&old_fd, orig_obj_name, O_RDONLY) != 0) { 1301 if (old_fd > 0) { 1302 (void) close(old_fd); 1303 } 1304 return (-1); 1305 } 1306 1307 while ((new_fd = open(new_obj_name, 1308 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR)) < 0) { 1309 if (errno != EINTR) 1310 break; 1311 } 1312 if (new_fd < 0) { 1313 (void) close(old_fd); 1314 return (-1); 1315 } 1316 1317 (void) fcntl(new_fd, F_SETFD, FD_CLOEXEC); 1318 1319 if (lock_file(new_fd, B_FALSE, B_TRUE) != 0) { 1320 /* unlock old file */ 1321 (void) lock_file(old_fd, B_TRUE, B_FALSE); 1322 (void) close(old_fd); 1323 (void) close(new_fd); 1324 return (-1); 1325 } 1326 1327 /* read version, increment, and write to tmp file */ 1328 if (looping_read(old_fd, (char *)&version, OBJ_VER_SIZE) 1329 != OBJ_VER_SIZE) { 1330 goto cleanup; 1331 } 1332 1333 version = SWAP32(version); 1334 version++; 1335 version = SWAP32(version); 1336 1337 if (looping_write(new_fd, (char *)&version, OBJ_VER_SIZE) 1338 != OBJ_VER_SIZE) { 1339 goto cleanup; 1340 } 1341 1342 /* read old iv */ 1343 if (looping_read(old_fd, (char *)old_iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 1344 goto cleanup; 1345 } 1346 1347 /* generate new IV */ 1348 if (soft_gen_iv(iv) != CKR_OK) { 1349 goto cleanup; 1350 } 1351 1352 if (looping_write(new_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 1353 goto cleanup; 1354 } 1355 1356 /* seek to the original encrypted data, and read all of them */ 1357 if (lseek(old_fd, OBJ_DATA_OFFSET, SEEK_SET) != OBJ_DATA_OFFSET) { 1358 goto cleanup; 1359 } 1360 1361 if (read_obj_data(old_fd, (char **)&buf, &nread) != CKR_OK) { 1362 goto cleanup; 1363 } 1364 1365 /* decrypt data using old key */ 1366 decrypted_len = 0; 1367 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread, 1368 NULL, &decrypted_len) != CKR_OK) { 1369 free(buf); 1370 goto cleanup; 1371 } 1372 1373 decrypted_buf = malloc(decrypted_len); 1374 if (decrypted_buf == NULL) { 1375 free(buf); 1376 goto cleanup; 1377 } 1378 1379 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread, 1380 decrypted_buf, &decrypted_len) != CKR_OK) { 1381 free(buf); 1382 free(decrypted_buf); 1383 goto cleanup; 1384 } 1385 1386 free(buf); 1387 1388 /* re-encrypt with new key */ 1389 encrypted_len = 0; 1390 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf, 1391 decrypted_len, NULL, &encrypted_len) != CKR_OK) { 1392 free(decrypted_buf); 1393 goto cleanup; 1394 } 1395 1396 buf = malloc(encrypted_len); 1397 if (buf == NULL) { 1398 free(decrypted_buf); 1399 goto cleanup; 1400 } 1401 1402 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf, 1403 decrypted_len, buf, &encrypted_len) != CKR_OK) { 1404 free(buf); 1405 free(decrypted_buf); 1406 goto cleanup; 1407 } 1408 1409 free(decrypted_buf); 1410 1411 /* calculate hmac on re-encrypted data using new hmac key */ 1412 hmac_len = OBJ_HMAC_SIZE; 1413 if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf, 1414 encrypted_len, hmac, &hmac_len) != CKR_OK) { 1415 free(buf); 1416 goto cleanup; 1417 } 1418 1419 /* just for sanity check */ 1420 if (hmac_len != OBJ_HMAC_SIZE) { 1421 free(buf); 1422 goto cleanup; 1423 } 1424 1425 /* write new hmac */ 1426 if (looping_write(new_fd, (char *)hmac, OBJ_HMAC_SIZE) 1427 != OBJ_HMAC_SIZE) { 1428 free(buf); 1429 goto cleanup; 1430 } 1431 1432 /* write re-encrypted buffer to temp file */ 1433 if (looping_write(new_fd, (void *)buf, encrypted_len) 1434 != encrypted_len) { 1435 free(buf); 1436 goto cleanup; 1437 } 1438 free(buf); 1439 ret_val = 0; 1440 1441 cleanup: 1442 /* unlock the files */ 1443 (void) lock_file(old_fd, B_TRUE, B_FALSE); 1444 (void) lock_file(new_fd, B_FALSE, B_FALSE); 1445 1446 (void) close(old_fd); 1447 (void) close(new_fd); 1448 if (ret_val != 0) { 1449 (void) remove(new_obj_name); 1450 } 1451 return (ret_val); 1452 } 1453 1454 /* 1455 * FUNCTION: soft_keystore_setpin 1456 * 1457 * ARGUMENTS: 1458 * newpin: new pin entered by the user. 1459 * lock_held: TRUE if the lock is held by caller. 1460 * 1461 * RETURN VALUE: 1462 * 0: no error 1463 * -1: failure 1464 * 1465 * DESCRIPTION: 1466 * 1467 * This function does the following: 1468 * 1469 * 1) Generates crypted value of newpin and store it 1470 * in keystore description file. 1471 * 2) Dervies the new encryption key from the newpin. This key 1472 * will be used to re-encrypt the private token objects. 1473 * 3) Re-encrypt all of this user's existing private token 1474 * objects (if any). 1475 * 4) Increments the keystore version number. 1476 */ 1477 int 1478 soft_keystore_setpin(uchar_t *oldpin, uchar_t *newpin, boolean_t lock_held) 1479 { 1480 int fd, tmp_ks_fd, version, ret_val = -1; 1481 soft_object_t *new_crypt_key = NULL, *new_hmac_key = NULL; 1482 char filebuf[BUFSIZ]; 1483 DIR *pri_dirp; 1484 struct dirent *pri_ent; 1485 char pri_obj_path[MAXPATHLEN], ks_desc_file[MAXPATHLEN], 1486 tmp_ks_desc_name[MAXPATHLEN]; 1487 typedef struct priobjs { 1488 char orig_name[MAXPATHLEN]; 1489 char tmp_name[MAXPATHLEN]; 1490 struct priobjs *next; 1491 } priobjs_t; 1492 priobjs_t *pri_objs = NULL, *tmp; 1493 CK_BYTE *crypt_salt = NULL, *hmac_salt = NULL; 1494 boolean_t pin_never_set = B_FALSE, user_logged_in; 1495 char *new_hashed_pin = NULL; 1496 uint64_t hashed_pin_salt_length, new_hashed_pin_len, swaped_val; 1497 char *hashed_pin_salt = NULL; 1498 priobjs_t *obj; 1499 1500 if ((enc_key == NULL) || 1501 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 1502 user_logged_in = B_FALSE; 1503 } else { 1504 user_logged_in = B_TRUE; 1505 } 1506 1507 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 1508 lock_held)) < 0) { 1509 return (-1); 1510 } 1511 1512 (void) get_desc_file_path(ks_desc_file); 1513 (void) get_tmp_desc_file_path(tmp_ks_desc_name); 1514 1515 /* 1516 * create a tempoary file for the keystore description 1517 * file for updating version and counter information 1518 */ 1519 while ((tmp_ks_fd = open(tmp_ks_desc_name, 1520 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR)) < 0) { 1521 if (errno != EINTR) 1522 break; 1523 } 1524 if (tmp_ks_fd < 0) { 1525 (void) close(fd); 1526 return (-1); 1527 } 1528 (void) fcntl(tmp_ks_fd, F_SETFD, FD_CLOEXEC); 1529 1530 /* read and write PKCS version to temp file */ 1531 if (looping_read(fd, filebuf, KS_PKCS11_VER_SIZE) 1532 != KS_PKCS11_VER_SIZE) { 1533 goto cleanup; 1534 } 1535 1536 if (looping_write(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE) 1537 != KS_PKCS11_VER_SIZE) { 1538 goto cleanup; 1539 } 1540 1541 /* get version number, and write updated number to temp file */ 1542 if (looping_read(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) { 1543 goto cleanup; 1544 } 1545 1546 version = SWAP32(version); 1547 version++; 1548 version = SWAP32(version); 1549 1550 if (looping_write(tmp_ks_fd, (void *)&version, KS_VER_SIZE) 1551 != KS_VER_SIZE) { 1552 goto cleanup; 1553 } 1554 1555 1556 /* read and write counter, no modification necessary */ 1557 if (looping_read(fd, filebuf, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) { 1558 goto cleanup; 1559 } 1560 1561 if (looping_write(tmp_ks_fd, filebuf, KS_COUNTER_SIZE) 1562 != KS_COUNTER_SIZE) { 1563 goto cleanup; 1564 } 1565 1566 /* read old encryption salt */ 1567 crypt_salt = malloc(KS_KEY_SALT_SIZE); 1568 if (crypt_salt == NULL) { 1569 goto cleanup; 1570 } 1571 if (looping_read(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 1572 != KS_KEY_SALT_SIZE) { 1573 goto cleanup; 1574 } 1575 1576 /* read old hmac salt */ 1577 hmac_salt = malloc(KS_HMAC_SALT_SIZE); 1578 if (hmac_salt == NULL) { 1579 goto cleanup; 1580 } 1581 if (looping_read(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE) 1582 != KS_HMAC_SALT_SIZE) { 1583 goto cleanup; 1584 } 1585 1586 /* just create some empty bytes */ 1587 bzero(filebuf, sizeof (filebuf)); 1588 1589 if (memcmp(crypt_salt, filebuf, KS_KEY_SALT_SIZE) == 0) { 1590 /* PIN as never been set */ 1591 CK_BYTE *new_crypt_salt = NULL, *new_hmac_salt = NULL; 1592 1593 pin_never_set = B_TRUE; 1594 if (soft_gen_crypt_key(newpin, &new_crypt_key, &new_crypt_salt) 1595 != CKR_OK) { 1596 goto cleanup; 1597 } 1598 if (looping_write(tmp_ks_fd, (void *)new_crypt_salt, 1599 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) { 1600 free(new_crypt_salt); 1601 (void) soft_cleanup_object(new_crypt_key); 1602 goto cleanup; 1603 } 1604 free(new_crypt_salt); 1605 1606 if (soft_gen_hmac_key(newpin, &new_hmac_key, &new_hmac_salt) 1607 != CKR_OK) { 1608 (void) soft_cleanup_object(new_crypt_key); 1609 goto cleanup; 1610 } 1611 if (looping_write(tmp_ks_fd, (void *)new_hmac_salt, 1612 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) { 1613 free(new_hmac_salt); 1614 goto cleanup3; 1615 } 1616 free(new_hmac_salt); 1617 } else { 1618 if (soft_gen_crypt_key(newpin, &new_crypt_key, 1619 (CK_BYTE **)&crypt_salt) != CKR_OK) { 1620 goto cleanup; 1621 } 1622 /* no change to the encryption salt */ 1623 if (looping_write(tmp_ks_fd, (void *)crypt_salt, 1624 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) { 1625 (void) soft_cleanup_object(new_crypt_key); 1626 goto cleanup; 1627 } 1628 1629 if (soft_gen_hmac_key(newpin, &new_hmac_key, 1630 (CK_BYTE **)&hmac_salt) != CKR_OK) { 1631 (void) soft_cleanup_object(new_crypt_key); 1632 goto cleanup; 1633 } 1634 1635 /* no change to the hmac salt */ 1636 if (looping_write(tmp_ks_fd, (void *)hmac_salt, 1637 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) { 1638 goto cleanup3; 1639 } 1640 } 1641 1642 /* 1643 * read hashed pin salt, and write to updated keystore description 1644 * file unmodified. 1645 */ 1646 if (looping_read(fd, (char *)&hashed_pin_salt_length, 1647 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 1648 goto cleanup3; 1649 } 1650 1651 if (looping_write(tmp_ks_fd, (void *)&hashed_pin_salt_length, 1652 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 1653 goto cleanup3; 1654 } 1655 1656 hashed_pin_salt_length = SWAP64(hashed_pin_salt_length); 1657 1658 hashed_pin_salt = malloc(hashed_pin_salt_length + 1); 1659 if (hashed_pin_salt == NULL) { 1660 goto cleanup3; 1661 } 1662 1663 if ((looping_read(fd, hashed_pin_salt, hashed_pin_salt_length)) != 1664 (ssize_t)hashed_pin_salt_length) { 1665 free(hashed_pin_salt); 1666 goto cleanup3; 1667 } 1668 1669 if ((looping_write(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length)) 1670 != (ssize_t)hashed_pin_salt_length) { 1671 free(hashed_pin_salt); 1672 goto cleanup3; 1673 } 1674 1675 hashed_pin_salt[hashed_pin_salt_length] = '\0'; 1676 1677 /* old hashed pin length and value can be ignored, generate new one */ 1678 if (soft_gen_hashed_pin(newpin, &new_hashed_pin, 1679 &hashed_pin_salt) < 0) { 1680 free(hashed_pin_salt); 1681 goto cleanup3; 1682 } 1683 1684 free(hashed_pin_salt); 1685 1686 if (new_hashed_pin == NULL) { 1687 goto cleanup3; 1688 } 1689 1690 new_hashed_pin_len = strlen(new_hashed_pin); 1691 1692 /* write new hashed pin length to file */ 1693 swaped_val = SWAP64(new_hashed_pin_len); 1694 if (looping_write(tmp_ks_fd, (void *)&swaped_val, 1695 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) { 1696 goto cleanup3; 1697 } 1698 1699 if (looping_write(tmp_ks_fd, (void *)new_hashed_pin, 1700 new_hashed_pin_len) != (ssize_t)new_hashed_pin_len) { 1701 goto cleanup3; 1702 } 1703 1704 if (pin_never_set) { 1705 /* there was no private object, no need to re-encrypt them */ 1706 goto rename_desc_file; 1707 } 1708 1709 /* re-encrypt all the private objects */ 1710 pri_dirp = opendir(get_pri_obj_path(pri_obj_path)); 1711 if (pri_dirp == NULL) { 1712 /* 1713 * this directory should exist, even if it doesn't contain 1714 * any objects. Don't want to update the pin if the 1715 * keystore is somehow messed up. 1716 */ 1717 1718 goto cleanup3; 1719 } 1720 1721 /* if user did not login, need to set the old pin */ 1722 if (!user_logged_in) { 1723 if (soft_keystore_authpin(oldpin) != 0) { 1724 goto cleanup3; 1725 } 1726 } 1727 1728 while ((pri_ent = readdir(pri_dirp)) != NULL) { 1729 1730 if ((strcmp(pri_ent->d_name, ".") == 0) || 1731 (strcmp(pri_ent->d_name, "..") == 0) || 1732 (strncmp(pri_ent->d_name, TMP_OBJ_PREFIX, 1733 strlen(TMP_OBJ_PREFIX)) == 0)) { 1734 continue; 1735 } 1736 1737 obj = malloc(sizeof (priobjs_t)); 1738 if (obj == NULL) { 1739 goto cleanup2; 1740 } 1741 (void) snprintf(obj->orig_name, MAXPATHLEN, 1742 "%s/%s", pri_obj_path, pri_ent->d_name); 1743 (void) snprintf(obj->tmp_name, MAXPATHLEN, "%s/%s%s", 1744 pri_obj_path, TMP_OBJ_PREFIX, 1745 (pri_ent->d_name) + strlen(OBJ_PREFIX)); 1746 if (reencrypt_obj(new_crypt_key, new_hmac_key, 1747 obj->orig_name, obj->tmp_name) != 0) { 1748 free(obj); 1749 goto cleanup2; 1750 } 1751 1752 /* insert into list of file to be renamed */ 1753 if (pri_objs == NULL) { 1754 obj->next = NULL; 1755 pri_objs = obj; 1756 } else { 1757 obj->next = pri_objs; 1758 pri_objs = obj; 1759 } 1760 } 1761 1762 /* rename all the private objects */ 1763 tmp = pri_objs; 1764 while (tmp) { 1765 (void) rename(tmp->tmp_name, tmp->orig_name); 1766 tmp = tmp->next; 1767 } 1768 1769 rename_desc_file: 1770 1771 /* destroy the old encryption key, and hmac key */ 1772 if ((!pin_never_set) && (user_logged_in)) { 1773 (void) soft_cleanup_object(enc_key); 1774 (void) soft_cleanup_object(hmac_key); 1775 } 1776 1777 if (user_logged_in) { 1778 enc_key = new_crypt_key; 1779 hmac_key = new_hmac_key; 1780 } 1781 (void) rename(tmp_ks_desc_name, ks_desc_file); 1782 1783 ret_val = 0; 1784 1785 cleanup2: 1786 if (pri_objs != NULL) { 1787 priobjs_t *p = pri_objs; 1788 while (p) { 1789 tmp = p->next; 1790 free(p); 1791 p = tmp; 1792 } 1793 } 1794 if (!pin_never_set) { 1795 (void) closedir(pri_dirp); 1796 } 1797 1798 if ((!user_logged_in) && (!pin_never_set)) { 1799 (void) soft_cleanup_object(enc_key); 1800 (void) soft_cleanup_object(hmac_key); 1801 enc_key = NULL; 1802 hmac_key = NULL; 1803 } 1804 cleanup3: 1805 if ((ret_val != 0) || (!user_logged_in)) { 1806 (void) soft_cleanup_object(new_crypt_key); 1807 (void) soft_cleanup_object(new_hmac_key); 1808 } 1809 1810 cleanup: 1811 if (!lock_held) { 1812 if (lock_file(fd, B_FALSE, B_FALSE) < 0) { 1813 ret_val = 1; 1814 } 1815 } 1816 if (crypt_salt != NULL) { 1817 free(crypt_salt); 1818 } 1819 if (hmac_salt != NULL) { 1820 free(hmac_salt); 1821 } 1822 (void) close(fd); 1823 (void) close(tmp_ks_fd); 1824 if (ret_val != 0) { 1825 (void) remove(tmp_ks_desc_name); 1826 } 1827 return (ret_val); 1828 } 1829 1830 /* 1831 * FUNCTION: soft_keystore_authpin 1832 * 1833 * ARGUMENTS: 1834 * pin: pin specified by the user for logging into 1835 * the keystore. 1836 * 1837 * RETURN VALUE: 1838 * 0: if no error 1839 * -1: if there is any error 1840 * 1841 * DESCRIPTION: 1842 * 1843 * This function takes the pin specified in the argument 1844 * and generates an encryption key based on the pin. 1845 * The generated encryption key will be used for 1846 * all future encryption and decryption for private 1847 * objects. Before this function is called, none 1848 * of the keystore related interfaces is able 1849 * to decrypt/encrypt any private object. 1850 */ 1851 int 1852 soft_keystore_authpin(uchar_t *pin) 1853 { 1854 int fd; 1855 int ret_val = -1; 1856 CK_BYTE *crypt_salt = NULL, *hmac_salt; 1857 1858 /* get the salt from the keystore description file */ 1859 if ((fd = open_and_lock_keystore_desc(O_RDONLY, 1860 B_FALSE, B_FALSE)) < 0) { 1861 return (-1); 1862 } 1863 1864 crypt_salt = malloc(KS_KEY_SALT_SIZE); 1865 if (crypt_salt == NULL) { 1866 goto cleanup; 1867 } 1868 1869 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) { 1870 goto cleanup; 1871 } 1872 1873 if (looping_read(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 1874 != KS_KEY_SALT_SIZE) { 1875 goto cleanup; 1876 } 1877 1878 if (soft_gen_crypt_key(pin, &enc_key, (CK_BYTE **)&crypt_salt) 1879 != CKR_OK) { 1880 goto cleanup; 1881 } 1882 1883 hmac_salt = malloc(KS_HMAC_SALT_SIZE); 1884 if (hmac_salt == NULL) { 1885 goto cleanup; 1886 } 1887 1888 if (lseek(fd, KS_HMAC_SALT_OFFSET, SEEK_SET) != KS_HMAC_SALT_OFFSET) { 1889 goto cleanup; 1890 } 1891 1892 if (looping_read(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE) 1893 != KS_HMAC_SALT_SIZE) { 1894 goto cleanup; 1895 } 1896 1897 if (soft_gen_hmac_key(pin, &hmac_key, (CK_BYTE **)&hmac_salt) 1898 != CKR_OK) { 1899 goto cleanup; 1900 } 1901 1902 ret_val = 0; 1903 1904 cleanup: 1905 /* unlock the file */ 1906 (void) lock_file(fd, B_TRUE, B_FALSE); 1907 (void) close(fd); 1908 if (crypt_salt != NULL) { 1909 free(crypt_salt); 1910 } 1911 if (hmac_salt != NULL) { 1912 free(hmac_salt); 1913 } 1914 return (ret_val); 1915 } 1916 1917 /* 1918 * FUNCTION: soft_keystore_get_objs 1919 * 1920 * ARGUMENTS: 1921 * 1922 * search_type: Specify type of objects to return. 1923 * lock_held: TRUE if the lock is held by caller. 1924 * 1925 * 1926 * RETURN VALUE: 1927 * 1928 * NULL: if there are no object in the database. 1929 * 1930 * Otherwise, linked list of objects as requested 1931 * in search type. 1932 * 1933 * The linked list returned will need to be freed 1934 * by the caller. 1935 * 1936 * DESCRIPTION: 1937 * 1938 * Returns objects as requested. 1939 * 1940 * If private objects is requested, and the caller 1941 * has not previously passed in the pin or if the pin 1942 * passed in is wrong, private objects will not 1943 * be returned. 1944 * 1945 * The buffers returned for private objects are already 1946 * decrypted. 1947 */ 1948 CK_RV 1949 soft_keystore_get_objs(ks_search_type_t search_type, 1950 ks_obj_t **result_obj_list, boolean_t lock_held) 1951 { 1952 DIR *dirp; 1953 ks_obj_handle_t ks_handle; 1954 CK_RV rv; 1955 ks_obj_t *tmp; 1956 int ks_fd; 1957 1958 *result_obj_list = NULL; 1959 1960 /* 1961 * lock the keystore description file in "read" mode so that 1962 * objects won't get added/deleted/modified while we are 1963 * doing the search 1964 */ 1965 if ((ks_fd = open_and_lock_keystore_desc(O_RDONLY, B_TRUE, 1966 B_FALSE)) < 0) { 1967 return (CKR_FUNCTION_FAILED); 1968 } 1969 1970 if ((search_type == ALL_TOKENOBJS) || (search_type == PUB_TOKENOBJS)) { 1971 1972 char pub_obj_path[MAXPATHLEN]; 1973 1974 ks_handle.public = B_TRUE; 1975 1976 if ((dirp = opendir(get_pub_obj_path(pub_obj_path))) == NULL) { 1977 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1978 (void) close(ks_fd); 1979 return (CKR_FUNCTION_FAILED); 1980 } 1981 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list, 1982 lock_held); 1983 if (rv != CKR_OK) { 1984 (void) closedir(dirp); 1985 goto cleanup; 1986 } 1987 1988 (void) closedir(dirp); 1989 } 1990 1991 if ((search_type == ALL_TOKENOBJS) || (search_type == PRI_TOKENOBJS)) { 1992 1993 char pri_obj_path[MAXPATHLEN]; 1994 1995 if ((enc_key == NULL) || 1996 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 1997 /* has not login - no need to go any further */ 1998 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1999 (void) close(ks_fd); 2000 return (CKR_OK); 2001 } 2002 2003 ks_handle.public = B_FALSE; 2004 2005 if ((dirp = opendir(get_pri_obj_path(pri_obj_path))) == NULL) { 2006 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 2007 (void) close(ks_fd); 2008 return (CKR_OK); 2009 } 2010 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list, 2011 lock_held); 2012 if (rv != CKR_OK) { 2013 (void) closedir(dirp); 2014 goto cleanup; 2015 } 2016 2017 (void) closedir(dirp); 2018 } 2019 /* close the keystore description file */ 2020 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 2021 (void) close(ks_fd); 2022 return (CKR_OK); 2023 cleanup: 2024 2025 /* close the keystore description file */ 2026 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 2027 (void) close(ks_fd); 2028 2029 /* free all the objects found before hitting the error */ 2030 tmp = *result_obj_list; 2031 while (tmp) { 2032 *result_obj_list = tmp->next; 2033 free(tmp->buf); 2034 free(tmp); 2035 tmp = *result_obj_list; 2036 } 2037 *result_obj_list = NULL; 2038 return (rv); 2039 } 2040 2041 2042 /* 2043 * FUNCTION: soft_keystore_get_single_obj 2044 * 2045 * ARGUMENTS: 2046 * ks_handle: handle of the key store object to be accessed 2047 * lock_held: TRUE if the lock is held by caller. 2048 * 2049 * RETURN VALUE: 2050 * 2051 * NULL: if handle doesn't match any object 2052 * 2053 * Otherwise, the object is returned in 2054 * the same structure used in soft_keystore_get_objs(). 2055 * The structure need to be freed by the caller. 2056 * 2057 * DESCRIPTION: 2058 * 2059 * Retrieves the object specified by the object 2060 * handle to the caller. 2061 * 2062 * If a private object is requested, and the caller 2063 * has not previously passed in the pin or if the pin 2064 * passed in is wrong, the requested private object will not 2065 * be returned. 2066 * 2067 * The buffer returned for the requested private object 2068 * is already decrypted. 2069 */ 2070 CK_RV 2071 soft_keystore_get_single_obj(ks_obj_handle_t *ks_handle, 2072 ks_obj_t **return_obj, boolean_t lock_held) 2073 { 2074 2075 ks_obj_t *obj; 2076 uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE]; 2077 uchar_t *buf, *decrypted_buf; 2078 int fd; 2079 ssize_t nread; 2080 CK_RV rv = CKR_FUNCTION_FAILED; 2081 2082 if (!(ks_handle->public)) { 2083 if ((enc_key == NULL) || 2084 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2085 return (CKR_FUNCTION_FAILED); 2086 } 2087 } 2088 2089 if ((fd = open_and_lock_object_file(ks_handle, O_RDONLY, 2090 lock_held)) < 0) { 2091 return (CKR_FUNCTION_FAILED); 2092 } 2093 2094 obj = malloc(sizeof (ks_obj_t)); 2095 if (obj == NULL) { 2096 return (CKR_HOST_MEMORY); 2097 } 2098 2099 obj->next = NULL; 2100 2101 (void) strcpy((char *)((obj->ks_handle).name), 2102 (char *)ks_handle->name); 2103 (obj->ks_handle).public = ks_handle->public; 2104 2105 /* 1st get the version */ 2106 if (looping_read(fd, &(obj->obj_version), OBJ_VER_SIZE) 2107 != OBJ_VER_SIZE) { 2108 goto cleanup; 2109 } 2110 obj->obj_version = SWAP32(obj->obj_version); 2111 2112 /* Then, read the IV */ 2113 if (looping_read(fd, iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 2114 goto cleanup; 2115 } 2116 2117 /* Then, read the HMAC */ 2118 if (looping_read(fd, obj_hmac, OBJ_HMAC_SIZE) != OBJ_HMAC_SIZE) { 2119 goto cleanup; 2120 } 2121 2122 /* read the object */ 2123 rv = read_obj_data(fd, (char **)&buf, &nread); 2124 if (rv != CKR_OK) { 2125 goto cleanup; 2126 } 2127 2128 if (ks_handle->public) { 2129 obj->size = nread; 2130 obj->buf = buf; 2131 *return_obj = obj; 2132 } else { 2133 2134 CK_ULONG out_len = 0, hmac_size; 2135 2136 /* verify HMAC of the object, make sure it matches */ 2137 hmac_size = OBJ_HMAC_SIZE; 2138 if (soft_keystore_hmac(hmac_key, B_FALSE, buf, 2139 nread, obj_hmac, &hmac_size) != CKR_OK) { 2140 free(buf); 2141 rv = CKR_FUNCTION_FAILED; 2142 goto cleanup; 2143 } 2144 2145 /* decrypt object */ 2146 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread, 2147 NULL, &out_len) != CKR_OK) { 2148 free(buf); 2149 rv = CKR_FUNCTION_FAILED; 2150 goto cleanup; 2151 } 2152 2153 decrypted_buf = malloc(sizeof (uchar_t) * out_len); 2154 if (decrypted_buf == NULL) { 2155 free(buf); 2156 rv = CKR_HOST_MEMORY; 2157 goto cleanup; 2158 } 2159 2160 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread, 2161 decrypted_buf, &out_len) != CKR_OK) { 2162 free(decrypted_buf); 2163 free(buf); 2164 rv = CKR_FUNCTION_FAILED; 2165 goto cleanup; 2166 } 2167 2168 obj->size = out_len - MAXPATHLEN; 2169 2170 /* 2171 * decrypted buf here actually contains full path name of 2172 * object plus the actual data. so, need to skip the 2173 * full pathname. 2174 * See prepare_data_for_encrypt() function in the file 2175 * to understand how and why the pathname is added. 2176 */ 2177 obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN)); 2178 if (obj->buf == NULL) { 2179 free(decrypted_buf); 2180 free(buf); 2181 rv = CKR_HOST_MEMORY; 2182 goto cleanup; 2183 } 2184 (void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size); 2185 free(decrypted_buf); 2186 free(buf); 2187 *return_obj = obj; 2188 } 2189 2190 cleanup: 2191 2192 if (rv != CKR_OK) { 2193 free(obj); 2194 } 2195 2196 /* unlock the file after reading */ 2197 if (!lock_held) { 2198 (void) lock_file(fd, B_TRUE, B_FALSE); 2199 } 2200 2201 (void) close(fd); 2202 2203 return (rv); 2204 } 2205 2206 2207 /* 2208 * FUNCTION: soft_keystore_put_new_obj 2209 * 2210 * ARGUMENTS: 2211 * buf: buffer containing un-encrypted data 2212 * to be stored in keystore. 2213 * len: length of data 2214 * public: TRUE if it is a public object, 2215 * FALSE if it is private obj 2216 * lock_held: TRUE if the lock is held by caller. 2217 * keyhandle: pointer to object handle to 2218 * receive keyhandle for new object 2219 * 2220 * RETURN VALUE: 2221 * 0: object successfully stored in file 2222 * -1: some error occurred, object is not stored in file. 2223 * 2224 * DESCRIPTION: 2225 * This API is used to write a newly created token object 2226 * to keystore. 2227 * 2228 * This function does the following: 2229 * 2230 * 1) Creates a token object file based on "public" parameter. 2231 * 2) Generates a new IV and stores it in obj_meta_data_t if it is 2232 * private object. 2233 * 3) Set object version number to 1. 2234 * 4) If it is a private object, it will be encrypted before 2235 * being written to the newly created keystore token object 2236 * file. 2237 * 5) Calculates the obj_chksum in obj_meta_data_t. 2238 * 6) Calculates the pin_chksum in obj_meta_data_t. 2239 * 7) Increments the keystore version number. 2240 */ 2241 int 2242 soft_keystore_put_new_obj(uchar_t *buf, size_t len, boolean_t public, 2243 boolean_t lock_held, ks_obj_handle_t *keyhandle) 2244 { 2245 2246 int fd, tmp_ks_fd, obj_fd; 2247 unsigned int counter, version; 2248 uchar_t obj_hmac[OBJ_HMAC_SIZE]; 2249 CK_BYTE iv[OBJ_IV_SIZE]; 2250 char obj_name[MAXPATHLEN], tmp_ks_desc_name[MAXPATHLEN]; 2251 char filebuf[BUFSIZ]; 2252 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2253 ks_desc_file[MAXPATHLEN]; 2254 CK_ULONG hmac_size; 2255 ssize_t nread; 2256 2257 if (keyhandle == NULL) { 2258 return (-1); 2259 } 2260 2261 /* if it is private object, make sure we have the key */ 2262 if (!public) { 2263 if ((enc_key == NULL) || 2264 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2265 return (-1); 2266 } 2267 } 2268 2269 /* open keystore, and set write lock */ 2270 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_TRUE, 2271 lock_held)) < 0) { 2272 return (-1); 2273 } 2274 2275 (void) get_desc_file_path(ks_desc_file); 2276 (void) get_tmp_desc_file_path(tmp_ks_desc_name); 2277 2278 /* 2279 * create a tempoary file for the keystore description 2280 * file for updating version and counter information 2281 */ 2282 while ((tmp_ks_fd = open(tmp_ks_desc_name, 2283 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR)) < 0) { 2284 if (errno != EINTR) 2285 break; 2286 } 2287 if (tmp_ks_fd < 0) { 2288 (void) close(fd); 2289 return (-1); 2290 } 2291 2292 (void) fcntl(tmp_ks_fd, F_SETFD, FD_CLOEXEC); 2293 2294 /* read and write pkcs11 version */ 2295 if (looping_read(fd, filebuf, KS_PKCS11_VER_SIZE) 2296 != KS_PKCS11_VER_SIZE) { 2297 goto cleanup; 2298 } 2299 2300 if (looping_write(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE) 2301 != KS_PKCS11_VER_SIZE) { 2302 goto cleanup; 2303 } 2304 2305 /* get version number, and write updated number to temp file */ 2306 if (looping_read(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) { 2307 goto cleanup; 2308 } 2309 2310 version = SWAP32(version); 2311 version++; 2312 version = SWAP32(version); 2313 2314 if (looping_write(tmp_ks_fd, (void *)&version, 2315 KS_VER_SIZE) != KS_VER_SIZE) { 2316 goto cleanup; 2317 } 2318 2319 /* get object count value */ 2320 if (looping_read(fd, &counter, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) { 2321 goto cleanup; 2322 } 2323 counter = SWAP32(counter); 2324 2325 bzero(obj_name, sizeof (obj_name)); 2326 if (public) { 2327 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d", 2328 get_pub_obj_path(pub_obj_path), OBJ_PREFIX, counter); 2329 } else { 2330 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d", 2331 get_pri_obj_path(pri_obj_path), OBJ_PREFIX, counter); 2332 } 2333 2334 /* create object file */ 2335 while ((obj_fd = open(obj_name, 2336 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR)) < 0) { 2337 if (errno != EINTR) 2338 break; 2339 } 2340 if (obj_fd < 0) { 2341 /* can't create object file */ 2342 goto cleanup; 2343 } 2344 2345 /* mark obj_fd "close on exec" */ 2346 (void) fcntl(obj_fd, F_SETFD, FD_CLOEXEC); 2347 2348 /* lock object file for writing */ 2349 if (lock_file(obj_fd, B_FALSE, B_TRUE) != 0) { 2350 (void) close(obj_fd); 2351 goto cleanup2; 2352 } 2353 2354 /* write object meta data */ 2355 version = SWAP32(1); 2356 if (looping_write(obj_fd, (void *)&version, sizeof (version)) 2357 != sizeof (version)) { 2358 goto cleanup2; 2359 } 2360 2361 if (public) { 2362 bzero(iv, sizeof (iv)); 2363 } else { 2364 /* generate an IV */ 2365 if (soft_gen_iv(iv) != CKR_OK) { 2366 goto cleanup2; 2367 } 2368 2369 } 2370 2371 if (looping_write(obj_fd, (void *)iv, sizeof (iv)) != sizeof (iv)) { 2372 goto cleanup2; 2373 } 2374 2375 if (public) { 2376 2377 bzero(obj_hmac, sizeof (obj_hmac)); 2378 if (looping_write(obj_fd, (void *)obj_hmac, 2379 sizeof (obj_hmac)) != sizeof (obj_hmac)) { 2380 goto cleanup2; 2381 } 2382 2383 if (looping_write(obj_fd, (char *)buf, len) != len) { 2384 goto cleanup2; 2385 } 2386 2387 } else { 2388 2389 uchar_t *encrypted_buf, *prepared_buf; 2390 CK_ULONG out_len = 0, prepared_len; 2391 2392 if (prepare_data_for_encrypt(obj_name, buf, len, 2393 &prepared_buf, &prepared_len) != 0) { 2394 goto cleanup2; 2395 } 2396 2397 if (soft_keystore_crypt(enc_key, iv, 2398 B_TRUE, prepared_buf, prepared_len, 2399 NULL, &out_len) != CKR_OK) { 2400 free(prepared_buf); 2401 goto cleanup2; 2402 } 2403 2404 encrypted_buf = malloc(out_len * sizeof (char)); 2405 if (encrypted_buf == NULL) { 2406 free(prepared_buf); 2407 goto cleanup2; 2408 } 2409 2410 if (soft_keystore_crypt(enc_key, iv, 2411 B_TRUE, prepared_buf, prepared_len, 2412 encrypted_buf, &out_len) != CKR_OK) { 2413 free(encrypted_buf); 2414 free(prepared_buf); 2415 goto cleanup2; 2416 } 2417 free(prepared_buf); 2418 2419 /* calculate HMAC of encrypted object */ 2420 hmac_size = OBJ_HMAC_SIZE; 2421 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf, 2422 out_len, obj_hmac, &hmac_size) != CKR_OK) { 2423 free(encrypted_buf); 2424 goto cleanup2; 2425 } 2426 2427 if (hmac_size != OBJ_HMAC_SIZE) { 2428 free(encrypted_buf); 2429 goto cleanup2; 2430 } 2431 2432 /* write hmac */ 2433 if (looping_write(obj_fd, (void *)obj_hmac, 2434 sizeof (obj_hmac)) != sizeof (obj_hmac)) { 2435 free(encrypted_buf); 2436 goto cleanup2; 2437 } 2438 2439 /* write encrypted object */ 2440 if (looping_write(obj_fd, (void *)encrypted_buf, out_len) 2441 != out_len) { 2442 free(encrypted_buf); 2443 goto cleanup2; 2444 } 2445 2446 free(encrypted_buf); 2447 } 2448 2449 2450 (void) close(obj_fd); 2451 (void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name), 2452 "obj%d", counter); 2453 keyhandle->public = public; 2454 2455 /* 2456 * store new counter to temp keystore description file. 2457 */ 2458 counter++; 2459 counter = SWAP32(counter); 2460 if (looping_write(tmp_ks_fd, (void *)&counter, 2461 sizeof (counter)) != sizeof (counter)) { 2462 goto cleanup2; 2463 } 2464 2465 /* read rest of keystore description file and store into temp file */ 2466 nread = looping_read(fd, filebuf, sizeof (filebuf)); 2467 while (nread > 0) { 2468 if (looping_write(tmp_ks_fd, filebuf, nread) != nread) { 2469 goto cleanup2; 2470 } 2471 nread = looping_read(fd, filebuf, sizeof (filebuf)); 2472 } 2473 2474 (void) close(tmp_ks_fd); 2475 (void) rename(tmp_ks_desc_name, ks_desc_file); 2476 2477 if (!lock_held) { 2478 /* release lock on description file */ 2479 if (lock_file(fd, B_FALSE, B_FALSE) != 0) { 2480 (void) close(fd); 2481 return (-1); 2482 } 2483 } 2484 (void) close(fd); 2485 return (0); 2486 2487 cleanup2: 2488 2489 /* remove object file. No need to remove lock first */ 2490 (void) unlink(obj_name); 2491 2492 cleanup: 2493 2494 (void) close(tmp_ks_fd); 2495 (void) remove(tmp_ks_desc_name); 2496 if (!lock_held) { 2497 /* release lock on description file */ 2498 (void) lock_file(fd, B_FALSE, B_FALSE); 2499 } 2500 2501 (void) close(fd); 2502 return (-1); 2503 } 2504 2505 /* 2506 * FUNCTION: soft_keystore_modify_obj 2507 * 2508 * ARGUMENTS: 2509 * ks_handle: handle of the key store object to be modified 2510 * buf: buffer containing un-encrypted data 2511 * to be modified in keystore. 2512 * len: length of data 2513 * lock_held: TRUE if the lock is held by caller. 2514 * 2515 * RETURN VALUE: 2516 * -1: if any error occurred. 2517 * Otherwise, 0 is returned. 2518 * 2519 * DESCRIPTION: 2520 * 2521 * This API is used to write a modified token object back 2522 * to keystore. This function will do the following: 2523 * 2524 * 1) If it is a private object, it will be encrypted before 2525 * being written to the corresponding keystore token 2526 * object file. 2527 * 2) Record incremented object version number. 2528 * 3) Record incremented keystore version number. 2529 */ 2530 int 2531 soft_keystore_modify_obj(ks_obj_handle_t *ks_handle, uchar_t *buf, 2532 size_t len, boolean_t lock_held) 2533 { 2534 int fd, ks_fd, tmp_fd, version; 2535 char orig_name[MAXPATHLEN], tmp_name[MAXPATHLEN], 2536 tmp_ks_name[MAXPATHLEN]; 2537 uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE]; 2538 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2539 ks_desc_file[MAXPATHLEN]; 2540 CK_ULONG hmac_size; 2541 2542 /* if it is private object, make sure we have the key */ 2543 if (!(ks_handle->public)) { 2544 if ((enc_key == NULL) || 2545 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2546 return (-1); 2547 } 2548 } 2549 2550 /* open and lock keystore description file */ 2551 if ((ks_fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2552 B_FALSE)) < 0) { 2553 return (-1); 2554 } 2555 2556 (void) get_desc_file_path(ks_desc_file); 2557 2558 /* update the version of for keystore file in tempoary file */ 2559 (void) get_tmp_desc_file_path(tmp_ks_name); 2560 if (create_updated_keystore_version(ks_fd, tmp_ks_name) != 0) { 2561 /* unlock keystore description file */ 2562 (void) lock_file(ks_fd, B_FALSE, B_FALSE); 2563 (void) close(ks_fd); 2564 return (-1); 2565 } 2566 2567 /* open object file */ 2568 if ((fd = open_and_lock_object_file(ks_handle, O_RDWR, 2569 lock_held)) < 0) { 2570 goto cleanup; 2571 } 2572 2573 /* 2574 * make the change in a temporary file. Create the temp 2575 * file in the same directory as the token object. That 2576 * way, the "rename" later will be an atomic operation 2577 */ 2578 if (ks_handle->public) { 2579 (void) snprintf(orig_name, MAXPATHLEN, "%s/%s", 2580 get_pub_obj_path(pub_obj_path), ks_handle->name); 2581 (void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s", 2582 pub_obj_path, TMP_OBJ_PREFIX, 2583 (ks_handle->name) + strlen(OBJ_PREFIX)); 2584 } else { 2585 (void) snprintf(orig_name, MAXPATHLEN, "%s/%s", 2586 get_pri_obj_path(pri_obj_path), ks_handle->name); 2587 (void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s", 2588 pri_obj_path, TMP_OBJ_PREFIX, 2589 (ks_handle->name) + strlen(OBJ_PREFIX)); 2590 } 2591 2592 while ((tmp_fd = open(tmp_name, 2593 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR)) < 0) { 2594 if (errno != EINTR) 2595 break; 2596 } 2597 if (tmp_fd < 0) { 2598 /* can't create tmp object file */ 2599 goto cleanup1; 2600 } 2601 (void) fcntl(tmp_fd, F_SETFD, FD_CLOEXEC); 2602 2603 /* read version, increment, and write to tmp file */ 2604 if (looping_read(fd, (char *)&version, OBJ_VER_SIZE) != OBJ_VER_SIZE) { 2605 goto cleanup2; 2606 } 2607 2608 version = SWAP32(version); 2609 version++; 2610 version = SWAP32(version); 2611 2612 if (looping_write(tmp_fd, (char *)&version, OBJ_VER_SIZE) 2613 != OBJ_VER_SIZE) { 2614 goto cleanup2; 2615 } 2616 2617 /* generate a new IV for the object, old one can be ignored */ 2618 if (soft_gen_iv(iv) != CKR_OK) { 2619 goto cleanup2; 2620 } 2621 2622 if (looping_write(tmp_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 2623 goto cleanup2; 2624 } 2625 2626 if (ks_handle->public) { 2627 2628 /* hmac is always NULL for public objects */ 2629 bzero(obj_hmac, sizeof (obj_hmac)); 2630 if (looping_write(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE) 2631 != OBJ_HMAC_SIZE) { 2632 goto cleanup2; 2633 } 2634 2635 /* write updated object */ 2636 if (looping_write(tmp_fd, (char *)buf, len) != len) { 2637 goto cleanup2; 2638 } 2639 2640 } else { 2641 2642 uchar_t *encrypted_buf, *prepared_buf; 2643 CK_ULONG out_len = 0, prepared_len; 2644 2645 if (prepare_data_for_encrypt(orig_name, buf, len, 2646 &prepared_buf, &prepared_len) != 0) { 2647 goto cleanup2; 2648 } 2649 2650 /* encrypt the data */ 2651 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf, 2652 prepared_len, NULL, &out_len) != CKR_OK) { 2653 free(prepared_buf); 2654 goto cleanup2; 2655 } 2656 2657 encrypted_buf = malloc(out_len * sizeof (char)); 2658 if (encrypted_buf == NULL) { 2659 free(prepared_buf); 2660 goto cleanup2; 2661 } 2662 2663 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf, 2664 prepared_len, encrypted_buf, &out_len) != CKR_OK) { 2665 free(encrypted_buf); 2666 free(prepared_buf); 2667 goto cleanup2; 2668 } 2669 2670 free(prepared_buf); 2671 2672 /* calculate hmac on encrypted buf */ 2673 hmac_size = OBJ_HMAC_SIZE; 2674 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf, 2675 out_len, obj_hmac, &hmac_size) != CKR_OK) { 2676 free(encrypted_buf); 2677 goto cleanup2; 2678 } 2679 2680 if (hmac_size != OBJ_HMAC_SIZE) { 2681 free(encrypted_buf); 2682 goto cleanup2; 2683 } 2684 2685 if (looping_write(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE) 2686 != OBJ_HMAC_SIZE) { 2687 free(encrypted_buf); 2688 goto cleanup2; 2689 } 2690 2691 if (looping_write(tmp_fd, (void *)encrypted_buf, out_len) 2692 != out_len) { 2693 free(encrypted_buf); 2694 goto cleanup2; 2695 } 2696 free(encrypted_buf); 2697 } 2698 (void) close(tmp_fd); 2699 2700 /* rename updated temporary object file */ 2701 if (rename(tmp_name, orig_name) != 0) { 2702 (void) unlink(tmp_name); 2703 return (-1); 2704 } 2705 2706 /* rename updated keystore description file */ 2707 if (rename(tmp_ks_name, ks_desc_file) != 0) { 2708 (void) unlink(tmp_name); 2709 (void) unlink(tmp_ks_name); 2710 return (-1); 2711 } 2712 2713 /* determine need to unlock file or not */ 2714 if (!lock_held) { 2715 if (lock_file(fd, B_FALSE, B_FALSE) < 0) { 2716 (void) close(fd); 2717 (void) unlink(tmp_name); 2718 return (-1); 2719 } 2720 } 2721 2722 /* unlock keystore description file */ 2723 if (lock_file(ks_fd, B_FALSE, B_FALSE) != 0) { 2724 (void) close(ks_fd); 2725 (void) close(fd); 2726 return (-1); 2727 } 2728 2729 (void) close(ks_fd); 2730 2731 (void) close(fd); 2732 2733 return (0); /* All operations completed successfully */ 2734 2735 cleanup2: 2736 (void) close(tmp_fd); 2737 (void) remove(tmp_name); 2738 2739 cleanup1: 2740 (void) close(fd); 2741 2742 cleanup: 2743 /* unlock keystore description file */ 2744 (void) lock_file(ks_fd, B_FALSE, B_FALSE); 2745 (void) close(ks_fd); 2746 (void) remove(tmp_ks_name); 2747 return (-1); 2748 } 2749 2750 /* 2751 * FUNCTION: soft_keystore_del_obj 2752 * 2753 * ARGUMENTS: 2754 * ks_handle: handle of the key store object to be deleted 2755 * lock_held: TRUE if the lock is held by caller. 2756 * 2757 * RETURN VALUE: 2758 * -1: if any error occurred. 2759 * 0: object successfully deleted from keystore. 2760 * 2761 * DESCRIPTION: 2762 * This API is used to delete a particular token object from 2763 * the keystore. The corresponding token object file will be 2764 * removed from the file system. 2765 * Any future reference to the deleted file will 2766 * return an CKR_OBJECT_HANDLE_INVALID error. 2767 */ 2768 int 2769 soft_keystore_del_obj(ks_obj_handle_t *ks_handle, boolean_t lock_held) 2770 { 2771 char objname[MAXPATHLEN], tmp_ks_name[MAXPATHLEN]; 2772 int fd; 2773 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2774 ks_desc_file[MAXPATHLEN]; 2775 int ret_val = -1; 2776 int obj_fd; 2777 2778 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2779 lock_held)) < 0) { 2780 return (-1); 2781 } 2782 2783 (void) get_desc_file_path(ks_desc_file); 2784 (void) get_tmp_desc_file_path(tmp_ks_name); 2785 if (create_updated_keystore_version(fd, tmp_ks_name) != 0) { 2786 goto cleanup; 2787 } 2788 2789 if (ks_handle->public) { 2790 (void) snprintf(objname, MAXPATHLEN, "%s/%s", 2791 get_pub_obj_path(pub_obj_path), ks_handle->name); 2792 } else { 2793 (void) snprintf(objname, MAXPATHLEN, "%s/%s", 2794 get_pri_obj_path(pri_obj_path), ks_handle->name); 2795 } 2796 2797 /* 2798 * make sure no other process is reading/writing the file 2799 * by acquiring the lock on the file 2800 */ 2801 if ((obj_fd = open_and_lock_object_file(ks_handle, O_WRONLY, 2802 B_FALSE)) < 0) { 2803 return (-1); 2804 } 2805 2806 if (unlink(objname) != 0) { 2807 (void) lock_file(obj_fd, B_FALSE, B_FALSE); 2808 (void) close(obj_fd); 2809 goto cleanup; 2810 } 2811 2812 (void) lock_file(obj_fd, B_FALSE, B_FALSE); 2813 (void) close(obj_fd); 2814 2815 if (rename(tmp_ks_name, ks_desc_file) != 0) { 2816 goto cleanup; 2817 } 2818 ret_val = 0; 2819 2820 cleanup: 2821 /* unlock keystore description file */ 2822 if (!lock_held) { 2823 if (lock_file(fd, B_FALSE, B_FALSE) != 0) { 2824 (void) close(fd); 2825 return (-1); 2826 } 2827 } 2828 2829 (void) close(fd); 2830 return (ret_val); 2831 } 2832 2833 /* 2834 * Get the salt used for generating hashed pin from the 2835 * keystore description file. 2836 * 2837 * The result will be stored in the provided buffer "salt" passed 2838 * in as an argument. 2839 * 2840 * Return 0 if no error, return -1 if there's any error. 2841 */ 2842 int 2843 soft_keystore_get_pin_salt(char **salt) 2844 { 2845 int fd, ret_val = -1; 2846 uint64_t hashed_pin_salt_size; 2847 2848 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_TRUE, 2849 B_FALSE)) < 0) { 2850 return (-1); 2851 } 2852 2853 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET) 2854 != KS_HASHED_PIN_SALT_LEN_OFFSET) { 2855 goto cleanup; 2856 } 2857 2858 if (looping_read(fd, (char *)&hashed_pin_salt_size, 2859 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 2860 goto cleanup; 2861 } 2862 hashed_pin_salt_size = SWAP64(hashed_pin_salt_size); 2863 2864 *salt = malloc(hashed_pin_salt_size + 1); 2865 if (*salt == NULL) { 2866 goto cleanup; 2867 } 2868 2869 if ((looping_read(fd, *salt, hashed_pin_salt_size)) 2870 != (ssize_t)hashed_pin_salt_size) { 2871 free(*salt); 2872 goto cleanup; 2873 } 2874 (*salt)[hashed_pin_salt_size] = '\0'; 2875 2876 ret_val = 0; 2877 2878 cleanup: 2879 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 2880 ret_val = -1; 2881 } 2882 2883 (void) close(fd); 2884 return (ret_val); 2885 } 2886 2887 /* 2888 * FUNCTION: soft_keystore_pin_initialized 2889 * 2890 * ARGUMENTS: 2891 * initialized: This value will be set to true if keystore is 2892 * initialized, and false otherwise. 2893 * hashed_pin: If the keystore is initialized, this will contain 2894 * the hashed pin. It will be NULL if the keystore 2895 * pin is not initialized. Memory allocated 2896 * for the hashed pin needs to be freed by 2897 * the caller. 2898 * lock_held: TRUE if the lock is held by caller. 2899 * 2900 * RETURN VALUE: 2901 * CKR_OK: No error 2902 * any other appropriate CKR_value 2903 * 2904 * DESCRIPTION: 2905 * This API is used to determine if the PIN in the keystore 2906 * has been initialized or not. 2907 * It makes the determination using the salt for generating the 2908 * encryption key. The salt is stored in the keystore 2909 * descryption file. The salt should be all zero if 2910 * the keystore pin has not been initialized. 2911 * If the pin has been initialized, it is returned in the 2912 * hashed_pin argument. 2913 */ 2914 CK_RV 2915 soft_keystore_pin_initialized(boolean_t *initialized, char **hashed_pin, 2916 boolean_t lock_held) 2917 { 2918 int fd; 2919 CK_BYTE crypt_salt[KS_KEY_SALT_SIZE], tmp_buf[KS_KEY_SALT_SIZE]; 2920 CK_RV ret_val = CKR_OK; 2921 2922 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_TRUE, 2923 lock_held)) < 0) { 2924 return (CKR_FUNCTION_FAILED); 2925 } 2926 2927 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) { 2928 ret_val = CKR_FUNCTION_FAILED; 2929 goto cleanup; 2930 } 2931 2932 if (looping_read(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 2933 != KS_KEY_SALT_SIZE) { 2934 ret_val = CKR_FUNCTION_FAILED; 2935 goto cleanup; 2936 } 2937 2938 (void) bzero(tmp_buf, KS_KEY_SALT_SIZE); 2939 2940 if (memcmp(crypt_salt, tmp_buf, KS_KEY_SALT_SIZE) == 0) { 2941 *initialized = B_FALSE; 2942 hashed_pin = NULL; 2943 } else { 2944 *initialized = B_TRUE; 2945 ret_val = get_hashed_pin(fd, hashed_pin); 2946 } 2947 2948 cleanup: 2949 2950 if (!lock_held) { 2951 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 2952 ret_val = CKR_FUNCTION_FAILED; 2953 } 2954 } 2955 2956 (void) close(fd); 2957 return (ret_val); 2958 } 2959