6666204 meta slot opens and closes /dev/urandom needlessly for every read
authorDina K Nimeh <Dina.Nimeh@Sun.COM>
Fri, 20 Mar 2009 11:56:57 -0700
changeset 9127 39de79f2e5d5
parent 9126 6acea8ac53c8
child 9128 ac1f68909e54
6666204 meta slot opens and closes /dev/urandom needlessly for every read 6722460 finish moving /dev/random and /dev/urandom seeding and usage to libcryptoutil
usr/src/cmd/cmd-crypto/decrypt/decrypt.c
usr/src/cmd/lofiadm/main.c
usr/src/common/crypto/ecc/ecc_impl.h
usr/src/common/crypto/rsa/rsa_impl.c
usr/src/lib/libcryptoutil/common/cryptoutil.h
usr/src/lib/libcryptoutil/common/mapfile-vers
usr/src/lib/libcryptoutil/common/random.c
usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c
usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h
usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c
usr/src/lib/pkcs11/libpkcs11/common/metaRand.c
usr/src/lib/pkcs11/pkcs11_softtoken/common/softEC.c
usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c
usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c
usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c
usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.h
usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c
usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c
usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c
usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h
--- a/usr/src/cmd/cmd-crypto/decrypt/decrypt.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/cmd/cmd-crypto/decrypt/decrypt.c	Fri Mar 20 11:56:57 2009 -0700
@@ -20,7 +20,7 @@
  */
 /* Portions Copyright 2005 Richard Lowe */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -650,7 +650,7 @@
 	}
 
 	if (cmd->type == CKA_ENCRYPT) {
-		if ((pkcs11_random_data((void *)pivbuf,
+		if ((pkcs11_get_urandom((void *)pivbuf,
 		    mech_aliases[mech_match].ivlen)) != 0) {
 			cryptoerror(LOG_STDERR, gettext(
 			    "Unable to generate random "
@@ -808,7 +808,7 @@
 			goto do_crypto;
 		}
 	} else if (cmd->type == CKA_ENCRYPT) {
-		rv = pkcs11_random_data((void *)salt, sizeof (salt));
+		rv = pkcs11_get_urandom((void *)salt, sizeof (salt));
 		if (rv != 0) {
 			cryptoerror(LOG_STDERR,
 			gettext("unable to generate random "
--- a/usr/src/cmd/lofiadm/main.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/cmd/lofiadm/main.c	Fri Mar 20 11:56:57 2009 -0700
@@ -894,7 +894,7 @@
 		if (*key == NULL)
 			die(gettext("failed to allocate memory for"
 			    " ephemeral key"));
-		if (pkcs11_random_data(*key, *ksz) < 0) {
+		if (pkcs11_get_urandom(*key, *ksz) < 0) {
 			free(*key);
 			die(gettext("failed to get enough random data"));
 		}
--- a/usr/src/common/crypto/ecc/ecc_impl.h	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/common/crypto/ecc/ecc_impl.h	Fri Mar 20 11:56:57 2009 -0700
@@ -36,7 +36,7 @@
  *
  * ***** END LICENSE BLOCK ***** */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  *
  * Sun elects to use this software under the MPL license.
@@ -45,8 +45,6 @@
 #ifndef _ECC_IMPL_H
 #define	_ECC_IMPL_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -207,7 +205,8 @@
 #ifdef _KERNEL
 #define	RNG_GenerateGlobalRandomBytes(p,l) ecc_knzero_random_generator((p), (l))
 #else
-#define	RNG_GenerateGlobalRandomBytes(p,l) soft_nzero_random_generator((p), (l))
+#define	RNG_GenerateGlobalRandomBytes(p,l) \
+	(pkcs11_get_nzero_urandom((p), (l)) < 0 ? CKR_DEVICE_ERROR : CKR_OK)
 #endif
 #define	CHECK_MPI_OK(func) if (MP_OKAY > (err = func)) goto cleanup
 #define	MP_TO_SEC_ERROR(err) 
@@ -216,7 +215,7 @@
 	CHECK_MPI_OK(mp_read_unsigned_octets((mp), (it).data, (it).len))
 
 extern int ecc_knzero_random_generator(uint8_t *, size_t);
-extern ulong_t soft_nzero_random_generator(uint8_t *, ulong_t);
+extern int pkcs11_get_nzero_urandom(void *, size_t);
 
 extern SECStatus EC_DecodeParams(const SECItem *, ECParams **, int);
 extern SECItem * SECITEM_AllocItem(PRArenaPool *, SECItem *, unsigned int, int);
--- a/usr/src/common/crypto/rsa/rsa_impl.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/common/crypto/rsa/rsa_impl.c	Fri Mar 20 11:56:57 2009 -0700
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * This file contains RSA helper routines common to
  * the PKCS11 soft token code and the kernel RSA code.
@@ -37,6 +35,7 @@
 #include <sys/param.h>
 #else
 #include <strings.h>
+#include <cryptoutil.h>
 #include "softRandom.h"
 #endif
 
@@ -197,7 +196,9 @@
 #ifdef _KERNEL
 	rv = knzero_random_generator(padbuf + 2, padbuflen - 3);
 #else
-	rv = soft_nzero_random_generator(padbuf + 2, padbuflen - 3);
+	rv = CKR_OK;
+	if (pkcs11_get_nzero_urandom(padbuf + 2, padbuflen - 3) < 0)
+		rv = CKR_DEVICE_ERROR;
 #endif
 	if (rv != CKR_OK) {
 		return (rv);
--- a/usr/src/lib/libcryptoutil/common/cryptoutil.h	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/libcryptoutil/common/cryptoutil.h	Fri Mar 20 11:56:57 2009 -0700
@@ -144,8 +144,13 @@
 extern int pkcs11_get_pass(char *token_name, char **pdata, size_t *psize,
     size_t min_psize, boolean_t with_confirmation);
 
-extern int pkcs11_random_data(void *dbuf, size_t dlen);
-extern int pkcs11_nzero_random_data(void *dbuf, size_t dlen);
+extern int pkcs11_seed_urandom(void *sbuf, size_t slen);
+extern int pkcs11_get_random(void *dbuf, size_t dlen);
+extern int pkcs11_get_urandom(void *dbuf, size_t dlen);
+extern int pkcs11_get_nzero_urandom(void *dbuf, size_t dlen);
+extern void pkcs11_close_random(void);
+extern void pkcs11_close_urandom(void);
+extern void pkcs11_close_urandom_seed(void);
 extern int pkcs11_read_data(char *filename, void **dbuf, size_t *dlen);
 
 extern int open_nointr(const char *path, int oflag, ...);
--- a/usr/src/lib/libcryptoutil/common/mapfile-vers	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/libcryptoutil/common/mapfile-vers	Fri Mar 20 11:56:57 2009 -0700
@@ -54,14 +54,20 @@
 	get_pkcs11conf_info;
 	hexstr_to_bytes;
 	open_nointr;
+	pkcs11_close_random;
+	pkcs11_close_urandom;
+	pkcs11_close_urandom_seed;
 	pkcs11_default_token;
+	pkcs11_get_nzero_urandom;
 	pkcs11_get_pass;
+	pkcs11_get_random;
+	pkcs11_get_urandom;
 	pkcs11_mech2keytype;
 	pkcs11_mech2keygen;
 	pkcs11_mech2str;
-	pkcs11_nzero_random_data;
-	pkcs11_random_data;
 	pkcs11_read_data;
+	pkcs11_seed_random;
+	pkcs11_seed_urandom;
 	pkcs11_str2mech;
 	pkcs11_strerror;
 	readn_nointr;
--- a/usr/src/lib/libcryptoutil/common/random.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/libcryptoutil/common/random.c	Fri Mar 20 11:56:57 2009 -0700
@@ -31,23 +31,14 @@
 #include <locale.h>
 #include <stdarg.h>
 #include <cryptoutil.h>
+#include <pthread.h>
 
-#ifdef	_REENTRANT
-
-#include <pthread.h>
 
 static pthread_mutex_t	random_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t	urandom_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-#define	RAND_LOCK(x)	(void) pthread_mutex_lock(x)
-#define	RAND_UNLOCK(x)	(void) pthread_mutex_unlock(x)
-
-#else
-
-#define	RAND_LOCK(x)
-#define	RAND_UNLOCK(x)
-
-#endif
+static pthread_mutex_t	random_seed_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t	urandom_seed_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 #define	RANDOM_DEVICE		"/dev/random"	/* random device name */
 #define	URANDOM_DEVICE		"/dev/urandom"	/* urandom device name */
@@ -55,6 +46,10 @@
 static int	random_fd = -1;
 static int	urandom_fd = -1;
 
+static int	random_seed_fd = -1;
+static int	urandom_seed_fd = -1;
+
+
 /*
  * Equivalent of open(2) insulated from EINTR.
  * Also sets close-on-exec.
@@ -135,49 +130,141 @@
  * Opens the random number generator devices if not already open.
  * Always returns the opened fd of the device, or error.
  */
-int
+static int
+pkcs11_open_common(int *fd, pthread_mutex_t *mtx, const char *dev, int oflag)
+{
+	if (*fd < 0) {
+		(void) pthread_mutex_lock(mtx);
+		if (*fd < 0)
+			*fd = open_nointr(dev, oflag);
+		(void) pthread_mutex_unlock(mtx);
+	}
+	return (*fd);
+}
+
+static int
 pkcs11_open_random(void)
 {
-	RAND_LOCK(&random_mutex);
-	if (random_fd < 0)
-		random_fd = open_nointr(RANDOM_DEVICE, O_RDONLY);
-	RAND_UNLOCK(&random_mutex);
-	return (random_fd);
+	return (pkcs11_open_common(&random_fd, &random_mutex,
+	    RANDOM_DEVICE, O_RDONLY));
+}
+
+static int
+pkcs11_open_urandom(void)
+{
+	return (pkcs11_open_common(&urandom_fd, &urandom_mutex,
+	    URANDOM_DEVICE, O_RDONLY));
 }
 
-int
-pkcs11_open_urandom(void)
+static int
+pkcs11_open_random_seed(void)
 {
-	RAND_LOCK(&urandom_mutex);
-	if (urandom_fd < 0)
-		urandom_fd = open_nointr(URANDOM_DEVICE, O_RDONLY);
-	RAND_UNLOCK(&urandom_mutex);
-	return (urandom_fd);
+	return (pkcs11_open_common(&random_seed_fd, &random_seed_mutex,
+	    RANDOM_DEVICE, O_WRONLY));
+}
+
+static int
+pkcs11_open_urandom_seed(void)
+{
+	return (pkcs11_open_common(&urandom_seed_fd, &urandom_seed_mutex,
+	    URANDOM_DEVICE, O_WRONLY));
 }
 
 /*
  * Close the random number generator devices if already open.
  */
+static void
+pkcs11_close_common(int *fd, pthread_mutex_t *mtx)
+{
+	if (*fd < 0)
+		return;
+	(void) pthread_mutex_lock(mtx);
+	(void) close(*fd);
+	*fd = -1;
+	(void) pthread_mutex_unlock(mtx);
+}
+
 void
 pkcs11_close_random(void)
 {
-	if (random_fd < 0)
-		return;
-	RAND_LOCK(&random_mutex);
-	(void) close(random_fd);
-	random_fd = -1;
-	RAND_UNLOCK(&random_mutex);
+	pkcs11_close_common(&random_fd, &random_mutex);
 }
 
 void
 pkcs11_close_urandom(void)
 {
-	if (urandom_fd < 0)
-		return;
-	RAND_LOCK(&urandom_mutex);
-	(void) close(urandom_fd);
-	urandom_fd = -1;
-	RAND_UNLOCK(&urandom_mutex);
+	pkcs11_close_common(&urandom_fd, &urandom_mutex);
+}
+
+static void
+pkcs11_close_random_seed(void)
+{
+	pkcs11_close_common(&random_seed_fd, &random_seed_mutex);
+}
+
+void
+pkcs11_close_urandom_seed(void)
+{
+	pkcs11_close_common(&urandom_seed_fd, &urandom_seed_mutex);
+}
+
+/*
+ * Seed /dev/random with the data in the buffer.
+ */
+int
+pkcs11_seed_random(void *sbuf, size_t slen)
+{
+	if (sbuf == NULL || slen == 0)
+		return (0);
+
+	/* Seeding error could mean it's not supported (errno = EACCES) */
+	if (pkcs11_open_random_seed() < 0)
+		return (-1);
+
+	if (writen_nointr(random_seed_fd, sbuf, slen) == slen) {
+		pkcs11_close_random_seed();
+		return (0);
+	}
+	return (-1);
+}
+
+/*
+ * Seed /dev/urandom with the data in the buffer.
+ */
+int
+pkcs11_seed_urandom(void *sbuf, size_t slen)
+{
+	if (sbuf == NULL || slen == 0)
+		return (0);
+
+	/* Seeding error could mean it's not supported (errno = EACCES) */
+	if (pkcs11_open_urandom_seed() < 0)
+		return (-1);
+
+	if (writen_nointr(urandom_seed_fd, sbuf, slen) == slen) {
+		pkcs11_close_urandom_seed();
+		return (0);
+	}
+	return (-1);
+}
+
+/*
+ * Put the requested amount of random data into a preallocated buffer.
+ * Good for token key data, persistent objects.
+ */
+int
+pkcs11_get_random(void *dbuf, size_t dlen)
+{
+	if (dbuf == NULL || dlen == 0)
+		return (0);
+
+	/* Read random data directly from /dev/random */
+	if (pkcs11_open_random() < 0)
+		return (-1);
+
+	if (readn_nointr(random_fd, dbuf, dlen) == dlen)
+		return (0);
+	return (-1);
 }
 
 /*
@@ -185,7 +272,7 @@
  * Good for passphrase salts, initialization vectors.
  */
 int
-pkcs11_random_data(void *dbuf, size_t dlen)
+pkcs11_get_urandom(void *dbuf, size_t dlen)
 {
 	if (dbuf == NULL || dlen == 0)
 		return (0);
@@ -200,17 +287,17 @@
 }
 
 /*
- * Same as pkcs11_random_data but ensures non zero data.
+ * Same as pkcs11_get_urandom but ensures non zero data.
  */
 int
-pkcs11_nzero_random_data(void *dbuf, size_t dlen)
+pkcs11_get_nzero_urandom(void *dbuf, size_t dlen)
 {
 	char	extrarand[32];
 	size_t	bytesleft = 0;
 	size_t	i = 0;
 
 	/* Start with some random data */
-	if (pkcs11_random_data(dbuf, dlen) < 0)
+	if (pkcs11_get_urandom(dbuf, dlen) < 0)
 		return (-1);
 
 	/* Walk through data replacing any 0 bytes with more random data */
@@ -222,7 +309,7 @@
 
 		if (bytesleft == 0) {
 			bytesleft = sizeof (extrarand);
-			if (pkcs11_random_data(extrarand, bytesleft) < 0)
+			if (pkcs11_get_urandom(extrarand, bytesleft) < 0)
 				return (-1);
 		}
 		bytesleft--;
--- a/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c	Fri Mar 20 11:56:57 2009 -0700
@@ -109,8 +109,6 @@
 
 pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;
 
-int meta_urandom_seed_fd = -1;
-
 ses_to_be_freed_list_t ses_delay_freed;
 object_to_be_freed_list_t obj_delay_freed;
 
@@ -198,10 +196,8 @@
 
 	(void) pthread_mutex_lock(&initmutex);
 
-	if (meta_urandom_seed_fd > 0) {
-		(void) close(meta_urandom_seed_fd);
-		meta_urandom_seed_fd = -1;
-	}
+	pkcs11_close_urandom();
+	pkcs11_close_urandom_seed();
 
 	meta_objectManager_finalize();
 
--- a/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h	Fri Mar 20 11:56:57 2009 -0700
@@ -110,7 +110,6 @@
 /* CK_TOKEN_INFO: More information about token */
 #define	METASLOT_TOKEN_LABEL		"Sun Metaslot                    "
 #define	METASLOT_TOKEN_MODEL		"1.0             "
-#define	RANDOM_DEVICE	"/dev/urandom"
 
 /*
  * Maximum number of objects and sessions to queue up before actually
@@ -556,7 +555,6 @@
 extern CK_SLOT_ID metaslot_keystore_slotid;
 extern boolean_t metaslot_auto_key_migrate;
 extern struct CK_FUNCTION_LIST metaslot_functionList;
-extern int meta_urandom_seed_fd;
 extern pthread_mutex_t initmutex;
 
 extern ses_to_be_freed_list_t ses_delay_freed;
--- a/usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c	Fri Mar 20 11:56:57 2009 -0700
@@ -1294,7 +1294,7 @@
 	}
 
 	/*
-	 * open the random device and read number of bytes required for
+	 * read number of bytes required from random device for
 	 * creating a secret key for wrapping and unwrapping
 	 */
 	if (wrap_info.class == CKO_SECRET_KEY) {
@@ -1305,29 +1305,19 @@
 		 * use /dev/urandom because this key is used for this
 		 * one time operation only.  It doesn't need to be stored.
 		 */
-		int fd;
-
-		fd = open_nointr(RANDOM_DEVICE, O_RDONLY);
-		if (fd == -1) {
-			rv = CKR_FUNCTION_FAILED;
-			goto finish;
-		}
 		key_len = wrap_info.key_length;
-
-		if (readn_nointr(fd, key_data, key_len) != key_len) {
+		if (pkcs11_get_urandom(key_data, key_len) < 0) {
 			rv = CKR_FUNCTION_FAILED;
 			goto finish;
 		}
 
 		if (wrap_info.iv_length > 0) {
-			if (readn_nointr(fd, ivbuf, wrap_info.iv_length)
-			    != wrap_info.iv_length) {
+			if (pkcs11_get_urandom(
+			    ivbuf, wrap_info.iv_length) < 0) {
 				rv = CKR_FUNCTION_FAILED;
 				goto finish;
 			}
 		}
-
-		(void) close(fd);
 	}
 
 	/* create the wrapping key */
--- a/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c	Fri Mar 20 11:56:57 2009 -0700
@@ -59,7 +59,6 @@
 {
 	CK_RV rv;
 	meta_session_t *session;
-	ssize_t n;
 
 	if (pSeed == NULL || ulSeedLen == 0)
 		return (CKR_ARGUMENTS_BAD);
@@ -70,27 +69,11 @@
 		return (rv);
 	REFRELEASE(session);
 
-	if (meta_urandom_seed_fd < 0) {
-		(void) pthread_mutex_lock(&initmutex);
-		/* Check again holding the mutex */
-		if (meta_urandom_seed_fd < 0) {
-			meta_urandom_seed_fd = open_nointr(RANDOM_DEVICE,
-			    O_WRONLY);
-			if (meta_urandom_seed_fd < 0) {
-				(void) pthread_mutex_unlock(&initmutex);
-				if (errno == EACCES)
-					return (CKR_RANDOM_SEED_NOT_SUPPORTED);
-				return (CKR_DEVICE_ERROR);
-			}
-		}
-		(void) pthread_mutex_unlock(&initmutex);
-	}
-
-	n = writen_nointr(meta_urandom_seed_fd, pSeed, ulSeedLen);
-	if (n <= 0) {
+	if (pkcs11_seed_urandom(pSeed, ulSeedLen) < 0) {
+		if (errno == EACCES)
+			return (CKR_RANDOM_SEED_NOT_SUPPORTED);
 		return (CKR_DEVICE_ERROR);
 	}
-
 	return (CKR_OK);
 }
 
@@ -110,8 +93,6 @@
 {
 	CK_RV rv;
 	meta_session_t *session;
-	int fd;
-	ssize_t n;
 
 	if (pRandomData == NULL || ulRandomLen < 1)
 		return (CKR_ARGUMENTS_BAD);
@@ -122,18 +103,8 @@
 		return (rv);
 	REFRELEASE(session);
 
-	fd = open_nointr(RANDOM_DEVICE, O_RDONLY);
-	if (fd == -1) {
+	if (pkcs11_get_urandom(pRandomData, ulRandomLen) < 0) {
 		return (CKR_DEVICE_ERROR);
 	}
-
-	n = readn_nointr(fd, pRandomData, ulRandomLen);
-	if (n <= 0) {
-		(void) close(fd);
-		return (CKR_DEVICE_ERROR);
-	}
-
-	(void) close(fd);
-
 	return (CKR_OK);
 }
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEC.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEC.c	Fri Mar 20 11:56:57 2009 -0700
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
@@ -37,7 +35,6 @@
 #include "softSession.h"
 #include "softObject.h"
 #include "softEC.h"
-#include "softRandom.h"
 #include "softCrypt.h"
 #include "softOps.h"
 #include "softMAC.h"
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c	Fri Mar 20 11:56:57 2009 -0700
@@ -120,10 +120,6 @@
 
 int all_sessions_closing = 0;
 
-int soft_urandom_fd = -1;
-int soft_urandom_seed_fd = -1;
-int soft_random_fd = -1;
-
 slot_t soft_slot;
 obj_to_be_freed_list_t obj_delay_freed;
 ses_to_be_freed_list_t ses_delay_freed;
@@ -328,20 +324,9 @@
 	softtoken_initialized = B_FALSE;
 	softtoken_pid = 0;
 
-	if (soft_urandom_fd > 0) {
-		(void) close(soft_urandom_fd);
-		soft_urandom_fd = -1;
-	}
-
-	if (soft_urandom_seed_fd > 0) {
-		(void) close(soft_urandom_seed_fd);
-		soft_urandom_seed_fd = -1;
-	}
-
-	if (soft_random_fd > 0) {
-		(void) close(soft_random_fd);
-		soft_random_fd = -1;
-	}
+	pkcs11_close_urandom();
+	pkcs11_close_urandom_seed();
+	pkcs11_close_random();
 
 	/* Destroy the session list lock here */
 	(void) pthread_mutex_destroy(&soft_sessionlist_mutex);
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c	Fri Mar 20 11:56:57 2009 -0700
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
@@ -36,6 +34,7 @@
 #include <blowfish_impl.h>
 #include <des_impl.h>
 #include <arcfour.h>
+#include <cryptoutil.h>
 #include "softGlobal.h"
 #include "softSession.h"
 #include "softObject.h"
@@ -43,7 +42,6 @@
 #include "softRSA.h"
 #include "softDH.h"
 #include "softEC.h"
-#include "softRandom.h"
 #include "softMAC.h"
 #include "softOps.h"
 #include "softKeys.h"
@@ -346,12 +344,13 @@
 		break;
 	default:
 		do {
-			rv = soft_random_generator(
-			    OBJ_SEC_VALUE(secret_key), keylen, B_FALSE);
-
 			/* If this fails, bail out */
-			if (rv != CKR_OK)
+			rv = CKR_OK;
+			if (pkcs11_get_urandom(
+			    OBJ_SEC_VALUE(secret_key), keylen) < 0) {
+				rv = CKR_DEVICE_ERROR;
 				break;
+			}
 
 			/* Perform weak key checking for DES and DES3. */
 			if (des_strength > 0) {
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c	Fri Mar 20 11:56:57 2009 -0700
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <crypt.h>
 #include <cryptoutil.h>
 #include <pwd.h>
@@ -42,25 +40,12 @@
 #include "softKeys.h"
 #include "softKeystore.h"
 #include "softKeystoreUtil.h"
-#include "softRandom.h"
 #include "softMAC.h"
 #include "softOps.h"
 
 soft_session_t token_session;
 
 /*
- * Generate a 16-byte Initialization Vector (IV).
- */
-CK_RV
-soft_gen_iv(CK_BYTE *iv)
-{
-
-	return (soft_nzero_random_generator(iv, 16));
-
-}
-
-
-/*
  * soft_gen_hashed_pin()
  *
  * Arguments:
@@ -718,7 +703,7 @@
 		 * value_len + value
 		 */
 		return (ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8) +
-			sizeof (uint64_t));
+		    sizeof (uint64_t));
 
 	case CKO_CERTIFICATE:
 		switch (certtype) {
@@ -727,20 +712,20 @@
 			 * subject_len + subject + value_len + value
 			 */
 			return (ROUNDUP(((cert_attr_t *)
-				X509_CERT_SUBJECT(objp))->length, 8) +
-				ROUNDUP(((cert_attr_t *)
-				X509_CERT_VALUE(objp))->length, 8) +
-				2 * sizeof (uint64_t));
+			    X509_CERT_SUBJECT(objp))->length, 8) +
+			    ROUNDUP(((cert_attr_t *)
+			    X509_CERT_VALUE(objp))->length, 8) +
+			    2 * sizeof (uint64_t));
 
 		case CKC_X_509_ATTR_CERT:
 			/*
 			 * owner_len + owner + value_len + value
 			 */
 			return (ROUNDUP(((cert_attr_t *)
-				X509_ATTR_CERT_OWNER(objp))->length, 8) +
-				ROUNDUP(((cert_attr_t *)
-				X509_ATTR_CERT_VALUE(objp))->length, 8) +
-				2 * sizeof (uint64_t));
+			    X509_ATTR_CERT_OWNER(objp))->length, 8) +
+			    ROUNDUP(((cert_attr_t *)
+			    X509_ATTR_CERT_VALUE(objp))->length, 8) +
+			    2 * sizeof (uint64_t));
 		}
 		return (0);
 
@@ -1717,7 +1702,7 @@
 			/* subject */
 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
 			    &cert->cert_type_u.x509.subject,
-				&offset, B_TRUE)) != CKR_OK) {
+			    &offset, B_TRUE)) != CKR_OK) {
 				free(cert);
 				return (rv);
 			}
@@ -1727,7 +1712,7 @@
 			/* value */
 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
 			    &cert->cert_type_u.x509.value,
-				&offset, B_TRUE)) != CKR_OK) {
+			    &offset, B_TRUE)) != CKR_OK) {
 				free(cert);
 				return (rv);
 			}
