3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /*
26 * Functions used for manipulating the keystore
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <time.h>
35 #include <unistd.h>
36 #include <pwd.h>
37 #include <sys/types.h>
38 #include <dirent.h>
39 #include <limits.h>
40 #include <libgen.h>
41 #include <strings.h>
42 #include <security/cryptoki.h>
453 if (writen_nointr(fd, (void *)hashed_pin_salt,
454 hashed_pin_salt_len) != hashed_pin_salt_len) {
455 goto cleanup;
456 }
457
458 /* write MD5 hashed pin of the default pin */
459 ulong_buf = SWAP64(hashed_pin_len);
460 if (writen_nointr(fd, (void *)&ulong_buf, KS_HASHED_PINLEN_SIZE)
461 != KS_HASHED_PINLEN_SIZE) {
462 goto cleanup;
463 }
464
465 if (writen_nointr(fd, (void *)hashed_pin, hashed_pin_len)
466 != hashed_pin_len) {
467 goto cleanup;
468 }
469
470 (void) lock_file(fd, B_FALSE, B_FALSE);
471
472 (void) close(fd);
473 if (hashed_pin_salt)
474 free(hashed_pin_salt);
475 return (0);
476
477 cleanup:
478 (void) lock_file(fd, B_FALSE, B_FALSE);
479 (void) unlink(ks_desc_file);
480 (void) close(fd);
481 (void) rmdir(get_keystore_path());
482 (void) rmdir(pub_obj_path);
483 (void) rmdir(pri_obj_path);
484 return (-1);
485 }
486
487 /*
488 * Determines if the file referenced by "fd" has the same
489 * inode as the file referenced by "fname".
490 *
491 * The argument "same" contains the result of determining
492 * if the inode is the same or not
493 *
494 * Returns 0 if there's no error.
875 /* first, get size of the hashed pin */
876 if (lseek(fd, ks_hashed_pinlen_offset, SEEK_SET)
877 != ks_hashed_pinlen_offset) {
878 return (CKR_FUNCTION_FAILED);
879 }
880
881 if (readn_nointr(fd, (char *)&hashed_pin_size,
882 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) {
883 return (CKR_FUNCTION_FAILED);
884 }
885
886 hashed_pin_size = SWAP64(hashed_pin_size);
887
888 *hashed_pin = malloc(hashed_pin_size + 1);
889 if (*hashed_pin == NULL) {
890 return (CKR_HOST_MEMORY);
891 }
892
893 if ((readn_nointr(fd, *hashed_pin, hashed_pin_size))
894 != (ssize_t)hashed_pin_size) {
895 free(*hashed_pin);
896 *hashed_pin = NULL;
897 return (CKR_FUNCTION_FAILED);
898 }
899 (*hashed_pin)[hashed_pin_size] = '\0';
900 return (CKR_OK);
901 }
902
903
904 /*
905 * FUNCTION: soft_keystore_lock
906 *
907 * ARGUMENTS:
908 * set_lock: TRUE to set readlock on the keystore object file,
909 * FALSE to remove readlock on keystore object file.
910 *
911 * RETURN VALUE:
912 *
913 * 0: success
914 * -1: failure
915 *
1303 goto cleanup;
1304 }
1305
1306 if (writen_nointr(new_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
1307 goto cleanup;
1308 }
1309
1310 /* seek to the original encrypted data, and read all of them */
1311 if (lseek(old_fd, OBJ_DATA_OFFSET, SEEK_SET) != OBJ_DATA_OFFSET) {
1312 goto cleanup;
1313 }
1314
1315 if (read_obj_data(old_fd, (char **)&buf, &nread) != CKR_OK) {
1316 goto cleanup;
1317 }
1318
1319 /* decrypt data using old key */
1320 decrypted_len = 0;
1321 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
1322 NULL, &decrypted_len) != CKR_OK) {
1323 free(buf);
1324 goto cleanup;
1325 }
1326
1327 decrypted_buf = malloc(decrypted_len);
1328 if (decrypted_buf == NULL) {
1329 free(buf);
1330 goto cleanup;
1331 }
1332
1333 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
1334 decrypted_buf, &decrypted_len) != CKR_OK) {
1335 free(buf);
1336 free(decrypted_buf);
1337 goto cleanup;
1338 }
1339
1340 free(buf);
1341
1342 /* re-encrypt with new key */
1343 encrypted_len = 0;
1344 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
1345 decrypted_len, NULL, &encrypted_len) != CKR_OK) {
1346 free(decrypted_buf);
1347 goto cleanup;
1348 }
1349
1350 buf = malloc(encrypted_len);
1351 if (buf == NULL) {
1352 free(decrypted_buf);
1353 goto cleanup;
1354 }
1355
1356 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
1357 decrypted_len, buf, &encrypted_len) != CKR_OK) {
1358 free(buf);
1359 free(decrypted_buf);
1360 goto cleanup;
1361 }
1362
1363 free(decrypted_buf);
1364
1365 /* calculate hmac on re-encrypted data using new hmac key */
1366 hmac_len = OBJ_HMAC_SIZE;
1367 if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf,
1368 encrypted_len, hmac, &hmac_len) != CKR_OK) {
1369 free(buf);
1370 goto cleanup;
1371 }
1372
1373 /* just for sanity check */
1374 if (hmac_len != OBJ_HMAC_SIZE) {
1375 free(buf);
1376 goto cleanup;
1377 }
1378
1379 /* write new hmac */
1380 if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE)
1381 != OBJ_HMAC_SIZE) {
1382 free(buf);
1383 goto cleanup;
1384 }
1385
1386 /* write re-encrypted buffer to temp file */
1387 if (writen_nointr(new_fd, (void *)buf, encrypted_len)
1388 != encrypted_len) {
1389 free(buf);
1390 goto cleanup;
1391 }
1392 free(buf);
1393 ret_val = 0;
1394
1395 cleanup:
1396 /* unlock the files */
1397 (void) lock_file(old_fd, B_TRUE, B_FALSE);
1398 (void) lock_file(new_fd, B_FALSE, B_FALSE);
1399
1400 (void) close(old_fd);
1401 (void) close(new_fd);
1402 if (ret_val != 0) {
1403 (void) remove(new_obj_name);
1404 }
1405 return (ret_val);
1406 }
1407
1408 /*
1409 * FUNCTION: soft_keystore_setpin
1410 *
1411 * ARGUMENTS:
1412 * newpin: new pin entered by the user.
1530 }
1531 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE)
1532 != KS_HMAC_SALT_SIZE) {
1533 goto cleanup;
1534 }
1535
1536 /* just create some empty bytes */
1537 bzero(filebuf, sizeof (filebuf));
1538
1539 if (memcmp(crypt_salt, filebuf, KS_KEY_SALT_SIZE) == 0) {
1540 /* PIN as never been set */
1541 CK_BYTE *new_crypt_salt = NULL, *new_hmac_salt = NULL;
1542
1543 pin_never_set = B_TRUE;
1544 if (soft_gen_crypt_key(newpin, &new_crypt_key, &new_crypt_salt)
1545 != CKR_OK) {
1546 goto cleanup;
1547 }
1548 if (writen_nointr(tmp_ks_fd, (void *)new_crypt_salt,
1549 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
1550 free(new_crypt_salt);
1551 (void) soft_cleanup_object(new_crypt_key);
1552 goto cleanup;
1553 }
1554 free(new_crypt_salt);
1555
1556 if (soft_gen_hmac_key(newpin, &new_hmac_key, &new_hmac_salt)
1557 != CKR_OK) {
1558 (void) soft_cleanup_object(new_crypt_key);
1559 goto cleanup;
1560 }
1561 if (writen_nointr(tmp_ks_fd, (void *)new_hmac_salt,
1562 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) {
1563 free(new_hmac_salt);
1564 goto cleanup3;
1565 }
1566 free(new_hmac_salt);
1567 } else {
1568 if (soft_gen_crypt_key(newpin, &new_crypt_key,
1569 (CK_BYTE **)&crypt_salt) != CKR_OK) {
1570 goto cleanup;
1571 }
1572 /* no change to the encryption salt */
1573 if (writen_nointr(tmp_ks_fd, (void *)crypt_salt,
1574 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
1575 (void) soft_cleanup_object(new_crypt_key);
1576 goto cleanup;
1577 }
1578
1579 if (soft_gen_hmac_key(newpin, &new_hmac_key,
1580 (CK_BYTE **)&hmac_salt) != CKR_OK) {
1581 (void) soft_cleanup_object(new_crypt_key);
1582 goto cleanup;
1583 }
1584
1585 /* no change to the hmac salt */
1586 if (writen_nointr(tmp_ks_fd, (void *)hmac_salt,
1595 */
1596 if (readn_nointr(fd, (char *)&hashed_pin_salt_length,
1597 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
1598 goto cleanup3;
1599 }
1600
1601 if (writen_nointr(tmp_ks_fd, (void *)&hashed_pin_salt_length,
1602 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
1603 goto cleanup3;
1604 }
1605
1606 hashed_pin_salt_length = SWAP64(hashed_pin_salt_length);
1607
1608 hashed_pin_salt = malloc(hashed_pin_salt_length + 1);
1609 if (hashed_pin_salt == NULL) {
1610 goto cleanup3;
1611 }
1612
1613 if ((readn_nointr(fd, hashed_pin_salt, hashed_pin_salt_length)) !=
1614 (ssize_t)hashed_pin_salt_length) {
1615 free(hashed_pin_salt);
1616 goto cleanup3;
1617 }
1618
1619 if ((writen_nointr(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length))
1620 != (ssize_t)hashed_pin_salt_length) {
1621 free(hashed_pin_salt);
1622 goto cleanup3;
1623 }
1624
1625 hashed_pin_salt[hashed_pin_salt_length] = '\0';
1626
1627 /* old hashed pin length and value can be ignored, generate new one */
1628 if (soft_gen_hashed_pin(newpin, &new_hashed_pin,
1629 &hashed_pin_salt) < 0) {
1630 free(hashed_pin_salt);
1631 goto cleanup3;
1632 }
1633
1634 free(hashed_pin_salt);
1635
1636 if (new_hashed_pin == NULL) {
1637 goto cleanup3;
1638 }
1639
1640 new_hashed_pin_len = strlen(new_hashed_pin);
1641
1642 /* write new hashed pin length to file */
1643 swaped_val = SWAP64(new_hashed_pin_len);
1644 if (writen_nointr(tmp_ks_fd, (void *)&swaped_val,
1645 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) {
1646 goto cleanup3;
1647 }
1648
1649 if (writen_nointr(tmp_ks_fd, (void *)new_hashed_pin,
1650 new_hashed_pin_len) != (ssize_t)new_hashed_pin_len) {
1651 goto cleanup3;
1652 }
1653
1654 if (pin_never_set) {
1746 }
1747
1748 if ((!user_logged_in) && (!pin_never_set)) {
1749 (void) soft_cleanup_object(enc_key);
1750 (void) soft_cleanup_object(hmac_key);
1751 enc_key = NULL;
1752 hmac_key = NULL;
1753 }
1754 cleanup3:
1755 if ((ret_val != 0) || (!user_logged_in)) {
1756 (void) soft_cleanup_object(new_crypt_key);
1757 (void) soft_cleanup_object(new_hmac_key);
1758 }
1759
1760 cleanup:
1761 if (!lock_held) {
1762 if (lock_file(fd, B_FALSE, B_FALSE) < 0) {
1763 ret_val = 1;
1764 }
1765 }
1766 if (crypt_salt != NULL) {
1767 free(crypt_salt);
1768 }
1769 if (hmac_salt != NULL) {
1770 free(hmac_salt);
1771 }
1772 (void) close(fd);
1773 (void) close(tmp_ks_fd);
1774 if (ret_val != 0) {
1775 (void) remove(tmp_ks_desc_name);
1776 }
1777 return (ret_val);
1778 }
1779
1780 /*
1781 * FUNCTION: soft_keystore_authpin
1782 *
1783 * ARGUMENTS:
1784 * pin: pin specified by the user for logging into
1785 * the keystore.
1786 *
1787 * RETURN VALUE:
1788 * 0: if no error
1789 * -1: if there is any error
1790 *
1791 * DESCRIPTION:
1838 if (lseek(fd, KS_HMAC_SALT_OFFSET, SEEK_SET) != KS_HMAC_SALT_OFFSET) {
1839 goto cleanup;
1840 }
1841
1842 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE)
1843 != KS_HMAC_SALT_SIZE) {
1844 goto cleanup;
1845 }
1846
1847 if (soft_gen_hmac_key(pin, &hmac_key, (CK_BYTE **)&hmac_salt)
1848 != CKR_OK) {
1849 goto cleanup;
1850 }
1851
1852 ret_val = 0;
1853
1854 cleanup:
1855 /* unlock the file */
1856 (void) lock_file(fd, B_TRUE, B_FALSE);
1857 (void) close(fd);
1858 if (crypt_salt != NULL) {
1859 free(crypt_salt);
1860 }
1861 if (hmac_salt != NULL) {
1862 free(hmac_salt);
1863 }
1864 return (ret_val);
1865 }
1866
1867 /*
1868 * FUNCTION: soft_keystore_get_objs
1869 *
1870 * ARGUMENTS:
1871 *
1872 * search_type: Specify type of objects to return.
1873 * lock_held: TRUE if the lock is held by caller.
1874 *
1875 *
1876 * RETURN VALUE:
1877 *
1878 * NULL: if there are no object in the database.
1879 *
1880 * Otherwise, linked list of objects as requested
1881 * in search type.
1882 *
1883 * The linked list returned will need to be freed
1963 (void) closedir(dirp);
1964 goto cleanup;
1965 }
1966
1967 (void) closedir(dirp);
1968 }
1969 /* close the keystore description file */
1970 (void) lock_file(ks_fd, B_TRUE, B_FALSE);
1971 (void) close(ks_fd);
1972 return (CKR_OK);
1973 cleanup:
1974
1975 /* close the keystore description file */
1976 (void) lock_file(ks_fd, B_TRUE, B_FALSE);
1977 (void) close(ks_fd);
1978
1979 /* free all the objects found before hitting the error */
1980 tmp = *result_obj_list;
1981 while (tmp) {
1982 *result_obj_list = tmp->next;
1983 free(tmp->buf);
1984 free(tmp);
1985 tmp = *result_obj_list;
1986 }
1987 *result_obj_list = NULL;
1988 return (rv);
1989 }
1990
1991
1992 /*
1993 * FUNCTION: soft_keystore_get_single_obj
1994 *
1995 * ARGUMENTS:
1996 * ks_handle: handle of the key store object to be accessed
1997 * lock_held: TRUE if the lock is held by caller.
1998 *
1999 * RETURN VALUE:
2000 *
2001 * NULL: if handle doesn't match any object
2002 *
2003 * Otherwise, the object is returned in
2070 }
2071
2072 /* read the object */
2073 rv = read_obj_data(fd, (char **)&buf, &nread);
2074 if (rv != CKR_OK) {
2075 goto cleanup;
2076 }
2077
2078 if (ks_handle->public) {
2079 obj->size = nread;
2080 obj->buf = buf;
2081 *return_obj = obj;
2082 } else {
2083
2084 CK_ULONG out_len = 0, hmac_size;
2085
2086 /* verify HMAC of the object, make sure it matches */
2087 hmac_size = OBJ_HMAC_SIZE;
2088 if (soft_keystore_hmac(hmac_key, B_FALSE, buf,
2089 nread, obj_hmac, &hmac_size) != CKR_OK) {
2090 free(buf);
2091 rv = CKR_FUNCTION_FAILED;
2092 goto cleanup;
2093 }
2094
2095 /* decrypt object */
2096 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
2097 NULL, &out_len) != CKR_OK) {
2098 free(buf);
2099 rv = CKR_FUNCTION_FAILED;
2100 goto cleanup;
2101 }
2102
2103 decrypted_buf = malloc(sizeof (uchar_t) * out_len);
2104 if (decrypted_buf == NULL) {
2105 free(buf);
2106 rv = CKR_HOST_MEMORY;
2107 goto cleanup;
2108 }
2109
2110 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
2111 decrypted_buf, &out_len) != CKR_OK) {
2112 free(decrypted_buf);
2113 free(buf);
2114 rv = CKR_FUNCTION_FAILED;
2115 goto cleanup;
2116 }
2117
2118 obj->size = out_len - MAXPATHLEN;
2119
2120 /*
2121 * decrypted buf here actually contains full path name of
2122 * object plus the actual data. so, need to skip the
2123 * full pathname.
2124 * See prepare_data_for_encrypt() function in the file
2125 * to understand how and why the pathname is added.
2126 */
2127 obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN));
2128 if (obj->buf == NULL) {
2129 free(decrypted_buf);
2130 free(buf);
2131 rv = CKR_HOST_MEMORY;
2132 goto cleanup;
2133 }
2134 (void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size);
2135 free(decrypted_buf);
2136 free(buf);
2137 *return_obj = obj;
2138 }
2139
2140 cleanup:
2141
2142 if (rv != CKR_OK) {
2143 free(obj);
2144 }
2145
2146 /* unlock the file after reading */
2147 if (!lock_held) {
2148 (void) lock_file(fd, B_TRUE, B_FALSE);
2149 }
2150
2151 (void) close(fd);
2152
2153 return (rv);
2154 }
2155
2156
2319 goto cleanup2;
2320 }
2321
2322 if (writen_nointr(obj_fd, (char *)buf, len) != len) {
2323 goto cleanup2;
2324 }
2325
2326 } else {
2327
2328 uchar_t *encrypted_buf, *prepared_buf;
2329 CK_ULONG out_len = 0, prepared_len;
2330
2331 if (prepare_data_for_encrypt(obj_name, buf, len,
2332 &prepared_buf, &prepared_len) != 0) {
2333 goto cleanup2;
2334 }
2335
2336 if (soft_keystore_crypt(enc_key, iv,
2337 B_TRUE, prepared_buf, prepared_len,
2338 NULL, &out_len) != CKR_OK) {
2339 free(prepared_buf);
2340 goto cleanup2;
2341 }
2342
2343 encrypted_buf = malloc(out_len * sizeof (char));
2344 if (encrypted_buf == NULL) {
2345 free(prepared_buf);
2346 goto cleanup2;
2347 }
2348
2349 if (soft_keystore_crypt(enc_key, iv,
2350 B_TRUE, prepared_buf, prepared_len,
2351 encrypted_buf, &out_len) != CKR_OK) {
2352 free(encrypted_buf);
2353 free(prepared_buf);
2354 goto cleanup2;
2355 }
2356 free(prepared_buf);
2357
2358 /* calculate HMAC of encrypted object */
2359 hmac_size = OBJ_HMAC_SIZE;
2360 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
2361 out_len, obj_hmac, &hmac_size) != CKR_OK) {
2362 free(encrypted_buf);
2363 goto cleanup2;
2364 }
2365
2366 if (hmac_size != OBJ_HMAC_SIZE) {
2367 free(encrypted_buf);
2368 goto cleanup2;
2369 }
2370
2371 /* write hmac */
2372 if (writen_nointr(obj_fd, (void *)obj_hmac,
2373 sizeof (obj_hmac)) != sizeof (obj_hmac)) {
2374 free(encrypted_buf);
2375 goto cleanup2;
2376 }
2377
2378 /* write encrypted object */
2379 if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len)
2380 != out_len) {
2381 free(encrypted_buf);
2382 goto cleanup2;
2383 }
2384
2385 free(encrypted_buf);
2386 }
2387
2388
2389 (void) close(obj_fd);
2390 (void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name),
2391 "obj%d", counter);
2392 keyhandle->public = public;
2393
2394 /*
2395 * store new counter to temp keystore description file.
2396 */
2397 counter++;
2398 counter = SWAP32(counter);
2399 if (writen_nointr(tmp_ks_fd, (void *)&counter,
2400 sizeof (counter)) != sizeof (counter)) {
2401 goto cleanup2;
2402 }
2403
2404 /* read rest of keystore description file and store into temp file */
2405 nread = readn_nointr(fd, filebuf, sizeof (filebuf));
2406 while (nread > 0) {
2407 if (writen_nointr(tmp_ks_fd, filebuf, nread) != nread) {
2408 goto cleanup2;
2409 }
2410 nread = readn_nointr(fd, filebuf, sizeof (filebuf));
2411 }
2412
2413 (void) close(tmp_ks_fd);
2414 (void) rename(tmp_ks_desc_name, ks_desc_file);
2415
2416 if (!lock_held) {
2417 /* release lock on description file */
2418 if (lock_file(fd, B_FALSE, B_FALSE) != 0) {
2419 (void) close(fd);
2420 return (-1);
2421 }
2422 }
2423 (void) close(fd);
2424 return (0);
2425
2426 cleanup2:
2427
2428 /* remove object file. No need to remove lock first */
2429 (void) unlink(obj_name);
2430
2431 cleanup:
2432
2433 (void) close(tmp_ks_fd);
2434 (void) remove(tmp_ks_desc_name);
2435 if (!lock_held) {
2436 /* release lock on description file */
2437 (void) lock_file(fd, B_FALSE, B_FALSE);
2438 }
2439
2440 (void) close(fd);
2441 return (-1);
2442 }
2443
2444 /*
2445 * FUNCTION: soft_keystore_modify_obj
2446 *
2447 * ARGUMENTS:
2448 * ks_handle: handle of the key store object to be modified
2449 * buf: buffer containing un-encrypted data
2450 * to be modified in keystore.
2451 * len: length of data
2452 * lock_held: TRUE if the lock is held by caller.
2453 *
2454 * RETURN VALUE:
2455 * -1: if any error occurred.
2456 * Otherwise, 0 is returned.
2457 *
2458 * DESCRIPTION:
2459 *
2460 * This API is used to write a modified token object back
2574
2575 } else {
2576
2577 uchar_t *encrypted_buf, *prepared_buf;
2578 CK_ULONG out_len = 0, prepared_len;
2579
2580 if (prepare_data_for_encrypt(orig_name, buf, len,
2581 &prepared_buf, &prepared_len) != 0) {
2582 goto cleanup2;
2583 }
2584
2585 /* encrypt the data */
2586 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf,
2587 prepared_len, NULL, &out_len) != CKR_OK) {
2588 free(prepared_buf);
2589 goto cleanup2;
2590 }
2591
2592 encrypted_buf = malloc(out_len * sizeof (char));
2593 if (encrypted_buf == NULL) {
2594 free(prepared_buf);
2595 goto cleanup2;
2596 }
2597
2598 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf,
2599 prepared_len, encrypted_buf, &out_len) != CKR_OK) {
2600 free(encrypted_buf);
2601 free(prepared_buf);
2602 goto cleanup2;
2603 }
2604
2605 free(prepared_buf);
2606
2607 /* calculate hmac on encrypted buf */
2608 hmac_size = OBJ_HMAC_SIZE;
2609 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
2610 out_len, obj_hmac, &hmac_size) != CKR_OK) {
2611 free(encrypted_buf);
2612 goto cleanup2;
2613 }
2614
2615 if (hmac_size != OBJ_HMAC_SIZE) {
2616 free(encrypted_buf);
2617 goto cleanup2;
2618 }
2619
2620 if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE)
2621 != OBJ_HMAC_SIZE) {
2622 free(encrypted_buf);
2623 goto cleanup2;
2624 }
2625
2626 if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len)
2627 != out_len) {
2628 free(encrypted_buf);
2629 goto cleanup2;
2630 }
2631 free(encrypted_buf);
2632 }
2633 (void) close(tmp_fd);
2634
2635 /* rename updated temporary object file */
2636 if (rename(tmp_name, orig_name) != 0) {
2637 (void) unlink(tmp_name);
2638 return (-1);
2639 }
2640
2641 /* rename updated keystore description file */
2642 if (rename(tmp_ks_name, ks_desc_file) != 0) {
2643 (void) unlink(tmp_name);
2644 (void) unlink(tmp_ks_name);
2645 return (-1);
2646 }
2647
2648 /* determine need to unlock file or not */
2649 if (!lock_held) {
2650 if (lock_file(fd, B_FALSE, B_FALSE) < 0) {
2651 (void) close(fd);
2652 (void) unlink(tmp_name);
2653 return (-1);
2654 }
2655 }
2656
2657 /* unlock keystore description file */
2658 if (lock_file(ks_fd, B_FALSE, B_FALSE) != 0) {
2659 (void) close(ks_fd);
2660 (void) close(fd);
2661 return (-1);
2662 }
2663
2664 (void) close(ks_fd);
2665
2666 (void) close(fd);
2667
2668 return (0); /* All operations completed successfully */
2669
2670 cleanup2:
2671 (void) close(tmp_fd);
2672 (void) remove(tmp_name);
2673
2674 cleanup1:
2675 (void) close(fd);
2676
2677 cleanup:
2678 /* unlock keystore description file */
2679 (void) lock_file(ks_fd, B_FALSE, B_FALSE);
2680 (void) close(ks_fd);
2681 (void) remove(tmp_ks_name);
2682 return (-1);
2683 }
2684
2685 /*
2686 * FUNCTION: soft_keystore_del_obj
2687 *
2688 * ARGUMENTS:
2689 * ks_handle: handle of the key store object to be deleted
2690 * lock_held: TRUE if the lock is held by caller.
2691 *
2692 * RETURN VALUE:
2693 * -1: if any error occurred.
2694 * 0: object successfully deleted from keystore.
2695 *
2696 * DESCRIPTION:
2697 * This API is used to delete a particular token object from
2698 * the keystore. The corresponding token object file will be
2699 * removed from the file system.
2700 * Any future reference to the deleted file will
2701 * return an CKR_OBJECT_HANDLE_INVALID error.
2786 }
2787
2788 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET)
2789 != KS_HASHED_PIN_SALT_LEN_OFFSET) {
2790 goto cleanup;
2791 }
2792
2793 if (readn_nointr(fd, (char *)&hashed_pin_salt_size,
2794 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
2795 goto cleanup;
2796 }
2797 hashed_pin_salt_size = SWAP64(hashed_pin_salt_size);
2798
2799 *salt = malloc(hashed_pin_salt_size + 1);
2800 if (*salt == NULL) {
2801 goto cleanup;
2802 }
2803
2804 if ((readn_nointr(fd, *salt, hashed_pin_salt_size))
2805 != (ssize_t)hashed_pin_salt_size) {
2806 free(*salt);
2807 goto cleanup;
2808 }
2809 (*salt)[hashed_pin_salt_size] = '\0';
2810
2811 ret_val = 0;
2812
2813 cleanup:
2814 if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
2815 ret_val = -1;
2816 }
2817
2818 (void) close(fd);
2819 return (ret_val);
2820 }
2821
2822 /*
2823 * FUNCTION: soft_keystore_pin_initialized
2824 *
2825 * ARGUMENTS:
2826 * initialized: This value will be set to true if keystore is
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018, Joyent, Inc.
24 */
25
26 /*
27 * Functions used for manipulating the keystore
28 */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <time.h>
36 #include <unistd.h>
37 #include <pwd.h>
38 #include <sys/types.h>
39 #include <dirent.h>
40 #include <limits.h>
41 #include <libgen.h>
42 #include <strings.h>
43 #include <security/cryptoki.h>
454 if (writen_nointr(fd, (void *)hashed_pin_salt,
455 hashed_pin_salt_len) != hashed_pin_salt_len) {
456 goto cleanup;
457 }
458
459 /* write MD5 hashed pin of the default pin */
460 ulong_buf = SWAP64(hashed_pin_len);
461 if (writen_nointr(fd, (void *)&ulong_buf, KS_HASHED_PINLEN_SIZE)
462 != KS_HASHED_PINLEN_SIZE) {
463 goto cleanup;
464 }
465
466 if (writen_nointr(fd, (void *)hashed_pin, hashed_pin_len)
467 != hashed_pin_len) {
468 goto cleanup;
469 }
470
471 (void) lock_file(fd, B_FALSE, B_FALSE);
472
473 (void) close(fd);
474 freezero(hashed_pin_salt, hashed_pin_salt_len);
475 return (0);
476
477 cleanup:
478 (void) lock_file(fd, B_FALSE, B_FALSE);
479 (void) unlink(ks_desc_file);
480 (void) close(fd);
481 (void) rmdir(get_keystore_path());
482 (void) rmdir(pub_obj_path);
483 (void) rmdir(pri_obj_path);
484 return (-1);
485 }
486
487 /*
488 * Determines if the file referenced by "fd" has the same
489 * inode as the file referenced by "fname".
490 *
491 * The argument "same" contains the result of determining
492 * if the inode is the same or not
493 *
494 * Returns 0 if there's no error.
875 /* first, get size of the hashed pin */
876 if (lseek(fd, ks_hashed_pinlen_offset, SEEK_SET)
877 != ks_hashed_pinlen_offset) {
878 return (CKR_FUNCTION_FAILED);
879 }
880
881 if (readn_nointr(fd, (char *)&hashed_pin_size,
882 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) {
883 return (CKR_FUNCTION_FAILED);
884 }
885
886 hashed_pin_size = SWAP64(hashed_pin_size);
887
888 *hashed_pin = malloc(hashed_pin_size + 1);
889 if (*hashed_pin == NULL) {
890 return (CKR_HOST_MEMORY);
891 }
892
893 if ((readn_nointr(fd, *hashed_pin, hashed_pin_size))
894 != (ssize_t)hashed_pin_size) {
895 freezero(*hashed_pin, hashed_pin_size + 1);
896 *hashed_pin = NULL;
897 return (CKR_FUNCTION_FAILED);
898 }
899 (*hashed_pin)[hashed_pin_size] = '\0';
900 return (CKR_OK);
901 }
902
903
904 /*
905 * FUNCTION: soft_keystore_lock
906 *
907 * ARGUMENTS:
908 * set_lock: TRUE to set readlock on the keystore object file,
909 * FALSE to remove readlock on keystore object file.
910 *
911 * RETURN VALUE:
912 *
913 * 0: success
914 * -1: failure
915 *
1303 goto cleanup;
1304 }
1305
1306 if (writen_nointr(new_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
1307 goto cleanup;
1308 }
1309
1310 /* seek to the original encrypted data, and read all of them */
1311 if (lseek(old_fd, OBJ_DATA_OFFSET, SEEK_SET) != OBJ_DATA_OFFSET) {
1312 goto cleanup;
1313 }
1314
1315 if (read_obj_data(old_fd, (char **)&buf, &nread) != CKR_OK) {
1316 goto cleanup;
1317 }
1318
1319 /* decrypt data using old key */
1320 decrypted_len = 0;
1321 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
1322 NULL, &decrypted_len) != CKR_OK) {
1323 freezero(buf, nread);
1324 goto cleanup;
1325 }
1326
1327 decrypted_buf = malloc(decrypted_len);
1328 if (decrypted_buf == NULL) {
1329 freezero(buf, nread);
1330 goto cleanup;
1331 }
1332
1333 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
1334 decrypted_buf, &decrypted_len) != CKR_OK) {
1335 freezero(buf, nread);
1336 freezero(decrypted_buf, decrypted_len);
1337 }
1338
1339 freezero(buf, nread);
1340
1341 /* re-encrypt with new key */
1342 encrypted_len = 0;
1343 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
1344 decrypted_len, NULL, &encrypted_len) != CKR_OK) {
1345 freezero(decrypted_buf, decrypted_len);
1346 goto cleanup;
1347 }
1348
1349 buf = malloc(encrypted_len);
1350 if (buf == NULL) {
1351 freezero(decrypted_buf, decrypted_len);
1352 goto cleanup;
1353 }
1354
1355 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
1356 decrypted_len, buf, &encrypted_len) != CKR_OK) {
1357 freezero(buf, encrypted_len);
1358 freezero(buf, decrypted_len);
1359 goto cleanup;
1360 }
1361
1362 freezero(decrypted_buf, decrypted_len);
1363
1364 /* calculate hmac on re-encrypted data using new hmac key */
1365 hmac_len = OBJ_HMAC_SIZE;
1366 if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf,
1367 encrypted_len, hmac, &hmac_len) != CKR_OK) {
1368 freezero(buf, encrypted_len);
1369 goto cleanup;
1370 }
1371
1372 /* just for sanity check */
1373 if (hmac_len != OBJ_HMAC_SIZE) {
1374 freezero(buf, encrypted_len);
1375 goto cleanup;
1376 }
1377
1378 /* write new hmac */
1379 if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE)
1380 != OBJ_HMAC_SIZE) {
1381 freezero(buf, encrypted_len);
1382 goto cleanup;
1383 }
1384
1385 /* write re-encrypted buffer to temp file */
1386 if (writen_nointr(new_fd, (void *)buf, encrypted_len)
1387 != encrypted_len) {
1388 freezero(buf, encrypted_len);
1389 goto cleanup;
1390 }
1391 freezero(buf, encrypted_len);
1392 ret_val = 0;
1393
1394 cleanup:
1395 /* unlock the files */
1396 (void) lock_file(old_fd, B_TRUE, B_FALSE);
1397 (void) lock_file(new_fd, B_FALSE, B_FALSE);
1398
1399 (void) close(old_fd);
1400 (void) close(new_fd);
1401 if (ret_val != 0) {
1402 (void) remove(new_obj_name);
1403 }
1404 return (ret_val);
1405 }
1406
1407 /*
1408 * FUNCTION: soft_keystore_setpin
1409 *
1410 * ARGUMENTS:
1411 * newpin: new pin entered by the user.
1529 }
1530 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE)
1531 != KS_HMAC_SALT_SIZE) {
1532 goto cleanup;
1533 }
1534
1535 /* just create some empty bytes */
1536 bzero(filebuf, sizeof (filebuf));
1537
1538 if (memcmp(crypt_salt, filebuf, KS_KEY_SALT_SIZE) == 0) {
1539 /* PIN as never been set */
1540 CK_BYTE *new_crypt_salt = NULL, *new_hmac_salt = NULL;
1541
1542 pin_never_set = B_TRUE;
1543 if (soft_gen_crypt_key(newpin, &new_crypt_key, &new_crypt_salt)
1544 != CKR_OK) {
1545 goto cleanup;
1546 }
1547 if (writen_nointr(tmp_ks_fd, (void *)new_crypt_salt,
1548 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
1549 freezero(new_crypt_salt,
1550 KS_KEY_SALT_SIZE);
1551 (void) soft_cleanup_object(new_crypt_key);
1552 goto cleanup;
1553 }
1554 freezero(new_crypt_salt, KS_KEY_SALT_SIZE);
1555
1556 if (soft_gen_hmac_key(newpin, &new_hmac_key, &new_hmac_salt)
1557 != CKR_OK) {
1558 (void) soft_cleanup_object(new_crypt_key);
1559 goto cleanup;
1560 }
1561 if (writen_nointr(tmp_ks_fd, (void *)new_hmac_salt,
1562 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) {
1563 freezero(new_hmac_salt,
1564 KS_HMAC_SALT_SIZE);
1565 goto cleanup3;
1566 }
1567 freezero(new_hmac_salt, KS_HMAC_SALT_SIZE);
1568 } else {
1569 if (soft_gen_crypt_key(newpin, &new_crypt_key,
1570 (CK_BYTE **)&crypt_salt) != CKR_OK) {
1571 goto cleanup;
1572 }
1573 /* no change to the encryption salt */
1574 if (writen_nointr(tmp_ks_fd, (void *)crypt_salt,
1575 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
1576 (void) soft_cleanup_object(new_crypt_key);
1577 goto cleanup;
1578 }
1579
1580 if (soft_gen_hmac_key(newpin, &new_hmac_key,
1581 (CK_BYTE **)&hmac_salt) != CKR_OK) {
1582 (void) soft_cleanup_object(new_crypt_key);
1583 goto cleanup;
1584 }
1585
1586 /* no change to the hmac salt */
1587 if (writen_nointr(tmp_ks_fd, (void *)hmac_salt,
1596 */
1597 if (readn_nointr(fd, (char *)&hashed_pin_salt_length,
1598 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
1599 goto cleanup3;
1600 }
1601
1602 if (writen_nointr(tmp_ks_fd, (void *)&hashed_pin_salt_length,
1603 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
1604 goto cleanup3;
1605 }
1606
1607 hashed_pin_salt_length = SWAP64(hashed_pin_salt_length);
1608
1609 hashed_pin_salt = malloc(hashed_pin_salt_length + 1);
1610 if (hashed_pin_salt == NULL) {
1611 goto cleanup3;
1612 }
1613
1614 if ((readn_nointr(fd, hashed_pin_salt, hashed_pin_salt_length)) !=
1615 (ssize_t)hashed_pin_salt_length) {
1616 freezero(hashed_pin_salt,
1617 hashed_pin_salt_length + 1);
1618 goto cleanup3;
1619 }
1620
1621 if ((writen_nointr(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length))
1622 != (ssize_t)hashed_pin_salt_length) {
1623 freezero(hashed_pin_salt,
1624 hashed_pin_salt_length + 1);
1625 goto cleanup3;
1626 }
1627
1628 hashed_pin_salt[hashed_pin_salt_length] = '\0';
1629
1630 /* old hashed pin length and value can be ignored, generate new one */
1631 if (soft_gen_hashed_pin(newpin, &new_hashed_pin,
1632 &hashed_pin_salt) < 0) {
1633 freezero(hashed_pin_salt,
1634 hashed_pin_salt_length + 1);
1635 goto cleanup3;
1636 }
1637
1638 freezero(hashed_pin_salt, hashed_pin_salt_length + 1);
1639
1640 if (new_hashed_pin == NULL) {
1641 goto cleanup3;
1642 }
1643
1644 new_hashed_pin_len = strlen(new_hashed_pin);
1645
1646 /* write new hashed pin length to file */
1647 swaped_val = SWAP64(new_hashed_pin_len);
1648 if (writen_nointr(tmp_ks_fd, (void *)&swaped_val,
1649 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) {
1650 goto cleanup3;
1651 }
1652
1653 if (writen_nointr(tmp_ks_fd, (void *)new_hashed_pin,
1654 new_hashed_pin_len) != (ssize_t)new_hashed_pin_len) {
1655 goto cleanup3;
1656 }
1657
1658 if (pin_never_set) {
1750 }
1751
1752 if ((!user_logged_in) && (!pin_never_set)) {
1753 (void) soft_cleanup_object(enc_key);
1754 (void) soft_cleanup_object(hmac_key);
1755 enc_key = NULL;
1756 hmac_key = NULL;
1757 }
1758 cleanup3:
1759 if ((ret_val != 0) || (!user_logged_in)) {
1760 (void) soft_cleanup_object(new_crypt_key);
1761 (void) soft_cleanup_object(new_hmac_key);
1762 }
1763
1764 cleanup:
1765 if (!lock_held) {
1766 if (lock_file(fd, B_FALSE, B_FALSE) < 0) {
1767 ret_val = 1;
1768 }
1769 }
1770 freezero(crypt_salt, KS_KEY_SALT_SIZE);
1771 freezero(hmac_salt, KS_HMAC_SALT_SIZE);
1772 (void) close(fd);
1773 (void) close(tmp_ks_fd);
1774 if (ret_val != 0) {
1775 (void) remove(tmp_ks_desc_name);
1776 }
1777 return (ret_val);
1778 }
1779
1780 /*
1781 * FUNCTION: soft_keystore_authpin
1782 *
1783 * ARGUMENTS:
1784 * pin: pin specified by the user for logging into
1785 * the keystore.
1786 *
1787 * RETURN VALUE:
1788 * 0: if no error
1789 * -1: if there is any error
1790 *
1791 * DESCRIPTION:
1838 if (lseek(fd, KS_HMAC_SALT_OFFSET, SEEK_SET) != KS_HMAC_SALT_OFFSET) {
1839 goto cleanup;
1840 }
1841
1842 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE)
1843 != KS_HMAC_SALT_SIZE) {
1844 goto cleanup;
1845 }
1846
1847 if (soft_gen_hmac_key(pin, &hmac_key, (CK_BYTE **)&hmac_salt)
1848 != CKR_OK) {
1849 goto cleanup;
1850 }
1851
1852 ret_val = 0;
1853
1854 cleanup:
1855 /* unlock the file */
1856 (void) lock_file(fd, B_TRUE, B_FALSE);
1857 (void) close(fd);
1858 freezero(crypt_salt, KS_KEY_SALT_SIZE);
1859 freezero(hmac_salt, KS_HMAC_SALT_SIZE);
1860 return (ret_val);
1861 }
1862
1863 /*
1864 * FUNCTION: soft_keystore_get_objs
1865 *
1866 * ARGUMENTS:
1867 *
1868 * search_type: Specify type of objects to return.
1869 * lock_held: TRUE if the lock is held by caller.
1870 *
1871 *
1872 * RETURN VALUE:
1873 *
1874 * NULL: if there are no object in the database.
1875 *
1876 * Otherwise, linked list of objects as requested
1877 * in search type.
1878 *
1879 * The linked list returned will need to be freed
1959 (void) closedir(dirp);
1960 goto cleanup;
1961 }
1962
1963 (void) closedir(dirp);
1964 }
1965 /* close the keystore description file */
1966 (void) lock_file(ks_fd, B_TRUE, B_FALSE);
1967 (void) close(ks_fd);
1968 return (CKR_OK);
1969 cleanup:
1970
1971 /* close the keystore description file */
1972 (void) lock_file(ks_fd, B_TRUE, B_FALSE);
1973 (void) close(ks_fd);
1974
1975 /* free all the objects found before hitting the error */
1976 tmp = *result_obj_list;
1977 while (tmp) {
1978 *result_obj_list = tmp->next;
1979 freezero(tmp->buf, tmp->size);
1980 free(tmp);
1981 tmp = *result_obj_list;
1982 }
1983 *result_obj_list = NULL;
1984 return (rv);
1985 }
1986
1987
1988 /*
1989 * FUNCTION: soft_keystore_get_single_obj
1990 *
1991 * ARGUMENTS:
1992 * ks_handle: handle of the key store object to be accessed
1993 * lock_held: TRUE if the lock is held by caller.
1994 *
1995 * RETURN VALUE:
1996 *
1997 * NULL: if handle doesn't match any object
1998 *
1999 * Otherwise, the object is returned in
2066 }
2067
2068 /* read the object */
2069 rv = read_obj_data(fd, (char **)&buf, &nread);
2070 if (rv != CKR_OK) {
2071 goto cleanup;
2072 }
2073
2074 if (ks_handle->public) {
2075 obj->size = nread;
2076 obj->buf = buf;
2077 *return_obj = obj;
2078 } else {
2079
2080 CK_ULONG out_len = 0, hmac_size;
2081
2082 /* verify HMAC of the object, make sure it matches */
2083 hmac_size = OBJ_HMAC_SIZE;
2084 if (soft_keystore_hmac(hmac_key, B_FALSE, buf,
2085 nread, obj_hmac, &hmac_size) != CKR_OK) {
2086 freezero(buf, nread);
2087 rv = CKR_FUNCTION_FAILED;
2088 goto cleanup;
2089 }
2090
2091 /* decrypt object */
2092 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
2093 NULL, &out_len) != CKR_OK) {
2094 freezero(buf, nread);
2095 rv = CKR_FUNCTION_FAILED;
2096 goto cleanup;
2097 }
2098
2099 decrypted_buf = malloc(sizeof (uchar_t) * out_len);
2100 if (decrypted_buf == NULL) {
2101 freezero(buf, nread);
2102 rv = CKR_HOST_MEMORY;
2103 goto cleanup;
2104 }
2105
2106 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
2107 decrypted_buf, &out_len) != CKR_OK) {
2108 freezero(buf, nread);
2109 freezero(decrypted_buf, out_len);
2110 rv = CKR_FUNCTION_FAILED;
2111 goto cleanup;
2112 }
2113
2114 obj->size = out_len - MAXPATHLEN;
2115
2116 /*
2117 * decrypted buf here actually contains full path name of
2118 * object plus the actual data. so, need to skip the
2119 * full pathname.
2120 * See prepare_data_for_encrypt() function in the file
2121 * to understand how and why the pathname is added.
2122 */
2123 obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN));
2124 if (obj->buf == NULL) {
2125 freezero(buf, nread);
2126 freezero(decrypted_buf, out_len);
2127 rv = CKR_HOST_MEMORY;
2128 goto cleanup;
2129 }
2130 (void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size);
2131 freezero(buf, nread);
2132 freezero(decrypted_buf, out_len);
2133 *return_obj = obj;
2134 }
2135
2136 cleanup:
2137
2138 if (rv != CKR_OK) {
2139 free(obj);
2140 }
2141
2142 /* unlock the file after reading */
2143 if (!lock_held) {
2144 (void) lock_file(fd, B_TRUE, B_FALSE);
2145 }
2146
2147 (void) close(fd);
2148
2149 return (rv);
2150 }
2151
2152
2315 goto cleanup2;
2316 }
2317
2318 if (writen_nointr(obj_fd, (char *)buf, len) != len) {
2319 goto cleanup2;
2320 }
2321
2322 } else {
2323
2324 uchar_t *encrypted_buf, *prepared_buf;
2325 CK_ULONG out_len = 0, prepared_len;
2326
2327 if (prepare_data_for_encrypt(obj_name, buf, len,
2328 &prepared_buf, &prepared_len) != 0) {
2329 goto cleanup2;
2330 }
2331
2332 if (soft_keystore_crypt(enc_key, iv,
2333 B_TRUE, prepared_buf, prepared_len,
2334 NULL, &out_len) != CKR_OK) {
2335 freezero(prepared_buf, prepared_len);
2336 goto cleanup2;
2337 }
2338
2339 encrypted_buf = malloc(out_len * sizeof (char));
2340 if (encrypted_buf == NULL) {
2341 freezero(prepared_buf, prepared_len);
2342 goto cleanup2;
2343 }
2344
2345 if (soft_keystore_crypt(enc_key, iv,
2346 B_TRUE, prepared_buf, prepared_len,
2347 encrypted_buf, &out_len) != CKR_OK) {
2348 freezero(encrypted_buf, out_len);
2349 freezero(prepared_buf, prepared_len);
2350 goto cleanup2;
2351 }
2352 freezero(prepared_buf, prepared_len);
2353
2354 /* calculate HMAC of encrypted object */
2355 hmac_size = OBJ_HMAC_SIZE;
2356 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
2357 out_len, obj_hmac, &hmac_size) != CKR_OK) {
2358 freezero(encrypted_buf, out_len);
2359 goto cleanup2;
2360 }
2361
2362 if (hmac_size != OBJ_HMAC_SIZE) {
2363 freezero(encrypted_buf, out_len);
2364 goto cleanup2;
2365 }
2366
2367 /* write hmac */
2368 if (writen_nointr(obj_fd, (void *)obj_hmac,
2369 sizeof (obj_hmac)) != sizeof (obj_hmac)) {
2370 freezero(encrypted_buf, out_len);
2371 goto cleanup2;
2372 }
2373
2374 /* write encrypted object */
2375 if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len)
2376 != out_len) {
2377 freezero(encrypted_buf, out_len);
2378 goto cleanup2;
2379 }
2380
2381 freezero(encrypted_buf, out_len);
2382 }
2383
2384
2385 (void) close(obj_fd);
2386 (void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name),
2387 "obj%d", counter);
2388 keyhandle->public = public;
2389
2390 /*
2391 * store new counter to temp keystore description file.
2392 */
2393 counter++;
2394 counter = SWAP32(counter);
2395 if (writen_nointr(tmp_ks_fd, (void *)&counter,
2396 sizeof (counter)) != sizeof (counter)) {
2397 goto cleanup2;
2398 }
2399
2400 /* read rest of keystore description file and store into temp file */
2401 nread = readn_nointr(fd, filebuf, sizeof (filebuf));
2402 while (nread > 0) {
2403 if (writen_nointr(tmp_ks_fd, filebuf, nread) != nread) {
2404 goto cleanup2;
2405 }
2406 nread = readn_nointr(fd, filebuf, sizeof (filebuf));
2407 }
2408
2409 (void) close(tmp_ks_fd);
2410 (void) rename(tmp_ks_desc_name, ks_desc_file);
2411
2412 if (!lock_held) {
2413 /* release lock on description file */
2414 if (lock_file(fd, B_FALSE, B_FALSE) != 0) {
2415 (void) close(fd);
2416 return (-1);
2417 }
2418 }
2419 (void) close(fd);
2420 explicit_bzero(obj_hmac, sizeof (obj_hmac));
2421 explicit_bzero(iv, sizeof (iv));
2422 return (0);
2423
2424 cleanup2:
2425
2426 /* remove object file. No need to remove lock first */
2427 (void) unlink(obj_name);
2428
2429 cleanup:
2430
2431 (void) close(tmp_ks_fd);
2432 (void) remove(tmp_ks_desc_name);
2433 if (!lock_held) {
2434 /* release lock on description file */
2435 (void) lock_file(fd, B_FALSE, B_FALSE);
2436 }
2437
2438 (void) close(fd);
2439 explicit_bzero(obj_hmac, sizeof (obj_hmac));
2440 explicit_bzero(iv, sizeof (iv));
2441 return (-1);
2442 }
2443
2444 /*
2445 * FUNCTION: soft_keystore_modify_obj
2446 *
2447 * ARGUMENTS:
2448 * ks_handle: handle of the key store object to be modified
2449 * buf: buffer containing un-encrypted data
2450 * to be modified in keystore.
2451 * len: length of data
2452 * lock_held: TRUE if the lock is held by caller.
2453 *
2454 * RETURN VALUE:
2455 * -1: if any error occurred.
2456 * Otherwise, 0 is returned.
2457 *
2458 * DESCRIPTION:
2459 *
2460 * This API is used to write a modified token object back
2574
2575 } else {
2576
2577 uchar_t *encrypted_buf, *prepared_buf;
2578 CK_ULONG out_len = 0, prepared_len;
2579
2580 if (prepare_data_for_encrypt(orig_name, buf, len,
2581 &prepared_buf, &prepared_len) != 0) {
2582 goto cleanup2;
2583 }
2584
2585 /* encrypt the data */
2586 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf,
2587 prepared_len, NULL, &out_len) != CKR_OK) {
2588 free(prepared_buf);
2589 goto cleanup2;
2590 }
2591
2592 encrypted_buf = malloc(out_len * sizeof (char));
2593 if (encrypted_buf == NULL) {
2594 freezero(prepared_buf, prepared_len);
2595 goto cleanup2;
2596 }
2597
2598 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf,
2599 prepared_len, encrypted_buf, &out_len) != CKR_OK) {
2600 freezero(prepared_buf, prepared_len);
2601 freezero(encrypted_buf, out_len);
2602 goto cleanup2;
2603 }
2604
2605 freezero(prepared_buf, prepared_len);
2606
2607 /* calculate hmac on encrypted buf */
2608 hmac_size = OBJ_HMAC_SIZE;
2609 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
2610 out_len, obj_hmac, &hmac_size) != CKR_OK) {
2611 freezero(encrypted_buf, out_len);
2612 goto cleanup2;
2613 }
2614
2615 if (hmac_size != OBJ_HMAC_SIZE) {
2616 freezero(encrypted_buf, out_len);
2617 goto cleanup2;
2618 }
2619
2620 if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE)
2621 != OBJ_HMAC_SIZE) {
2622 freezero(encrypted_buf, out_len);
2623 goto cleanup2;
2624 }
2625
2626 if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len)
2627 != out_len) {
2628 freezero(encrypted_buf, out_len);
2629 goto cleanup2;
2630 }
2631 freezero(encrypted_buf, out_len);
2632 }
2633 (void) close(tmp_fd);
2634
2635 /* rename updated temporary object file */
2636 if (rename(tmp_name, orig_name) != 0) {
2637 (void) unlink(tmp_name);
2638 return (-1);
2639 }
2640
2641 /* rename updated keystore description file */
2642 if (rename(tmp_ks_name, ks_desc_file) != 0) {
2643 (void) unlink(tmp_name);
2644 (void) unlink(tmp_ks_name);
2645 return (-1);
2646 }
2647
2648 /* determine need to unlock file or not */
2649 if (!lock_held) {
2650 if (lock_file(fd, B_FALSE, B_FALSE) < 0) {
2651 (void) close(fd);
2652 (void) unlink(tmp_name);
2653 return (-1);
2654 }
2655 }
2656
2657 /* unlock keystore description file */
2658 if (lock_file(ks_fd, B_FALSE, B_FALSE) != 0) {
2659 (void) close(ks_fd);
2660 (void) close(fd);
2661 return (-1);
2662 }
2663
2664 (void) close(ks_fd);
2665
2666 (void) close(fd);
2667
2668 explicit_bzero(iv, sizeof (iv));
2669 explicit_bzero(obj_hmac, sizeof (obj_hmac));
2670 return (0); /* All operations completed successfully */
2671
2672 cleanup2:
2673 (void) close(tmp_fd);
2674 (void) remove(tmp_name);
2675
2676 cleanup1:
2677 (void) close(fd);
2678
2679 cleanup:
2680 /* unlock keystore description file */
2681 (void) lock_file(ks_fd, B_FALSE, B_FALSE);
2682 (void) close(ks_fd);
2683 (void) remove(tmp_ks_name);
2684 explicit_bzero(iv, sizeof (iv));
2685 explicit_bzero(obj_hmac, sizeof (obj_hmac));
2686 return (-1);
2687 }
2688
2689 /*
2690 * FUNCTION: soft_keystore_del_obj
2691 *
2692 * ARGUMENTS:
2693 * ks_handle: handle of the key store object to be deleted
2694 * lock_held: TRUE if the lock is held by caller.
2695 *
2696 * RETURN VALUE:
2697 * -1: if any error occurred.
2698 * 0: object successfully deleted from keystore.
2699 *
2700 * DESCRIPTION:
2701 * This API is used to delete a particular token object from
2702 * the keystore. The corresponding token object file will be
2703 * removed from the file system.
2704 * Any future reference to the deleted file will
2705 * return an CKR_OBJECT_HANDLE_INVALID error.
2790 }
2791
2792 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET)
2793 != KS_HASHED_PIN_SALT_LEN_OFFSET) {
2794 goto cleanup;
2795 }
2796
2797 if (readn_nointr(fd, (char *)&hashed_pin_salt_size,
2798 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
2799 goto cleanup;
2800 }
2801 hashed_pin_salt_size = SWAP64(hashed_pin_salt_size);
2802
2803 *salt = malloc(hashed_pin_salt_size + 1);
2804 if (*salt == NULL) {
2805 goto cleanup;
2806 }
2807
2808 if ((readn_nointr(fd, *salt, hashed_pin_salt_size))
2809 != (ssize_t)hashed_pin_salt_size) {
2810 freezero(*salt, hashed_pin_salt_size + 1);
2811 goto cleanup;
2812 }
2813 (*salt)[hashed_pin_salt_size] = '\0';
2814
2815 ret_val = 0;
2816
2817 cleanup:
2818 if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
2819 ret_val = -1;
2820 }
2821
2822 (void) close(fd);
2823 return (ret_val);
2824 }
2825
2826 /*
2827 * FUNCTION: soft_keystore_pin_initialized
2828 *
2829 * ARGUMENTS:
2830 * initialized: This value will be set to true if keystore is
|