1356143Scy/* $OpenBSD: getentropy_freebsd.c,v 1.3 2016/08/07 03:27:21 tb Exp $ */ 2356143Scy 3356143Scy/* 4356143Scy * Copyright (c) 2014 Pawel Jakub Dawidek <pjd@FreeBSD.org> 5356143Scy * Copyright (c) 2014 Brent Cook <bcook@openbsd.org> 6356143Scy * 7356143Scy * Permission to use, copy, modify, and distribute this software for any 8356143Scy * purpose with or without fee is hereby granted, provided that the above 9356143Scy * copyright notice and this permission notice appear in all copies. 10356143Scy * 11356143Scy * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12356143Scy * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13356143Scy * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14356143Scy * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15356143Scy * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16356143Scy * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17356143Scy * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18356143Scy * 19356143Scy * Emulation of getentropy(2) as documented at: 20356143Scy * http://man.openbsd.org/getentropy.2 21356143Scy */ 22356143Scy 23356143Scy#include <sys/types.h> 24356143Scy#include <sys/sysctl.h> 25356143Scy 26356143Scy#include <errno.h> 27356143Scy#include <stddef.h> 28356143Scy 29356143Scy/* 30356143Scy * Derived from lib/libc/gen/arc4random.c from FreeBSD. 31356143Scy */ 32356143Scystatic size_t 33356143Scygetentropy_sysctl(u_char *buf, size_t size) 34356143Scy{ 35356143Scy int mib[2]; 36356143Scy size_t len, done; 37356143Scy 38356143Scy mib[0] = CTL_KERN; 39356143Scy mib[1] = KERN_ARND; 40356143Scy done = 0; 41356143Scy 42356143Scy do { 43356143Scy len = size; 44356143Scy if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) 45356143Scy return (done); 46356143Scy done += len; 47356143Scy buf += len; 48356143Scy size -= len; 49356143Scy } while (size > 0); 50356143Scy 51356143Scy return (done); 52356143Scy} 53356143Scy 54356143Scyint 55356143Scygetentropy(void *buf, size_t len) 56356143Scy{ 57356143Scy if (len <= 256 && getentropy_sysctl(buf, len) == len) 58356143Scy return (0); 59356143Scy 60356143Scy errno = EIO; 61356143Scy return (-1); 62356143Scy} 63