--- old/usr/src/lib/pkcs11/libpkcs11/common/metaAttrManager.c	Fri Jul  6 15:55:04 2018
+++ new/usr/src/lib/pkcs11/libpkcs11/common/metaAttrManager.c	Fri Jul  6 15:55:04 2018
@@ -22,6 +22,7 @@
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  * Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <string.h>
@@ -526,7 +527,8 @@
 		 * extra work to just do them all. [Most attributes are just
 		 * 1 or 4 bytes]
 		 */
-		bzero(attr->attribute.pValue, attr->attribute.ulValueLen);
+		explicit_bzero(attr->attribute.pValue,
+		    attr->attribute.ulValueLen);
 
 		if (attr->isMalloced)
 			free(attr->attribute.pValue);
@@ -564,13 +566,15 @@
 		/* Existing storage is sufficient to store new value. */
 
 		/* bzero() out any data that won't be overwritten. */
-		bzero((char *)attr->attribute.pValue + new_attr->ulValueLen,
+		explicit_bzero((char *)attr->attribute.pValue +
+		    new_attr->ulValueLen,
 		    attr->attribute.ulValueLen - new_attr->ulValueLen);
 
 	} else if (new_attr->ulValueLen <= sizeof (attr->generic_data)) {
 		/* Use generic storage to avoid a malloc. */
 
-		bzero(attr->attribute.pValue, attr->attribute.ulValueLen);
+		explicit_bzero(attr->attribute.pValue,
+		    attr->attribute.ulValueLen);
 		if (attr->isMalloced) {
 			/*
 			 * If app sets a large value (triggering a malloc),
--- old/usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c	Fri Jul  6 15:55:04 2018
+++ new/usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c	Fri Jul  6 15:55:04 2018
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 
@@ -596,7 +597,8 @@
 
 	if (object->clone_template) {
 		for (i = 0; i < object->clone_template_size; i++) {
-			free(((object->clone_template)[i]).pValue);
+			freezero((object->clone_template)[i].pValue,
+			    (object->clone_template)[i].ulValueLen);
 		}
 		free(object->clone_template);
 	}
@@ -859,7 +861,8 @@
 	if (attrs_with_val) {
 		for (i = 0; i < num_attrs; i++) {
 			if (attrs_with_val[i].pValue != NULL) {
-				free(attrs_with_val[i].pValue);
+				freezero(attrs_with_val[i].pValue,
+				    attrs_with_val[i].ulValueLen);
 			}
 		}
 		free(attrs_with_val);
@@ -1491,7 +1494,7 @@
 	}
 
 	if (wrappedKey) {
-		free(wrappedKey);
+		freezero(wrappedKey, wrappedKeyLen);
 	}
 
 	if (src_slot_session) {
--- old/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelKeys.c	Fri Jul  6 15:55:05 2018
+++ new/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelKeys.c	Fri Jul  6 15:55:05 2018
@@ -21,6 +21,7 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2018, Joyent, Inc.
  */
 
 #include <strings.h>
@@ -343,21 +344,15 @@
 	}
 	new_objp->is_lib_obj = B_TRUE;
 	new_objp->session_handle = (CK_SESSION_HANDLE)session_p;
-	(void) free(newTemplate);
-	bzero(key_buf, key_len);
-	(void) free(key_buf);
+	free(newTemplate);
+	freezero(key_buf, key_len);
 	return (CKR_OK);
 
 failed_exit:
 	free_attributes(obj_ngk.ngk_in_attributes, &obj_ngk.ngk_in_count);
 	free_attributes(obj_ngk.ngk_out_attributes, &obj_ngk.ngk_out_count);
-	if (key_buf != NULL) {
-		bzero(key_buf, key_len);
-		(void) free(key_buf);
-	}
-	if (newTemplate != NULL) {
-		(void) free(newTemplate);
-	}
+	freezero(key_buf, key_len);
+	free(newTemplate);
 	return (rv);
 }
 
