summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authormcpowers <none@none>2006-05-01 16:17:15 -0700
committermcpowers <none@none>2006-05-01 16:17:15 -0700
commit8047c9fb10f4d3f14385d535d6b23a5eb80c0c0f (patch)
tree192b7c0157fe031e0882c2cd25d196fd9ad70bc4 /usr
parentb7b2cb069f0572c787a861df08054e686404c23e (diff)
downloadillumos-joyent-8047c9fb10f4d3f14385d535d6b23a5eb80c0c0f.tar.gz
PSARC 2006/214 Crypto Framework random number API/SPI update
6374503 C_SeedRandom is too slow causing poor performance with Apache/OpenSSL when using pkcs11
Diffstat (limited to 'usr')
-rw-r--r--usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c17
-rw-r--r--usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h9
-rw-r--r--usr/src/lib/pkcs11/libpkcs11/common/metaRand.c42
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c13
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c44
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h8
-rw-r--r--usr/src/uts/common/crypto/api/kcf_random.c36
-rw-r--r--usr/src/uts/common/crypto/core/kcf_callprov.c3
-rw-r--r--usr/src/uts/common/crypto/io/crypto.c5
-rw-r--r--usr/src/uts/common/crypto/io/dprov.c25
-rw-r--r--usr/src/uts/common/crypto/io/swrand.c92
-rw-r--r--usr/src/uts/common/io/random.c26
-rw-r--r--usr/src/uts/common/sys/crypto/impl.h12
-rw-r--r--usr/src/uts/common/sys/crypto/ops_impl.h14
-rw-r--r--usr/src/uts/common/sys/crypto/spi.h14
-rw-r--r--usr/src/uts/common/sys/random.h9
16 files changed, 247 insertions, 122 deletions
diff --git a/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c b/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c
index a9c60b1b1e..5f16e7727f 100644
--- a/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c
+++ b/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -110,7 +109,9 @@ struct CK_FUNCTION_LIST metaslot_functionList = {
meta_WaitForSlotEvent
};
-static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;
+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;
@@ -163,7 +164,6 @@ meta_Initialize(CK_VOID_PTR pInitArgs)
meta_slotManager_find_object_token();
-
/* Initialize the object_to_be_freed list */
(void) pthread_mutex_init(&obj_delay_freed.obj_to_be_free_mutex, NULL);
obj_delay_freed.count = 0;
@@ -200,6 +200,11 @@ 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;
+ }
+
meta_objectManager_finalize();
meta_sessionManager_finalize();
diff --git a/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h b/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h
index 17757d574e..cf741e0a61 100644
--- a/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h
+++ b/usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -530,6 +529,8 @@ 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;
extern object_to_be_freed_list_t obj_delay_freed;
diff --git a/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c b/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c
index 53249240b5..ec3b9ad70d 100644
--- a/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c
+++ b/usr/src/lib/pkcs11/libpkcs11/common/metaRand.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -62,7 +61,6 @@ meta_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
{
CK_RV rv;
meta_session_t *session;
- int fd;
ssize_t n;
if (pSeed == NULL || ulSeedLen == 0)
@@ -74,25 +72,33 @@ meta_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
return (rv);
REFRELEASE(session);
- while ((fd = open(RANDOM_DEVICE, O_WRONLY)) < 0) {
- if (errno != EINTR)
- break;
- }
- if (fd == -1) {
- if (errno == EACCES)
- return (CKR_RANDOM_SEED_NOT_SUPPORTED);
- else
- return (CKR_DEVICE_ERROR);
+ if (meta_urandom_seed_fd < 0) {
+ (void) pthread_mutex_lock(&initmutex);
+ /* Check again holding the mutex */
+ if (meta_urandom_seed_fd < 0) {
+ while ((meta_urandom_seed_fd = open(
+ RANDOM_DEVICE, O_WRONLY)) < 0) {
+ if (errno != EINTR)
+ break;
+ }
+ 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) fcntl(meta_urandom_seed_fd, F_SETFD,
+ FD_CLOEXEC);
+ }
+ (void) pthread_mutex_unlock(&initmutex);
}
- n = looping_write(fd, pSeed, ulSeedLen);
+ n = looping_write(meta_urandom_seed_fd, pSeed, ulSeedLen);
if (n <= 0) {
- (void) close(fd);
return (CKR_DEVICE_ERROR);
}
- (void) close(fd);
-
return (CKR_OK);
}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c
index 74ff7cd08f..6c5acf6875 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -123,6 +122,7 @@ 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;
@@ -340,6 +340,11 @@ finalize_common(boolean_t force, CK_VOID_PTR pReserved) {
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;
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c
index 1b4d8ea0d3..8b74d88048 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRand.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,7 +34,6 @@
#include "softRandom.h"
#include "softSession.h"
-
CK_RV
C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
{
@@ -43,7 +41,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;
- int fd;
long nwrite;
if (!softtoken_initialized)
@@ -60,25 +57,34 @@ C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
return (CKR_ARGUMENTS_BAD);
}
- while ((fd = open(DEV_URANDOM, O_WRONLY)) < 0) {
- if (errno != EINTR)
- break;
- }
- if (fd == -1) {
- if (errno == EACCES)
- return (CKR_RANDOM_SEED_NOT_SUPPORTED);
- return (CKR_DEVICE_ERROR);
+ if (soft_urandom_seed_fd < 0) {
+ (void) pthread_mutex_lock(&soft_giant_mutex);
+ /* Check again holding the mutex */
+ if (soft_urandom_seed_fd < 0) {
+ while ((soft_urandom_seed_fd = open(DEV_URANDOM,
+ O_WRONLY)) < 0) {
+ if (errno != EINTR)
+ break;
+ }
+ 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) fcntl(soft_urandom_seed_fd, F_SETFD,
+ FD_CLOEXEC);
+ }
+ (void) pthread_mutex_unlock(&soft_giant_mutex);
}
- (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
- nwrite = looping_write(fd, pSeed, ulSeedLen);
+ nwrite = looping_write(soft_urandom_seed_fd, pSeed, ulSeedLen);
if (nwrite <= 0) {
- (void) close(fd);
return (CKR_DEVICE_ERROR);
}
- (void) close(fd);
-
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 a0b25cb3e5..6f0f5ce440 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,6 +38,7 @@ extern "C" {
#include "softSession.h"
extern int soft_urandom_fd;
+extern int soft_urandom_seed_fd;
extern int soft_random_fd;
#define DEV_URANDOM "/dev/urandom"
diff --git a/usr/src/uts/common/crypto/api/kcf_random.c b/usr/src/uts/common/crypto/api/kcf_random.c
index 0271a7ad11..ee133d2702 100644
--- a/usr/src/uts/common/crypto/api/kcf_random.c
+++ b/usr/src/uts/common/crypto/api/kcf_random.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -185,15 +185,13 @@ kcf_rngprov_check(void)
* its random number generator.
*/
static void
-rngprov_seed(uint8_t *buf, int len)
+rngprov_seed(uint8_t *buf, int len, uint_t entropy_est, uint32_t flags)
{
kcf_provider_desc_t *pd = NULL;
- kcf_req_params_t params;
if (kcf_get_sw_prov(rngmech_type, &pd, B_FALSE) == CRYPTO_SUCCESS) {
- KCF_WRAP_RANDOM_OPS_PARAMS(&params, KCF_OP_RANDOM_SEED,
- pd->pd_sid, buf, len);
- (void) kcf_submit_request(pd, NULL, NULL, &params, B_FALSE);
+ (void) KCF_PROV_SEED_RANDOM(pd, pd->pd_sid, buf, len,
+ entropy_est, flags, NULL);
KCF_PROV_REFRELE(pd);
}
}
@@ -249,7 +247,7 @@ rngprov_getbytes(uint8_t *ptr, size_t need, boolean_t from_user_api,
}
KCF_WRAP_RANDOM_OPS_PARAMS(&params, KCF_OP_RANDOM_GENERATE,
- pd->pd_sid, ptr, need);
+ pd->pd_sid, ptr, need, 0, 0);
rv = kcf_submit_request(pd, NULL, NULL, &params, B_FALSE);
ASSERT(rv != CRYPTO_QUEUED);
@@ -346,7 +344,7 @@ rngprov_getbytes_nblk(uint8_t *ptr, size_t len, boolean_t from_user_api)
req.cr_callback_arg = rndbuf;
KCF_WRAP_RANDOM_OPS_PARAMS(&params,
KCF_OP_RANDOM_GENERATE,
- pd->pd_sid, rndbuf, MINEXTRACTBYTES);
+ pd->pd_sid, rndbuf, MINEXTRACTBYTES, 0, 0);
break;
case CRYPTO_SW_PROVIDER:
@@ -357,7 +355,7 @@ rngprov_getbytes_nblk(uint8_t *ptr, size_t len, boolean_t from_user_api)
*/
KCF_WRAP_RANDOM_OPS_PARAMS(&params,
KCF_OP_RANDOM_GENERATE,
- pd->pd_sid, ptr, len);
+ pd->pd_sid, ptr, len, 0, 0);
break;
}
@@ -999,14 +997,28 @@ rndc_getbytes(uint8_t *ptr, size_t len)
* Mix the supplied bytes into the entropy pool of a kCF
* RNG provider.
*/
-/* ARGSUSED */
int
-random_add_entropy(uint8_t *ptr, size_t len, uint16_t entropy_est)
+random_add_pseudo_entropy(uint8_t *ptr, size_t len, uint_t entropy_est)
+{
+ if (len < 1)
+ return (-1);
+
+ rngprov_seed(ptr, len, entropy_est, 0);
+
+ return (0);
+}
+
+/*
+ * Mix the supplied bytes into the entropy pool of a kCF
+ * RNG provider. Mix immediately.
+ */
+int
+random_add_entropy(uint8_t *ptr, size_t len, uint_t entropy_est)
{
if (len < 1)
return (-1);
- rngprov_seed(ptr, len);
+ rngprov_seed(ptr, len, entropy_est, CRYPTO_SEED_NOW);
return (0);
}
diff --git a/usr/src/uts/common/crypto/core/kcf_callprov.c b/usr/src/uts/common/crypto/core/kcf_callprov.c
index 2f51ae27fd..de2268dcc2 100644
--- a/usr/src/uts/common/crypto/core/kcf_callprov.c
+++ b/usr/src/uts/common/crypto/core/kcf_callprov.c
@@ -1270,7 +1270,8 @@ common_submit_request(kcf_provider_desc_t *pd, crypto_ctx_t *ctx,
switch (optype) {
case KCF_OP_RANDOM_SEED:
err = KCF_PROV_SEED_RANDOM(pd, rops->rn_sid,
- rops->rn_buf, rops->rn_buflen, rhndl);
+ rops->rn_buf, rops->rn_buflen, rops->rn_entropy_est,
+ rops->rn_flags, rhndl);
break;
case KCF_OP_RANDOM_GENERATE:
diff --git a/usr/src/uts/common/crypto/io/crypto.c b/usr/src/uts/common/crypto/io/crypto.c
index 491e318ca9..047c5f4b0e 100644
--- a/usr/src/uts/common/crypto/io/crypto.c
+++ b/usr/src/uts/common/crypto/io/crypto.c
@@ -4086,7 +4086,8 @@ seed_random(dev_t dev, caddr_t arg, int mode, int *rval)
}
KCF_WRAP_RANDOM_OPS_PARAMS(&params, KCF_OP_RANDOM_SEED,
- sp->sd_provider_session->ps_session, seed_buffer, seed_len);
+ sp->sd_provider_session->ps_session, seed_buffer, seed_len, 0,
+ CRYPTO_SEED_NOW);
rv = kcf_submit_request(real_provider, NULL, NULL, &params, B_FALSE);
@@ -4176,7 +4177,7 @@ generate_random(dev_t dev, caddr_t arg, int mode, int *rval)
}
KCF_WRAP_RANDOM_OPS_PARAMS(&params, KCF_OP_RANDOM_GENERATE,
- sp->sd_provider_session->ps_session, buffer, len);
+ sp->sd_provider_session->ps_session, buffer, len, 0, 0);
rv = kcf_submit_request(real_provider, NULL, NULL, &params, B_FALSE);
diff --git a/usr/src/uts/common/crypto/io/dprov.c b/usr/src/uts/common/crypto/io/dprov.c
index 5bf0be0e90..7f36913563 100644
--- a/usr/src/uts/common/crypto/io/dprov.c
+++ b/usr/src/uts/common/crypto/io/dprov.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -777,7 +776,7 @@ static crypto_dual_cipher_mac_ops_t dprov_cipher_mac_ops = {
};
static int dprov_seed_random(crypto_provider_handle_t, crypto_session_id_t,
- uchar_t *, size_t, crypto_req_handle_t);
+ uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
static int dprov_generate_random(crypto_provider_handle_t, crypto_session_id_t,
uchar_t *, size_t, crypto_req_handle_t);
@@ -1272,6 +1271,8 @@ typedef struct dprov_random_req {
uchar_t *rr_buf;
size_t rr_len;
crypto_session_id_t rr_session_id;
+ uint_t rr_entropy_est;
+ uint32_t rr_flags;
} dprov_random_req_t;
/* for DPROV_REQ_SESSION requests */
@@ -1396,7 +1397,8 @@ static int dprov_cipher_mac_submit_req(dprov_req_type_t, dprov_state_t *,
crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, crypto_key_t *,
crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, int);
static int dprov_random_submit_req(dprov_req_type_t, dprov_state_t *,
- crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t);
+ crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t, uint_t,
+ uint32_t);
static int dprov_session_submit_req(dprov_req_type_t, dprov_state_t *,
crypto_req_handle_t, crypto_session_id_t *, crypto_session_id_t,
crypto_user_type_t, char *, size_t);
@@ -3384,7 +3386,8 @@ dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider,
static int
dprov_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid,
- uchar_t *buf, size_t len, crypto_req_handle_t req)
+ uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags,
+ crypto_req_handle_t req)
{
int error = CRYPTO_FAILED;
dprov_state_t *softc = (dprov_state_t *)provider;
@@ -3396,7 +3399,7 @@ dprov_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid,
instance));
error = dprov_random_submit_req(DPROV_REQ_RANDOM_SEED, softc,
- req, buf, len, sid);
+ req, buf, len, sid, entropy_est, flags);
DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: done err = 0x0%x\n",
instance, error));
@@ -3418,7 +3421,7 @@ dprov_generate_random(crypto_provider_handle_t provider,
instance));
error = dprov_random_submit_req(DPROV_REQ_RANDOM_GENERATE, softc,
- req, buf, len, sid);
+ req, buf, len, sid, 0, 0);
DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: done "
"err = 0x0%x\n", instance, error));
@@ -4548,7 +4551,7 @@ dprov_cipher_submit_req(dprov_req_type_t req_type,
static int
dprov_random_submit_req(dprov_req_type_t req_type,
dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len,
- crypto_session_id_t sid)
+ crypto_session_id_t sid, uint_t entropy_est, uint32_t flags)
{
dprov_req_t *taskq_req;
@@ -4559,6 +4562,8 @@ dprov_random_submit_req(dprov_req_type_t req_type,
taskq_req->dr_random_req.rr_buf = buf;
taskq_req->dr_random_req.rr_len = len;
taskq_req->dr_random_req.rr_session_id = sid;
+ taskq_req->dr_random_req.rr_entropy_est = entropy_est;
+ taskq_req->dr_random_req.rr_flags = flags;
return (dprov_taskq_dispatch(softc, taskq_req,
(task_func_t *)dprov_random_task, KM_NOSLEEP));
diff --git a/usr/src/uts/common/crypto/io/swrand.c b/usr/src/uts/common/crypto/io/swrand.c
index fc5543167d..63f30aa628 100644
--- a/usr/src/uts/common/crypto/io/swrand.c
+++ b/usr/src/uts/common/crypto/io/swrand.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -83,12 +82,17 @@ typedef struct physmem_entsrc_s {
} physmem_entsrc_t;
static uint32_t srndpool[RNDPOOLSIZE/4]; /* Pool of random bits */
+static uint32_t buffer[RNDPOOLSIZE/4]; /* entropy mixed in later */
+static int buffer_bytes; /* bytes written to buffer */
static uint32_t entropy_bits; /* pool's current amount of entropy */
static kmutex_t srndpool_lock; /* protects r/w accesses to the pool, */
/* and the global variables */
+static kmutex_t buffer_lock; /* protects r/w accesses to buffer */
static kcondvar_t srndpool_read_cv; /* serializes poll/read syscalls */
static int pindex; /* Global index for adding/extracting */
/* from the pool */
+static int bstart, bindex; /* Global vars for adding/extracting */
+ /* from the buffer */
static uint8_t leftover[HASHSIZE]; /* leftover output */
static int leftover_bytes; /* leftover length */
@@ -111,6 +115,7 @@ static void swrand_init();
static void swrand_schedule_timeout(void);
static int swrand_get_entropy(uint8_t *ptr, size_t len, boolean_t);
static void swrand_add_entropy(uint8_t *ptr, size_t len, uint16_t entropy_est);
+static void swrand_add_entropy_later(uint8_t *ptr, size_t len);
/* Dynamic Reconfiguration related declarations */
kphysm_setup_vector_t rnd_dr_callback_vec = {
@@ -146,7 +151,7 @@ static crypto_control_ops_t swrand_control_ops = {
};
static int swrand_seed_random(crypto_provider_handle_t, crypto_session_id_t,
- uchar_t *, size_t, crypto_req_handle_t);
+ uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
static int swrand_generate_random(crypto_provider_handle_t,
crypto_session_id_t, uchar_t *, size_t, crypto_req_handle_t);
@@ -201,11 +206,15 @@ _init(void)
}
mutex_init(&srndpool_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&buffer_lock, NULL, MUTEX_DEFAULT, NULL);
cv_init(&srndpool_read_cv, NULL, CV_DEFAULT, NULL);
entropy_bits = 0;
pindex = 0;
+ bindex = 0;
+ bstart = 0;
snum_waiters = 0;
leftover_bytes = 0;
+ buffer_bytes = 0;
/*
* Initialize the pool using
@@ -224,6 +233,7 @@ _init(void)
if (physmem_ent_init(&entsrc) != 0) {
mutex_destroy(&srndpool_lock);
+ mutex_destroy(&buffer_lock);
cv_destroy(&srndpool_read_cv);
(void) crypto_unregister_provider(swrand_prov_handle);
return (ENOMEM);
@@ -231,6 +241,7 @@ _init(void)
if ((ret = mod_install(&modlinkage)) != 0) {
mutex_destroy(&srndpool_lock);
+ mutex_destroy(&buffer_lock);
cv_destroy(&srndpool_read_cv);
physmem_ent_fini(&entsrc);
(void) crypto_unregister_provider(swrand_prov_handle);
@@ -267,10 +278,14 @@ swrand_provider_status(crypto_provider_handle_t provider, uint_t *status)
/* ARGSUSED */
static int
swrand_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid,
- uchar_t *buf, size_t len, crypto_req_handle_t req)
+ uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags,
+ crypto_req_handle_t req)
{
/* The entropy estimate is always 0 in this path */
- swrand_add_entropy(buf, len, 0);
+ if (flags & CRYPTO_SEED_NOW)
+ swrand_add_entropy(buf, len, 0);
+ else
+ swrand_add_entropy_later(buf, len);
return (CRYPTO_SUCCESS);
}
@@ -386,6 +401,15 @@ swrand_get_entropy(uint8_t *ptr, size_t len, boolean_t nonblock)
return (0);
}
+#define SWRAND_ADD_BYTES(ptr, len, i, pool) \
+ ASSERT((ptr) != NULL && (len) > 0); \
+ BUMP_SWRAND_STATS(ss_bytesIn, (len)); \
+ while ((len)--) { \
+ (pool)[(i)++] ^= *(ptr); \
+ (ptr)++; \
+ (i) &= (RNDPOOLSIZE - 1); \
+ }
+
/* Write some more user-provided entropy to the pool */
static void
swrand_add_bytes(uint8_t *ptr, size_t len)
@@ -393,16 +417,25 @@ swrand_add_bytes(uint8_t *ptr, size_t len)
uint8_t *pool = (uint8_t *)srndpool;
ASSERT(MUTEX_HELD(&srndpool_lock));
- ASSERT(ptr != NULL && len > 0);
+ SWRAND_ADD_BYTES(ptr, len, pindex, pool);
+}
- BUMP_SWRAND_STATS(ss_bytesIn, len);
- while (len--) {
- pool[pindex++] ^= *ptr;
- ptr++;
- pindex &= (RNDPOOLSIZE - 1);
- }
+/*
+ * Add bytes to buffer. Adding the buffer to the random pool
+ * is deferred until the random pool is mixed.
+ */
+static void
+swrand_add_bytes_later(uint8_t *ptr, size_t len)
+{
+ uint8_t *pool = (uint8_t *)buffer;
+
+ ASSERT(MUTEX_HELD(&buffer_lock));
+ SWRAND_ADD_BYTES(ptr, len, bindex, pool);
+ buffer_bytes += len;
}
+#undef SWRAND_ADD_BYTES
+
/* Mix the pool */
static void
swrand_mix_pool(uint16_t entropy_est)
@@ -411,9 +444,32 @@ swrand_mix_pool(uint16_t entropy_est)
HASH_CTX hashctx;
uint8_t digest[HASHSIZE];
uint8_t *pool = (uint8_t *)srndpool;
+ uint8_t *bp = (uint8_t *)buffer;
ASSERT(MUTEX_HELD(&srndpool_lock));
+ /* add deferred bytes */
+ mutex_enter(&buffer_lock);
+ if (buffer_bytes > 0) {
+ if (buffer_bytes >= RNDPOOLSIZE) {
+ for (i = 0; i < RNDPOOLSIZE/4; i++) {
+ srndpool[i] ^= buffer[i];
+ buffer[i] = 0;
+ }
+ bstart = bindex = 0;
+ } else {
+ for (i = 0; i < buffer_bytes; i++) {
+ pool[pindex++] ^= bp[bstart];
+ bp[bstart++] = 0;
+ pindex &= (RNDPOOLSIZE - 1);
+ bstart &= (RNDPOOLSIZE - 1);
+ }
+ ASSERT(bstart == bindex);
+ }
+ buffer_bytes = 0;
+ }
+ mutex_exit(&buffer_lock);
+
start = 0;
for (i = 0; i < RNDPOOLSIZE/HASHSIZE + 1; i++) {
HashInit(&hashctx);
@@ -449,6 +505,14 @@ swrand_mix_pool(uint16_t entropy_est)
}
static void
+swrand_add_entropy_later(uint8_t *ptr, size_t len)
+{
+ mutex_enter(&buffer_lock);
+ swrand_add_bytes_later(ptr, len);
+ mutex_exit(&buffer_lock);
+}
+
+static void
swrand_add_entropy(uint8_t *ptr, size_t len, uint16_t entropy_est)
{
mutex_enter(&srndpool_lock);
diff --git a/usr/src/uts/common/io/random.c b/usr/src/uts/common/io/random.c
index d1d335ee7f..9d3a7d8b56 100644
--- a/usr/src/uts/common/io/random.c
+++ b/usr/src/uts/common/io/random.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,7 +18,7 @@
*
* CDDL HEADER END
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -278,6 +277,9 @@ rnd_write(dev_t dev, struct uio *uiop, cred_t *credp)
int error;
uint8_t buf[WRITEBUFSIZE];
size_t bytes;
+ minor_t devno;
+
+ devno = getminor(dev);
while (uiop->uio_resid > 0) {
bytes = min(sizeof (buf), uiop->uio_resid);
@@ -287,9 +289,19 @@ rnd_write(dev_t dev, struct uio *uiop, cred_t *credp)
if ((error = uiomove(buf, bytes, UIO_WRITE, uiop)) != 0)
return (error);
- /* Add bytes to the pool but don't change the entropy level */
- if ((error = random_add_entropy(buf, bytes, 0)) != 0)
- return (error);
+ switch (devno) {
+ case DEVRANDOM:
+ if ((error = random_add_entropy(buf, bytes, 0)) != 0)
+ return (error);
+ break;
+ case DEVURANDOM:
+ if ((error = random_add_pseudo_entropy(buf, bytes,
+ 0)) != 0)
+ return (error);
+ break;
+ default:
+ return (ENXIO);
+ }
}
return (0);
diff --git a/usr/src/uts/common/sys/crypto/impl.h b/usr/src/uts/common/sys/crypto/impl.h
index b240dc0a5a..7ae06f4eda 100644
--- a/usr/src/uts/common/sys/crypto/impl.h
+++ b/usr/src/uts/common/sys/crypto/impl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -954,10 +953,10 @@ extern rctl_hndl_t rc_project_crypto_mem;
* Wrappers for crypto_random_number_ops(9S) entry points.
*/
-#define KCF_PROV_SEED_RANDOM(pd, session, buf, len, req) ( \
+#define KCF_PROV_SEED_RANDOM(pd, session, buf, len, est, flags, req) ( \
(KCF_PROV_RANDOM_OPS(pd) && KCF_PROV_RANDOM_OPS(pd)->seed_random) ? \
KCF_PROV_RANDOM_OPS(pd)->seed_random((pd)->pd_prov_handle, \
- session, buf, len, req) : CRYPTO_NOT_SUPPORTED)
+ session, buf, len, est, flags, req) : CRYPTO_NOT_SUPPORTED)
#define KCF_PROV_GENERATE_RANDOM(pd, session, buf, len, req) ( \
(KCF_PROV_RANDOM_OPS(pd) && \
@@ -1249,6 +1248,7 @@ extern void kcf_rnd_init();
extern boolean_t kcf_rngprov_check(void);
extern int kcf_rnd_get_pseudo_bytes(uint8_t *, size_t);
extern int kcf_rnd_get_bytes(uint8_t *, size_t, boolean_t, boolean_t);
+extern int random_add_pseudo_entropy(uint8_t *, size_t, uint_t);
extern void kcf_rnd_chpoll(int, short *, struct pollhead **);
extern void kcf_rnd_schedule_timeout(boolean_t);
diff --git a/usr/src/uts/common/sys/crypto/ops_impl.h b/usr/src/uts/common/sys/crypto/ops_impl.h
index 5004c0396b..3552f50c17 100644
--- a/usr/src/uts/common/sys/crypto/ops_impl.h
+++ b/usr/src/uts/common/sys/crypto/ops_impl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -146,6 +145,8 @@ typedef struct kcf_random_number_ops_params {
crypto_session_id_t rn_sid;
uchar_t *rn_buf;
size_t rn_buflen;
+ uint_t rn_entropy_est;
+ uint32_t rn_flags;
} kcf_random_number_ops_params_t;
/*
@@ -476,7 +477,8 @@ typedef struct kcf_req_params {
cmops->md_decr_templ = _decr_templ; \
}
-#define KCF_WRAP_RANDOM_OPS_PARAMS(req, ftype, _sid, _buf, _buflen) { \
+#define KCF_WRAP_RANDOM_OPS_PARAMS(req, ftype, _sid, _buf, _buflen, \
+ _est, _flags) { \
kcf_random_number_ops_params_t *rops = \
&(req)->rp_u.random_number_params; \
\
@@ -485,6 +487,8 @@ typedef struct kcf_req_params {
rops->rn_sid = _sid; \
rops->rn_buf = _buf; \
rops->rn_buflen = _buflen; \
+ rops->rn_entropy_est = _est; \
+ rops->rn_flags = _flags; \
}
#define KCF_WRAP_SESSION_OPS_PARAMS(req, ftype, _sid_ptr, _sid, \
diff --git a/usr/src/uts/common/sys/crypto/spi.h b/usr/src/uts/common/sys/crypto/spi.h
index e06f260d02..3022cf1d01 100644
--- a/usr/src/uts/common/sys/crypto/spi.h
+++ b/usr/src/uts/common/sys/crypto/spi.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -386,12 +385,17 @@ typedef struct crypto_dual_cipher_mac_ops {
*/
typedef struct crypto_random_number_ops {
int (*seed_random)(crypto_provider_handle_t, crypto_session_id_t,
- uchar_t *, size_t, crypto_req_handle_t);
+ uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
int (*generate_random)(crypto_provider_handle_t, crypto_session_id_t,
uchar_t *, size_t, crypto_req_handle_t);
} crypto_random_number_ops_t;
/*
+ * Flag values for seed_random.
+ */
+#define CRYPTO_SEED_NOW 0x00000001
+
+/*
* The crypto_session_ops structure contains pointers to session
* operations for cryptographic providers. It is passed through
* the crypto_ops(9S) structure when providers register with the
diff --git a/usr/src/uts/common/sys/random.h b/usr/src/uts/common/sys/random.h
index 2628277964..919e50fb31 100644
--- a/usr/src/uts/common/sys/random.h
+++ b/usr/src/uts/common/sys/random.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -59,7 +58,7 @@ typedef struct swrand_stats {
#define BUMP_RND_STATS(x, v) atomic_add_64(&(rnd_stats).x, (v))
#define BUMP_SWRAND_STATS(x, v) atomic_add_64(&(swrand_stats).x, (v))
-extern int random_add_entropy(uint8_t *, size_t, uint16_t);
+extern int random_add_entropy(uint8_t *, size_t, uint_t);
extern int random_get_bytes(uint8_t *, size_t);
extern int random_get_pseudo_bytes(uint8_t *, size_t);