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,10 +18,11 @@
*
* 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,12 +469,11 @@
}
(void) lock_file(fd, B_FALSE, B_FALSE);
(void) close(fd);
- if (hashed_pin_salt)
- free(hashed_pin_salt);
+ 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,11 +890,11 @@
return (CKR_HOST_MEMORY);
}
if ((readn_nointr(fd, *hashed_pin, hashed_pin_size))
!= (ssize_t)hashed_pin_size) {
- free(*hashed_pin);
+ freezero(*hashed_pin, hashed_pin_size + 1);
*hashed_pin = NULL;
return (CKR_FUNCTION_FAILED);
}
(*hashed_pin)[hashed_pin_size] = '\0';
return (CKR_OK);
@@ -1318,80 +1318,79 @@
/* 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);
+ freezero(buf, nread);
goto cleanup;
}
decrypted_buf = malloc(decrypted_len);
if (decrypted_buf == NULL) {
- free(buf);
+ freezero(buf, nread);
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;
+ freezero(buf, nread);
+ freezero(decrypted_buf, decrypted_len);
}
- free(buf);
+ 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) {
- free(decrypted_buf);
+ freezero(decrypted_buf, decrypted_len);
goto cleanup;
}
buf = malloc(encrypted_len);
if (buf == NULL) {
- free(decrypted_buf);
+ 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) {
- free(buf);
- free(decrypted_buf);
+ freezero(buf, encrypted_len);
+ freezero(buf, decrypted_len);
goto cleanup;
}
- free(decrypted_buf);
+ 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) {
- free(buf);
+ freezero(buf, encrypted_len);
goto cleanup;
}
/* just for sanity check */
if (hmac_len != OBJ_HMAC_SIZE) {
- free(buf);
+ freezero(buf, encrypted_len);
goto cleanup;
}
/* write new hmac */
if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE)
!= OBJ_HMAC_SIZE) {
- free(buf);
+ freezero(buf, encrypted_len);
goto cleanup;
}
/* write re-encrypted buffer to temp file */
if (writen_nointr(new_fd, (void *)buf, encrypted_len)
!= encrypted_len) {
- free(buf);
+ freezero(buf, encrypted_len);
goto cleanup;
}
- free(buf);
+ freezero(buf, encrypted_len);
ret_val = 0;
cleanup:
/* unlock the files */
(void) lock_file(old_fd, B_TRUE, B_FALSE);
@@ -1545,27 +1544,29 @@
!= 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);
+ freezero(new_crypt_salt,
+ KS_KEY_SALT_SIZE);
(void) soft_cleanup_object(new_crypt_key);
goto cleanup;
}
- free(new_crypt_salt);
+ 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) {
- free(new_hmac_salt);
+ freezero(new_hmac_salt,
+ KS_HMAC_SALT_SIZE);
goto cleanup3;
}
- free(new_hmac_salt);
+ 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,30 +1611,33 @@
goto cleanup3;
}
if ((readn_nointr(fd, hashed_pin_salt, hashed_pin_salt_length)) !=
(ssize_t)hashed_pin_salt_length) {
- free(hashed_pin_salt);
+ 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) {
- free(hashed_pin_salt);
+ 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) {
- free(hashed_pin_salt);
+ freezero(hashed_pin_salt,
+ hashed_pin_salt_length + 1);
goto cleanup3;
}
- free(hashed_pin_salt);
+ freezero(hashed_pin_salt, hashed_pin_salt_length + 1);
if (new_hashed_pin == NULL) {
goto cleanup3;
}
@@ -1761,16 +1765,12 @@
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);
- }
+ 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,16 +1853,12 @@
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);
- }
+ freezero(crypt_salt, KS_KEY_SALT_SIZE);
+ freezero(hmac_salt, KS_HMAC_SALT_SIZE);
return (ret_val);
}
/*
* FUNCTION: soft_keystore_get_objs
@@ -1978,11 +1974,11 @@
/* free all the objects found before hitting the error */
tmp = *result_obj_list;
while (tmp) {
*result_obj_list = tmp->next;
- free(tmp->buf);
+ freezero(tmp->buf, tmp->size);
free(tmp);
tmp = *result_obj_list;
}
*result_obj_list = NULL;
return (rv);
@@ -2085,34 +2081,34 @@
/* 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);
+ 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) {
- free(buf);
+ freezero(buf, nread);
rv = CKR_FUNCTION_FAILED;
goto cleanup;
}
decrypted_buf = malloc(sizeof (uchar_t) * out_len);
if (decrypted_buf == NULL) {
- free(buf);
+ 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) {
- free(decrypted_buf);
- free(buf);
+ freezero(buf, nread);
+ freezero(decrypted_buf, out_len);
rv = CKR_FUNCTION_FAILED;
goto cleanup;
}
obj->size = out_len - MAXPATHLEN;
@@ -2124,18 +2120,18 @@
* 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);
+ freezero(buf, nread);
+ freezero(decrypted_buf, out_len);
rv = CKR_HOST_MEMORY;
goto cleanup;
}
(void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size);
- free(decrypted_buf);
- free(buf);
+ freezero(buf, nread);
+ freezero(decrypted_buf, out_len);
*return_obj = obj;
}
cleanup:
@@ -2334,57 +2330,57 @@
}
if (soft_keystore_crypt(enc_key, iv,
B_TRUE, prepared_buf, prepared_len,
NULL, &out_len) != CKR_OK) {
- free(prepared_buf);
+ freezero(prepared_buf, prepared_len);
goto cleanup2;
}
encrypted_buf = malloc(out_len * sizeof (char));
if (encrypted_buf == NULL) {
- free(prepared_buf);
+ 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) {
- free(encrypted_buf);
- free(prepared_buf);
+ freezero(encrypted_buf, out_len);
+ freezero(prepared_buf, prepared_len);
goto cleanup2;
}
- free(prepared_buf);
+ 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) {
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
goto cleanup2;
}
if (hmac_size != OBJ_HMAC_SIZE) {
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
goto cleanup2;
}
/* write hmac */
if (writen_nointr(obj_fd, (void *)obj_hmac,
sizeof (obj_hmac)) != sizeof (obj_hmac)) {
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
goto cleanup2;
}
/* write encrypted object */
if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len)
!= out_len) {
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
goto cleanup2;
}
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
}
(void) close(obj_fd);
(void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name),
@@ -2419,10 +2415,12 @@
(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,10 +2434,12 @@
/* 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,48 +2589,48 @@
goto cleanup2;
}
encrypted_buf = malloc(out_len * sizeof (char));
if (encrypted_buf == NULL) {
- free(prepared_buf);
+ 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) {
- free(encrypted_buf);
- free(prepared_buf);
+ freezero(prepared_buf, prepared_len);
+ freezero(encrypted_buf, out_len);
goto cleanup2;
}
- free(prepared_buf);
+ 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) {
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
goto cleanup2;
}
if (hmac_size != OBJ_HMAC_SIZE) {
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
goto cleanup2;
}
if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE)
!= OBJ_HMAC_SIZE) {
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
goto cleanup2;
}
if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len)
!= out_len) {
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
goto cleanup2;
}
- free(encrypted_buf);
+ freezero(encrypted_buf, out_len);
}
(void) close(tmp_fd);
/* rename updated temporary object file */
if (rename(tmp_name, orig_name) != 0) {
@@ -2663,10 +2663,12 @@
(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,10 +2679,12 @@
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,11 +2805,11 @@
goto cleanup;
}
if ((readn_nointr(fd, *salt, hashed_pin_salt_size))
!= (ssize_t)hashed_pin_salt_size) {
- free(*salt);
+ freezero(*salt, hashed_pin_salt_size + 1);
goto cleanup;
}
(*salt)[hashed_pin_salt_size] = '\0';
ret_val = 0;