--- old/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelObjectUtil.c	Fri Jul  6 15:55:05 2018
+++ new/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelObjectUtil.c	Fri Jul  6 15:55:05 2018
@@ -21,6 +21,7 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <stdio.h>
@@ -77,8 +78,7 @@
 	 */
 	if (objp->class == CKO_SECRET_KEY) {
 		if (OBJ_SEC(objp) != NULL && OBJ_SEC_VALUE(objp) != NULL) {
-			bzero(OBJ_SEC_VALUE(objp), OBJ_SEC_VALUE_LEN(objp));
-			free(OBJ_SEC_VALUE(objp));
+			freezero(OBJ_SEC_VALUE(objp), OBJ_SEC_VALUE_LEN(objp));
 			OBJ_SEC_VALUE(objp) = NULL;
 			OBJ_SEC_VALUE_LEN(objp) = 0;
 		}
--- old/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelSoftCommon.c	Fri Jul  6 15:55:05 2018
+++ new/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelSoftCommon.c	Fri Jul  6 15:55:05 2018
@@ -22,10 +22,9 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <pthread.h>
 #include <errno.h>
 #include <stdio.h>
@@ -234,22 +233,16 @@
 		return;
 
 	if (opflag & OP_SIGN) {
-		if (session_p->sign.context == NULL)
-			return;
-		bzero(session_p->sign.context, sizeof (soft_hmac_ctx_t));
-		free(session_p->sign.context);
+		freezero(session_p->sign.context,
+		    sizeof (soft_hmac_ctx_t));
 		session_p->sign.context = NULL;
 		session_p->sign.flags = 0;
 	} else if (opflag & OP_VERIFY) {
-		if (session_p->verify.context == NULL)
-			return;
-		bzero(session_p->verify.context, sizeof (soft_hmac_ctx_t));
-		free(session_p->verify.context);
+		freezero(session_p->verify.context,
+		    sizeof (soft_hmac_ctx_t));
 		session_p->verify.context = NULL;
 		session_p->verify.flags = 0;
 	} else {
-		if (session_p->digest.context == NULL)
-			return;
 		free(session_p->digest.context);
 		session_p->digest.context = NULL;
 		session_p->digest.flags = 0;
--- old/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelUtil.c	Fri Jul  6 15:55:06 2018
+++ new/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelUtil.c	Fri Jul  6 15:55:06 2018
@@ -480,11 +480,8 @@
 	if (key->ck_format == CRYPTO_KEY_ATTR_LIST &&
 	    (key->ck_count > 0) && key->ck_attrs != NULL) {
 		for (i = 0; i < key->ck_count; i++) {
-			if (key->ck_attrs[i].oa_value != NULL) {
-				bzero(key->ck_attrs[i].oa_value,
-				    key->ck_attrs[i].oa_value_len);
-				free(key->ck_attrs[i].oa_value);
-			}
+			freezero(key->ck_attrs[i].oa_value,
+			    key->ck_attrs[i].oa_value_len);
 		}
 		free(key->ck_attrs);
 	}
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c	Fri Jul  6 15:55:06 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c	Fri Jul  6 15:55:06 2018
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <pthread.h>
@@ -488,14 +489,21 @@
 cleanup:
 	(void) pthread_mutex_lock(&session_p->session_mutex);
 	aes_ctx = (aes_ctx_t *)soft_aes_ctx->aes_cbc;
-	if (aes_ctx != NULL) {
-		bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len);
-		free(soft_aes_ctx->aes_cbc);
+	switch (mechanism) {
+	case CKM_AES_ECB:
+		freezero(aes_ctx, sizeof (ecb_ctx_t));
+		break;
+	case CKM_AES_CMAC:
+	case CKM_AES_CBC:
+	case CKM_AES_CBC_PAD:
+		freezero(aes_ctx, sizeof (cbc_ctx_t));
+		break;
+	case CKM_AES_CTR:
+		freezero(aes_ctx, sizeof (ctr_ctx_t));
+		break;
 	}
-
-	bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
-	free(soft_aes_ctx->key_sched);
-	free(session_p->encrypt.context);
+	freezero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
+	freezero(session_p->encrypt.context, sizeof (soft_aes_ctx_t));
 	session_p->encrypt.context = NULL;
 	(void) pthread_mutex_unlock(&session_p->session_mutex);
 
@@ -851,14 +859,9 @@
 cleanup:
 	(void) pthread_mutex_lock(&session_p->session_mutex);
 	aes_ctx = (aes_ctx_t *)soft_aes_ctx->aes_cbc;
-	if (aes_ctx != NULL) {
-		bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len);
-		free(soft_aes_ctx->aes_cbc);
-	}
-
-	bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
-	free(soft_aes_ctx->key_sched);
-	free(session_p->decrypt.context);
+	free(aes_ctx);
+	freezero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
+	freezero(session_p->decrypt.context, sizeof (soft_aes_ctx_t));
 	session_p->decrypt.context = NULL;
 	(void) pthread_mutex_unlock(&session_p->session_mutex);
 
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c	Fri Jul  6 15:55:07 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c	Fri Jul  6 15:55:07 2018
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright (c) 2018, Joyent. Inc.
  */
 
 #include <stdlib.h>
@@ -87,7 +88,7 @@
 	 * clear out potentially sensitive data before that happens.
 	 */
 	if (dst->big_value != NULL)
-		(void) memset(dst->big_value, 0x0, dst->big_value_len);
+		explicit_bzero(dst->big_value, dst->big_value_len);
 
 	padding = (src->big_value[0] < 0x80) ? 0 : 1;
 	dst->big_value_len = src->big_value_len + padding;
@@ -338,10 +339,7 @@
 
 cleanup_rsapri2asn:
 
-	if (tmp_pad.big_value != NULL) {
-		(void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
-		free(tmp_pad.big_value);
-	}
+	freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 
 	if (key_asn != NULLBER)
 		ber_free(key_asn, 1);
@@ -527,10 +525,7 @@
 
 cleanup_dsapri2asn:
 
-	if (tmp_pad.big_value != NULL) {
-		(void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
-		free(tmp_pad.big_value);
-	}
+	freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 
 	if (key_asn != NULLBER)
 		ber_free(key_asn, 1);
@@ -701,10 +696,7 @@
 
 cleanup_dhpri2asn:
 
-	if (tmp_pad.big_value != NULL) {
-		(void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
-		free(tmp_pad.big_value);
-	}
+	freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 
 	if (key_asn != NULLBER)
 		ber_free(key_asn, 1);
@@ -893,10 +885,7 @@
 
 cleanup_x942dhpri2asn:
 
-	if (tmp_pad.big_value != NULL) {
-		(void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
-		free(tmp_pad.big_value);
-	}
+	freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 
 	if (key_asn != NULLBER)
 		ber_free(key_asn, 1);
@@ -1240,11 +1229,7 @@
 
 cleanup_asn2rsapri:
 
-	if (tmp_nopad.big_value != NULL) {
-		(void) memset(tmp_nopad.big_value, 0x0,
-		    tmp_nopad.big_value_len);
-		free(tmp_nopad.big_value);
-	}
+	freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
 
 	if (p8obj_asn != NULLBER)
 		ber_free(p8obj_asn, 1);
@@ -1448,11 +1433,7 @@
 
 cleanup_asn2dsapri:
 
-	if (tmp_nopad.big_value != NULL) {
-		(void) memset(tmp_nopad.big_value, 0x0,
-		    tmp_nopad.big_value_len);
-		free(tmp_nopad.big_value);
-	}
+	freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
 
 	if (p8obj_asn != NULLBER)
 		ber_free(p8obj_asn, 1);
@@ -1632,11 +1613,7 @@
 
 cleanup_asn2dhpri:
 
-	if (tmp_nopad.big_value != NULL) {
-		(void) memset(tmp_nopad.big_value, 0x0,
-		    tmp_nopad.big_value_len);
-		free(tmp_nopad.big_value);
-	}
+	freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
 
 	if (p8obj_asn != NULLBER)
 		ber_free(p8obj_asn, 1);
@@ -1840,11 +1817,7 @@
 
 cleanup_asn2x942dhpri:
 
-	if (tmp_nopad.big_value != NULL) {
-		(void) memset(tmp_nopad.big_value, 0x0,
-		    tmp_nopad.big_value_len);
-		free(tmp_nopad.big_value);
-	}
+	freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
 
 	if (p8obj_asn != NULLBER)
 		ber_free(p8obj_asn, 1);
@@ -1864,7 +1837,7 @@
 CK_RV
 soft_asn1_to_object(soft_object_t *objp, uchar_t *buf, ulong_t buf_len)
 {
-	CK_RV 		rv = CKR_OK;
+	CK_RV		rv = CKR_OK;
 	CK_OBJECT_CLASS class = objp->class;
 	CK_KEY_TYPE	keytype = objp->key_type;
 	private_key_obj_t *pvk;
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAttributeUtil.c	Fri Jul  6 15:55:07 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAttributeUtil.c	Fri Jul  6 15:55:07 2018
@@ -22,6 +22,7 @@
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  * Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <stdlib.h>
@@ -322,11 +323,8 @@
 static void
 cleanup_cert_attr(cert_attr_t *attr)
 {
-	if (attr) {
-		if (attr->value) {
-			(void) memset(attr->value, 0, attr->length);
-			free(attr->value);
-		}
+	if (attr != NULL) {
+		freezero(attr->value, attr->length);
 		attr->value = NULL;
 		attr->length = 0;
 	}
@@ -345,8 +343,7 @@
 
 	/* free memory if its already allocated */
 	if (*dest_attr != NULL) {
-		if ((*dest_attr)->value != (CK_BYTE *)NULL)
-			free((*dest_attr)->value);
+		cleanup_cert_attr(*dest_attr);
 	} else {
 		*dest_attr = malloc(sizeof (cert_attr_t));
 		if (*dest_attr == NULL)
@@ -421,7 +418,7 @@
 	extra_attr = object_p->extra_attrlistp;
 	while (extra_attr) {
 		tmp = extra_attr->next;
-		if (extra_attr->attr.pValue)
+		if (extra_attr->attr.pValue != NULL) {
 			/*
 			 * All extra attributes in the extra attribute
 			 * list have pValue points to the value of the
@@ -428,7 +425,9 @@
 			 * attribute (with simple byte array type).
 			 * Free the storage for the value of the attribute.
 			 */
-			free(extra_attr->attr.pValue);
+			freezero(extra_attr->attr.pValue,
+			    extra_attr->attr.ulValueLen);
+		}
 
 		/* Free the storage for the attribute_info struct. */
 		free(extra_attr);
@@ -672,9 +671,11 @@
 	    (template->ulValueLen > 0)) {
 		if (template->ulValueLen > extra_attr->attr.ulValueLen) {
 			/* The old buffer is too small to hold the new value. */
-			if (extra_attr->attr.pValue != NULL)
+			if (extra_attr->attr.pValue != NULL) {
 				/* Free storage for the old attribute value. */
-				free(extra_attr->attr.pValue);
+				freezero(extra_attr->attr.pValue,
+				    extra_attr->attr.ulValueLen);
+			}
 
 			/* Allocate storage for the new attribute value. */
 			extra_attr->attr.pValue = malloc(template->ulValueLen);
@@ -930,11 +931,7 @@
 		 * existing value and release the memory.
 		 */
 		if (*dest != NULL) {
-			if ((*dest)->value != NULL) {
-				(void) memset((*dest)->value, 0,
-				    (*dest)->length);
-				free((*dest)->value);
-			}
+			cleanup_cert_attr(*dest);
 		} else {
 			*dest = malloc(sizeof (cert_attr_t));
 			if (*dest == NULL) {
@@ -987,12 +984,9 @@
 void
 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
 {
-
-	if (template->pValue) {
-		free(template->pValue);
-		template->pValue = NULL;
-		template->ulValueLen = 0;
-	}
+	freezero(template->pValue, template->ulValueLen);
+	template->pValue = NULL;
+	template->ulValueLen = 0;
 }
 
 /*
@@ -1006,12 +1000,9 @@
 	if (big == NULL)
 		return;
 
-	if (big->big_value) {
-		(void) memset(big->big_value, 0, big->big_value_len);
-		free(big->big_value);
-		big->big_value = NULL;
-		big->big_value_len = 0;
-	}
+	freezero(big->big_value, big->big_value_len);
+	big->big_value = NULL;
+	big->big_value_len = 0;
 }
 
 
@@ -1151,16 +1142,14 @@
 			/* cleanup key data area */
 			if (OBJ_SEC_VALUE(object_p) != NULL &&
 			    OBJ_SEC_VALUE_LEN(object_p) > 0) {
-				(void) memset(OBJ_SEC_VALUE(object_p), 0,
+				freezero(OBJ_SEC_VALUE(object_p),
 				    OBJ_SEC_VALUE_LEN(object_p));
-				free(OBJ_SEC_VALUE(object_p));
 			}
 			/* cleanup key schedule data area */
 			if (OBJ_KEY_SCHED(object_p) != NULL &&
 			    OBJ_KEY_SCHED_LEN(object_p) > 0) {
-				(void) memset(OBJ_KEY_SCHED(object_p), 0,
+				freezero(OBJ_KEY_SCHED(object_p),
 				    OBJ_KEY_SCHED_LEN(object_p));
-				free(OBJ_KEY_SCHED(object_p));
 			}
 
 			/* Release Secret Key Object struct. */
@@ -6319,7 +6308,7 @@
 	(void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
 
 	/* copy the secret key value */
-	sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
+	sk->sk_value = malloc(sk->sk_value_len);
 	if (sk->sk_value == NULL) {
 		free(sk);
 		return (CKR_HOST_MEMORY);
@@ -6334,6 +6323,7 @@
 	    old_secret_key_obj_p->keysched_len > 0) {
 		sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
 		if (sk->key_sched == NULL) {
+			freezero(sk->sk_value, sk->sk_value_len);
 			free(sk);
 			return (CKR_HOST_MEMORY);
 		}
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softBlowfishCrypt.c	Fri Jul  6 15:55:08 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softBlowfishCrypt.c	Fri Jul  6 15:55:08 2018
@@ -21,6 +21,7 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <pthread.h>
@@ -297,15 +298,11 @@
 cleanup:
 	(void) pthread_mutex_lock(&session_p->session_mutex);
 	blowfish_ctx = (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc;
-	if (blowfish_ctx != NULL) {
-		bzero(blowfish_ctx->bc_keysched,
-		    blowfish_ctx->bc_keysched_len);
-		free(soft_blowfish_ctx->blowfish_cbc);
-	}
-
-	bzero(soft_blowfish_ctx->key_sched, soft_blowfish_ctx->keysched_len);
-	free(soft_blowfish_ctx->key_sched);
-	free(session_p->encrypt.context);
+	freezero(blowfish_ctx, sizeof (cbc_ctx_t));
+	freezero(soft_blowfish_ctx->key_sched,
+	    soft_blowfish_ctx->keysched_len);
+	freezero(session_p->encrypt.context,
+	    sizeof (soft_blowfish_ctx_t));
 	session_p->encrypt.context = NULL;
 	(void) pthread_mutex_unlock(&session_p->session_mutex);
 
@@ -465,15 +462,11 @@
 cleanup:
 	(void) pthread_mutex_lock(&session_p->session_mutex);
 	blowfish_ctx = (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc;
-	if (blowfish_ctx != NULL) {
-		bzero(blowfish_ctx->bc_keysched,
-		    blowfish_ctx->bc_keysched_len);
-		free(soft_blowfish_ctx->blowfish_cbc);
-	}
-
-	bzero(soft_blowfish_ctx->key_sched, soft_blowfish_ctx->keysched_len);
-	free(soft_blowfish_ctx->key_sched);
-	free(session_p->decrypt.context);
+	free(blowfish_ctx);
+	freezero(soft_blowfish_ctx->key_sched,
+	    soft_blowfish_ctx->keysched_len);
+	freezero(session_p->decrypt.context,
+	    sizeof (soft_blowfish_ctx_t));
 	session_p->decrypt.context = NULL;
 	(void) pthread_mutex_unlock(&session_p->session_mutex);
 
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c	Fri Jul  6 15:55:09 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c	Fri Jul  6 15:55:09 2018
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <pthread.h>
@@ -448,14 +449,9 @@
 cleanup:
 	(void) pthread_mutex_lock(&session_p->session_mutex);
 	des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
-	if (des_ctx != NULL) {
-		bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
-		free(soft_des_ctx->des_cbc);
-	}
-
-	bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
-	free(soft_des_ctx->key_sched);
-	free(session_p->encrypt.context);
+	free(des_ctx);
+	freezero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
+	freezero(session_p->encrypt.context, sizeof (soft_des_ctx_t));
 	session_p->encrypt.context = NULL;
 	(void) pthread_mutex_unlock(&session_p->session_mutex);
 
@@ -777,15 +773,9 @@
 cleanup:
 	(void) pthread_mutex_lock(&session_p->session_mutex);
 	des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
-	if (des_ctx != NULL) {
-		bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
-		free(soft_des_ctx->des_cbc);
-	}
-
-	bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
-	free(soft_des_ctx->key_sched);
-	free(session_p->decrypt.context);
-	session_p->decrypt.context = NULL;
+	free(des_ctx);
+	freezero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
+	freezero(session_p->decrypt.context, sizeof (soft_des_ctx_t));
 	(void) pthread_mutex_unlock(&session_p->session_mutex);
 
 	return (rv);
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c	Fri Jul  6 15:55:09 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c	Fri Jul  6 15:55:09 2018
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <pthread.h>
@@ -151,10 +152,10 @@
 		    soft_des_ctx->ivec, key_p->key_type);
 
 		if (soft_des_ctx->des_cbc == NULL) {
-			bzero(soft_des_ctx->key_sched,
+			freezero(soft_des_ctx->key_sched,
 			    soft_des_ctx->keysched_len);
-			free(soft_des_ctx->key_sched);
-			free(session_p->decrypt.context);
+			freezero(session_p->decrypt.context,
+			    sizeof (soft_des_ctx_t));
 			session_p->decrypt.context = NULL;
 			(void) pthread_mutex_unlock(&session_p->session_mutex);
 			return (CKR_HOST_MEMORY);
@@ -207,10 +208,10 @@
 		    soft_aes_ctx->ivec);
 
 		if (soft_aes_ctx->aes_cbc == NULL) {
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
-			free(session_p->decrypt.context);
+			freezero(session_p->decrypt.context,
+			    sizeof (soft_aes_ctx_t));
 			session_p->decrypt.context = NULL;
 			(void) pthread_mutex_unlock(&session_p->session_mutex);
 			return (CKR_HOST_MEMORY);
@@ -247,10 +248,10 @@
 		    pMechanism->pParameter);
 
 		if (soft_aes_ctx->aes_cbc == NULL) {
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
-			free(session_p->decrypt.context);
+			freezero(session_p->decrypt.context,
+			    sizeof (soft_aes_ctx_t));
 			session_p->decrypt.context = NULL;
 			rv = CKR_HOST_MEMORY;
 		}
@@ -292,10 +293,11 @@
 		    soft_blowfish_ctx->ivec);
 
 		if (soft_blowfish_ctx->blowfish_cbc == NULL) {
-			bzero(soft_blowfish_ctx->key_sched,
+			freezero(soft_blowfish_ctx->key_sched,
 			    soft_blowfish_ctx->keysched_len);
-			free(soft_blowfish_ctx->key_sched);
-			free(session_p->decrypt.context = NULL);
+			freezero(session_p->decrypt.context,
+			    sizeof (soft_blowfish_ctx_t));
+			session_p->decrypt.context = NULL;
 			(void) pthread_mutex_unlock(&session_p->session_mutex);
 			return (CKR_HOST_MEMORY);
 		}
@@ -554,9 +556,8 @@
 			rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
 			/* Cleanup memory space. */
 			free(soft_des_ctx->des_cbc);
-			bzero(soft_des_ctx->key_sched,
+			freezero(soft_des_ctx->key_sched,
 			    soft_des_ctx->keysched_len);
-			free(soft_des_ctx->key_sched);
 
 			goto clean1;
 		}
@@ -608,9 +609,8 @@
 
 			/* Cleanup memory space. */
 			free(soft_des_ctx->des_cbc);
-			bzero(soft_des_ctx->key_sched,
+			freezero(soft_des_ctx->key_sched,
 			    soft_des_ctx->keysched_len);
-			free(soft_des_ctx->key_sched);
 
 		}
 
@@ -641,8 +641,8 @@
 
 		/* Cleanup memory space. */
 		free(soft_des_ctx->des_cbc);
-		bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
-		free(soft_des_ctx->key_sched);
+		freezero(soft_des_ctx->key_sched,
+		    soft_des_ctx->keysched_len);
 
 		break;
 	}
@@ -663,9 +663,8 @@
 			rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
 			/* Cleanup memory space. */
 			free(soft_aes_ctx->aes_cbc);
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
 
 			goto clean1;
 		}
@@ -717,9 +716,8 @@
 
 			/* Cleanup memory space. */
 			free(soft_aes_ctx->aes_cbc);
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
 
 		}
 
@@ -747,8 +745,8 @@
 
 		/* Cleanup memory space. */
 		free(soft_aes_ctx->aes_cbc);
-		bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
-		free(soft_aes_ctx->key_sched);
+		freezero(soft_aes_ctx->key_sched,
+		    soft_aes_ctx->keysched_len);
 
 		break;
 	}
@@ -784,8 +782,8 @@
 
 		/* Cleanup memory space. */
 		free(ctr_ctx);
-		bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
-		free(soft_aes_ctx->key_sched);
+		freezero(soft_aes_ctx->key_sched,
+		    soft_aes_ctx->keysched_len);
 
 		break;
 	}
@@ -805,9 +803,8 @@
 		}
 
 		free(soft_blowfish_ctx->blowfish_cbc);
-		bzero(soft_blowfish_ctx->key_sched,
+		freezero(soft_blowfish_ctx->key_sched,
 		    soft_blowfish_ctx->keysched_len);
-		free(soft_blowfish_ctx->key_sched);
 
 		break;
 	}
@@ -815,7 +812,7 @@
 	case CKM_RC4:
 	{
 		ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context;
-		bzero(key, sizeof (*key));
+		explicit_bzero(key, sizeof (*key));
 		*pulLastPartLen = 0;
 		break;
 	}
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDigestUtil.c	Fri Jul  6 15:55:09 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDigestUtil.c	Fri Jul  6 15:55:09 2018
@@ -21,6 +21,7 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <strings.h>
@@ -302,7 +303,7 @@
 
 	/* Paranoia on behalf of C_DigestKey callers: bzero the context */
 	if (session_p->digest.flags & CRYPTO_KEY_DIGESTED) {
-		bzero(session_p->digest.context, len);
+		explicit_bzero(session_p->digest.context, len);
 		session_p->digest.flags &= ~CRYPTO_KEY_DIGESTED;
 	}
 	*pulDigestLen = digestLen;
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c	Fri Jul  6 15:55:10 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c	Fri Jul  6 15:55:10 2018
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <pthread.h>
@@ -175,10 +176,10 @@
 		    soft_des_ctx->ivec, key_p->key_type);
 
 		if (soft_des_ctx->des_cbc == NULL) {
-			bzero(soft_des_ctx->key_sched,
+			freezero(soft_des_ctx->key_sched,
 			    soft_des_ctx->keysched_len);
-			free(soft_des_ctx->key_sched);
-			free(session_p->encrypt.context);
+			freezero(session_p->encrypt.context,
+			    sizeof (soft_des_ctx_t));
 			session_p->encrypt.context = NULL;
 			rv = CKR_HOST_MEMORY;
 		}
@@ -239,10 +240,10 @@
 			    soft_aes_ctx->ivec);
 		}
 		if (soft_aes_ctx->aes_cbc == NULL) {
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
-			free(session_p->encrypt.context);
+			freezero(session_p->encrypt.context,
+			    sizeof (soft_aes_ctx_t));
 			session_p->encrypt.context = NULL;
 			rv = CKR_HOST_MEMORY;
 		}
@@ -278,10 +279,10 @@
 		    pMechanism->pParameter);
 
 		if (soft_aes_ctx->aes_cbc == NULL) {
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
-			free(session_p->encrypt.context);
+			freezero(session_p->encrypt.context,
+			    sizeof (soft_aes_ctx_t));
 			session_p->encrypt.context = NULL;
 			rv = CKR_HOST_MEMORY;
 		}
@@ -341,10 +342,10 @@
 		    soft_blowfish_ctx->ivec);
 
 		if (soft_blowfish_ctx->blowfish_cbc == NULL) {
-			bzero(soft_blowfish_ctx->key_sched,
+			freezero(soft_blowfish_ctx->key_sched,
 			    soft_blowfish_ctx->keysched_len);
-			free(soft_blowfish_ctx->key_sched);
-			free(session_p->encrypt.context);
+			freezero(session_p->encrypt.context,
+			    sizeof (soft_blowfish_ctx_t));
 			session_p->encrypt.context = NULL;
 			rv = CKR_HOST_MEMORY;
 		}
@@ -628,9 +629,8 @@
 
 			/* Cleanup memory space. */
 			free(soft_des_ctx->des_cbc);
-			bzero(soft_des_ctx->key_sched,
+			freezero(soft_des_ctx->key_sched,
 			    soft_des_ctx->keysched_len);
-			free(soft_des_ctx->key_sched);
 		}
 
 		break;
@@ -659,8 +659,8 @@
 
 		/* Cleanup memory space. */
 		free(soft_des_ctx->des_cbc);
-		bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
-		free(soft_des_ctx->key_sched);
+		freezero(soft_des_ctx->key_sched,
+		    soft_des_ctx->keysched_len);
 
 		break;
 	}
@@ -723,9 +723,8 @@
 
 			/* Cleanup memory space. */
 			free(soft_aes_ctx->aes_cbc);
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
 		}
 
 		break;
@@ -763,9 +762,8 @@
 
 			/* Cleanup memory space. */
 			free(soft_aes_ctx->aes_cbc);
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
 		}
 
 		break;
@@ -791,8 +789,8 @@
 
 		/* Cleanup memory space. */
 		free(soft_aes_ctx->aes_cbc);
-		bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
-		free(soft_aes_ctx->key_sched);
+		freezero(soft_aes_ctx->key_sched,
+		    soft_aes_ctx->keysched_len);
 
 		break;
 	}
@@ -827,8 +825,8 @@
 
 		/* Cleanup memory space. */
 		free(ctr_ctx);
-		bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
-		free(soft_aes_ctx->key_sched);
+		freezero(soft_aes_ctx->key_sched,
+		    soft_aes_ctx->keysched_len);
 
 		break;
 	}
@@ -852,9 +850,8 @@
 		}
 
 		free(soft_blowfish_ctx->blowfish_cbc);
-		bzero(soft_blowfish_ctx->key_sched,
+		freezero(soft_blowfish_ctx->key_sched,
 		    soft_blowfish_ctx->keysched_len);
-		free(soft_blowfish_ctx->key_sched);
 		break;
 	}
 
@@ -865,7 +862,7 @@
 		*pulLastEncryptedPartLen = 0;
 		if (pLastEncryptedPart == NULL)
 			goto clean1;
-		bzero(key, sizeof (*key));
+		explicit_bzero(key, sizeof (*key));
 		break;
 	}
 	default:
@@ -921,13 +918,12 @@
 		if (soft_des_ctx != NULL) {
 			des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
 			if (des_ctx != NULL) {
-				bzero(des_ctx->dc_keysched,
+				explicit_bzero(des_ctx->dc_keysched,
 				    des_ctx->dc_keysched_len);
 				free(soft_des_ctx->des_cbc);
 			}
-			bzero(soft_des_ctx->key_sched,
+			freezero(soft_des_ctx->key_sched,
 			    soft_des_ctx->keysched_len);
-			free(soft_des_ctx->key_sched);
 		}
 		break;
 	}
@@ -944,13 +940,12 @@
 		if (soft_aes_ctx != NULL) {
 			aes_ctx = (aes_ctx_t *)soft_aes_ctx->aes_cbc;
 			if (aes_ctx != NULL) {
-				bzero(aes_ctx->ac_keysched,
+				explicit_bzero(aes_ctx->ac_keysched,
 				    aes_ctx->ac_keysched_len);
 				free(soft_aes_ctx->aes_cbc);
 			}
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
 		}
 		break;
 	}
@@ -965,14 +960,13 @@
 			blowfish_ctx =
 			    (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc;
 			if (blowfish_ctx != NULL) {
-				bzero(blowfish_ctx->bc_keysched,
+				explicit_bzero(blowfish_ctx->bc_keysched,
 				    blowfish_ctx->bc_keysched_len);
 				free(soft_blowfish_ctx->blowfish_cbc);
 			}
 
-			bzero(soft_blowfish_ctx->key_sched,
+			freezero(soft_blowfish_ctx->key_sched,
 			    soft_blowfish_ctx->keysched_len);
-			free(soft_blowfish_ctx->key_sched);
 		}
 		break;
 	}
@@ -982,7 +976,7 @@
 		ARCFour_key *key = (ARCFour_key *)active_op->context;
 
 		if (key != NULL)
-			bzero(key, sizeof (*key));
+			explicit_bzero(key, sizeof (*key));
 		break;
 	}
 
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c	Fri Jul  6 15:55:10 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c	Fri Jul  6 15:55:10 2018
@@ -21,6 +21,7 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <pthread.h>
@@ -822,26 +823,11 @@
 	(void) memcpy(keybuf, A, keysize);
 
 cleanup:
-	if (A) {
-		bzero(A, Alen);
-		free(A);
-	}
-	if (Ai) {
-		bzero(Ai, AiLen);
-		free(Ai);
-	}
-	if (B) {
-		bzero(B, Blen);
-		free(B);
-	}
-	if (D) {
-		bzero(D, Dlen);
-		free(D);
-	}
-	if (I) {
-		bzero(I, Ilen);
-		free(I);
-	}
+	freezero(A, Alen);
+	freezero(Ai, AiLen);
+	freezero(B, Blen);
+	freezero(D, Dlen);
+	freezero(I, Ilen);
 	return (rv);
 }
 
@@ -1400,7 +1386,7 @@
 		keydata += hLen;
 	}
 	(void) soft_delete_object(session_p, hmac_key, B_FALSE, B_FALSE);
-	free(salt);
+	freezero(salt, params->ulSaltSourceDataLen);
 
 	return (rv);
 }
@@ -1535,14 +1521,12 @@
 cleanup_wrap:
 	if (padded_data != NULL && padded_len != plain_len) {
 		/* Clear buffer before returning to memory pool. */
-		(void) memset(padded_data, 0x0, padded_len);
-		free(padded_data);
+		freezero(padded_data, padded_len);
 	}
 
 	if ((hkey_p->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
 		/* Clear buffer before returning to memory pool. */
-		(void) memset(plain_data, 0x0, plain_len);
-		free(plain_data);
+		freezero(plain_data, plain_len);
 	}
 
 	return (rv);
@@ -1822,8 +1806,7 @@
 
 	if (new_objp->class != CKO_SECRET_KEY) {
 		/* Clear buffer before returning to memory pool. */
-		(void) memset(plain_data, 0x0, plain_len);
-		free(plain_data);
+		freezero(plain_data, plain_len);
 	}
 
 	*phKey = (CK_OBJECT_HANDLE)new_objp;
@@ -1834,8 +1817,7 @@
 	/* The decrypted private key buffer must be freed explicitly. */
 	if ((new_objp->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
 		/* Clear buffer before returning to memory pool. */
-		(void) memset(plain_data, 0x0, plain_len);
-		free(plain_data);
+		freezero(plain_data, plain_len);
 	}
 
 	/* sck and new_objp are indirectly free()d inside these functions */
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c	Fri Jul  6 15:55:10 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c	Fri Jul  6 15:55:10 2018
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2018, Joyent, Inc.
  */
 
 #include <crypt.h>
@@ -98,8 +99,11 @@
 	}
 
 	if ((*result = crypt((char *)pPin, *salt)) == NULL) {
-		if (new_salt)
-			free(*salt);
+		if (new_salt) {
+			size_t saltlen = strlen(*salt) + 1;
+
+			freezero(*salt, saltlen);
+		}
 		return (-1);
 	}
 
@@ -119,6 +123,7 @@
 	uchar_t	*tmp_pin = NULL;
 	boolean_t pin_initialized = B_FALSE;
 	CK_RV	rv = CKR_OK;
+	size_t	len = 0;
 
 	/*
 	 * Check to see if keystore is initialized.
@@ -189,13 +194,18 @@
 	}
 
 cleanup:
-	if (salt)
-		free(salt);
-	if (tmp_pin)
-		free(tmp_pin);
-	if (ks_cryptpin)
-		free(ks_cryptpin);
-
+	if (salt) {
+		len = strlen(salt) + 1;
+		freezero(salt, len);
+	}
+	if (tmp_pin) {
+		len = strlen((char *)tmp_pin) + 1;
+		freezero(tmp_pin, len);
+	}
+	if (ks_cryptpin) {
+		len = strlen(ks_cryptpin) + 1;
+		freezero(ks_cryptpin, len);
+	}
 	return (rv);
 }
 
@@ -213,6 +223,7 @@
 	boolean_t pin_initialized = B_FALSE;
 	uchar_t	*tmp_old_pin = NULL, *tmp_new_pin = NULL;
 	CK_RV	rv = CKR_OK;
+	size_t	len = 0;
 
 	/*
 	 * Check to see if keystore is initialized.
@@ -290,14 +301,22 @@
 	}
 
 cleanup:
-	if (salt)
-		free(salt);
-	if (ks_cryptpin)
-		free(ks_cryptpin);
-	if (tmp_old_pin)
-		free(tmp_old_pin);
-	if (tmp_new_pin)
-		free(tmp_new_pin);
+	if (salt) {
+		len = strlen(salt) + 1;
+		freezero(salt, len);
+	}
+	if (ks_cryptpin) {
+		len = strlen(ks_cryptpin) + 1;
+		freezero(ks_cryptpin, len);
+	}
+	if (tmp_old_pin) {
+		len = strlen((char *)tmp_old_pin) + 1;
+		freezero(tmp_old_pin, len);
+	}
+	if (tmp_new_pin) {
+		len = strlen((char *)tmp_new_pin) + 1;
+		freezero(tmp_new_pin, len);
+	}
 
 	return (rv);
 }
@@ -475,9 +494,7 @@
 		}
 
 		rv = soft_add_extra_attr(&template, obj);
-		if (template.pValue) {
-			free(template.pValue);
-		}
+		freezero(template.pValue, template.ulValueLen);
 
 		if (rv != CKR_OK) {
 			return (rv);
@@ -543,7 +560,7 @@
 		rv = get_bigint_attr_from_template(key_dest, &template);
 	}
 
-	free(template.pValue);
+	freezero(template.pValue, template.ulValueLen);
 	if (rv != CKR_OK) {
 		return (rv);
 	}
@@ -1857,25 +1874,15 @@
 		return (rv);
 
 	(void) pthread_mutex_lock(&soft_slot.slot_mutex);
-	if (objp->object_type == TOKEN_PUBLIC) {
-		if ((soft_keystore_put_new_obj(buf, len, B_TRUE,
-		    B_FALSE, &objp->ks_handle)) == -1) {
-			(void) pthread_mutex_unlock(&soft_slot.slot_mutex);
-			free(buf);
-			return (CKR_FUNCTION_FAILED);
-		}
-	} else {
-		if ((soft_keystore_put_new_obj(buf, len, B_FALSE,
-		    B_FALSE, &objp->ks_handle)) == -1) {
-			(void) pthread_mutex_unlock(&soft_slot.slot_mutex);
-			free(buf);
-			return (CKR_FUNCTION_FAILED);
-		}
+	if (soft_keystore_put_new_obj(buf, len,
+	    !!(objp->object_type == TOKEN_PUBLIC), B_FALSE,
+	    &objp->ks_handle) == -1) {
+		rv = CKR_FUNCTION_FAILED;
 	}
 	(void) pthread_mutex_unlock(&soft_slot.slot_mutex);
-	free(buf);
-	return (CKR_OK);
 
+	freezero(buf, len);
+	return (rv);
 }
 
 /*
@@ -1897,11 +1904,11 @@
 	/* B_TRUE: caller has held a writelock on the keystore */
 	if (soft_keystore_modify_obj(&objp->ks_handle, buf, len,
 	    B_TRUE) < 0) {
-		return (CKR_FUNCTION_FAILED);
+		rv = CKR_FUNCTION_FAILED;
 	}
 
-	free(buf);
-	return (CKR_OK);
+	freezero(buf, len);
+	return (rv);
 
 }
 
@@ -1942,8 +1949,7 @@
 
 		/* Free the ks_obj list */
 		ks_obj_next = ks_obj->next;
-		if (ks_obj->buf)
-			free(ks_obj->buf);
+		freezero(ks_obj->buf, ks_obj->size);
 		free(ks_obj);
 		ks_obj = ks_obj_next;
 	}
