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 #include <crypt.h>
26 #include <cryptoutil.h>
27 #include <pwd.h>
28 #include <pthread.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <strings.h>
32 #include <sys/types.h>
33 #include <sys/sysmacros.h>
34 #include <security/cryptoki.h>
35 #include "softGlobal.h"
36 #include "softCrypt.h"
37 #include "softSession.h"
38 #include "softObject.h"
39 #include "softKeys.h"
40 #include "softKeystore.h"
41 #include "softKeystoreUtil.h"
42 #include "softMAC.h"
81 */
82 uid = geteuid();
83 if (getpwuid_r(uid, &pwd, pwdbuf, PWD_BUFFER_SIZE, &pw) != 0) {
84 return (-1);
85 }
86
87 if (*salt == NULL) {
88 new_salt = B_TRUE;
89 /*
90 * crypt_gensalt() will allocate memory to store the new salt.
91 * on return. Pass "$5" here to default to crypt_sha256 since
92 * SHA256 is a FIPS 140-2 certified algorithm and we shouldn't
93 * assume the system default is that strong.
94 */
95 if ((*salt = crypt_gensalt("$5", pw)) == NULL) {
96 return (-1);
97 }
98 }
99
100 if ((*result = crypt((char *)pPin, *salt)) == NULL) {
101 if (new_salt)
102 free(*salt);
103 return (-1);
104 }
105
106 return (0);
107 }
108
109 /*
110 * Authenticate user's PIN for C_Login.
111 */
112 CK_RV
113 soft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
114 {
115
116 char *user_cryptpin = NULL;
117 char *ks_cryptpin = NULL;
118 char *salt = NULL;
119 uchar_t *tmp_pin = NULL;
120 boolean_t pin_initialized = B_FALSE;
121 CK_RV rv = CKR_OK;
122
123 /*
124 * Check to see if keystore is initialized.
125 */
126 rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
127 B_FALSE);
128 if (rv != CKR_OK)
129 return (rv);
130
131 /*
132 * Authenticate user's PIN for C_Login.
133 */
134 if (pin_initialized) {
135
136 if (soft_keystore_get_pin_salt(&salt) < 0) {
137 rv = CKR_FUNCTION_FAILED;
138 goto cleanup;
139 }
140
141 /*
172 */
173 if (soft_keystore_authpin(tmp_pin) != 0) {
174 rv = CKR_FUNCTION_FAILED;
175 } else {
176 rv = CKR_OK;
177 }
178 goto cleanup;
179 } else {
180 /*
181 * The PIN is not initialized in the keystore
182 * We will let it pass the authentication anyway but set the
183 * "userpin_change_needed" flag so that the application
184 * will get CKR_PIN_EXPIRED by other C_functions such as
185 * C_CreateObject, C_FindObjectInit, C_GenerateKey etc.
186 */
187 soft_slot.userpin_change_needed = 1;
188 rv = CKR_OK;
189 }
190
191 cleanup:
192 if (salt)
193 free(salt);
194 if (tmp_pin)
195 free(tmp_pin);
196 if (ks_cryptpin)
197 free(ks_cryptpin);
198
199 return (rv);
200 }
201
202 /*
203 * The second level C_SetPIN function.
204 */
205 CK_RV
206 soft_setpin(CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
207 CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
208 {
209
210 char *user_cryptpin = NULL;
211 char *ks_cryptpin = NULL;
212 char *salt = NULL;
213 boolean_t pin_initialized = B_FALSE;
214 uchar_t *tmp_old_pin = NULL, *tmp_new_pin = NULL;
215 CK_RV rv = CKR_OK;
216
217 /*
218 * Check to see if keystore is initialized.
219 */
220 rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
221 B_FALSE);
222 if (rv != CKR_OK)
223 return (rv);
224
225 /*
226 * Authenticate user's PIN for C_SetPIN.
227 */
228 if (pin_initialized) {
229 /*
230 * Generate the hashed value based on the user supplied PIN.
231 */
232 if (soft_keystore_get_pin_salt(&salt) < 0) {
233 rv = CKR_FUNCTION_FAILED;
234 goto cleanup;
235 }
273 rv = CKR_HOST_MEMORY;
274 goto cleanup;
275 }
276 (void) memcpy(tmp_new_pin, pNewPin, ulNewPinLen);
277 tmp_new_pin[ulNewPinLen] = '\0';
278
279 /*
280 * Set the new pin after the old pin is authenticated.
281 */
282 if (soft_keystore_setpin(tmp_old_pin, tmp_new_pin, B_FALSE)) {
283 rv = CKR_FUNCTION_FAILED;
284 goto cleanup;
285 } else {
286 (void) pthread_mutex_lock(&soft_giant_mutex);
287 soft_slot.userpin_change_needed = 0;
288 (void) pthread_mutex_unlock(&soft_giant_mutex);
289 rv = CKR_OK;
290 }
291
292 cleanup:
293 if (salt)
294 free(salt);
295 if (ks_cryptpin)
296 free(ks_cryptpin);
297 if (tmp_old_pin)
298 free(tmp_old_pin);
299 if (tmp_new_pin)
300 free(tmp_new_pin);
301
302 return (rv);
303 }
304
305 /*
306 * soft_keystore_pack_obj()
307 *
308 * Arguments:
309 *
310 * obj: pointer to the soft_object_t of the token object to
311 * be packed
312 * ks_buf: output argument which contains the address of the
313 * pointer to the buf of the packed token object
314 * soft_keystore_pack_obj() will allocate memory for the buf,
315 * it is caller's responsibility to free it.
316 * len: output argument which contains the address of the
317 * buffer length of the packed token object
318 *
319 * Description:
320 *
458 * Unpack extra attribute list.
459 */
460 for (i = 0; i < SWAP32(hdr->num_attrs); i++) {
461 /* LINTED: pointer alignment */
462 attr_hdr = (ks_attr_hdr_t *)buf;
463 (void) memset(&template, 0, sizeof (CK_ATTRIBUTE));
464 template.type = (CK_ATTRIBUTE_TYPE)(SWAP64(attr_hdr->type));
465 template.ulValueLen = (CK_ULONG)(SWAP64(attr_hdr->ulValueLen));
466 buf = buf + sizeof (ks_attr_hdr_t);
467 /* Allocate storage for the value of the attribute. */
468 if (template.ulValueLen > 0) {
469 template.pValue = malloc(template.ulValueLen);
470 if (template.pValue == NULL) {
471 return (CKR_HOST_MEMORY);
472 }
473 (void) memcpy(template.pValue, buf,
474 template.ulValueLen);
475 }
476
477 rv = soft_add_extra_attr(&template, obj);
478 if (template.pValue) {
479 free(template.pValue);
480 }
481
482 if (rv != CKR_OK) {
483 return (rv);
484 }
485
486 buf = buf + ROUNDUP(template.ulValueLen, 8);
487 }
488
489 /*
490 * Unpack the key itself.
491 */
492 rv = soft_unpack_object(obj, buf);
493 return (rv);
494
495 }
496
497
498 /*
499 * soft_unpack_obj_attribute()
500 *
526 {
527
528 CK_RV rv;
529 CK_ATTRIBUTE template;
530
531 /* LINTED: pointer alignment */
532 template.ulValueLen = SWAP64(*(uint64_t *)buf);
533 buf = buf + sizeof (uint64_t);
534 template.pValue = malloc(template.ulValueLen);
535 if (template.pValue == NULL) {
536 return (CKR_HOST_MEMORY);
537 }
538
539 (void) memcpy(template.pValue, buf, template.ulValueLen);
540 if (cert) {
541 rv = get_cert_attr_from_template(cert_dest, &template);
542 } else {
543 rv = get_bigint_attr_from_template(key_dest, &template);
544 }
545
546 free(template.pValue);
547 if (rv != CKR_OK) {
548 return (rv);
549 }
550
551 *offset = sizeof (uint64_t) + template.ulValueLen;
552 return (CKR_OK);
553 }
554
555
556 /*
557 * Calculate the total buffer length required to store the
558 * object key (the third part) in a keystore format.
559 */
560 ulong_t
561 soft_pack_object_size(soft_object_t *objp)
562 {
563
564 CK_OBJECT_CLASS class = objp->class;
565 CK_KEY_TYPE keytype = objp->key_type;
566 CK_CERTIFICATE_TYPE certtype = objp->cert_type;
1840 return (rv);
1841 }
1842
1843
1844 /*
1845 * Store the token object to a keystore file.
1846 */
1847 CK_RV
1848 soft_put_object_to_keystore(soft_object_t *objp)
1849 {
1850
1851 uchar_t *buf;
1852 size_t len;
1853 CK_RV rv;
1854
1855 rv = soft_keystore_pack_obj(objp, &buf, &len);
1856 if (rv != CKR_OK)
1857 return (rv);
1858
1859 (void) pthread_mutex_lock(&soft_slot.slot_mutex);
1860 if (objp->object_type == TOKEN_PUBLIC) {
1861 if ((soft_keystore_put_new_obj(buf, len, B_TRUE,
1862 B_FALSE, &objp->ks_handle)) == -1) {
1863 (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1864 free(buf);
1865 return (CKR_FUNCTION_FAILED);
1866 }
1867 } else {
1868 if ((soft_keystore_put_new_obj(buf, len, B_FALSE,
1869 B_FALSE, &objp->ks_handle)) == -1) {
1870 (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1871 free(buf);
1872 return (CKR_FUNCTION_FAILED);
1873 }
1874 }
1875 (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1876 free(buf);
1877 return (CKR_OK);
1878
1879 }
1880
1881 /*
1882 * Modify the in-core token object and then write it to
1883 * a keystore file.
1884 */
1885 CK_RV
1886 soft_modify_object_to_keystore(soft_object_t *objp)
1887 {
1888
1889 uchar_t *buf;
1890 size_t len;
1891 CK_RV rv;
1892
1893 rv = soft_keystore_pack_obj(objp, &buf, &len);
1894 if (rv != CKR_OK)
1895 return (rv);
1896
1897 /* B_TRUE: caller has held a writelock on the keystore */
1898 if (soft_keystore_modify_obj(&objp->ks_handle, buf, len,
1899 B_TRUE) < 0) {
1900 return (CKR_FUNCTION_FAILED);
1901 }
1902
1903 free(buf);
1904 return (CKR_OK);
1905
1906 }
1907
1908 /*
1909 * Read the token object from the keystore file.
1910 */
1911 CK_RV
1912 soft_get_token_objects_from_keystore(ks_search_type_t type)
1913 {
1914 CK_RV rv;
1915 ks_obj_t *ks_obj = NULL, *ks_obj_next;
1916 soft_object_t *new_objp = NULL;
1917
1918 /* Load the token object from keystore based on the object type */
1919 rv = soft_keystore_get_objs(type, &ks_obj, B_FALSE);
1920 if (rv != CKR_OK) {
1921 return (rv);
1922 }
1923
1924 while (ks_obj) {
1925
1926 new_objp = calloc(1, sizeof (soft_object_t));
1927 if (new_objp == NULL) {
1928 rv = CKR_HOST_MEMORY;
1929 goto cleanup;
1930 }
1931 /* Convert the keystore format to memory format */
1932 rv = soft_keystore_unpack_obj(new_objp, ks_obj);
1933 if (rv != CKR_OK) {
1934 if (new_objp->class == CKO_CERTIFICATE)
1935 soft_cleanup_cert_object(new_objp);
1936 else
1937 soft_cleanup_object(new_objp);
1938 goto cleanup;
1939 }
1940
1941 soft_add_token_object_to_slot(new_objp);
1942
1943 /* Free the ks_obj list */
1944 ks_obj_next = ks_obj->next;
1945 if (ks_obj->buf)
1946 free(ks_obj->buf);
1947 free(ks_obj);
1948 ks_obj = ks_obj_next;
1949 }
1950
1951 return (CKR_OK);
1952
1953 cleanup:
1954 while (ks_obj) {
1955 ks_obj_next = ks_obj->next;
1956 free(ks_obj->buf);
1957 free(ks_obj);
1958 ks_obj = ks_obj_next;
1959 }
1960 return (rv);
1961 }
1962
1963 /*
1964 * soft_gen_crypt_key()
1965 *
1966 * Arguments:
1967 *
1968 * pPIN: pointer to caller provided Pin
1969 * key: output argument which contains the address of the
1970 * pointer to encryption key in the soft_object_t.
1971 * It is caller's responsibility to call soft_delete_object()
1972 * if this key is no longer in use.
1973 * saltdata: input argument (if non-NULL), or
1974 * output argument (if NULL):
1975 * address of pointer to the "salt" of the encryption key
1976 *
2287
2288
2289 (void) pthread_mutex_lock(&token_session.session_mutex);
2290
2291 if (encrypt)
2292 soft_aes_ctx =
2293 (soft_aes_ctx_t *)token_session.encrypt.context;
2294 else
2295 soft_aes_ctx =
2296 (soft_aes_ctx_t *)token_session.decrypt.context;
2297
2298 /* Copy Initialization Vector (IV) into the context. */
2299 (void) memcpy(soft_aes_ctx->ivec, ivec, AES_BLOCK_LEN);
2300
2301 /* Allocate a context for AES cipher-block chaining. */
2302 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
2303 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2304 soft_aes_ctx->ivec);
2305
2306 if (soft_aes_ctx->aes_cbc == NULL) {
2307 bzero(soft_aes_ctx->key_sched,
2308 soft_aes_ctx->keysched_len);
2309 free(soft_aes_ctx->key_sched);
2310 if (encrypt) {
2311 free(token_session.encrypt.context);
2312 token_session.encrypt.context = NULL;
2313 } else {
2314 free(token_session.encrypt.context);
2315 token_session.encrypt.context = NULL;
2316 }
2317
2318 (void) pthread_mutex_unlock(&token_session.
2319 session_mutex);
2320 return (CKR_HOST_MEMORY);
2321 }
2322
2323 (void) pthread_mutex_unlock(&token_session.session_mutex);
2324 /*
2325 * Since out == NULL, the soft_aes_xxcrypt_common() will
2326 * simply return the output buffer length to the caller.
2327 */
2328 if (encrypt) {
2329 rv = soft_aes_encrypt_common(&token_session, in,
|
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 #include <crypt.h>
27 #include <cryptoutil.h>
28 #include <pwd.h>
29 #include <pthread.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <sys/types.h>
34 #include <sys/sysmacros.h>
35 #include <security/cryptoki.h>
36 #include "softGlobal.h"
37 #include "softCrypt.h"
38 #include "softSession.h"
39 #include "softObject.h"
40 #include "softKeys.h"
41 #include "softKeystore.h"
42 #include "softKeystoreUtil.h"
43 #include "softMAC.h"
82 */
83 uid = geteuid();
84 if (getpwuid_r(uid, &pwd, pwdbuf, PWD_BUFFER_SIZE, &pw) != 0) {
85 return (-1);
86 }
87
88 if (*salt == NULL) {
89 new_salt = B_TRUE;
90 /*
91 * crypt_gensalt() will allocate memory to store the new salt.
92 * on return. Pass "$5" here to default to crypt_sha256 since
93 * SHA256 is a FIPS 140-2 certified algorithm and we shouldn't
94 * assume the system default is that strong.
95 */
96 if ((*salt = crypt_gensalt("$5", pw)) == NULL) {
97 return (-1);
98 }
99 }
100
101 if ((*result = crypt((char *)pPin, *salt)) == NULL) {
102 if (new_salt) {
103 size_t saltlen = strlen(*salt) + 1;
104
105 freezero(*salt, saltlen);
106 }
107 return (-1);
108 }
109
110 return (0);
111 }
112
113 /*
114 * Authenticate user's PIN for C_Login.
115 */
116 CK_RV
117 soft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
118 {
119
120 char *user_cryptpin = NULL;
121 char *ks_cryptpin = NULL;
122 char *salt = NULL;
123 uchar_t *tmp_pin = NULL;
124 boolean_t pin_initialized = B_FALSE;
125 CK_RV rv = CKR_OK;
126 size_t len = 0;
127
128 /*
129 * Check to see if keystore is initialized.
130 */
131 rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
132 B_FALSE);
133 if (rv != CKR_OK)
134 return (rv);
135
136 /*
137 * Authenticate user's PIN for C_Login.
138 */
139 if (pin_initialized) {
140
141 if (soft_keystore_get_pin_salt(&salt) < 0) {
142 rv = CKR_FUNCTION_FAILED;
143 goto cleanup;
144 }
145
146 /*
177 */
178 if (soft_keystore_authpin(tmp_pin) != 0) {
179 rv = CKR_FUNCTION_FAILED;
180 } else {
181 rv = CKR_OK;
182 }
183 goto cleanup;
184 } else {
185 /*
186 * The PIN is not initialized in the keystore
187 * We will let it pass the authentication anyway but set the
188 * "userpin_change_needed" flag so that the application
189 * will get CKR_PIN_EXPIRED by other C_functions such as
190 * C_CreateObject, C_FindObjectInit, C_GenerateKey etc.
191 */
192 soft_slot.userpin_change_needed = 1;
193 rv = CKR_OK;
194 }
195
196 cleanup:
197 if (salt) {
198 len = strlen(salt) + 1;
199 freezero(salt, len);
200 }
201 if (tmp_pin) {
202 len = strlen((char *)tmp_pin) + 1;
203 freezero(tmp_pin, len);
204 }
205 if (ks_cryptpin) {
206 len = strlen(ks_cryptpin) + 1;
207 freezero(ks_cryptpin, len);
208 }
209 return (rv);
210 }
211
212 /*
213 * The second level C_SetPIN function.
214 */
215 CK_RV
216 soft_setpin(CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
217 CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
218 {
219
220 char *user_cryptpin = NULL;
221 char *ks_cryptpin = NULL;
222 char *salt = NULL;
223 boolean_t pin_initialized = B_FALSE;
224 uchar_t *tmp_old_pin = NULL, *tmp_new_pin = NULL;
225 CK_RV rv = CKR_OK;
226 size_t len = 0;
227
228 /*
229 * Check to see if keystore is initialized.
230 */
231 rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
232 B_FALSE);
233 if (rv != CKR_OK)
234 return (rv);
235
236 /*
237 * Authenticate user's PIN for C_SetPIN.
238 */
239 if (pin_initialized) {
240 /*
241 * Generate the hashed value based on the user supplied PIN.
242 */
243 if (soft_keystore_get_pin_salt(&salt) < 0) {
244 rv = CKR_FUNCTION_FAILED;
245 goto cleanup;
246 }
284 rv = CKR_HOST_MEMORY;
285 goto cleanup;
286 }
287 (void) memcpy(tmp_new_pin, pNewPin, ulNewPinLen);
288 tmp_new_pin[ulNewPinLen] = '\0';
289
290 /*
291 * Set the new pin after the old pin is authenticated.
292 */
293 if (soft_keystore_setpin(tmp_old_pin, tmp_new_pin, B_FALSE)) {
294 rv = CKR_FUNCTION_FAILED;
295 goto cleanup;
296 } else {
297 (void) pthread_mutex_lock(&soft_giant_mutex);
298 soft_slot.userpin_change_needed = 0;
299 (void) pthread_mutex_unlock(&soft_giant_mutex);
300 rv = CKR_OK;
301 }
302
303 cleanup:
304 if (salt) {
305 len = strlen(salt) + 1;
306 freezero(salt, len);
307 }
308 if (ks_cryptpin) {
309 len = strlen(ks_cryptpin) + 1;
310 freezero(ks_cryptpin, len);
311 }
312 if (tmp_old_pin) {
313 len = strlen((char *)tmp_old_pin) + 1;
314 freezero(tmp_old_pin, len);
315 }
316 if (tmp_new_pin) {
317 len = strlen((char *)tmp_new_pin) + 1;
318 freezero(tmp_new_pin, len);
319 }
320
321 return (rv);
322 }
323
324 /*
325 * soft_keystore_pack_obj()
326 *
327 * Arguments:
328 *
329 * obj: pointer to the soft_object_t of the token object to
330 * be packed
331 * ks_buf: output argument which contains the address of the
332 * pointer to the buf of the packed token object
333 * soft_keystore_pack_obj() will allocate memory for the buf,
334 * it is caller's responsibility to free it.
335 * len: output argument which contains the address of the
336 * buffer length of the packed token object
337 *
338 * Description:
339 *
477 * Unpack extra attribute list.
478 */
479 for (i = 0; i < SWAP32(hdr->num_attrs); i++) {
480 /* LINTED: pointer alignment */
481 attr_hdr = (ks_attr_hdr_t *)buf;
482 (void) memset(&template, 0, sizeof (CK_ATTRIBUTE));
483 template.type = (CK_ATTRIBUTE_TYPE)(SWAP64(attr_hdr->type));
484 template.ulValueLen = (CK_ULONG)(SWAP64(attr_hdr->ulValueLen));
485 buf = buf + sizeof (ks_attr_hdr_t);
486 /* Allocate storage for the value of the attribute. */
487 if (template.ulValueLen > 0) {
488 template.pValue = malloc(template.ulValueLen);
489 if (template.pValue == NULL) {
490 return (CKR_HOST_MEMORY);
491 }
492 (void) memcpy(template.pValue, buf,
493 template.ulValueLen);
494 }
495
496 rv = soft_add_extra_attr(&template, obj);
497 freezero(template.pValue, template.ulValueLen);
498
499 if (rv != CKR_OK) {
500 return (rv);
501 }
502
503 buf = buf + ROUNDUP(template.ulValueLen, 8);
504 }
505
506 /*
507 * Unpack the key itself.
508 */
509 rv = soft_unpack_object(obj, buf);
510 return (rv);
511
512 }
513
514
515 /*
516 * soft_unpack_obj_attribute()
517 *
543 {
544
545 CK_RV rv;
546 CK_ATTRIBUTE template;
547
548 /* LINTED: pointer alignment */
549 template.ulValueLen = SWAP64(*(uint64_t *)buf);
550 buf = buf + sizeof (uint64_t);
551 template.pValue = malloc(template.ulValueLen);
552 if (template.pValue == NULL) {
553 return (CKR_HOST_MEMORY);
554 }
555
556 (void) memcpy(template.pValue, buf, template.ulValueLen);
557 if (cert) {
558 rv = get_cert_attr_from_template(cert_dest, &template);
559 } else {
560 rv = get_bigint_attr_from_template(key_dest, &template);
561 }
562
563 freezero(template.pValue, template.ulValueLen);
564 if (rv != CKR_OK) {
565 return (rv);
566 }
567
568 *offset = sizeof (uint64_t) + template.ulValueLen;
569 return (CKR_OK);
570 }
571
572
573 /*
574 * Calculate the total buffer length required to store the
575 * object key (the third part) in a keystore format.
576 */
577 ulong_t
578 soft_pack_object_size(soft_object_t *objp)
579 {
580
581 CK_OBJECT_CLASS class = objp->class;
582 CK_KEY_TYPE keytype = objp->key_type;
583 CK_CERTIFICATE_TYPE certtype = objp->cert_type;
1857 return (rv);
1858 }
1859
1860
1861 /*
1862 * Store the token object to a keystore file.
1863 */
1864 CK_RV
1865 soft_put_object_to_keystore(soft_object_t *objp)
1866 {
1867
1868 uchar_t *buf;
1869 size_t len;
1870 CK_RV rv;
1871
1872 rv = soft_keystore_pack_obj(objp, &buf, &len);
1873 if (rv != CKR_OK)
1874 return (rv);
1875
1876 (void) pthread_mutex_lock(&soft_slot.slot_mutex);
1877 if (soft_keystore_put_new_obj(buf, len,
1878 !!(objp->object_type == TOKEN_PUBLIC), B_FALSE,
1879 &objp->ks_handle) == -1) {
1880 rv = CKR_FUNCTION_FAILED;
1881 }
1882 (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1883
1884 freezero(buf, len);
1885 return (rv);
1886 }
1887
1888 /*
1889 * Modify the in-core token object and then write it to
1890 * a keystore file.
1891 */
1892 CK_RV
1893 soft_modify_object_to_keystore(soft_object_t *objp)
1894 {
1895
1896 uchar_t *buf;
1897 size_t len;
1898 CK_RV rv;
1899
1900 rv = soft_keystore_pack_obj(objp, &buf, &len);
1901 if (rv != CKR_OK)
1902 return (rv);
1903
1904 /* B_TRUE: caller has held a writelock on the keystore */
1905 if (soft_keystore_modify_obj(&objp->ks_handle, buf, len,
1906 B_TRUE) < 0) {
1907 rv = CKR_FUNCTION_FAILED;
1908 }
1909
1910 freezero(buf, len);
1911 return (rv);
1912
1913 }
1914
1915 /*
1916 * Read the token object from the keystore file.
1917 */
1918 CK_RV
1919 soft_get_token_objects_from_keystore(ks_search_type_t type)
1920 {
1921 CK_RV rv;
1922 ks_obj_t *ks_obj = NULL, *ks_obj_next;
1923 soft_object_t *new_objp = NULL;
1924
1925 /* Load the token object from keystore based on the object type */
1926 rv = soft_keystore_get_objs(type, &ks_obj, B_FALSE);
1927 if (rv != CKR_OK) {
1928 return (rv);
1929 }
1930
1931 while (ks_obj) {
1932
1933 new_objp = calloc(1, sizeof (soft_object_t));
1934 if (new_objp == NULL) {
1935 rv = CKR_HOST_MEMORY;
1936 goto cleanup;
1937 }
1938 /* Convert the keystore format to memory format */
1939 rv = soft_keystore_unpack_obj(new_objp, ks_obj);
1940 if (rv != CKR_OK) {
1941 if (new_objp->class == CKO_CERTIFICATE)
1942 soft_cleanup_cert_object(new_objp);
1943 else
1944 soft_cleanup_object(new_objp);
1945 goto cleanup;
1946 }
1947
1948 soft_add_token_object_to_slot(new_objp);
1949
1950 /* Free the ks_obj list */
1951 ks_obj_next = ks_obj->next;
1952 freezero(ks_obj->buf, ks_obj->size);
1953 free(ks_obj);
1954 ks_obj = ks_obj_next;
1955 }
1956
1957 return (CKR_OK);
1958
1959 cleanup:
1960 while (ks_obj) {
1961 ks_obj_next = ks_obj->next;
1962 freezero(ks_obj->buf, ks_obj->size);
1963 free(ks_obj);
1964 ks_obj = ks_obj_next;
1965 }
1966 return (rv);
1967 }
1968
1969 /*
1970 * soft_gen_crypt_key()
1971 *
1972 * Arguments:
1973 *
1974 * pPIN: pointer to caller provided Pin
1975 * key: output argument which contains the address of the
1976 * pointer to encryption key in the soft_object_t.
1977 * It is caller's responsibility to call soft_delete_object()
1978 * if this key is no longer in use.
1979 * saltdata: input argument (if non-NULL), or
1980 * output argument (if NULL):
1981 * address of pointer to the "salt" of the encryption key
1982 *
2293
2294
2295 (void) pthread_mutex_lock(&token_session.session_mutex);
2296
2297 if (encrypt)
2298 soft_aes_ctx =
2299 (soft_aes_ctx_t *)token_session.encrypt.context;
2300 else
2301 soft_aes_ctx =
2302 (soft_aes_ctx_t *)token_session.decrypt.context;
2303
2304 /* Copy Initialization Vector (IV) into the context. */
2305 (void) memcpy(soft_aes_ctx->ivec, ivec, AES_BLOCK_LEN);
2306
2307 /* Allocate a context for AES cipher-block chaining. */
2308 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
2309 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2310 soft_aes_ctx->ivec);
2311
2312 if (soft_aes_ctx->aes_cbc == NULL) {
2313 freezero(soft_aes_ctx->key_sched,
2314 soft_aes_ctx->keysched_len);
2315 if (encrypt) {
2316 free(token_session.encrypt.context);
2317 token_session.encrypt.context = NULL;
2318 } else {
2319 free(token_session.encrypt.context);
2320 token_session.encrypt.context = NULL;
2321 }
2322
2323 (void) pthread_mutex_unlock(&token_session.
2324 session_mutex);
2325 return (CKR_HOST_MEMORY);
2326 }
2327
2328 (void) pthread_mutex_unlock(&token_session.session_mutex);
2329 /*
2330 * Since out == NULL, the soft_aes_xxcrypt_common() will
2331 * simply return the output buffer length to the caller.
2332 */
2333 if (encrypt) {
2334 rv = soft_aes_encrypt_common(&token_session, in,
|