@@ -1738,7 +1723,7 @@
 			/* owner */
 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
 			    &cert->cert_type_u.x509_attr.owner,
-				&offset, B_TRUE)) != CKR_OK) {
+			    &offset, B_TRUE)) != CKR_OK) {
 				free(cert);
 				return (rv);
 			}
@@ -1748,7 +1733,7 @@
 			/* value */
 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
 			    &cert->cert_type_u.x509_attr.value,
-				&offset, B_TRUE)) != CKR_OK) {
+			    &offset, B_TRUE)) != CKR_OK) {
 				free(cert);
 				return (rv);
 			}
@@ -1989,7 +1974,7 @@
 
 	if (*saltdata == NULL) {
 		bzero(salt, sizeof (salt));
-		(void) soft_nzero_random_generator(salt, sizeof (salt));
+		(void) pkcs11_get_nzero_urandom(salt, sizeof (salt));
 		*saltdata = malloc(PBKD2_SALT_SIZE);
 		if (*saltdata == NULL)
 			return (CKR_HOST_MEMORY);
@@ -2112,7 +2097,7 @@
 
 	if (*saltdata == NULL) {
 		bzero(salt, sizeof (salt));
-		(void) soft_nzero_random_generator(salt, sizeof (salt));
+		(void) pkcs11_get_nzero_urandom(salt, sizeof (salt));
 		*saltdata = malloc(PBKD2_SALT_SIZE);
 		if (*saltdata == NULL)
 			return (CKR_HOST_MEMORY);
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.h	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.h	Fri Mar 20 11:56:57 2009 -0700
@@ -19,15 +19,13 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #ifndef _SOFTKEYSTORE_H
 #define	_SOFTKEYSTORE_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -87,8 +85,6 @@
 /*
  * Function Prototypes
  */
-CK_RV soft_gen_iv(CK_BYTE *iv);
-
 int soft_gen_hashed_pin(CK_UTF8CHAR_PTR pPin, char **result, char **salt);
 
 CK_RV soft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen);
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c	Fri Mar 20 11:56:57 2009 -0700
@@ -1180,6 +1180,18 @@
 	return (ret_val);
 }
 