@@ -1953,7 +1959,7 @@
 cleanup:
 	while (ks_obj) {
 		ks_obj_next = ks_obj->next;
-		free(ks_obj->buf);
+		freezero(ks_obj->buf, ks_obj->size);
 		free(ks_obj);
 		ks_obj = ks_obj_next;
 	}
@@ -2304,9 +2310,8 @@
 		    soft_aes_ctx->ivec);
 
 		if (soft_aes_ctx->aes_cbc == NULL) {
-			bzero(soft_aes_ctx->key_sched,
+			freezero(soft_aes_ctx->key_sched,
 			    soft_aes_ctx->keysched_len);
-			free(soft_aes_ctx->key_sched);
 			if (encrypt) {
 				free(token_session.encrypt.context);
 				token_session.encrypt.context = NULL;
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c	Fri Jul  6 15:55:11 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c	Fri Jul  6 15:55:11 2018
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2018, Joyent, Inc.
  */
 
 /*
@@ -470,8 +471,7 @@
 	(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:
@@ -892,7 +892,7 @@
 
 	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);
 	}
@@ -1320,59 +1320,58 @@
 	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;
 	}
 
@@ -1379,7 +1378,7 @@
 	/* write new hmac */
 	if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE)
 	    != OBJ_HMAC_SIZE) {
-		free(buf);
+		freezero(buf, encrypted_len);
 		goto cleanup;
 	}
 
@@ -1386,10 +1385,10 @@
 	/* 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:
@@ -1547,11 +1546,12 @@
 		}
 		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) {
@@ -1560,10 +1560,11 @@
 		}
 		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) {
@@ -1612,13 +1613,15 @@
 
 	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;
 	}
 
@@ -1627,11 +1630,12 @@
 	/* 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;
@@ -1763,12 +1767,8 @@
 			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) {
@@ -1855,17 +1855,13 @@
 	/* 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
+ *	FUNCTION: soft_keystore_get_objs
  *
  *	ARGUMENTS:
  *
@@ -1980,7 +1976,7 @@
 	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;
 	}
@@ -2087,7 +2083,7 @@
 		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;
 		}
@@ -2095,7 +2091,7 @@
 		/* 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;
 		}
@@ -2102,7 +2098,7 @@
 
 		decrypted_buf = malloc(sizeof (uchar_t) * out_len);
 		if (decrypted_buf == NULL) {
-			free(buf);
+			freezero(buf, nread);
 			rv = CKR_HOST_MEMORY;
 			goto cleanup;
 		}
@@ -2109,8 +2105,8 @@
 
 		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;
 		}
@@ -2126,14 +2122,14 @@
 		 */
 		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;
 	}
 
