diff options
author | Dina K Nimeh <Dina.Nimeh@Sun.COM> | 2009-03-20 11:56:57 -0700 |
---|---|---|
committer | Dina K Nimeh <Dina.Nimeh@Sun.COM> | 2009-03-20 11:56:57 -0700 |
commit | 7b79d84636ec82b45f00c982cf6810db81852d17 (patch) | |
tree | 9e090007ba93df8148d15dd065d5051f8abd44ee | |
parent | 47e946e784719ae402ace34695f67b0e6e76ae5c (diff) | |
download | illumos-joyent-7b79d84636ec82b45f00c982cf6810db81852d17.tar.gz |
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
20 files changed, 217 insertions, 312 deletions
diff --git a/usr/src/cmd/cmd-crypto/decrypt/decrypt.c b/usr/src/cmd/cmd-crypto/decrypt/decrypt.c index aece7023ca..831ccf05d5 100644 --- a/usr/src/cmd/cmd-crypto/decrypt/decrypt.c +++ b/usr/src/cmd/cmd-crypto/decrypt/decrypt.c @@ -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 @@ execute_cmd(struct CommandInfo *cmd, char *algo_str) } 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 @@ execute_cmd(struct CommandInfo *cmd, char *algo_str) 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 " diff --git a/usr/src/cmd/lofiadm/main.c b/usr/src/cmd/lofiadm/main.c index 63dda817f6..deadd4c5d7 100644 --- a/usr/src/cmd/lofiadm/main.c +++ b/usr/src/cmd/lofiadm/main.c @@ -894,7 +894,7 @@ getkeyfromfile(const char *pathname, mech_alias_t *cipher, char **key, 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")); } diff --git a/usr/src/common/crypto/ecc/ecc_impl.h b/usr/src/common/crypto/ecc/ecc_impl.h index 506267c4a8..01728001d9 100644 --- a/usr/src/common/crypto/ecc/ecc_impl.h +++ b/usr/src/common/crypto/ecc/ecc_impl.h @@ -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 @@ typedef enum _SECStatus { #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 @@ typedef enum _SECStatus { 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); diff --git a/usr/src/common/crypto/rsa/rsa_impl.c b/usr/src/common/crypto/rsa/rsa_impl.c index 39f47ba3ae..8ff3823eba 100644 --- a/usr/src/common/crypto/rsa/rsa_impl.c +++ b/usr/src/common/crypto/rsa/rsa_impl.c @@ -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 @@ soft_encrypt_rsa_pkcs_encode(uint8_t *databuf, #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); diff --git a/usr/src/lib/libcryptoutil/common/cryptoutil.h b/usr/src/lib/libcryptoutil/common/cryptoutil.h index d041262129..6687417e29 100644 --- a/usr/src/lib/libcryptoutil/common/cryptoutil.h +++ b/usr/src/lib/libcryptoutil/common/cryptoutil.h @@ -144,8 +144,13 @@ extern char *pkcs11_default_token(void); 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, ...); diff --git a/usr/src/lib/libcryptoutil/common/mapfile-vers b/usr/src/lib/libcryptoutil/common/mapfile-vers index e7e5b12789..282d7c5f0b 100644 --- a/usr/src/lib/libcryptoutil/common/mapfile-vers +++ b/usr/src/lib/libcryptoutil/common/mapfile-vers @@ -54,14 +54,20 @@ SUNWprivate { 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; diff --git a/usr/src/lib/libcryptoutil/common/random.c b/usr/src/lib/libcryptoutil/common/random.c index 5a254ed34d..1ef3f5d1a3 100644 --- a/usr/src/lib/libcryptoutil/common/random.c +++ b/usr/src/lib/libcryptoutil/common/random.c @@ -31,23 +31,14 @@ #include <locale.h> #include <stdarg.h> #include <cryptoutil.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 pthread_mutex_t urandom_mutex = PTHREAD_MUTEX_INITIALIZER; 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 @@ writen_nointr(int fd, void *dbuf, size_t dlen) * 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)); } -int +static int pkcs11_open_urandom(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(&urandom_fd, &urandom_mutex, + URANDOM_DEVICE, O_RDONLY)); +} + +static int +pkcs11_open_random_seed(void) +{ + 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 @@ pkcs11_close_urandom(void) * 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 @@ pkcs11_random_data(void *dbuf, size_t dlen) } /* - * 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 @@ pkcs11_nzero_random_data(void *dbuf, size_t dlen) if (bytesleft == 0) { bytesleft = sizeof (extrarand); - if (pkcs11_random_data(extrarand, bytesleft) < 0) + if (pkcs11_get_urandom(extrarand, bytesleft) < 0) return (-1); } bytesleft--; diff --git a/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c b/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c index 3df701d2eb..5e5c339b03 100644 --- a/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c +++ b/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c @@ -109,8 +109,6 @@ struct CK_FUNCTION_LIST metaslot_functionList = { 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 @@ meta_Finalize(CK_VOID_PTR pReserved) (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(); diff --git a/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h b/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h index 8c3b92d0ff..c0032cdcd9 100644 --- a/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h +++ b/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h @@ -110,7 +110,6 @@ extern "C" { /* 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 boolean_t metaslot_enabled; 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; diff --git a/usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c b/usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c index f3cea9dad2..1aaa66b12c 100644 --- a/usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c +++ b/usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c @@ -1294,7 +1294,7 @@ clone_by_wrap(meta_object_t *object, slot_object_t *new_clone, } /* - * 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 @@ clone_by_wrap(meta_object_t *object, slot_object_t *new_clone, * 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 */ diff --git a/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c b/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c index 402ef7ce19..12ba8de0fa 100644 --- a/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c +++ b/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c @@ -59,7 +59,6 @@ meta_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, { CK_RV rv; meta_session_t *session; - ssize_t n; if (pSeed == NULL || ulSeedLen == 0) return (CKR_ARGUMENTS_BAD); @@ -70,27 +69,11 @@ meta_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, 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 @@ meta_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, { 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 @@ meta_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, return (rv); REFRELEASE(session); - fd = open_nointr(RANDOM_DEVICE, O_RDONLY); - if (fd == -1) { - return (CKR_DEVICE_ERROR); - } - - n = readn_nointr(fd, pRandomData, ulRandomLen); - if (n <= 0) { - (void) close(fd); + if (pkcs11_get_urandom(pRandomData, ulRandomLen) < 0) { return (CKR_DEVICE_ERROR); } - - (void) close(fd); - return (CKR_OK); } diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEC.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEC.c index 27d18b290b..50fdcc1ea9 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEC.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEC.c @@ -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" diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c index d215dc11e2..ab52db753c 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c @@ -120,10 +120,6 @@ soft_session_t *soft_session_list = NULL; 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 @@ finalize_common(boolean_t force, CK_VOID_PTR pReserved) { 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); diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c index 56dfc75069..c4fa438210 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c @@ -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 @@ soft_genkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 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) { diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c index b0ee8d2acb..027de2b195 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c @@ -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 @@ soft_pack_object_size(soft_object_t *objp) * 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 @@ soft_pack_object_size(soft_object_t *objp) * 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 @@ soft_unpack_object(soft_object_t *objp, uchar_t *buf) /* 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 @@ soft_unpack_object(soft_object_t *objp, uchar_t *buf) /* 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 @@ soft_unpack_object(soft_object_t *objp, uchar_t *buf) /* 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 @@ soft_unpack_object(soft_object_t *objp, uchar_t *buf) /* 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 @@ soft_gen_crypt_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata) 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 @@ soft_gen_hmac_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata) 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); diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.h index d62fe19c96..aab64ac405 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.h +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.h @@ -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 @@ typedef struct ks_attr_hdr { /* * 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); diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c index 1b30da9021..8498d2985b 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c @@ -1180,6 +1180,18 @@ cleanup: 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 diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c index 0ef1586274..9c602110c1 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c @@ -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 @@ C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) 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 @@ C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) 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 @@ C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, 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); } diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c index bf2c843ba5..0a63501cf2 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c @@ -42,111 +42,18 @@ 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); - } - 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]; + if (pkcs11_get_urandom(ran_out, ran_len) < 0) + return (CKR_DEVICE_ERROR); } - return (CKR_OK); } diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h index 6f0f5ce440..2307ac7264 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h @@ -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 @@ extern "C" { #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 |