Remove GIANT from device random.

Submitted by:	ups
This commit is contained in:
Paul Saab 2005-12-20 21:41:52 +00:00
parent 13ae4dad3a
commit efbbe8fa79
6 changed files with 69 additions and 16 deletions

View File

@ -41,12 +41,13 @@ __FBSDID("$FreeBSD$");
#define CIPHER_BLOCK_SIZE 16
static void random_nehemiah_init(void);
static void random_nehemiah_deinit(void);
static int random_nehemiah_read(void *, int);
struct random_systat random_nehemiah = {
.ident = "Hardware, VIA Nehemiah",
.init = random_nehemiah_init,
.deinit = (random_deinit_func_t *)random_null_func,
.deinit = random_nehemiah_deinit,
.read = random_nehemiah_read,
.write = (random_write_func_t *)random_null_func,
.reseed = (random_reseed_func_t *)random_null_func,
@ -81,6 +82,8 @@ static uint8_t out[RANDOM_BLOCK_SIZE+7] __aligned(16);
static union VIA_ACE_CW acw __aligned(16);
static struct mtx random_nehemiah_mtx;
/* ARGSUSED */
static __inline size_t
VIA_RNG_store(void *buf)
@ -126,6 +129,14 @@ random_nehemiah_init(void)
{
acw.raw = 0ULL;
acw.field.round_count = 12;
mtx_init(&random_nehemiah_mtx, "random nehemiah", NULL, MTX_DEF);
}
void
random_nehemiah_deinit(void)
{
mtx_destroy(&random_nehemiah_mtx);
}
static int
@ -135,6 +146,8 @@ random_nehemiah_read(void *buf, int c)
size_t count, ret;
uint8_t *p;
mtx_lock(&random_nehemiah_mtx);
/* Get a random AES key */
count = 0;
p = key;
@ -174,5 +187,6 @@ random_nehemiah_read(void *buf, int c)
c = MIN(RANDOM_BLOCK_SIZE, c);
memcpy(buf, out, (size_t)c);
mtx_unlock(&random_nehemiah_mtx);
return (c);
}

View File

@ -61,7 +61,6 @@ static d_poll_t random_poll;
static struct cdevsw random_cdevsw = {
.d_version = D_VERSION,
.d_flags = D_NEEDGIANT,
.d_close = random_close,
.d_read = random_read,
.d_write = random_write,
@ -103,15 +102,8 @@ random_read(struct cdev *dev __unused, struct uio *uio, int flag)
void *random_buf;
/* Blocking logic */
while (!random_systat.seeded && !error) {
if (flag & O_NONBLOCK)
error = EWOULDBLOCK;
else {
printf("Entropy device is blocking.\n");
error = tsleep(&random_systat,
PUSER | PCATCH, "block", 0);
}
}
if (!random_systat.seeded)
error = (*random_systat.block)(flag);
/* The actual read */
if (!error) {
@ -181,7 +173,7 @@ random_poll(struct cdev *dev __unused, int events, struct thread *td)
if (random_systat.seeded)
revents = events & (POLLIN | POLLRDNORM);
else
selrecord(td, &random_systat.rsel);
revents = (*random_systat.poll) (events,td);
}
return (revents);
}

View File

@ -32,8 +32,10 @@
typedef void random_init_func_t(void);
typedef void random_deinit_func_t(void);
typedef int random_block_func_t(int);
typedef int random_read_func_t(void *, int);
typedef void random_write_func_t(void *, int);
typedef int random_poll_func_t(int, struct thread *);
typedef void random_reseed_func_t(void);
struct random_systat {
@ -42,8 +44,10 @@ struct random_systat {
int seeded;
random_init_func_t *init;
random_deinit_func_t *deinit;
random_block_func_t *block;
random_read_func_t *read;
random_write_func_t *write;
random_poll_func_t *poll;
random_reseed_func_t *reseed;
};

View File

@ -59,13 +59,17 @@ static void random_kthread(void *);
static void
random_harvest_internal(u_int64_t, const void *, u_int,
u_int, u_int, enum esource);
static int random_yarrow_poll(int event,struct thread *td);
static int random_yarrow_block(int flag);
struct random_systat random_yarrow = {
.ident = "Software, Yarrow",
.init = random_yarrow_init,
.deinit = random_yarrow_deinit,
.block = random_yarrow_block,
.read = random_yarrow_read,
.write = random_yarrow_write,
.poll = random_yarrow_poll,
.reseed = random_yarrow_reseed,
.seeded = 1,
};
@ -366,3 +370,41 @@ random_yarrow_unblock(void)
wakeup(&random_systat);
}
}
static int
random_yarrow_poll(int events, struct thread *td)
{
int revents = 0;
mtx_lock(&random_reseed_mtx);
if (random_systat.seeded)
revents = events & (POLLIN | POLLRDNORM);
else
selrecord(td, &random_systat.rsel);
mtx_unlock(&random_reseed_mtx);
return revents;
}
static int
random_yarrow_block(int flag)
{
int error = 0;
mtx_lock(&random_reseed_mtx);
/* Blocking logic */
while (random_systat.seeded && !error) {
if (flag & O_NONBLOCK)
error = EWOULDBLOCK;
else {
printf("Entropy device is blocking.\n");
error = msleep(&random_systat,
&random_reseed_mtx,
PUSER | PCATCH, "block", 0);
}
}
mtx_unlock(&random_reseed_mtx);
return error;
}

View File

@ -76,6 +76,7 @@ void random_yarrow_init_alg(struct sysctl_ctx_list *, struct sysctl_oid *);
void random_yarrow_deinit_alg(void);
extern struct random_systat random_yarrow;
extern struct mtx random_reseed_mtx;
/* If this was c++, this would be a template */
#define RANDOM_CHECK_UINT(name, min, max) \

View File

@ -57,7 +57,7 @@ static void generator_gate(void);
static void reseed(u_int);
/* The reseed thread mutex */
static struct mtx random_reseed_mtx;
struct mtx random_reseed_mtx;
/* Process a single stochastic event off the harvest queue */
void
@ -258,11 +258,11 @@ reseed(u_int fastslow)
/* 7. Dump to seed file */
/* XXX Not done here yet */
/* Release the reseed mutex */
mtx_unlock(&random_reseed_mtx);
/* Unblock the device if it was blocked due to being unseeded */
random_yarrow_unblock();
/* Release the reseed mutex */
mtx_unlock(&random_reseed_mtx);
}
/* Internal function to return processed entropy from the PRNG */