diff options
author | krishna <none@none> | 2006-11-11 21:39:34 -0800 |
---|---|---|
committer | krishna <none@none> | 2006-11-11 21:39:34 -0800 |
commit | f317a3a3712d9b82387b437ac621db3733d8c804 (patch) | |
tree | e200b5e95a7ef6ff466317efee22cc1f0b2d6a66 /usr/src | |
parent | c92ff65068cd791405fb72f945470ff128896dfb (diff) | |
download | illumos-joyent-f317a3a3712d9b82387b437ac621db3733d8c804.tar.gz |
6488985 kcf_submit_request() should handle the EMPTYQ case for a hardware provider
6478655 kcf should not log complaints as frequently as it does
6470608 /dev/urandom should provide data blocks larger then 1040 bytes
6478016 crypto_mechanism32_t should be available from sys/crypto/spi.h
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/crypto/api/kcf_random.c | 37 | ||||
-rw-r--r-- | usr/src/uts/common/crypto/core/kcf_sched.c | 54 | ||||
-rw-r--r-- | usr/src/uts/common/crypto/io/dca_dsa.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/crypto/io/dca_rsa.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/io/random.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/sys/crypto/common.h | 40 | ||||
-rw-r--r-- | usr/src/uts/common/sys/crypto/ioctl.h | 45 |
7 files changed, 105 insertions, 81 deletions
diff --git a/usr/src/uts/common/crypto/api/kcf_random.c b/usr/src/uts/common/crypto/api/kcf_random.c index ee133d2702..2ff8a80ac7 100644 --- a/usr/src/uts/common/crypto/api/kcf_random.c +++ b/usr/src/uts/common/crypto/api/kcf_random.c @@ -123,6 +123,8 @@ static struct pollhead rnd_pollhead; static timeout_id_t kcf_rndtimeout_id; static crypto_mech_type_t rngmech_type = CRYPTO_MECH_INVALID; rnd_stats_t rnd_stats; +static boolean_t rng_prov_found = B_TRUE; +static boolean_t rng_ok_to_log = B_TRUE; static void rndc_addbytes(uint8_t *, size_t); static void rndc_getbytes(uint8_t *ptr, size_t len); @@ -175,9 +177,18 @@ kcf_rngprov_check(void) if ((pd = kcf_get_mech_provider(rngmech_type, NULL, &rv, NULL, CRYPTO_FG_RANDOM, B_FALSE, 0)) != NULL) { KCF_PROV_REFRELE(pd); + /* + * We logged a warning once about no provider being available + * and now a provider became available. So, set the flag so + * that we can log again if the problem recurs. + */ + rng_ok_to_log = B_TRUE; + rng_prov_found = B_TRUE; return (B_TRUE); - } else + } else { + rng_prov_found = B_FALSE; return (B_FALSE); + } } /* @@ -276,7 +287,12 @@ try_next: kcf_free_triedlist(list); if (prov_cnt == 0) { /* no provider could be found. */ + rng_prov_found = B_FALSE; return (-1); + } else { + rng_prov_found = B_TRUE; + /* See comments in kcf_rngprov_check() */ + rng_ok_to_log = B_TRUE; } return (total_bytes); @@ -416,7 +432,12 @@ try_next: } if (prov_cnt == 0) { /* no provider could be found. */ + rng_prov_found = B_FALSE; return (-1); + } else { + rng_prov_found = B_TRUE; + /* See comments in kcf_rngprov_check() */ + rng_ok_to_log = B_TRUE; } return (total_bytes); @@ -429,10 +450,7 @@ rngprov_task(void *arg) uchar_t tbuf[MAXEXTRACTBYTES]; ASSERT(len <= MAXEXTRACTBYTES); - if (rngprov_getbytes(tbuf, len, B_FALSE, B_TRUE) == -1) { - cmn_err(CE_WARN, "No randomness provider enabled for " - "/dev/random. Use cryptoadm(1M) to enable a provider."); - } + (void) rngprov_getbytes(tbuf, len, B_FALSE, B_TRUE); } /* @@ -846,6 +864,12 @@ rnd_handler(void *arg) { int len = 0; + if (!rng_prov_found && rng_ok_to_log) { + cmn_err(CE_WARN, "No randomness provider enabled for " + "/dev/random. Use cryptoadm(1M) to enable a provider."); + rng_ok_to_log = B_FALSE; + } + if (num_waiters > 0) len = MAXEXTRACTBYTES; else if (rnbyte_cnt < RNDPOOLSIZE) @@ -854,9 +878,6 @@ rnd_handler(void *arg) if (len > 0) { (void) taskq_dispatch(system_taskq, rngprov_task, (void *)(uintptr_t)len, TQ_NOSLEEP); - } else if (!kcf_rngprov_check()) { - cmn_err(CE_WARN, "No randomness provider enabled for " - "/dev/random. Use cryptoadm(1M) to enable a provider."); } mutex_enter(&rndpool_lock); diff --git a/usr/src/uts/common/crypto/core/kcf_sched.c b/usr/src/uts/common/crypto/core/kcf_sched.c index 651327f252..aaf516d7a6 100644 --- a/usr/src/uts/common/crypto/core/kcf_sched.c +++ b/usr/src/uts/common/crypto/core/kcf_sched.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. */ @@ -578,6 +577,7 @@ kcf_resubmit_request(kcf_areq_node_t *areq) return (error); } +#define EMPTY_TASKQ(tq) ((tq)->tq_task.tqent_next == &(tq)->tq_task) /* * Routine called by both ioctl and k-api. The consumer should @@ -613,11 +613,6 @@ kcf_submit_request(kcf_provider_desc_t *pd, crypto_ctx_t *ctx, break; case CRYPTO_HW_PROVIDER: - /* - * Bug# 4715197 - * TO DO - Add the logic for EMPTYQ() case. - * For now, we always queue. - */ sreq = kmem_cache_alloc(kcf_sreq_cache, KM_SLEEP); sreq->sn_state = REQ_ALLOCATED; sreq->sn_rv = CRYPTO_FAILED; @@ -635,22 +630,33 @@ kcf_submit_request(kcf_provider_desc_t *pd, crypto_ctx_t *ctx, ASSERT(taskq != NULL); /* - * We can not tell from taskq_dispatch() return - * value if we exceeded maxalloc. Hence the check - * here. Since we are allowed to wait in the - * synchronous case, we wait for the taskq to - * become empty. + * Call the SPI directly if the taskq is empty and the + * provider is not busy, else dispatch to the taskq. + * Calling directly is fine as this is the synchronous + * case. This is unlike the asynchronous case where we + * must always dispatch to the taskq. */ - if (taskq->tq_nalloc >= crypto_taskq_maxalloc) { - taskq_wait(taskq); - } - if (taskq_dispatch(taskq, - process_req_hwp, sreq, TQ_SLEEP) == - (taskqid_t)0) { - error = CRYPTO_HOST_MEMORY; - KCF_PROV_REFRELE(sreq->sn_provider); - kmem_cache_free(kcf_sreq_cache, sreq); - goto done; + if (EMPTY_TASKQ(taskq) && + pd->pd_state == KCF_PROV_READY) { + process_req_hwp(sreq); + } else { + /* + * We can not tell from taskq_dispatch() return + * value if we exceeded maxalloc. Hence the + * check here. Since we are allowed to wait in + * the synchronous case, we wait for the taskq + * to become empty. + */ + if (taskq->tq_nalloc >= crypto_taskq_maxalloc) { + taskq_wait(taskq); + } + if (taskq_dispatch(taskq, process_req_hwp, + sreq, TQ_SLEEP) == (taskqid_t)0) { + error = CRYPTO_HOST_MEMORY; + KCF_PROV_REFRELE(sreq->sn_provider); + kmem_cache_free(kcf_sreq_cache, sreq); + goto done; + } } /* diff --git a/usr/src/uts/common/crypto/io/dca_dsa.c b/usr/src/uts/common/crypto/io/dca_dsa.c index 8e16346940..fae4bea536 100644 --- a/usr/src/uts/common/crypto/io/dca_dsa.c +++ b/usr/src/uts/common/crypto/io/dca_dsa.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -34,9 +34,7 @@ #include <sys/ddi.h> #include <sys/sunddi.h> #include <sys/kmem.h> -#include <sys/crypto/common.h> #include <sys/crypto/spi.h> -#include <sys/crypto/ioctl.h> #include <sys/crypto/dca.h> /* diff --git a/usr/src/uts/common/crypto/io/dca_rsa.c b/usr/src/uts/common/crypto/io/dca_rsa.c index 71ec60d82c..bcfe1ebdea 100644 --- a/usr/src/uts/common/crypto/io/dca_rsa.c +++ b/usr/src/uts/common/crypto/io/dca_rsa.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,9 +35,7 @@ #include <sys/sunddi.h> #include <sys/kmem.h> #include <sys/note.h> -#include <sys/crypto/common.h> #include <sys/crypto/spi.h> -#include <sys/crypto/ioctl.h> #include <sys/crypto/dca.h> diff --git a/usr/src/uts/common/io/random.c b/usr/src/uts/common/io/random.c index 9d3a7d8b56..1455625587 100644 --- a/usr/src/uts/common/io/random.c +++ b/usr/src/uts/common/io/random.c @@ -259,7 +259,7 @@ rnd_read(dev_t dev, struct uio *uiop, cred_t *credp) nbytes += len; - if (nbytes >= MAXRETBYTES) + if (devno == DEVRANDOM && nbytes >= MAXRETBYTES) break; } else if ((error == EAGAIN) && (nbytes > 0)) { diff --git a/usr/src/uts/common/sys/crypto/common.h b/usr/src/uts/common/sys/crypto/common.h index b4016684d6..d597a6b567 100644 --- a/usr/src/uts/common/sys/crypto/common.h +++ b/usr/src/uts/common/sys/crypto/common.h @@ -56,6 +56,16 @@ typedef struct crypto_mechanism { size_t cm_param_len; /* mech. parameter len */ } crypto_mechanism_t; +#ifdef _SYSCALL32 + +typedef struct crypto_mechanism32 { + crypto_mech_type_t cm_type; /* mechanism type */ + caddr32_t cm_param; /* mech. parameter */ + size32_t cm_param_len; /* mech. parameter len */ +} crypto_mechanism32_t; + +#endif /* _SYSCALL32 */ + /* * The measurement unit flag for a mechanism's minimum or maximum key size. * The unit are mechanism dependant. It can be in bits or in bytes. @@ -197,6 +207,36 @@ typedef struct crypto_key { } cku_data; /* Crypto Key union */ } crypto_key_t; +#ifdef _SYSCALL32 + +typedef struct crypto_object_attribute32 { + uint64_t oa_type; /* attribute type */ + caddr32_t oa_value; /* attribute value */ + ssize32_t oa_value_len; /* length of attribute value */ +} crypto_object_attribute32_t; + +typedef struct crypto_key32 { + crypto_key_format_t ck_format; /* format identifier */ + union { + /* for CRYPTO_KEY_RAW ck_format */ + struct { + uint32_t cku_v_length; /* # of bytes in ck_data */ + caddr32_t cku_v_data; /* ptr to key value */ + } cku_key_value; + + /* for CRYPTO_KEY_REFERENCE ck_format */ + crypto_object_id_t cku_key_id; /* reference to object key */ + + /* for CRYPTO_KEY_ATTR_LIST ck_format */ + struct { + uint32_t cku_a_count; /* number of attributes */ + caddr32_t cku_a_oattr; + } cku_key_attrs; + } cku_data; /* Crypto Key union */ +} crypto_key32_t; + +#endif /* _SYSCALL32 */ + #define ck_data cku_data.cku_key_value.cku_v_data #define ck_length cku_data.cku_key_value.cku_v_length #define ck_obj_id cku_data.cku_key_id diff --git a/usr/src/uts/common/sys/crypto/ioctl.h b/usr/src/uts/common/sys/crypto/ioctl.h index 1547a6c703..24389b3df3 100644 --- a/usr/src/uts/common/sys/crypto/ioctl.h +++ b/usr/src/uts/common/sys/crypto/ioctl.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. */ @@ -482,44 +481,6 @@ typedef struct crypto_decrypt_verify_update { #ifdef _KERNEL #ifdef _SYSCALL32 -/* crypto_mechanism_t is defined in <sys/crypto/common.h> */ - -typedef struct crypto_mechanism32 { - crypto_mech_type_t cm_type; /* mech. type */ - caddr32_t cm_param; /* mech. parameter */ - size32_t cm_param_len; /* mech. parameter len */ -} crypto_mechanism32_t; - -/* crypto_object_attribute_t is defined in <sys/crypto/common.h> */ - -typedef struct crypto_object_attribute32 { - uint64_t oa_type; /* attribute type */ - caddr32_t oa_value; /* attribute value */ - ssize32_t oa_value_len; /* length of attribute value */ -} crypto_object_attribute32_t; - -/* crypto_key_t is defined in <sys/crypto/common.h> */ - -typedef struct crypto_key32 { - crypto_key_format_t ck_format; /* format identifier */ - union { - /* for CRYPTO_KEY_RAW ck_format */ - struct { - uint32_t cku_v_length; /* # of bytes in ck_data */ - caddr32_t cku_v_data; /* ptr to key value */ - } cku_key_value; - - /* for CRYPTO_KEY_REFERENCE ck_format */ - crypto_object_id_t cku_key_id; /* reference to object key */ - - /* for CRYPTO_KEY_ATTR_LIST ck_format */ - struct { - uint32_t cku_a_count; /* number of attributes */ - caddr32_t cku_a_oattr; - } cku_key_attrs; - } cku_data; /* Crypto Key union */ -} crypto_key32_t; - typedef struct crypto_encrypt32 { uint32_t ce_return_value; crypto_session_id_t ce_session; |