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