Print this page
9642 PKCS#11 softtoken should use explicit_bzero
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
*** 18,27 ****
--- 18,28 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2018, Joyent, Inc.
*/
/*
* Functions used for manipulating the keystore
*/
*** 468,479 ****
}
(void) lock_file(fd, B_FALSE, B_FALSE);
(void) close(fd);
! if (hashed_pin_salt)
! free(hashed_pin_salt);
return (0);
cleanup:
(void) lock_file(fd, B_FALSE, B_FALSE);
(void) unlink(ks_desc_file);
--- 469,479 ----
}
(void) lock_file(fd, B_FALSE, B_FALSE);
(void) close(fd);
! freezero(hashed_pin_salt, hashed_pin_salt_len);
return (0);
cleanup:
(void) lock_file(fd, B_FALSE, B_FALSE);
(void) unlink(ks_desc_file);
*** 890,900 ****
return (CKR_HOST_MEMORY);
}
if ((readn_nointr(fd, *hashed_pin, hashed_pin_size))
!= (ssize_t)hashed_pin_size) {
! free(*hashed_pin);
*hashed_pin = NULL;
return (CKR_FUNCTION_FAILED);
}
(*hashed_pin)[hashed_pin_size] = '\0';
return (CKR_OK);
--- 890,900 ----
return (CKR_HOST_MEMORY);
}
if ((readn_nointr(fd, *hashed_pin, hashed_pin_size))
!= (ssize_t)hashed_pin_size) {
! freezero(*hashed_pin, hashed_pin_size + 1);
*hashed_pin = NULL;
return (CKR_FUNCTION_FAILED);
}
(*hashed_pin)[hashed_pin_size] = '\0';
return (CKR_OK);
*** 1318,1397 ****
/* decrypt data using old key */
decrypted_len = 0;
if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
NULL, &decrypted_len) != CKR_OK) {
! free(buf);
goto cleanup;
}
decrypted_buf = malloc(decrypted_len);
if (decrypted_buf == NULL) {
! free(buf);
goto cleanup;
}
if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
decrypted_buf, &decrypted_len) != CKR_OK) {
! free(buf);
! free(decrypted_buf);
! goto cleanup;
}
! free(buf);
/* re-encrypt with new key */
encrypted_len = 0;
if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
decrypted_len, NULL, &encrypted_len) != CKR_OK) {
! free(decrypted_buf);
goto cleanup;
}
buf = malloc(encrypted_len);
if (buf == NULL) {
! free(decrypted_buf);
goto cleanup;
}
if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
decrypted_len, buf, &encrypted_len) != CKR_OK) {
! free(buf);
! free(decrypted_buf);
goto cleanup;
}
! free(decrypted_buf);
/* calculate hmac on re-encrypted data using new hmac key */
hmac_len = OBJ_HMAC_SIZE;
if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf,
encrypted_len, hmac, &hmac_len) != CKR_OK) {
! free(buf);
goto cleanup;
}
/* just for sanity check */
if (hmac_len != OBJ_HMAC_SIZE) {
! free(buf);
goto cleanup;
}
/* write new hmac */
if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE)
!= OBJ_HMAC_SIZE) {
! free(buf);
goto cleanup;
}
/* write re-encrypted buffer to temp file */
if (writen_nointr(new_fd, (void *)buf, encrypted_len)
!= encrypted_len) {
! free(buf);
goto cleanup;
}
! free(buf);
ret_val = 0;
cleanup:
/* unlock the files */
(void) lock_file(old_fd, B_TRUE, B_FALSE);
--- 1318,1396 ----
/* decrypt data using old key */
decrypted_len = 0;
if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
NULL, &decrypted_len) != CKR_OK) {
! freezero(buf, nread);
goto cleanup;
}
decrypted_buf = malloc(decrypted_len);
if (decrypted_buf == NULL) {
! freezero(buf, nread);
goto cleanup;
}
if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
decrypted_buf, &decrypted_len) != CKR_OK) {
! freezero(buf, nread);
! freezero(decrypted_buf, decrypted_len);
}
! freezero(buf, nread);
/* re-encrypt with new key */
encrypted_len = 0;
if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
decrypted_len, NULL, &encrypted_len) != CKR_OK) {
! freezero(decrypted_buf, decrypted_len);
goto cleanup;
}
buf = malloc(encrypted_len);
if (buf == NULL) {
! freezero(decrypted_buf, decrypted_len);
goto cleanup;
}
if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
decrypted_len, buf, &encrypted_len) != CKR_OK) {
! freezero(buf, encrypted_len);
! freezero(buf, decrypted_len);
goto cleanup;
}
! freezero(decrypted_buf, decrypted_len);
/* calculate hmac on re-encrypted data using new hmac key */
hmac_len = OBJ_HMAC_SIZE;
if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf,
encrypted_len, hmac, &hmac_len) != CKR_OK) {
! freezero(buf, encrypted_len);
goto cleanup;
}
/* just for sanity check */
if (hmac_len != OBJ_HMAC_SIZE) {
! freezero(buf, encrypted_len);
goto cleanup;
}
/* write new hmac */
if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE)
!= OBJ_HMAC_SIZE) {
! freezero(buf, encrypted_len);
goto cleanup;
}
/* write re-encrypted buffer to temp file */
if (writen_nointr(new_fd, (void *)buf, encrypted_len)
!= encrypted_len) {
! freezero(buf, encrypted_len);
goto cleanup;
}
! freezero(buf, encrypted_len);
ret_val = 0;
cleanup:
/* unlock the files */
(void) lock_file(old_fd, B_TRUE, B_FALSE);
*** 1545,1571 ****
!= CKR_OK) {
goto cleanup;
}
if (writen_nointr(tmp_ks_fd, (void *)new_crypt_salt,
KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
! free(new_crypt_salt);
(void) soft_cleanup_object(new_crypt_key);
goto cleanup;
}
! free(new_crypt_salt);
if (soft_gen_hmac_key(newpin, &new_hmac_key, &new_hmac_salt)
!= CKR_OK) {
(void) soft_cleanup_object(new_crypt_key);
goto cleanup;
}
if (writen_nointr(tmp_ks_fd, (void *)new_hmac_salt,
KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) {
! free(new_hmac_salt);
goto cleanup3;
}
! free(new_hmac_salt);
} else {
if (soft_gen_crypt_key(newpin, &new_crypt_key,
(CK_BYTE **)&crypt_salt) != CKR_OK) {
goto cleanup;
}
--- 1544,1572 ----
!= CKR_OK) {
goto cleanup;
}
if (writen_nointr(tmp_ks_fd, (void *)new_crypt_salt,
KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
! freezero(new_crypt_salt,
! KS_KEY_SALT_SIZE);
(void) soft_cleanup_object(new_crypt_key);
goto cleanup;
}
! freezero(new_crypt_salt, KS_KEY_SALT_SIZE);
if (soft_gen_hmac_key(newpin, &new_hmac_key, &new_hmac_salt)
!= CKR_OK) {
(void) soft_cleanup_object(new_crypt_key);
goto cleanup;
}
if (writen_nointr(tmp_ks_fd, (void *)new_hmac_salt,
KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) {
! freezero(new_hmac_salt,
! KS_HMAC_SALT_SIZE);
goto cleanup3;
}
! freezero(new_hmac_salt, KS_HMAC_SALT_SIZE);
} else {
if (soft_gen_crypt_key(newpin, &new_crypt_key,
(CK_BYTE **)&crypt_salt) != CKR_OK) {
goto cleanup;
}
*** 1610,1639 ****
goto cleanup3;
}
if ((readn_nointr(fd, hashed_pin_salt, hashed_pin_salt_length)) !=
(ssize_t)hashed_pin_salt_length) {
! free(hashed_pin_salt);
goto cleanup3;
}
if ((writen_nointr(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length))
!= (ssize_t)hashed_pin_salt_length) {
! free(hashed_pin_salt);
goto cleanup3;
}
hashed_pin_salt[hashed_pin_salt_length] = '\0';
/* old hashed pin length and value can be ignored, generate new one */
if (soft_gen_hashed_pin(newpin, &new_hashed_pin,
&hashed_pin_salt) < 0) {
! free(hashed_pin_salt);
goto cleanup3;
}
! free(hashed_pin_salt);
if (new_hashed_pin == NULL) {
goto cleanup3;
}
--- 1611,1643 ----
goto cleanup3;
}
if ((readn_nointr(fd, hashed_pin_salt, hashed_pin_salt_length)) !=
(ssize_t)hashed_pin_salt_length) {
! freezero(hashed_pin_salt,
! hashed_pin_salt_length + 1);
goto cleanup3;
}
if ((writen_nointr(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length))
!= (ssize_t)hashed_pin_salt_length) {
! freezero(hashed_pin_salt,
! hashed_pin_salt_length + 1);
goto cleanup3;
}
hashed_pin_salt[hashed_pin_salt_length] = '\0';
/* old hashed pin length and value can be ignored, generate new one */
if (soft_gen_hashed_pin(newpin, &new_hashed_pin,
&hashed_pin_salt) < 0) {
! freezero(hashed_pin_salt,
! hashed_pin_salt_length + 1);
goto cleanup3;
}
! freezero(hashed_pin_salt, hashed_pin_salt_length + 1);
if (new_hashed_pin == NULL) {
goto cleanup3;
}
*** 1761,1776 ****
if (!lock_held) {
if (lock_file(fd, B_FALSE, B_FALSE) < 0) {
ret_val = 1;
}
}
! if (crypt_salt != NULL) {
! free(crypt_salt);
! }
! if (hmac_salt != NULL) {
! free(hmac_salt);
! }
(void) close(fd);
(void) close(tmp_ks_fd);
if (ret_val != 0) {
(void) remove(tmp_ks_desc_name);
}
--- 1765,1776 ----
if (!lock_held) {
if (lock_file(fd, B_FALSE, B_FALSE) < 0) {
ret_val = 1;
}
}
! freezero(crypt_salt, KS_KEY_SALT_SIZE);
! freezero(hmac_salt, KS_HMAC_SALT_SIZE);
(void) close(fd);
(void) close(tmp_ks_fd);
if (ret_val != 0) {
(void) remove(tmp_ks_desc_name);
}
*** 1853,1868 ****
cleanup:
/* unlock the file */
(void) lock_file(fd, B_TRUE, B_FALSE);
(void) close(fd);
! if (crypt_salt != NULL) {
! free(crypt_salt);
! }
! if (hmac_salt != NULL) {
! free(hmac_salt);
! }
return (ret_val);
}
/*
* FUNCTION: soft_keystore_get_objs
--- 1853,1864 ----
cleanup:
/* unlock the file */
(void) lock_file(fd, B_TRUE, B_FALSE);
(void) close(fd);
! freezero(crypt_salt, KS_KEY_SALT_SIZE);
! freezero(hmac_salt, KS_HMAC_SALT_SIZE);
return (ret_val);
}
/*
* FUNCTION: soft_keystore_get_objs
*** 1978,1988 ****
/* free all the objects found before hitting the error */
tmp = *result_obj_list;
while (tmp) {
*result_obj_list = tmp->next;
! free(tmp->buf);
free(tmp);
tmp = *result_obj_list;
}
*result_obj_list = NULL;
return (rv);
--- 1974,1984 ----
/* free all the objects found before hitting the error */
tmp = *result_obj_list;
while (tmp) {
*result_obj_list = tmp->next;
! freezero(tmp->buf, tmp->size);
free(tmp);
tmp = *result_obj_list;
}
*result_obj_list = NULL;
return (rv);
*** 2085,2118 ****
/* verify HMAC of the object, make sure it matches */
hmac_size = OBJ_HMAC_SIZE;
if (soft_keystore_hmac(hmac_key, B_FALSE, buf,
nread, obj_hmac, &hmac_size) != CKR_OK) {
! free(buf);
rv = CKR_FUNCTION_FAILED;
goto cleanup;
}
/* decrypt object */
if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
NULL, &out_len) != CKR_OK) {
! free(buf);
rv = CKR_FUNCTION_FAILED;
goto cleanup;
}
decrypted_buf = malloc(sizeof (uchar_t) * out_len);
if (decrypted_buf == NULL) {
! free(buf);
rv = CKR_HOST_MEMORY;
goto cleanup;
}
if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
decrypted_buf, &out_len) != CKR_OK) {
! free(decrypted_buf);
! free(buf);
rv = CKR_FUNCTION_FAILED;
goto cleanup;
}
obj->size = out_len - MAXPATHLEN;
--- 2081,2114 ----
/* verify HMAC of the object, make sure it matches */
hmac_size = OBJ_HMAC_SIZE;
if (soft_keystore_hmac(hmac_key, B_FALSE, buf,
nread, obj_hmac, &hmac_size) != CKR_OK) {
! freezero(buf, nread);
rv = CKR_FUNCTION_FAILED;
goto cleanup;
}
/* decrypt object */
if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
NULL, &out_len) != CKR_OK) {
! freezero(buf, nread);
rv = CKR_FUNCTION_FAILED;
goto cleanup;
}
decrypted_buf = malloc(sizeof (uchar_t) * out_len);
if (decrypted_buf == NULL) {
! freezero(buf, nread);
rv = CKR_HOST_MEMORY;
goto cleanup;
}
if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
decrypted_buf, &out_len) != CKR_OK) {
! freezero(buf, nread);
! freezero(decrypted_buf, out_len);
rv = CKR_FUNCTION_FAILED;
goto cleanup;
}
obj->size = out_len - MAXPATHLEN;
*** 2124,2141 ****
* See prepare_data_for_encrypt() function in the file
* to understand how and why the pathname is added.
*/
obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN));
if (obj->buf == NULL) {
! free(decrypted_buf);
! free(buf);
rv = CKR_HOST_MEMORY;
goto cleanup;
}
(void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size);
! free(decrypted_buf);
! free(buf);
*return_obj = obj;
}
cleanup:
--- 2120,2137 ----
* See prepare_data_for_encrypt() function in the file
* to understand how and why the pathname is added.
*/
obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN));
if (obj->buf == NULL) {
! freezero(buf, nread);
! freezero(decrypted_buf, out_len);
rv = CKR_HOST_MEMORY;
goto cleanup;
}
(void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size);
! freezero(buf, nread);
! freezero(decrypted_buf, out_len);
*return_obj = obj;
}
cleanup:
*** 2334,2390 ****
}
if (soft_keystore_crypt(enc_key, iv,
B_TRUE, prepared_buf, prepared_len,
NULL, &out_len) != CKR_OK) {
! free(prepared_buf);
goto cleanup2;
}
encrypted_buf = malloc(out_len * sizeof (char));
if (encrypted_buf == NULL) {
! free(prepared_buf);
goto cleanup2;
}
if (soft_keystore_crypt(enc_key, iv,
B_TRUE, prepared_buf, prepared_len,
encrypted_buf, &out_len) != CKR_OK) {
! free(encrypted_buf);
! free(prepared_buf);
goto cleanup2;
}
! free(prepared_buf);
/* calculate HMAC of encrypted object */
hmac_size = OBJ_HMAC_SIZE;
if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
out_len, obj_hmac, &hmac_size) != CKR_OK) {
! free(encrypted_buf);
goto cleanup2;
}
if (hmac_size != OBJ_HMAC_SIZE) {
! free(encrypted_buf);
goto cleanup2;
}
/* write hmac */
if (writen_nointr(obj_fd, (void *)obj_hmac,
sizeof (obj_hmac)) != sizeof (obj_hmac)) {
! free(encrypted_buf);
goto cleanup2;
}
/* write encrypted object */
if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len)
!= out_len) {
! free(encrypted_buf);
goto cleanup2;
}
! free(encrypted_buf);
}
(void) close(obj_fd);
(void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name),
--- 2330,2386 ----
}
if (soft_keystore_crypt(enc_key, iv,
B_TRUE, prepared_buf, prepared_len,
NULL, &out_len) != CKR_OK) {
! freezero(prepared_buf, prepared_len);
goto cleanup2;
}
encrypted_buf = malloc(out_len * sizeof (char));
if (encrypted_buf == NULL) {
! freezero(prepared_buf, prepared_len);
goto cleanup2;
}
if (soft_keystore_crypt(enc_key, iv,
B_TRUE, prepared_buf, prepared_len,
encrypted_buf, &out_len) != CKR_OK) {
! freezero(encrypted_buf, out_len);
! freezero(prepared_buf, prepared_len);
goto cleanup2;
}
! freezero(prepared_buf, prepared_len);
/* calculate HMAC of encrypted object */
hmac_size = OBJ_HMAC_SIZE;
if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
out_len, obj_hmac, &hmac_size) != CKR_OK) {
! freezero(encrypted_buf, out_len);
goto cleanup2;
}
if (hmac_size != OBJ_HMAC_SIZE) {
! freezero(encrypted_buf, out_len);
goto cleanup2;
}
/* write hmac */
if (writen_nointr(obj_fd, (void *)obj_hmac,
sizeof (obj_hmac)) != sizeof (obj_hmac)) {
! freezero(encrypted_buf, out_len);
goto cleanup2;
}
/* write encrypted object */
if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len)
!= out_len) {
! freezero(encrypted_buf, out_len);
goto cleanup2;
}
! freezero(encrypted_buf, out_len);
}
(void) close(obj_fd);
(void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name),
*** 2419,2428 ****
--- 2415,2426 ----
(void) close(fd);
return (-1);
}
}
(void) close(fd);
+ explicit_bzero(obj_hmac, sizeof (obj_hmac));
+ explicit_bzero(iv, sizeof (iv));
return (0);
cleanup2:
/* remove object file. No need to remove lock first */
*** 2436,2445 ****
--- 2434,2445 ----
/* release lock on description file */
(void) lock_file(fd, B_FALSE, B_FALSE);
}
(void) close(fd);
+ explicit_bzero(obj_hmac, sizeof (obj_hmac));
+ explicit_bzero(iv, sizeof (iv));
return (-1);
}
/*
* FUNCTION: soft_keystore_modify_obj
*** 2589,2636 ****
goto cleanup2;
}
encrypted_buf = malloc(out_len * sizeof (char));
if (encrypted_buf == NULL) {
! free(prepared_buf);
goto cleanup2;
}
if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf,
prepared_len, encrypted_buf, &out_len) != CKR_OK) {
! free(encrypted_buf);
! free(prepared_buf);
goto cleanup2;
}
! free(prepared_buf);
/* calculate hmac on encrypted buf */
hmac_size = OBJ_HMAC_SIZE;
if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
out_len, obj_hmac, &hmac_size) != CKR_OK) {
! free(encrypted_buf);
goto cleanup2;
}
if (hmac_size != OBJ_HMAC_SIZE) {
! free(encrypted_buf);
goto cleanup2;
}
if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE)
!= OBJ_HMAC_SIZE) {
! free(encrypted_buf);
goto cleanup2;
}
if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len)
!= out_len) {
! free(encrypted_buf);
goto cleanup2;
}
! free(encrypted_buf);
}
(void) close(tmp_fd);
/* rename updated temporary object file */
if (rename(tmp_name, orig_name) != 0) {
--- 2589,2636 ----
goto cleanup2;
}
encrypted_buf = malloc(out_len * sizeof (char));
if (encrypted_buf == NULL) {
! freezero(prepared_buf, prepared_len);
goto cleanup2;
}
if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf,
prepared_len, encrypted_buf, &out_len) != CKR_OK) {
! freezero(prepared_buf, prepared_len);
! freezero(encrypted_buf, out_len);
goto cleanup2;
}
! freezero(prepared_buf, prepared_len);
/* calculate hmac on encrypted buf */
hmac_size = OBJ_HMAC_SIZE;
if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
out_len, obj_hmac, &hmac_size) != CKR_OK) {
! freezero(encrypted_buf, out_len);
goto cleanup2;
}
if (hmac_size != OBJ_HMAC_SIZE) {
! freezero(encrypted_buf, out_len);
goto cleanup2;
}
if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE)
!= OBJ_HMAC_SIZE) {
! freezero(encrypted_buf, out_len);
goto cleanup2;
}
if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len)
!= out_len) {
! freezero(encrypted_buf, out_len);
goto cleanup2;
}
! freezero(encrypted_buf, out_len);
}
(void) close(tmp_fd);
/* rename updated temporary object file */
if (rename(tmp_name, orig_name) != 0) {
*** 2663,2672 ****
--- 2663,2674 ----
(void) close(ks_fd);
(void) close(fd);
+ explicit_bzero(iv, sizeof (iv));
+ explicit_bzero(obj_hmac, sizeof (obj_hmac));
return (0); /* All operations completed successfully */
cleanup2:
(void) close(tmp_fd);
(void) remove(tmp_name);
*** 2677,2686 ****
--- 2679,2690 ----
cleanup:
/* unlock keystore description file */
(void) lock_file(ks_fd, B_FALSE, B_FALSE);
(void) close(ks_fd);
(void) remove(tmp_ks_name);
+ explicit_bzero(iv, sizeof (iv));
+ explicit_bzero(obj_hmac, sizeof (obj_hmac));
return (-1);
}
/*
* FUNCTION: soft_keystore_del_obj
*** 2801,2811 ****
goto cleanup;
}
if ((readn_nointr(fd, *salt, hashed_pin_salt_size))
!= (ssize_t)hashed_pin_salt_size) {
! free(*salt);
goto cleanup;
}
(*salt)[hashed_pin_salt_size] = '\0';
ret_val = 0;
--- 2805,2815 ----
goto cleanup;
}
if ((readn_nointr(fd, *salt, hashed_pin_salt_size))
!= (ssize_t)hashed_pin_salt_size) {
! freezero(*salt, hashed_pin_salt_size + 1);
goto cleanup;
}
(*salt)[hashed_pin_salt_size] = '\0';
ret_val = 0;