+
+/*
+ * Generate a 16-byte Initialization Vector (IV).
+ */
+CK_RV
+soft_gen_iv(CK_BYTE *iv)
+{
+	return (pkcs11_get_nzero_urandom(iv, 16) < 0 ?
+	    CKR_DEVICE_ERROR : CKR_OK);
+}
+
+
 /*
  * This function reads all the data until the end of the file, and
  * put the data into the "buf" in argument.  Memory for buf will
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c	Fri Mar 20 11:56:57 2009 -0700
@@ -30,7 +30,6 @@
 #include <security/cryptoki.h>
 #include <cryptoutil.h>
 #include "softGlobal.h"
-#include "softRandom.h"
 #include "softSession.h"
 
 CK_RV
@@ -40,7 +39,6 @@
 	CK_RV	rv;
 	soft_session_t	*session_p;
 	boolean_t	lock_held = B_FALSE;
-	long		nwrite;
 
 	if (!softtoken_initialized)
 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
@@ -56,27 +54,11 @@
 		return (CKR_ARGUMENTS_BAD);
 	}
 
-	if (soft_urandom_seed_fd < 0) {
-		(void) pthread_mutex_lock(&soft_giant_mutex);
-		/* Check again holding the mutex */
-		if (soft_urandom_seed_fd < 0) {
-			soft_urandom_seed_fd = open_nointr(DEV_URANDOM,
-			    O_WRONLY);
-			if (soft_urandom_seed_fd < 0) {
-				(void) pthread_mutex_unlock(&soft_giant_mutex);
-				if (errno == EACCES)
-					return (CKR_RANDOM_SEED_NOT_SUPPORTED);
-				return (CKR_DEVICE_ERROR);
-			}
-		}
-		(void) pthread_mutex_unlock(&soft_giant_mutex);
-	}
-
-	nwrite = writen_nointr(soft_urandom_seed_fd, pSeed, ulSeedLen);
-	if (nwrite <= 0) {
+	if (pkcs11_seed_urandom(pSeed, ulSeedLen) < 0) {
+		if (errno == EACCES)
+			return (CKR_RANDOM_SEED_NOT_SUPPORTED);
 		return (CKR_DEVICE_ERROR);
 	}
-
 	return (CKR_OK);
 
 }
