1 /* 2 * rand - generate random bytes 3 * 4 * Copyright(c) 2016 Glenn Strauss gstrauss()gluelogic.com All rights reserved 5 * License: BSD 3-clause (same as lighttpd) 6 */ 7 #include "first.h" 8 9 #include "rand.h" 10 #include "buffer.h" 11 #include "fdevent.h" 12 #include "safe_memclear.h" 13 14 #include <sys/types.h> 15 #include <sys/stat.h> 16 #include <errno.h> 17 #include <fcntl.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <time.h> 21 #include <unistd.h> 22 23 #include "sys-crypto.h" /* USE_LIB_CRYPTO */ 24 #ifdef USE_NETTLE_CRYPTO 25 #undef USE_MBEDTLS_CRYPTO 26 #undef USE_OPENSSL_CRYPTO 27 #undef USE_GNUTLS_CRYPTO 28 #include <nettle/knuth-lfib.h> 29 #include <nettle/arcfour.h> 30 #include <nettle/yarrow.h> 31 #endif 32 #ifdef USE_MBEDTLS_CRYPTO 33 #undef USE_OPENSSL_CRYPTO 34 #undef USE_GNUTLS_CRYPTO 35 #include <mbedtls/ctr_drbg.h> 36 #include <mbedtls/entropy.h> 37 #endif 38 #ifdef USE_OPENSSL_CRYPTO 39 #undef USE_GNUTLS_CRYPTO 40 #include <openssl/opensslv.h> /* OPENSSL_VERSION_NUMBER */ 41 #include <openssl/rand.h> 42 #endif 43 #ifdef USE_GNUTLS_CRYPTO 44 #include <gnutls/crypto.h> 45 #endif 46 #ifdef HAVE_GETENTROPY 47 #include <sys/random.h> 48 #endif 49 #ifdef HAVE_LINUX_RANDOM_H 50 #include <sys/syscall.h> 51 #include <linux/random.h> 52 #endif 53 #ifdef RNDGETENTCNT 54 #include <sys/ioctl.h> 55 #endif 56 57 /* Take some reasonable steps to attempt to *seed* random number generators with 58 * cryptographically random data. Some of these initialization routines may 59 * block, and are intended to be called only at startup in lighttpd, or 60 * immediately after fork() to start lighttpd workers. 61 * 62 * Update: li_rand_init() is now deferred until first use so that installations 63 * that do not use modules which use these routines do need to potentially block 64 * at startup. Current use by core lighttpd modules is in mod_auth HTTP Digest 65 * auth and in mod_usertrack. Deferring collection of random data until first 66 * use may allow sufficient entropy to be collected by kernel before first use, 67 * helping reduce or avoid situations in low-entropy-generating embedded devices 68 * which might otherwise block lighttpd for minutes at device startup. 69 * Further discussion in https://redmine.lighttpd.net/boards/2/topics/6981 70 * 71 * Note: results from li_rand_pseudo_bytes() are not necessarily 72 * cryptographically random and must not be used for purposes such 73 * as key generation which require cryptographic randomness. 74 * 75 * https://wiki.openssl.org/index.php/Random_Numbers 76 * https://wiki.openssl.org/index.php/Random_fork-safety 77 * 78 * openssl random number generators are not thread-safe by default 79 * https://wiki.openssl.org/index.php/Manual:Threads(3) 80 * 81 * RFE: add more paranoid checks from the following to improve confidence: 82 * http://insanecoding.blogspot.co.uk/2014/05/a-good-idea-with-bad-usage-devurandom.html 83 * RFE: retry on EINTR 84 * RFE: check RAND_status() 85 */ 86 87 static int li_getentropy (void *buf, size_t buflen) 88 { 89 #ifdef HAVE_GETENTROPY 90 return getentropy(buf, buflen); 91 #else 92 /*(see NOTES section in 'man getrandom' on Linux)*/ 93 #if defined(HAVE_GETRANDOM) || defined(SYS_getrandom) 94 if (buflen <= 256) { 95 #ifdef HAVE_GETRANDOM /*(not implemented in glibc yet)*/ 96 int num = getrandom(buf, buflen, 0); 97 #elif defined(SYS_getrandom) 98 /* https://lwn.net/Articles/605828/ */ 99 /* https://bbs.archlinux.org/viewtopic.php?id=200039 */ 100 int num = (int)syscall(SYS_getrandom, buf, buflen, 0); 101 #endif 102 if (num == (int)buflen) return 0; 103 if (num < 0) return num; /* -1 */ 104 } 105 #else 106 UNUSED(buf); 107 UNUSED(buflen); 108 #endif 109 errno = EIO; 110 return -1; 111 #endif 112 } 113 114 static int li_rand_device_bytes (unsigned char *buf, int num) 115 { 116 /* randomness from these devices is cryptographically strong, 117 * unless /dev/urandom is low on entropy */ 118 119 static const char * const devices[] = { 120 #ifdef __OpenBSD__ 121 "/dev/arandom", 122 #endif 123 "/dev/urandom", 124 "/dev/random" 125 }; 126 127 /* device files might not be available in chroot environment, 128 * so prefer syscall, if available */ 129 if (0 == li_getentropy(buf, (size_t)num)) return 1; 130 131 for (unsigned int u = 0; u < sizeof(devices)/sizeof(devices[0]); ++u) { 132 /*(some systems might have symlink to another device; omit O_NOFOLLOW)*/ 133 int fd = fdevent_open_cloexec(devices[u], 0, O_RDONLY, 0); 134 if (fd >= 0) { 135 ssize_t rd = 0; 136 #ifdef RNDGETENTCNT 137 int entropy; 138 if (0 == ioctl(fd, (unsigned long)(RNDGETENTCNT), &entropy) 139 && entropy >= num*8) 140 #endif 141 rd = read(fd, buf, (size_t)num); 142 close(fd); 143 if (rd == num) { 144 return 1; 145 } 146 } 147 } 148 149 return 0; 150 } 151 152 static int li_rand_inited; 153 static unsigned short xsubi[3]; 154 #ifdef USE_MBEDTLS_CRYPTO 155 #ifdef MBEDTLS_ENTROPY_C 156 static mbedtls_entropy_context entropy; 157 #ifdef MBEDTLS_CTR_DRBG_C 158 static mbedtls_ctr_drbg_context ctr_drbg; 159 #endif 160 #endif 161 #endif 162 #ifdef USE_NETTLE_CRYPTO 163 static struct knuth_lfib_ctx knuth_lfib_ctx; 164 static struct arcfour_ctx arcfour_ctx; 165 static struct yarrow256_ctx yarrow256_ctx; 166 #endif 167 168 #ifdef USE_NETTLE_CRYPTO 169 /* adapted from Nettle documentation arcfour_set_key_hashed() in nettle.pdf */ 170 /* A more robust key setup function for ARCFOUR */ 171 static void 172 li_arcfour_init_random_key_hashed(struct arcfour_ctx *ctx) 173 { 174 uint8_t key[ARCFOUR_KEY_SIZE]; 175 const size_t length = sizeof(key); 176 if (1 != li_rand_device_bytes(key, (int)sizeof(key))) { 177 log_failed_assert(__FILE__, __LINE__, 178 "gathering entropy for arcfour seed failed"); 179 } 180 memset(ctx, 0, sizeof(*ctx)); 181 182 struct sha256_ctx hash; 183 uint8_t digest[SHA256_DIGEST_SIZE]; 184 uint8_t buf[0x200]; 185 memset(buf, 0, sizeof(buf)); 186 sha256_init(&hash); 187 sha256_update(&hash, length, key); 188 sha256_digest(&hash, SHA256_DIGEST_SIZE, digest); 189 nettle_arcfour_set_key(ctx, SHA256_DIGEST_SIZE, digest); 190 nettle_arcfour_crypt(ctx, sizeof(buf), buf, buf); 191 nettle_arcfour_crypt(ctx, sizeof(buf), buf, buf); 192 nettle_arcfour_crypt(ctx, sizeof(buf), buf, buf); 193 } 194 #endif 195 196 static void li_rand_init (void) 197 { 198 /* (intended to be called at init and after fork() in order to re-seed PRNG 199 * so that forked children, grandchildren, etc do not share PRNG seed) 200 * https://github.com/ramsey/uuid/issues/80 201 * https://www.agwa.name/blog/post/libressls_prng_is_unsafe_on_linux 202 * (issue in early version of libressl has since been fixed) 203 * https://github.com/libressl-portable/portable/commit/32d9eeeecf4e951e1566d5f4a42b36ea37b60f35 204 */ 205 unsigned int u; 206 li_rand_inited = 1; 207 if (1 == li_rand_device_bytes((unsigned char *)xsubi, (int)sizeof(xsubi))) { 208 u = ((unsigned int)xsubi[0] << 16) | xsubi[1]; 209 } 210 else { 211 #ifdef HAVE_ARC4RANDOM_BUF 212 u = arc4random(); 213 arc4random_buf(xsubi, sizeof(xsubi)); 214 #else 215 /* NOTE: not cryptographically random !!! */ 216 srand((unsigned int)(time(NULL) ^ getpid())); 217 for (u = 0; u < sizeof(unsigned short); ++u) 218 /* coverity[dont_call : FALSE] */ 219 xsubi[u] = (unsigned short)(rand() & 0xFFFF); 220 u = ((unsigned int)xsubi[0] << 16) | xsubi[1]; 221 #endif 222 } 223 srand(u); /*(initialize just in case rand() used elsewhere)*/ 224 #ifdef HAVE_SRANDOM 225 srandom(u); /*(initialize just in case random() used elsewhere)*/ 226 #endif 227 #ifdef USE_NETTLE_CRYPTO 228 nettle_knuth_lfib_init(&knuth_lfib_ctx, u); 229 nettle_yarrow256_init(&yarrow256_ctx, 0, NULL); 230 li_arcfour_init_random_key_hashed(&arcfour_ctx); 231 #endif 232 #ifdef USE_OPENSSL_CRYPTO 233 RAND_poll(); 234 RAND_seed(xsubi, (int)sizeof(xsubi)); 235 #endif 236 #ifdef USE_MBEDTLS_CRYPTO 237 #ifdef MBEDTLS_ENTROPY_C 238 mbedtls_entropy_init(&entropy); 239 #ifdef MBEDTLS_CTR_DRBG_C 240 mbedtls_ctr_drbg_init(&ctr_drbg); 241 int rc = 242 mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, 243 (unsigned char *)xsubi, sizeof(xsubi)); 244 if (0 != rc) /*(not expecting built-in entropy function to fail)*/ 245 log_failed_assert(__FILE__, __LINE__, "mbedtls_ctr_drbg_seed() failed"); 246 #endif 247 #endif 248 #endif 249 } 250 251 void li_rand_reseed (void) 252 { 253 #ifdef USE_GNUTLS_CRYPTO 254 gnutls_rnd_refresh(); 255 return; 256 #endif 257 #ifdef USE_MBEDTLS_CRYPTO 258 if (li_rand_inited) { 259 #ifdef MBEDTLS_ENTROPY_C 260 #ifdef MBEDTLS_CTR_DRBG_C 261 mbedtls_ctr_drbg_free(&ctr_drbg); 262 #endif 263 mbedtls_entropy_free(&entropy); 264 #endif 265 } 266 #endif 267 if (li_rand_inited) li_rand_init(); 268 } 269 270 int li_rand_pseudo (void) 271 { 272 #ifdef USE_GNUTLS_CRYPTO 273 int i; 274 if (0 == gnutls_rnd(GNUTLS_RND_NONCE, &i, sizeof(i))) return i; 275 #endif 276 if (!li_rand_inited) li_rand_init(); 277 /* randomness *is not* cryptographically strong */ 278 /* (attempt to use better mechanisms to replace the more portable rand()) */ 279 #ifdef USE_OPENSSL_CRYPTO /* (openssl 1.1.0 deprecates RAND_pseudo_bytes()) */ 280 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 281 int i; 282 if (-1 != RAND_pseudo_bytes((unsigned char *)&i, sizeof(i))) return i; 283 #endif 284 #endif 285 #ifdef USE_NETTLE_CRYPTO 286 int i = (int)nettle_knuth_lfib_get(&knuth_lfib_ctx); 287 nettle_arcfour_crypt(&arcfour_ctx, sizeof(i), (uint8_t *)&i, (uint8_t *)&i); 288 if (i) return i; /*(cond to avoid compiler warning for code after return)*/ 289 #endif 290 #ifdef USE_MBEDTLS_CRYPTO 291 #ifdef MBEDTLS_CTR_DRBG_C 292 int i; 293 if (0 == mbedtls_ctr_drbg_random(&ctr_drbg, (unsigned char *)&i, sizeof(i))) 294 return i; 295 #endif 296 #endif 297 #ifdef HAVE_ARC4RANDOM_BUF 298 return (int)arc4random(); 299 #elif defined(HAVE_SRANDOM) 300 /* coverity[dont_call : FALSE] */ 301 return (int)random(); 302 #elif defined(HAVE_JRAND48) 303 /*(FYI: jrand48() reentrant, but use of file-scoped static xsubi[] is not)*/ 304 /* coverity[dont_call : FALSE] */ 305 return (int)jrand48(xsubi); 306 #else 307 /* coverity[dont_call : FALSE] */ 308 return rand(); 309 #endif 310 } 311 312 void li_rand_pseudo_bytes (unsigned char *buf, int num) 313 { 314 #ifdef USE_GNUTLS_CRYPTO 315 if (0 == gnutls_rnd(GNUTLS_RND_NONCE, buf, (size_t)num)) return; 316 #endif 317 #ifdef USE_MBEDTLS_CRYPTO 318 #ifdef MBEDTLS_CTR_DRBG_C 319 if (0 == mbedtls_ctr_drbg_random(&ctr_drbg, buf, (size_t)num)) return; 320 #endif 321 #endif 322 for (int i = 0; i < num; ++i) 323 buf[i] = li_rand_pseudo() & 0xFF; 324 } 325 326 int li_rand_bytes (unsigned char *buf, int num) 327 { 328 #ifdef USE_GNUTLS_CRYPTO /* should use GNUTLS_RND_KEY for long-term keys */ 329 if (0 == gnutls_rnd(GNUTLS_RND_RANDOM, buf, (size_t)num)) return 1; 330 #endif 331 #ifdef USE_NETTLE_CRYPTO 332 #if 0 /* not implemented: periodic nettle_yarrow256_update() and reseed */ 333 if (!nettle_yarrow256_is_seeded(&yarrow256_ctx)) { 334 uint8_t seed_file[YARROW256_SEED_FILE_SIZE]; 335 if (1 == li_rand_device_bytes((unsigned char *)seed_file, 336 (int)sizeof(seed_file))) { 337 nettle_yarrow256_seed(&yarrow256_ctx, sizeof(seed_file), seed_file); 338 } 339 } 340 if (nettle_yarrow256_is_seeded(&yarrow256_ctx)) { 341 nettle_yarrow256_random(&yarrow256_ctx, (size_t)num, (uint8_t *)buf); 342 return 1; 343 } 344 #endif 345 #endif 346 #ifdef USE_OPENSSL_CRYPTO 347 int rc = RAND_bytes(buf, num); 348 if (-1 != rc) { 349 return rc; 350 } 351 #endif 352 #ifdef USE_MBEDTLS_CRYPTO 353 #ifdef MBEDTLS_ENTROPY_C 354 /*(each call <= MBEDTLS_ENTROPY_BLOCK_SIZE; could implement loop here)*/ 355 if (num <= MBEDTLS_ENTROPY_BLOCK_SIZE 356 && 0 == mbedtls_entropy_func(&entropy, buf, (size_t)num)) { 357 return 1; 358 } 359 #endif 360 #endif 361 if (1 == li_rand_device_bytes(buf, num)) { 362 return 1; 363 } 364 else { 365 /* NOTE: not cryptographically random !!! */ 366 li_rand_pseudo_bytes(buf, num); 367 /*(openssl RAND_pseudo_bytes rc for non-cryptographically random data)*/ 368 return 0; 369 } 370 } 371 372 void li_rand_cleanup (void) 373 { 374 #ifdef USE_OPENSSL_CRYPTO 375 #if OPENSSL_VERSION_NUMBER < 0x10100000L 376 RAND_cleanup(); 377 #endif 378 #endif 379 #ifdef USE_MBEDTLS_CRYPTO 380 #ifdef MBEDTLS_ENTROPY_C 381 #ifdef MBEDTLS_CTR_DRBG_C 382 mbedtls_ctr_drbg_free(&ctr_drbg); 383 #endif 384 mbedtls_entropy_free(&entropy); 385 #endif 386 #endif 387 safe_memclear(xsubi, sizeof(xsubi)); 388 } 389