@@ -2155,7 +2151,7 @@
 
 
 /*
- * 	FUNCTION: soft_keystore_put_new_obj
+ *	FUNCTION: soft_keystore_put_new_obj
  *
  *	ARGUMENTS:
  *		buf: buffer containing un-encrypted data
@@ -2336,13 +2332,13 @@
 		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;
 		}
 
@@ -2349,22 +2345,22 @@
 		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;
 		}
 
@@ -2371,7 +2367,7 @@
 		/* 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;
 		}
 
@@ -2378,11 +2374,11 @@
 		/* 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);
 	}
 
 
@@ -2421,6 +2417,8 @@
 		}
 	}
 	(void) close(fd);
+	explicit_bzero(obj_hmac, sizeof (obj_hmac));
+	explicit_bzero(iv, sizeof (iv));
 	return (0);
 
 cleanup2:
@@ -2438,6 +2436,8 @@
 	}
 
 	(void) close(fd);
+	explicit_bzero(obj_hmac, sizeof (obj_hmac));
+	explicit_bzero(iv, sizeof (iv));
 	return (-1);
 }
 
@@ -2591,44 +2591,44 @@
 
 		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);
 
@@ -2665,6 +2665,8 @@
 
 	(void) close(fd);
 
+	explicit_bzero(iv, sizeof (iv));
+	explicit_bzero(obj_hmac, sizeof (obj_hmac));
 	return (0); /* All operations completed successfully */
 
 cleanup2:
