#include <sys/types.h>
#include <sys/errno.h>
#include <sys/systm.h>
#include <sys/random.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/sysmacros.h>
#include <sys/random.h>
#define MAXRANDBYTES 1024
#define MAXURANDBYTES INT_MAX
ssize_t
getrandom(void *bufp, size_t buflen, unsigned int flags)
{
int out = 0;
uint8_t rbytes[128];
uint8_t *buf = bufp;
if (flags & ~(GRND_NONBLOCK | GRND_RANDOM))
return (set_errno(EINVAL));
if ((flags & GRND_RANDOM) && buflen > MAXRANDBYTES) {
buflen = MAXRANDBYTES;
} else if (buflen > MAXURANDBYTES) {
buflen = MAXURANDBYTES;
}
while (out < buflen) {
int err;
size_t len = MIN(sizeof (rbytes), buflen - out);
if (flags & GRND_RANDOM) {
if (flags & GRND_NONBLOCK)
err = random_get_bytes(rbytes, len);
else
err = random_get_blocking_bytes(rbytes, len);
} else {
err = random_get_pseudo_bytes(rbytes, len);
}
if (err == 0) {
if (ddi_copyout(rbytes, buf + out, len, 0) != 0)
return (set_errno(EFAULT));
out += len;
} else if (err == EAGAIN && out > 0) {
break;
} else {
return (set_errno(err));
}
}
return (out);
}