xref: /netbsd-src/lib/librumpuser/rumpuser_random.c (revision 23dfcd7408ac64d59d92beb90663ee97670c6648)
1*23dfcd74Spooka /*	$NetBSD: rumpuser_random.c,v 1.4 2014/11/04 19:05:17 pooka Exp $	*/
282dada91Spooka 
3648d66f0Sjustin /*
4648d66f0Sjustin  * Copyright (c) 2014 Justin Cormack.  All Rights Reserved.
5648d66f0Sjustin  *
6648d66f0Sjustin  * Redistribution and use in source and binary forms, with or without
7648d66f0Sjustin  * modification, are permitted provided that the following conditions
8648d66f0Sjustin  * are met:
9648d66f0Sjustin  * 1. Redistributions of source code must retain the above copyright
10648d66f0Sjustin  *    notice, this list of conditions and the following disclaimer.
11648d66f0Sjustin  * 2. Redistributions in binary form must reproduce the above copyright
12648d66f0Sjustin  *    notice, this list of conditions and the following disclaimer in the
13648d66f0Sjustin  *    documentation and/or other materials provided with the distribution.
14648d66f0Sjustin  *
15648d66f0Sjustin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16648d66f0Sjustin  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17648d66f0Sjustin  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18648d66f0Sjustin  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19648d66f0Sjustin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20648d66f0Sjustin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21648d66f0Sjustin  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22648d66f0Sjustin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23648d66f0Sjustin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24648d66f0Sjustin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25648d66f0Sjustin  * SUCH DAMAGE.
26648d66f0Sjustin  */
27648d66f0Sjustin 
28648d66f0Sjustin #include "rumpuser_port.h"
29648d66f0Sjustin 
30648d66f0Sjustin #if !defined(lint)
31*23dfcd74Spooka __RCSID("$NetBSD: rumpuser_random.c,v 1.4 2014/11/04 19:05:17 pooka Exp $");
32648d66f0Sjustin #endif /* !lint */
33648d66f0Sjustin 
34648d66f0Sjustin #include <sys/types.h>
35648d66f0Sjustin 
36648d66f0Sjustin #include <assert.h>
37648d66f0Sjustin #include <errno.h>
38648d66f0Sjustin #include <fcntl.h>
39648d66f0Sjustin #include <stdint.h>
40648d66f0Sjustin #include <stdio.h>
41648d66f0Sjustin #include <stdlib.h>
42648d66f0Sjustin #include <string.h>
43648d66f0Sjustin #include <unistd.h>
44648d66f0Sjustin 
45648d66f0Sjustin #include <rump/rumpuser.h>
46648d66f0Sjustin 
47648d66f0Sjustin #include "rumpuser_int.h"
48648d66f0Sjustin 
49648d66f0Sjustin static const size_t random_maxread = 32;
50648d66f0Sjustin 
51*23dfcd74Spooka #ifdef HAVE_ARC4RANDOM_BUF
52648d66f0Sjustin int
rumpuser__random_init(void)53648d66f0Sjustin rumpuser__random_init(void)
54648d66f0Sjustin {
55648d66f0Sjustin 
56648d66f0Sjustin 	return 0;
57648d66f0Sjustin }
58648d66f0Sjustin #else
59648d66f0Sjustin static const char *random_device = "/dev/urandom";
60648d66f0Sjustin static int random_fd = -1;
61648d66f0Sjustin 
62648d66f0Sjustin int
rumpuser__random_init(void)63648d66f0Sjustin rumpuser__random_init(void)
64648d66f0Sjustin {
65648d66f0Sjustin 
66648d66f0Sjustin 	random_fd = open(random_device, O_RDONLY);
67648d66f0Sjustin 	if (random_fd < 0) {
68648d66f0Sjustin 		fprintf(stderr, "random init open failed\n");
6928e2f06eSjustin 		return errno;
70648d66f0Sjustin 	}
71648d66f0Sjustin 	return 0;
72648d66f0Sjustin }
73648d66f0Sjustin #endif
74648d66f0Sjustin 
75648d66f0Sjustin int
rumpuser_getrandom(void * buf,size_t buflen,int flags,size_t * retp)76648d66f0Sjustin rumpuser_getrandom(void *buf, size_t buflen, int flags, size_t *retp)
77648d66f0Sjustin {
78*23dfcd74Spooka #ifndef HAVE_ARC4RANDOM_BUF
79648d66f0Sjustin 	ssize_t rv;
80648d66f0Sjustin 
81648d66f0Sjustin 	rv = read(random_fd, buf, buflen > random_maxread ? random_maxread : buflen);
82648d66f0Sjustin 	if (rv < 0) {
83648d66f0Sjustin 		ET(errno);
84648d66f0Sjustin 	}
85648d66f0Sjustin 	*retp = rv;
86648d66f0Sjustin #else
87648d66f0Sjustin 	buflen = buflen > random_maxread ? random_maxread : buflen;
88648d66f0Sjustin 	arc4random_buf(buf, buflen);
89648d66f0Sjustin 	*retp = buflen;
90648d66f0Sjustin #endif
91648d66f0Sjustin 
9228e2f06eSjustin 	return 0;
93648d66f0Sjustin }
94