@@ -2679,6 +2681,8 @@
 	(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);
 }
 
@@ -2803,7 +2807,7 @@
 
 	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';
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softMAC.c	Fri Jul  6 15:55:12 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softMAC.c	Fri Jul  6 15:55:12 2018
@@ -22,10 +22,9 @@
 /*
  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <pthread.h>
 #include <sys/md5.h>
 #include <sys/sha1.h>
@@ -562,12 +561,10 @@
 	(void) pthread_mutex_lock(&session_p->session_mutex);
 
 	if (sign_op) {
-		bzero(session_p->sign.context, sizeof (soft_hmac_ctx_t));
-		free(session_p->sign.context);
+		freezero(session_p->sign.context, sizeof (soft_hmac_ctx_t));
 		session_p->sign.context = NULL;
 	} else {
-		bzero(session_p->verify.context, sizeof (soft_hmac_ctx_t));
-		free(session_p->verify.context);
+		freezero(session_p->verify.context, sizeof (soft_hmac_ctx_t));
 		session_p->verify.context = NULL;
 	}
 
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.c	Fri Jul  6 15:55:12 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.c	Fri Jul  6 15:55:12 2018
@@ -21,6 +21,7 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2018, Joyent, Inc.
  */
 
 #include <fcntl.h>
@@ -925,8 +926,7 @@
 	if (new_tmpl_allocated)
 		free(new_tmpl);
 
