Deleted Added
full compact
getentropy_linux.c (282089) getentropy_linux.c (287917)
1/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $ */
2
3/*
4 * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
5 * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above

--- 63 unchanged lines hidden (view full) ---

72#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
73
74int getentropy(void *buf, size_t len);
75
76#ifdef CAN_REFERENCE_MAIN
77extern int main(int, char *argv[]);
78#endif
79static int gotdata(char *buf, size_t len);
1/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $ */
2
3/*
4 * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
5 * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above

--- 63 unchanged lines hidden (view full) ---

72#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
73
74int getentropy(void *buf, size_t len);
75
76#ifdef CAN_REFERENCE_MAIN
77extern int main(int, char *argv[]);
78#endif
79static int gotdata(char *buf, size_t len);
80#ifdef SYS_getrandom
81static int getentropy_getrandom(void *buf, size_t len);
82#endif
80static int getentropy_urandom(void *buf, size_t len);
81#ifdef SYS__sysctl
82static int getentropy_sysctl(void *buf, size_t len);
83#endif
84static int getentropy_fallback(void *buf, size_t len);
85
86int
87getentropy(void *buf, size_t len)
88{
89 int ret = -1;
90
91 if (len > 256) {
92 errno = EIO;
93 return -1;
94 }
95
96#ifdef SYS_getrandom
83static int getentropy_urandom(void *buf, size_t len);
84#ifdef SYS__sysctl
85static int getentropy_sysctl(void *buf, size_t len);
86#endif
87static int getentropy_fallback(void *buf, size_t len);
88
89int
90getentropy(void *buf, size_t len)
91{
92 int ret = -1;
93
94 if (len > 256) {
95 errno = EIO;
96 return -1;
97 }
98
99#ifdef SYS_getrandom
97 /* try to use getrandom syscall introduced with kernel 3.17 */
98 ret = syscall(SYS_getrandom, buf, len, 0);
100 /*
101 * Try descriptor-less getrandom()
102 */
103 ret = getentropy_getrandom(buf, len);
99 if (ret != -1)
100 return (ret);
104 if (ret != -1)
105 return (ret);
101#endif /* SYS_getrandom */
106 if (errno != ENOSYS)
107 return (-1);
108#endif
102
103 /*
104 * Try to get entropy with /dev/urandom
105 *
106 * This can fail if the process is inside a chroot or if file
107 * descriptors are exhausted.
108 */
109 ret = getentropy_urandom(buf, len);

--- 70 unchanged lines hidden (view full) ---

180
181 for (i = 0; i < len; ++i)
182 any_set |= buf[i];
183 if (any_set == 0)
184 return -1;
185 return 0;
186}
187
109
110 /*
111 * Try to get entropy with /dev/urandom
112 *
113 * This can fail if the process is inside a chroot or if file
114 * descriptors are exhausted.
115 */
116 ret = getentropy_urandom(buf, len);

--- 70 unchanged lines hidden (view full) ---

187
188 for (i = 0; i < len; ++i)
189 any_set |= buf[i];
190 if (any_set == 0)
191 return -1;
192 return 0;
193}
194
195#ifdef SYS_getrandom
188static int
196static int
197getentropy_getrandom(void *buf, size_t len)
198{
199 int pre_errno = errno;
200 int ret;
201 if (len > 256)
202 return (-1);
203 do {
204 ret = syscall(SYS_getrandom, buf, len, 0);
205 } while (ret == -1 && errno == EINTR);
206
207 if (ret != (int)len)
208 return (-1);
209 errno = pre_errno;
210 return (0);
211}
212#endif
213
214static int
189getentropy_urandom(void *buf, size_t len)
190{
191 struct stat st;
192 size_t i;
193 int fd, cnt, flags;
194 int save_errno = errno;
195
196start:

--- 56 unchanged lines hidden (view full) ---

253
254 for (i = 0; i < len; ) {
255 size_t chunk = min(len - i, 16);
256
257 /* SYS__sysctl because some systems already removed sysctl() */
258 struct __sysctl_args args = {
259 .name = mib,
260 .nlen = 3,
215getentropy_urandom(void *buf, size_t len)
216{
217 struct stat st;
218 size_t i;
219 int fd, cnt, flags;
220 int save_errno = errno;
221
222start:

--- 56 unchanged lines hidden (view full) ---

279
280 for (i = 0; i < len; ) {
281 size_t chunk = min(len - i, 16);
282
283 /* SYS__sysctl because some systems already removed sysctl() */
284 struct __sysctl_args args = {
285 .name = mib,
286 .nlen = 3,
261 .oldval = buf + i,
287 .oldval = (char *)buf + i,
262 .oldlenp = &chunk,
263 };
264 if (syscall(SYS__sysctl, &args) != 0)
265 goto sysctlfailed;
266 i += chunk;
267 }
268 if (gotdata(buf, len) == 0) {
269 errno = save_errno;

--- 245 unchanged lines hidden ---
288 .oldlenp = &chunk,
289 };
290 if (syscall(SYS__sysctl, &args) != 0)
291 goto sysctlfailed;
292 i += chunk;
293 }
294 if (gotdata(buf, len) == 0) {
295 errno = save_errno;

--- 245 unchanged lines hidden ---