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