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