annotate compat/getentropy.c @ 0:d541e748cfd8

Initial revision
author Guido Berhoerster <guido+libpws@berhoerster.name>
date Tue, 10 Feb 2015 11:29:54 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
1 /*
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
2 * Copyright (C) 2015 Guido Berhoerster <guido+libpws@berhoerster.name>
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
3 *
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
5 * a copy of this software and associated documentation files (the
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
6 * "Software"), to deal in the Software without restriction, including
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
7 * without limitation the rights to use, copy, modify, merge, publish,
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
8 * distribute, sublicense, and/or sell copies of the Software, and to
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
9 * permit persons to whom the Software is furnished to do so, subject to
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
10 * the following conditions:
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
11 *
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
12 * The above copyright notice and this permission notice shall be included
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
13 * in all copies or substantial portions of the Software.
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
14 *
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
22 */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
23
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
24 /* needed for syscall(2) on Linux */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
25 #define _GNU_SOURCE
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
26
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
27 /* Linux >= 3.17 has getrandom(2) system call */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
28 #ifdef __linux__
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
29 #include <unistd.h>
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
30 #include <sys/syscall.h>
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
31 #include <linux/random.h>
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
32 #ifdef SYS_getrandom
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
33 #define HAVE_GETRANDOM
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
34 #endif /* SYS_getrandom */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
35 #endif /* __linux__ */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
36 /*
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
37 * on unknown Unix systems without getentropy(2) or Linux without getrandom(2)
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
38 * fall back to * reading from /dev/(u)random
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
39 */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
40 #ifndef HAVE_GETRANDOM
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
41 #include <stdio.h>
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
42 #ifndef RANDOM_DEVICE
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
43 #ifdef __linux__
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
44 /* on Linux /dev/urandom should be good enough */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
45 #define RANDOM_DEVICE "/dev/urandom"
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
46 #else /* __linux__ */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
47 /* on unknown Unix systems use the possibly blocking /dev/random */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
48 #define RANDOM_DEVICE "/dev/random"
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
49 #endif /* __linux__ */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
50 #endif /* !RANDOM_DEVICE */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
51 #endif /* !HAVE_GETRANDOM */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
52 #include <errno.h>
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
53
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
54 #include "pws-compat.h"
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
55
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
56 #ifdef HAVE_GETRANDOM
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
57 static int
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
58 getentropy_linux_getrandom(void *buf, size_t buf_len)
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
59 {
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
60 int retval;
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
61
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
62 retval = syscall(SYS_getrandom, buf, buf_len, 0);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
63 if (retval < 0) {
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
64 return (-1);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
65 } else if ((size_t)retval != buf_len) {
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
66 errno = EIO;
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
67 return (-1);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
68 }
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
69
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
70 return (0);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
71 }
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
72 #else
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
73 static int
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
74 getentropy_dev_random(void *buf, size_t buf_len)
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
75 {
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
76 FILE *fp;
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
77 int saved_errno;
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
78
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
79 fp = fopen(RANDOM_DEVICE, "r");
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
80 if (fp == NULL) {
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
81 return (-1);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
82 }
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
83 if (fread(buf, 1, buf_len, fp) != buf_len) {
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
84 saved_errno = errno;
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
85 fclose(fp);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
86 errno = saved_errno;
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
87 return (-1);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
88 }
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
89 if (fclose(fp) != 0) {
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
90 return (-1);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
91 }
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
92
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
93 return (0);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
94 }
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
95 #endif /* HAVE_GETRANDOM */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
96
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
97 int
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
98 getentropy(void *buf, size_t buf_len)
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
99 {
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
100 if (buf_len > 256) {
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
101 errno = EIO;
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
102 return (-1);
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
103 }
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
104
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
105 return (
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
106 #ifdef HAVE_GETRANDOM
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
107 getentropy_linux_getrandom(
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
108 #else /* HAVE_GETRANDOM */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
109 getentropy_dev_random(
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
110 #endif /* HAVE_GETRANDOM */
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
111 buf, buf_len));
d541e748cfd8 Initial revision
Guido Berhoerster <guido+libpws@berhoerster.name>
parents:
diff changeset
112 }