@@ -104,6 +86,8 @@
 		return (CKR_ARGUMENTS_BAD);
 	}
 
-	return (soft_random_generator(pRandomData, ulRandomLen, B_FALSE));
+	if (pkcs11_get_urandom(pRandomData, ulRandomLen) < 0)
+		return (CKR_DEVICE_ERROR);
+	return (CKR_OK);
 
 }
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c	Fri Mar 20 11:56:57 2009 -0700
@@ -42,112 +42,19 @@
 CK_RV
 soft_random_generator(CK_BYTE *ran_out, CK_ULONG ran_len, boolean_t token)
 {
-
-	long	nread;
-
 	/*
 	 * When random-number generator is called by asymmetric token
 	 * (persistent) key generation, use /dev/random. Otherwise,
 	 * use /dev/urandom.
 	 */
 	if (token) {
-		if (soft_random_fd < 0) {
-			(void) pthread_mutex_lock(&soft_giant_mutex);
-			/* Check again holding the mutex */
-			if (soft_random_fd < 0) {
-				soft_random_fd = open_nointr(DEV_RANDOM,
-				    O_RDONLY);
-				if (soft_random_fd < 0) {
-					(void) pthread_mutex_unlock(
-					    &soft_giant_mutex);
-					return (CKR_DEVICE_ERROR);
-				}
-			}
-			(void) pthread_mutex_unlock(&soft_giant_mutex);
-		}
+		if (pkcs11_get_random(ran_out, ran_len) < 0)
+			return (CKR_DEVICE_ERROR);
 	} else {
-		if (soft_urandom_fd < 0) {
-			(void) pthread_mutex_lock(&soft_giant_mutex);
-			/* Check again holding the mutex */
-			if (soft_urandom_fd < 0) {
-				soft_urandom_fd = open_nointr(DEV_URANDOM,
-				    O_RDONLY);
-				if (soft_urandom_fd < 0) {
-					(void) pthread_mutex_unlock(
-					    &soft_giant_mutex);
-					return (CKR_DEVICE_ERROR);
-				}
-			}
-			(void) pthread_mutex_unlock(&soft_giant_mutex);
-		}
-	}
-
-	if (token)
-		nread = readn_nointr(soft_random_fd, ran_out, ran_len);
-	else
-		nread = readn_nointr(soft_urandom_fd, ran_out, ran_len);
-
-	if (nread <= 0) {
-		return (CKR_DEVICE_ERROR);
+		if (pkcs11_get_urandom(ran_out, ran_len) < 0)
+			return (CKR_DEVICE_ERROR);
 	}
 	return (CKR_OK);
-
-}
-
-
-/*
- * This function guarantees to return non-zero random numbers.
- */
-CK_RV
-soft_nzero_random_generator(CK_BYTE *ran_out, CK_ULONG ran_len)
-{
-
-	CK_RV rv = CKR_OK;
-	size_t ebc = 0; /* count of extra bytes in extrarand */
-	size_t i = 0;
-	char extrarand[32];
-	size_t extrarand_len;
-
-	/*
-	 * soft_random_generator() may return zeros.
-	 */
-	if ((rv = soft_random_generator(ran_out, ran_len, B_FALSE)) != CKR_OK) {
-		return (rv);
-	}
-
-	/*
-	 * Walk through the returned random numbers pointed by ran_out,
-	 * and look for any random number which is zero.
-	 * If we find zero, call soft_random_generator() to generate
-	 * another 32 random numbers pool. Replace any zeros in ran_out[]
-	 * from the random number in pool.
-	 */
-	while (i < ran_len) {
-		if (((char *)ran_out)[i] != 0) {
-			i++;
-			continue;
-		}
-
-		if (ebc == 0) {
-			/* refresh extrarand */
-			extrarand_len = sizeof (extrarand);
-			if ((rv = soft_random_generator((CK_BYTE *)extrarand,
-			    extrarand_len, B_FALSE)) != CKR_OK) {
-				return (rv);
-			}
-
-			ebc = extrarand_len;
-		}
-		-- ebc;
-
-		/*
-		 * The new random byte zero/non-zero will be checked in
-		 * the next pass through the loop.
-		 */
-		((char *)ran_out)[i] = extrarand[ebc];
-	}
-
-	return (CKR_OK);
 }
 
 
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h	Fri Mar 20 11:15:04 2009 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h	Fri Mar 20 11:56:57 2009 -0700
@@ -19,15 +19,13 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #ifndef _SOFTRANDOM_H
 #define	_SOFTRANDOM_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -37,17 +35,6 @@
 #include <bignum.h>
 #include "softSession.h"
 
-extern int soft_urandom_fd;
-extern int soft_urandom_seed_fd;
-extern int soft_random_fd;
-
-#define	DEV_URANDOM		"/dev/urandom"
-#define	DEV_RANDOM		"/dev/random"
-
-CK_RV soft_random_generator(CK_BYTE *, CK_ULONG, boolean_t);
-
-CK_RV soft_nzero_random_generator(CK_BYTE *, CK_ULONG);
-
 BIG_ERR_CODE random_bignum(BIGNUM *, int, boolean_t);
 
 #ifdef	__cplusplus