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 --- |