-	if (export_keys != NULL)
-		free(export_keys);
+	freezero(export_keys, 2 * MD5_HASH_SIZE);
 
 	return (rv);
 
@@ -955,8 +955,7 @@
 	if (new_tmpl_allocated)
 		free(new_tmpl);
 
-	if (export_keys != NULL)
-		free(export_keys);
+	freezero(export_keys, 2 * MD5_HASH_SIZE);
 
 	return (rv);
 }
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSignUtil.c	Fri Jul  6 15:55:12 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSignUtil.c	Fri Jul  6 15:55:12 2018
@@ -22,6 +22,7 @@
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 #include <stdlib.h>
@@ -562,8 +563,10 @@
 	case CKM_SHA384_HMAC:
 	case CKM_SHA512_HMAC_GENERAL:
 	case CKM_SHA512_HMAC:
-		if (active_op->context != NULL)
-			bzero(active_op->context, sizeof (soft_hmac_ctx_t));
+		if (active_op->context != NULL) {
+			explicit_bzero(active_op->context,
+			    sizeof (soft_hmac_ctx_t));
+		}
 		break;
 	case CKM_DES_MAC_GENERAL:
 	case CKM_DES_MAC:
@@ -572,8 +575,10 @@
 			session_p->encrypt.context = NULL;
 			session_p->encrypt.flags = 0;
 		}
