2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright (c) 2015, Joyent, Inc.
17 * getrandom system call implementation
20 #include <sys/types.h>
21 #include <sys/errno.h>
22 #include <sys/systm.h>
23 #include <sys/random.h>
25 #include <sys/sunddi.h>
26 #include <sys/sysmacros.h>
28 #include <sys/random.h>
31 * Impose a maximum upper bound on the number of bytes that we'll read in one
32 * go, ala a read of /dev/random. For /dev/urandom, we clamp it based on our
33 * return value, because the system call returns an int, we can't handle more
36 #define MAXRANDBYTES 1024
37 #define MAXURANDBYTES INT_MAX
40 getrandom(void *bufp
, size_t buflen
, int flags
)
46 if (flags
& ~(GRND_NONBLOCK
| GRND_RANDOM
))
47 return (set_errno(EINVAL
));
49 if ((flags
& GRND_RANDOM
) && buflen
> MAXRANDBYTES
) {
50 buflen
= MAXRANDBYTES
;
51 } else if (buflen
> MAXURANDBYTES
) {
52 buflen
= MAXURANDBYTES
;
55 while (out
< buflen
) {
57 size_t len
= MIN(sizeof (rbytes
), buflen
- out
);
59 if (flags
& GRND_RANDOM
) {
60 if (flags
& GRND_NONBLOCK
)
61 err
= random_get_bytes(rbytes
, len
);
63 err
= random_get_blocking_bytes(rbytes
, len
);
65 err
= random_get_pseudo_bytes(rbytes
, len
);
69 if (ddi_copyout(rbytes
, buf
+ out
, len
, 0) != 0)
70 return (set_errno(EFAULT
));
72 } else if (err
== EAGAIN
&& out
> 0) {
75 return (set_errno(err
));