Move substantive part of rnd_ioctl to kern_rndq.c.
This commit is contained in:
parent
2ade1483d8
commit
e75aac8fa3
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rndpseudo.c,v 1.30 2015/04/14 12:27:02 riastradh Exp $ */
|
||||
/* $NetBSD: rndpseudo.c,v 1.31 2015/04/14 12:51:30 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2013 The NetBSD Foundation, Inc.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.30 2015/04/14 12:27:02 riastradh Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.31 2015/04/14 12:51:30 riastradh Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_compat_netbsd.h"
|
||||
|
@ -63,9 +63,6 @@ __KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.30 2015/04/14 12:27:02 riastradh Exp
|
|||
#include <sys/rnd.h>
|
||||
#include <sys/rndpool.h>
|
||||
#include <sys/rndsource.h>
|
||||
#ifdef COMPAT_50
|
||||
#include <compat/sys/rnd.h>
|
||||
#endif
|
||||
|
||||
#include <dev/rnd_private.h>
|
||||
|
||||
|
@ -498,322 +495,17 @@ rnd_write(struct file *fp, off_t *offp, struct uio *uio,
|
|||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
krndsource_to_rndsource(krndsource_t *kr, rndsource_t *r)
|
||||
{
|
||||
memset(r, 0, sizeof(*r));
|
||||
strlcpy(r->name, kr->name, sizeof(r->name));
|
||||
r->total = kr->total;
|
||||
r->type = kr->type;
|
||||
r->flags = kr->flags;
|
||||
}
|
||||
|
||||
static void
|
||||
krndsource_to_rndsource_est(krndsource_t *kr, rndsource_est_t *re)
|
||||
{
|
||||
memset(re, 0, sizeof(*re));
|
||||
krndsource_to_rndsource(kr, &re->rt);
|
||||
re->dt_samples = kr->time_delta.insamples;
|
||||
re->dt_total = kr->time_delta.outbits;
|
||||
re->dv_samples = kr->value_delta.insamples;
|
||||
re->dv_total = kr->value_delta.outbits;
|
||||
}
|
||||
|
||||
static void
|
||||
krs_setflags(krndsource_t *kr, uint32_t flags, uint32_t mask)
|
||||
{
|
||||
uint32_t oflags = kr->flags;
|
||||
|
||||
kr->flags &= ~mask;
|
||||
kr->flags |= (flags & mask);
|
||||
|
||||
if (oflags & RND_FLAG_HASENABLE &&
|
||||
((oflags & RND_FLAG_NO_COLLECT) != (flags & RND_FLAG_NO_COLLECT))) {
|
||||
kr->enable(kr, !(flags & RND_FLAG_NO_COLLECT));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rnd_ioctl(struct file *fp, u_long cmd, void *addr)
|
||||
{
|
||||
krndsource_t *kr;
|
||||
rndstat_t *rst;
|
||||
rndstat_name_t *rstnm;
|
||||
rndstat_est_t *rset;
|
||||
rndstat_est_name_t *rsetnm;
|
||||
rndctl_t *rctl;
|
||||
rnddata_t *rnddata;
|
||||
uint32_t count, start;
|
||||
int ret = 0;
|
||||
int estimate_ok = 0, estimate = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case FIONBIO:
|
||||
case FIOASYNC:
|
||||
case RNDGETENTCNT:
|
||||
break;
|
||||
|
||||
case RNDGETPOOLSTAT:
|
||||
case RNDGETSRCNUM:
|
||||
case RNDGETSRCNAME:
|
||||
case RNDGETESTNUM:
|
||||
case RNDGETESTNAME:
|
||||
ret = kauth_authorize_device(curlwp->l_cred,
|
||||
KAUTH_DEVICE_RND_GETPRIV, NULL, NULL, NULL, NULL);
|
||||
if (ret)
|
||||
return (ret);
|
||||
break;
|
||||
|
||||
case RNDCTL:
|
||||
ret = kauth_authorize_device(curlwp->l_cred,
|
||||
KAUTH_DEVICE_RND_SETPRIV, NULL, NULL, NULL, NULL);
|
||||
if (ret)
|
||||
return (ret);
|
||||
break;
|
||||
|
||||
case RNDADDDATA:
|
||||
ret = kauth_authorize_device(curlwp->l_cred,
|
||||
KAUTH_DEVICE_RND_ADDDATA, NULL, NULL, NULL, NULL);
|
||||
if (ret)
|
||||
return (ret);
|
||||
estimate_ok = !kauth_authorize_device(curlwp->l_cred,
|
||||
KAUTH_DEVICE_RND_ADDDATA_ESTIMATE, NULL, NULL, NULL, NULL);
|
||||
break;
|
||||
|
||||
return 0;
|
||||
default:
|
||||
#ifdef COMPAT_50
|
||||
return compat_50_rnd_ioctl(fp, cmd, addr);
|
||||
#else
|
||||
return ENOTTY;
|
||||
#endif
|
||||
return rnd_system_ioctl(fp, cmd, addr);
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
/*
|
||||
* Handled in upper layer really, but we have to return zero
|
||||
* for it to be accepted by the upper layer.
|
||||
*/
|
||||
case FIONBIO:
|
||||
case FIOASYNC:
|
||||
break;
|
||||
|
||||
case RNDGETENTCNT:
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
*(uint32_t *)addr = rndpool_get_entropy_count(&rnd_pool);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
break;
|
||||
|
||||
case RNDGETPOOLSTAT:
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rndpool_get_stats(&rnd_pool, addr, sizeof(rndpoolstat_t));
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
break;
|
||||
|
||||
case RNDGETSRCNUM:
|
||||
rst = (rndstat_t *)addr;
|
||||
|
||||
if (rst->count == 0)
|
||||
break;
|
||||
|
||||
if (rst->count > RND_MAXSTATCOUNT)
|
||||
return (EINVAL);
|
||||
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
/*
|
||||
* Find the starting source by running through the
|
||||
* list of sources.
|
||||
*/
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
start = rst->start;
|
||||
while (kr != NULL && start >= 1) {
|
||||
kr = LIST_NEXT(kr, list);
|
||||
start--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return up to as many structures as the user asked
|
||||
* for. If we run out of sources, a count of zero
|
||||
* will be returned, without an error.
|
||||
*/
|
||||
for (count = 0; count < rst->count && kr != NULL; count++) {
|
||||
krndsource_to_rndsource(kr, &rst->source[count]);
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
|
||||
rst->count = count;
|
||||
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
break;
|
||||
|
||||
case RNDGETESTNUM:
|
||||
rset = (rndstat_est_t *)addr;
|
||||
|
||||
if (rset->count == 0)
|
||||
break;
|
||||
|
||||
if (rset->count > RND_MAXSTATCOUNT)
|
||||
return (EINVAL);
|
||||
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
/*
|
||||
* Find the starting source by running through the
|
||||
* list of sources.
|
||||
*/
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
start = rset->start;
|
||||
while (kr != NULL && start > 1) {
|
||||
kr = LIST_NEXT(kr, list);
|
||||
start--;
|
||||
}
|
||||
|
||||
/* Return up to as many structures as the user asked
|
||||
* for. If we run out of sources, a count of zero
|
||||
* will be returned, without an error.
|
||||
*/
|
||||
for (count = 0; count < rset->count && kr != NULL; count++) {
|
||||
krndsource_to_rndsource_est(kr, &rset->source[count]);
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
|
||||
rset->count = count;
|
||||
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
break;
|
||||
|
||||
case RNDGETSRCNAME:
|
||||
/*
|
||||
* Scan through the list, trying to find the name.
|
||||
*/
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rstnm = (rndstat_name_t *)addr;
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
while (kr != NULL) {
|
||||
if (strncmp(kr->name, rstnm->name,
|
||||
MIN(sizeof(kr->name),
|
||||
sizeof(rstnm->name))) == 0) {
|
||||
krndsource_to_rndsource(kr, &rstnm->source);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
return (0);
|
||||
}
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
|
||||
ret = ENOENT; /* name not found */
|
||||
|
||||
break;
|
||||
|
||||
case RNDGETESTNAME:
|
||||
/*
|
||||
* Scan through the list, trying to find the name.
|
||||
*/
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rsetnm = (rndstat_est_name_t *)addr;
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
while (kr != NULL) {
|
||||
if (strncmp(kr->name, rsetnm->name,
|
||||
MIN(sizeof(kr->name),
|
||||
sizeof(rsetnm->name))) == 0) {
|
||||
krndsource_to_rndsource_est(kr,
|
||||
&rsetnm->source);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
return (0);
|
||||
}
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
|
||||
ret = ENOENT; /* name not found */
|
||||
|
||||
break;
|
||||
|
||||
case RNDCTL:
|
||||
/*
|
||||
* Set flags to enable/disable entropy counting and/or
|
||||
* collection.
|
||||
*/
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rctl = (rndctl_t *)addr;
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
|
||||
/*
|
||||
* Flags set apply to all sources of this type.
|
||||
*/
|
||||
if (rctl->type != 0xff) {
|
||||
while (kr != NULL) {
|
||||
if (kr->type == rctl->type) {
|
||||
krs_setflags(kr,
|
||||
rctl->flags, rctl->mask);
|
||||
}
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* scan through the list, trying to find the name
|
||||
*/
|
||||
while (kr != NULL) {
|
||||
if (strncmp(kr->name, rctl->name,
|
||||
MIN(sizeof(kr->name),
|
||||
sizeof(rctl->name))) == 0) {
|
||||
krs_setflags(kr, rctl->flags, rctl->mask);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
return (0);
|
||||
}
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
ret = ENOENT; /* name not found */
|
||||
|
||||
break;
|
||||
|
||||
case RNDADDDATA:
|
||||
/*
|
||||
* Don't seed twice if our bootloader has
|
||||
* seed loading support.
|
||||
*/
|
||||
if (!boot_rsp) {
|
||||
rnddata = (rnddata_t *)addr;
|
||||
|
||||
if (rnddata->len > sizeof(rnddata->data))
|
||||
return EINVAL;
|
||||
|
||||
if (estimate_ok) {
|
||||
/*
|
||||
* Do not accept absurd entropy estimates, and
|
||||
* do not flood the pool with entropy such that
|
||||
* new samples are discarded henceforth.
|
||||
*/
|
||||
estimate = MIN((rnddata->len * NBBY) / 2,
|
||||
MIN(rnddata->entropy,
|
||||
RND_POOLBITS / 2));
|
||||
} else {
|
||||
estimate = 0;
|
||||
}
|
||||
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rndpool_add_data(&rnd_pool, rnddata->data,
|
||||
rnddata->len, estimate);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
|
||||
rnd_wakeup_readers();
|
||||
}
|
||||
#ifdef RND_VERBOSE
|
||||
else {
|
||||
printf("rnd: already seeded by boot loader\n");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
return ENOTTY;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_rndq.c,v 1.52 2015/04/14 12:35:44 riastradh Exp $ */
|
||||
/* $NetBSD: kern_rndq.c,v 1.53 2015/04/14 12:51:30 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2013 The NetBSD Foundation, Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.52 2015/04/14 12:35:44 riastradh Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.53 2015/04/14 12:51:30 riastradh Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/atomic.h>
|
||||
|
@ -60,6 +60,10 @@ __KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.52 2015/04/14 12:35:44 riastradh Exp
|
|||
|
||||
#include <dev/rnd_private.h>
|
||||
|
||||
#ifdef COMPAT_50
|
||||
#include <compat/sys/rnd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__HAVE_CPU_COUNTER)
|
||||
#include <machine/cpu_counter.h>
|
||||
#endif
|
||||
|
@ -1309,3 +1313,310 @@ rnd_seed(void *base, size_t len)
|
|||
rnd_printf_verbose("rnd: not ready, deferring seed feed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
krndsource_to_rndsource(krndsource_t *kr, rndsource_t *r)
|
||||
{
|
||||
memset(r, 0, sizeof(*r));
|
||||
strlcpy(r->name, kr->name, sizeof(r->name));
|
||||
r->total = kr->total;
|
||||
r->type = kr->type;
|
||||
r->flags = kr->flags;
|
||||
}
|
||||
|
||||
static void
|
||||
krndsource_to_rndsource_est(krndsource_t *kr, rndsource_est_t *re)
|
||||
{
|
||||
memset(re, 0, sizeof(*re));
|
||||
krndsource_to_rndsource(kr, &re->rt);
|
||||
re->dt_samples = kr->time_delta.insamples;
|
||||
re->dt_total = kr->time_delta.outbits;
|
||||
re->dv_samples = kr->value_delta.insamples;
|
||||
re->dv_total = kr->value_delta.outbits;
|
||||
}
|
||||
|
||||
static void
|
||||
krs_setflags(krndsource_t *kr, uint32_t flags, uint32_t mask)
|
||||
{
|
||||
uint32_t oflags = kr->flags;
|
||||
|
||||
kr->flags &= ~mask;
|
||||
kr->flags |= (flags & mask);
|
||||
|
||||
if (oflags & RND_FLAG_HASENABLE &&
|
||||
((oflags & RND_FLAG_NO_COLLECT) != (flags & RND_FLAG_NO_COLLECT))) {
|
||||
kr->enable(kr, !(flags & RND_FLAG_NO_COLLECT));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rnd_system_ioctl(struct file *fp, u_long cmd, void *addr)
|
||||
{
|
||||
krndsource_t *kr;
|
||||
rndstat_t *rst;
|
||||
rndstat_name_t *rstnm;
|
||||
rndstat_est_t *rset;
|
||||
rndstat_est_name_t *rsetnm;
|
||||
rndctl_t *rctl;
|
||||
rnddata_t *rnddata;
|
||||
uint32_t count, start;
|
||||
int ret = 0;
|
||||
int estimate_ok = 0, estimate = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case RNDGETENTCNT:
|
||||
break;
|
||||
|
||||
case RNDGETPOOLSTAT:
|
||||
case RNDGETSRCNUM:
|
||||
case RNDGETSRCNAME:
|
||||
case RNDGETESTNUM:
|
||||
case RNDGETESTNAME:
|
||||
ret = kauth_authorize_device(curlwp->l_cred,
|
||||
KAUTH_DEVICE_RND_GETPRIV, NULL, NULL, NULL, NULL);
|
||||
if (ret)
|
||||
return (ret);
|
||||
break;
|
||||
|
||||
case RNDCTL:
|
||||
ret = kauth_authorize_device(curlwp->l_cred,
|
||||
KAUTH_DEVICE_RND_SETPRIV, NULL, NULL, NULL, NULL);
|
||||
if (ret)
|
||||
return (ret);
|
||||
break;
|
||||
|
||||
case RNDADDDATA:
|
||||
ret = kauth_authorize_device(curlwp->l_cred,
|
||||
KAUTH_DEVICE_RND_ADDDATA, NULL, NULL, NULL, NULL);
|
||||
if (ret)
|
||||
return (ret);
|
||||
estimate_ok = !kauth_authorize_device(curlwp->l_cred,
|
||||
KAUTH_DEVICE_RND_ADDDATA_ESTIMATE, NULL, NULL, NULL, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef COMPAT_50
|
||||
return compat_50_rnd_ioctl(fp, cmd, addr);
|
||||
#else
|
||||
return ENOTTY;
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case RNDGETENTCNT:
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
*(uint32_t *)addr = rndpool_get_entropy_count(&rnd_pool);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
break;
|
||||
|
||||
case RNDGETPOOLSTAT:
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rndpool_get_stats(&rnd_pool, addr, sizeof(rndpoolstat_t));
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
break;
|
||||
|
||||
case RNDGETSRCNUM:
|
||||
rst = (rndstat_t *)addr;
|
||||
|
||||
if (rst->count == 0)
|
||||
break;
|
||||
|
||||
if (rst->count > RND_MAXSTATCOUNT)
|
||||
return (EINVAL);
|
||||
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
/*
|
||||
* Find the starting source by running through the
|
||||
* list of sources.
|
||||
*/
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
start = rst->start;
|
||||
while (kr != NULL && start >= 1) {
|
||||
kr = LIST_NEXT(kr, list);
|
||||
start--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return up to as many structures as the user asked
|
||||
* for. If we run out of sources, a count of zero
|
||||
* will be returned, without an error.
|
||||
*/
|
||||
for (count = 0; count < rst->count && kr != NULL; count++) {
|
||||
krndsource_to_rndsource(kr, &rst->source[count]);
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
|
||||
rst->count = count;
|
||||
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
break;
|
||||
|
||||
case RNDGETESTNUM:
|
||||
rset = (rndstat_est_t *)addr;
|
||||
|
||||
if (rset->count == 0)
|
||||
break;
|
||||
|
||||
if (rset->count > RND_MAXSTATCOUNT)
|
||||
return (EINVAL);
|
||||
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
/*
|
||||
* Find the starting source by running through the
|
||||
* list of sources.
|
||||
*/
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
start = rset->start;
|
||||
while (kr != NULL && start > 1) {
|
||||
kr = LIST_NEXT(kr, list);
|
||||
start--;
|
||||
}
|
||||
|
||||
/* Return up to as many structures as the user asked
|
||||
* for. If we run out of sources, a count of zero
|
||||
* will be returned, without an error.
|
||||
*/
|
||||
for (count = 0; count < rset->count && kr != NULL; count++) {
|
||||
krndsource_to_rndsource_est(kr, &rset->source[count]);
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
|
||||
rset->count = count;
|
||||
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
break;
|
||||
|
||||
case RNDGETSRCNAME:
|
||||
/*
|
||||
* Scan through the list, trying to find the name.
|
||||
*/
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rstnm = (rndstat_name_t *)addr;
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
while (kr != NULL) {
|
||||
if (strncmp(kr->name, rstnm->name,
|
||||
MIN(sizeof(kr->name),
|
||||
sizeof(rstnm->name))) == 0) {
|
||||
krndsource_to_rndsource(kr, &rstnm->source);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
return (0);
|
||||
}
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
|
||||
ret = ENOENT; /* name not found */
|
||||
|
||||
break;
|
||||
|
||||
case RNDGETESTNAME:
|
||||
/*
|
||||
* Scan through the list, trying to find the name.
|
||||
*/
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rsetnm = (rndstat_est_name_t *)addr;
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
while (kr != NULL) {
|
||||
if (strncmp(kr->name, rsetnm->name,
|
||||
MIN(sizeof(kr->name),
|
||||
sizeof(rsetnm->name))) == 0) {
|
||||
krndsource_to_rndsource_est(kr,
|
||||
&rsetnm->source);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
return (0);
|
||||
}
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
|
||||
ret = ENOENT; /* name not found */
|
||||
|
||||
break;
|
||||
|
||||
case RNDCTL:
|
||||
/*
|
||||
* Set flags to enable/disable entropy counting and/or
|
||||
* collection.
|
||||
*/
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rctl = (rndctl_t *)addr;
|
||||
kr = LIST_FIRST(&rnd_sources);
|
||||
|
||||
/*
|
||||
* Flags set apply to all sources of this type.
|
||||
*/
|
||||
if (rctl->type != 0xff) {
|
||||
while (kr != NULL) {
|
||||
if (kr->type == rctl->type) {
|
||||
krs_setflags(kr,
|
||||
rctl->flags, rctl->mask);
|
||||
}
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* scan through the list, trying to find the name
|
||||
*/
|
||||
while (kr != NULL) {
|
||||
if (strncmp(kr->name, rctl->name,
|
||||
MIN(sizeof(kr->name),
|
||||
sizeof(rctl->name))) == 0) {
|
||||
krs_setflags(kr, rctl->flags, rctl->mask);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
return (0);
|
||||
}
|
||||
kr = LIST_NEXT(kr, list);
|
||||
}
|
||||
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
ret = ENOENT; /* name not found */
|
||||
|
||||
break;
|
||||
|
||||
case RNDADDDATA:
|
||||
/*
|
||||
* Don't seed twice if our bootloader has
|
||||
* seed loading support.
|
||||
*/
|
||||
if (!boot_rsp) {
|
||||
rnddata = (rnddata_t *)addr;
|
||||
|
||||
if (rnddata->len > sizeof(rnddata->data))
|
||||
return EINVAL;
|
||||
|
||||
if (estimate_ok) {
|
||||
/*
|
||||
* Do not accept absurd entropy estimates, and
|
||||
* do not flood the pool with entropy such that
|
||||
* new samples are discarded henceforth.
|
||||
*/
|
||||
estimate = MIN((rnddata->len * NBBY) / 2,
|
||||
MIN(rnddata->entropy,
|
||||
RND_POOLBITS / 2));
|
||||
} else {
|
||||
estimate = 0;
|
||||
}
|
||||
|
||||
mutex_spin_enter(&rndpool_mtx);
|
||||
rndpool_add_data(&rnd_pool, rnddata->data,
|
||||
rnddata->len, estimate);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
|
||||
rnd_wakeup_readers();
|
||||
}
|
||||
#ifdef RND_VERBOSE
|
||||
else {
|
||||
printf("rnd: already seeded by boot loader\n");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
return ENOTTY;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rnd.h,v 1.48 2015/04/13 22:52:52 riastradh Exp $ */
|
||||
/* $NetBSD: rnd.h,v 1.49 2015/04/14 12:51:30 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
|
@ -35,12 +35,17 @@
|
|||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct file;
|
||||
|
||||
#define RND_DEV_RANDOM 0 /* minor for blocking until unpredictable */
|
||||
#define RND_DEV_URANDOM 1 /* minor for randomly generating data */
|
||||
|
||||
void rnd_init(void);
|
||||
void rnd_init_softint(void);
|
||||
void rnd_seed(void *, size_t);
|
||||
int rnd_system_ioctl(struct file *, u_long, void *);
|
||||
|
||||
extern int rnd_initial_entropy;
|
||||
|
||||
|
|
Loading…
Reference in New Issue