-		if (active_op->context != NULL)
-			bzero(active_op->context, sizeof (soft_des_ctx_t));
+		if (active_op->context != NULL) {
+			explicit_bzero(active_op->context,
+			    sizeof (soft_des_ctx_t));
+		}
 		break;
 
 	case CKM_AES_CMAC_GENERAL:
@@ -583,8 +588,10 @@
 			session_p->encrypt.context = NULL;
 			session_p->encrypt.flags = 0;
 		}
-		if (active_op->context != NULL)
-			bzero(active_op->context, sizeof (soft_aes_ctx_t));
+		if (active_op->context != NULL) {
+			explicit_bzero(active_op->context,
+			    sizeof (soft_aes_ctx_t));
+		}
 		break;
 
 	}
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c	Fri Jul  6 15:55:13 2018
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c	Fri Jul  6 15:55:13 2018
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2018, Joyent, Inc.
  */
 
 #include <strings.h>
@@ -337,9 +338,12 @@
 			pInfo->flags |= CKF_USER_PIN_TO_BE_CHANGED;
 	}
 
-	if (ks_cryptpin)
-		free(ks_cryptpin);
+	if (ks_cryptpin != NULL) {
+		size_t cplen = strlen(ks_cryptpin) + 1;
 
+		freezero(ks_cryptpin, cplen);
+	}
+
 	/* Provide information about a token in the provided buffer */
 	(void) strncpy((char *)pInfo->label, SOFT_TOKEN_LABEL, 32);
 	(void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
