1*9d12795fSRobert Mustacchi /* 2*9d12795fSRobert Mustacchi * This file and its contents are supplied under the terms of the 3*9d12795fSRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0. 4*9d12795fSRobert Mustacchi * You may only use this file in accordance with the terms of version 5*9d12795fSRobert Mustacchi * 1.0 of the CDDL. 6*9d12795fSRobert Mustacchi * 7*9d12795fSRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this 8*9d12795fSRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at 9*9d12795fSRobert Mustacchi * http://www.illumos.org/license/CDDL. 10*9d12795fSRobert Mustacchi */ 11*9d12795fSRobert Mustacchi 12*9d12795fSRobert Mustacchi /* 13*9d12795fSRobert Mustacchi * Copyright (c) 2015, Joyent, Inc. 14*9d12795fSRobert Mustacchi */ 15*9d12795fSRobert Mustacchi 16*9d12795fSRobert Mustacchi /* 17*9d12795fSRobert Mustacchi * getrandom system call implementation 18*9d12795fSRobert Mustacchi */ 19*9d12795fSRobert Mustacchi 20*9d12795fSRobert Mustacchi #include <sys/types.h> 21*9d12795fSRobert Mustacchi #include <sys/errno.h> 22*9d12795fSRobert Mustacchi #include <sys/systm.h> 23*9d12795fSRobert Mustacchi #include <sys/random.h> 24*9d12795fSRobert Mustacchi #include <sys/ddi.h> 25*9d12795fSRobert Mustacchi #include <sys/sunddi.h> 26*9d12795fSRobert Mustacchi #include <sys/sysmacros.h> 27*9d12795fSRobert Mustacchi 28*9d12795fSRobert Mustacchi #include <sys/random.h> 29*9d12795fSRobert Mustacchi 30*9d12795fSRobert Mustacchi /* 31*9d12795fSRobert Mustacchi * Impose a maximum upper bound on the number of bytes that we'll read in one 32*9d12795fSRobert Mustacchi * go, ala a read of /dev/random. For /dev/urandom, we clamp it based on our 33*9d12795fSRobert Mustacchi * return value, because the system call returns an int, we can't handle more 34*9d12795fSRobert Mustacchi * than INT_MAX. 35*9d12795fSRobert Mustacchi */ 36*9d12795fSRobert Mustacchi #define MAXRANDBYTES 1024 37*9d12795fSRobert Mustacchi #define MAXURANDBYTES INT_MAX 38*9d12795fSRobert Mustacchi 39*9d12795fSRobert Mustacchi int 40*9d12795fSRobert Mustacchi getrandom(void *bufp, size_t buflen, int flags) 41*9d12795fSRobert Mustacchi { 42*9d12795fSRobert Mustacchi int out = 0; 43*9d12795fSRobert Mustacchi uint8_t rbytes[128]; 44*9d12795fSRobert Mustacchi uint8_t *buf = bufp; 45*9d12795fSRobert Mustacchi 46*9d12795fSRobert Mustacchi if (flags & ~(GRND_NONBLOCK | GRND_RANDOM)) 47*9d12795fSRobert Mustacchi return (set_errno(EINVAL)); 48*9d12795fSRobert Mustacchi 49*9d12795fSRobert Mustacchi if ((flags & GRND_RANDOM) && buflen > MAXRANDBYTES) { 50*9d12795fSRobert Mustacchi buflen = MAXRANDBYTES; 51*9d12795fSRobert Mustacchi } else if (buflen > MAXURANDBYTES) { 52*9d12795fSRobert Mustacchi buflen = MAXURANDBYTES; 53*9d12795fSRobert Mustacchi } 54*9d12795fSRobert Mustacchi 55*9d12795fSRobert Mustacchi while (buflen > out) { 56*9d12795fSRobert Mustacchi int err; 57*9d12795fSRobert Mustacchi size_t len = MIN(sizeof (rbytes), buflen); 58*9d12795fSRobert Mustacchi 59*9d12795fSRobert Mustacchi if (flags & GRND_RANDOM) { 60*9d12795fSRobert Mustacchi if (flags & GRND_NONBLOCK) 61*9d12795fSRobert Mustacchi err = random_get_bytes(rbytes, len); 62*9d12795fSRobert Mustacchi else 63*9d12795fSRobert Mustacchi err = random_get_blocking_bytes(rbytes, len); 64*9d12795fSRobert Mustacchi } else { 65*9d12795fSRobert Mustacchi err = random_get_pseudo_bytes(rbytes, len); 66*9d12795fSRobert Mustacchi } 67*9d12795fSRobert Mustacchi 68*9d12795fSRobert Mustacchi if (err == 0) { 69*9d12795fSRobert Mustacchi if (ddi_copyout(rbytes, buf + out, len, 0) != 0) 70*9d12795fSRobert Mustacchi return (set_errno(EFAULT)); 71*9d12795fSRobert Mustacchi out += len; 72*9d12795fSRobert Mustacchi } else if (err == EAGAIN && out > 0) { 73*9d12795fSRobert Mustacchi break; 74*9d12795fSRobert Mustacchi } else { 75*9d12795fSRobert Mustacchi return (set_errno(err)); 76*9d12795fSRobert Mustacchi } 77*9d12795fSRobert Mustacchi } 78*9d12795fSRobert Mustacchi 79*9d12795fSRobert Mustacchi return (out); 80*9d12795fSRobert Mustacchi } 81