1 /* 2 * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #ifndef _GNU_SOURCE 11 # define _GNU_SOURCE 12 #endif 13 #include "internal/e_os.h" 14 #include <stdio.h> 15 #include "internal/cryptlib.h" 16 #include <openssl/rand.h> 17 #include <openssl/crypto.h> 18 #include "crypto/rand_pool.h" 19 #include "crypto/rand.h" 20 #include "internal/dso.h" 21 #include "internal/nelem.h" 22 #include "prov/seeding.h" 23 24 #ifndef OPENSSL_SYS_UEFI 25 # ifdef __linux 26 # include <sys/syscall.h> 27 # ifdef DEVRANDOM_WAIT 28 # include <sys/shm.h> 29 # include <sys/utsname.h> 30 # endif 31 # endif 32 # if defined(__FreeBSD__) || defined(__NetBSD__) 33 # include <sys/types.h> 34 # include <sys/sysctl.h> 35 # include <sys/param.h> 36 # endif 37 # if defined(__FreeBSD__) && __FreeBSD_version >= 1200061 38 # include <sys/random.h> 39 # endif 40 # if defined(__OpenBSD__) 41 # include <sys/param.h> 42 # endif 43 # if defined(__DragonFly__) 44 # include <sys/param.h> 45 # include <sys/random.h> 46 # endif 47 #endif 48 49 #if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \ 50 || defined(__DJGPP__) 51 # include <sys/types.h> 52 # include <sys/stat.h> 53 # include <fcntl.h> 54 # include <unistd.h> 55 # include <sys/time.h> 56 57 static uint64_t get_time_stamp(void); 58 59 /* Macro to convert two thirty two bit values into a sixty four bit one */ 60 # define TWO32TO64(a, b) ((((uint64_t)(a)) << 32) + (b)) 61 62 /* 63 * Check for the existence and support of POSIX timers. The standard 64 * says that the _POSIX_TIMERS macro will have a positive value if they 65 * are available. 66 * 67 * However, we want an additional constraint: that the timer support does 68 * not require an extra library dependency. Early versions of glibc 69 * require -lrt to be specified on the link line to access the timers, 70 * so this needs to be checked for. 71 * 72 * It is worse because some libraries define __GLIBC__ but don't 73 * support the version testing macro (e.g. uClibc). This means 74 * an extra check is needed. 75 * 76 * The final condition is: 77 * "have posix timers and either not glibc or glibc without -lrt" 78 * 79 * The nested #if sequences are required to avoid using a parameterised 80 * macro that might be undefined. 81 */ 82 # undef OSSL_POSIX_TIMER_OKAY 83 /* On some systems, _POSIX_TIMERS is defined but empty. 84 * Subtracting by 0 when comparing avoids an error in this case. */ 85 # if defined(_POSIX_TIMERS) && _POSIX_TIMERS -0 > 0 86 # if defined(__GLIBC__) 87 # if defined(__GLIBC_PREREQ) 88 # if __GLIBC_PREREQ(2, 17) 89 # define OSSL_POSIX_TIMER_OKAY 90 # endif 91 # endif 92 # else 93 # define OSSL_POSIX_TIMER_OKAY 94 # endif 95 # endif 96 #endif /* (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) 97 || defined(__DJGPP__) */ 98 99 #if defined(OPENSSL_RAND_SEED_NONE) 100 /* none means none. this simplifies the following logic */ 101 # undef OPENSSL_RAND_SEED_OS 102 # undef OPENSSL_RAND_SEED_GETRANDOM 103 # undef OPENSSL_RAND_SEED_DEVRANDOM 104 # undef OPENSSL_RAND_SEED_RDTSC 105 # undef OPENSSL_RAND_SEED_RDCPU 106 # undef OPENSSL_RAND_SEED_EGD 107 #endif 108 109 #if defined(OPENSSL_SYS_UEFI) && !defined(OPENSSL_RAND_SEED_NONE) 110 # error "UEFI only supports seeding NONE" 111 #endif 112 113 #if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) \ 114 || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VXWORKS) \ 115 || defined(OPENSSL_SYS_UEFI)) 116 117 # if defined(OPENSSL_SYS_VOS) 118 119 # ifndef OPENSSL_RAND_SEED_OS 120 # error "Unsupported seeding method configured; must be os" 121 # endif 122 123 # if defined(OPENSSL_SYS_VOS_HPPA) && defined(OPENSSL_SYS_VOS_IA32) 124 # error "Unsupported HP-PA and IA32 at the same time." 125 # endif 126 # if !defined(OPENSSL_SYS_VOS_HPPA) && !defined(OPENSSL_SYS_VOS_IA32) 127 # error "Must have one of HP-PA or IA32" 128 # endif 129 130 /* 131 * The following algorithm repeatedly samples the real-time clock (RTC) to 132 * generate a sequence of unpredictable data. The algorithm relies upon the 133 * uneven execution speed of the code (due to factors such as cache misses, 134 * interrupts, bus activity, and scheduling) and upon the rather large 135 * relative difference between the speed of the clock and the rate at which 136 * it can be read. If it is ported to an environment where execution speed 137 * is more constant or where the RTC ticks at a much slower rate, or the 138 * clock can be read with fewer instructions, it is likely that the results 139 * would be far more predictable. This should only be used for legacy 140 * platforms. 141 * 142 * As a precaution, we assume only 2 bits of entropy per byte. 143 */ 144 size_t ossl_pool_acquire_entropy(RAND_POOL *pool) 145 { 146 short int code; 147 int i, k; 148 size_t bytes_needed; 149 struct timespec ts; 150 unsigned char v; 151 # ifdef OPENSSL_SYS_VOS_HPPA 152 long duration; 153 extern void s$sleep(long *_duration, short int *_code); 154 # else 155 long long duration; 156 extern void s$sleep2(long long *_duration, short int *_code); 157 # endif 158 159 bytes_needed = ossl_rand_pool_bytes_needed(pool, 4 /*entropy_factor*/); 160 161 for (i = 0; i < bytes_needed; i++) { 162 /* 163 * burn some cpu; hope for interrupts, cache collisions, bus 164 * interference, etc. 165 */ 166 for (k = 0; k < 99; k++) 167 ts.tv_nsec = random(); 168 169 # ifdef OPENSSL_SYS_VOS_HPPA 170 /* sleep for 1/1024 of a second (976 us). */ 171 duration = 1; 172 s$sleep(&duration, &code); 173 # else 174 /* sleep for 1/65536 of a second (15 us). */ 175 duration = 1; 176 s$sleep2(&duration, &code); 177 # endif 178 179 /* Get wall clock time, take 8 bits. */ 180 clock_gettime(CLOCK_REALTIME, &ts); 181 v = (unsigned char)(ts.tv_nsec & 0xFF); 182 ossl_rand_pool_add(pool, arg, &v, sizeof(v), 2); 183 } 184 return ossl_rand_pool_entropy_available(pool); 185 } 186 187 void ossl_rand_pool_cleanup(void) 188 { 189 } 190 191 void ossl_rand_pool_keep_random_devices_open(int keep) 192 { 193 } 194 195 # else 196 197 # if defined(OPENSSL_RAND_SEED_EGD) && \ 198 (defined(OPENSSL_NO_EGD) || !defined(DEVRANDOM_EGD)) 199 # error "Seeding uses EGD but EGD is turned off or no device given" 200 # endif 201 202 # if defined(OPENSSL_RAND_SEED_DEVRANDOM) && !defined(DEVRANDOM) 203 # error "Seeding uses urandom but DEVRANDOM is not configured" 204 # endif 205 206 # if defined(OPENSSL_RAND_SEED_OS) 207 # if !defined(DEVRANDOM) 208 # error "OS seeding requires DEVRANDOM to be configured" 209 # endif 210 # define OPENSSL_RAND_SEED_GETRANDOM 211 # define OPENSSL_RAND_SEED_DEVRANDOM 212 # endif 213 214 # if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND) 215 /* 216 * sysctl_random(): Use sysctl() to read a random number from the kernel 217 * Returns the number of bytes returned in buf on success, -1 on failure. 218 */ 219 static ssize_t sysctl_random(char *buf, size_t buflen) 220 { 221 int mib[2]; 222 size_t done = 0; 223 size_t len; 224 225 /* 226 * Note: sign conversion between size_t and ssize_t is safe even 227 * without a range check, see comment in syscall_random() 228 */ 229 230 /* 231 * On FreeBSD old implementations returned longs, newer versions support 232 * variable sizes up to 256 byte. The code below would not work properly 233 * when the sysctl returns long and we want to request something not a 234 * multiple of longs, which should never be the case. 235 */ 236 #if defined(__FreeBSD__) 237 if (!ossl_assert(buflen % sizeof(long) == 0)) { 238 errno = EINVAL; 239 return -1; 240 } 241 #endif 242 243 /* 244 * On NetBSD before 4.0 KERN_ARND was an alias for KERN_URND, and only 245 * filled in an int, leaving the rest uninitialized. Since NetBSD 4.0 246 * it returns a variable number of bytes with the current version supporting 247 * up to 256 bytes. 248 * Just return an error on older NetBSD versions. 249 */ 250 #if defined(__NetBSD__) && __NetBSD_Version__ < 400000000 251 errno = ENOSYS; 252 return -1; 253 #endif 254 255 mib[0] = CTL_KERN; 256 mib[1] = KERN_ARND; 257 258 do { 259 len = buflen > 256 ? 256 : buflen; 260 if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) 261 return done > 0 ? done : -1; 262 done += len; 263 buf += len; 264 buflen -= len; 265 } while (buflen > 0); 266 267 return done; 268 } 269 # endif 270 271 # if defined(OPENSSL_RAND_SEED_GETRANDOM) 272 273 # if defined(__linux) && !defined(__NR_getrandom) 274 # if defined(__arm__) 275 # define __NR_getrandom (__NR_SYSCALL_BASE+384) 276 # elif defined(__i386__) 277 # define __NR_getrandom 355 278 # elif defined(__x86_64__) 279 # if defined(__ILP32__) 280 # define __NR_getrandom (__X32_SYSCALL_BIT + 318) 281 # else 282 # define __NR_getrandom 318 283 # endif 284 # elif defined(__xtensa__) 285 # define __NR_getrandom 338 286 # elif defined(__s390__) || defined(__s390x__) 287 # define __NR_getrandom 349 288 # elif defined(__bfin__) 289 # define __NR_getrandom 389 290 # elif defined(__powerpc__) 291 # define __NR_getrandom 359 292 # elif defined(__mips__) || defined(__mips64) 293 # if _MIPS_SIM == _MIPS_SIM_ABI32 294 # define __NR_getrandom (__NR_Linux + 353) 295 # elif _MIPS_SIM == _MIPS_SIM_ABI64 296 # define __NR_getrandom (__NR_Linux + 313) 297 # elif _MIPS_SIM == _MIPS_SIM_NABI32 298 # define __NR_getrandom (__NR_Linux + 317) 299 # endif 300 # elif defined(__hppa__) 301 # define __NR_getrandom (__NR_Linux + 339) 302 # elif defined(__sparc__) 303 # define __NR_getrandom 347 304 # elif defined(__ia64__) 305 # define __NR_getrandom 1339 306 # elif defined(__alpha__) 307 # define __NR_getrandom 511 308 # elif defined(__sh__) 309 # if defined(__SH5__) 310 # define __NR_getrandom 373 311 # else 312 # define __NR_getrandom 384 313 # endif 314 # elif defined(__avr32__) 315 # define __NR_getrandom 317 316 # elif defined(__microblaze__) 317 # define __NR_getrandom 385 318 # elif defined(__m68k__) 319 # define __NR_getrandom 352 320 # elif defined(__cris__) 321 # define __NR_getrandom 356 322 # else /* generic (f.e. aarch64, loongarch, loongarch64) */ 323 # define __NR_getrandom 278 324 # endif 325 # endif 326 327 /* 328 * syscall_random(): Try to get random data using a system call 329 * returns the number of bytes returned in buf, or < 0 on error. 330 */ 331 static ssize_t syscall_random(void *buf, size_t buflen) 332 { 333 /* 334 * Note: 'buflen' equals the size of the buffer which is used by the 335 * get_entropy() callback of the RAND_DRBG. It is roughly bounded by 336 * 337 * 2 * RAND_POOL_FACTOR * (RAND_DRBG_STRENGTH / 8) = 2^14 338 * 339 * which is way below the OSSL_SSIZE_MAX limit. Therefore sign conversion 340 * between size_t and ssize_t is safe even without a range check. 341 */ 342 343 /* 344 * Do runtime detection to find getentropy(). 345 * 346 * Known OSs that should support this: 347 * - Darwin since 16 (OSX 10.12, IOS 10.0). 348 * - Solaris since 11.3 349 * - OpenBSD since 5.6 350 * - Linux since 3.17 with glibc 2.25 351 * 352 * Note: Sometimes getentropy() can be provided but not implemented 353 * internally. So we need to check errno for ENOSYS 354 */ 355 # if !defined(__DragonFly__) && !defined(__NetBSD__) && !defined(__FreeBSD__) 356 # if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux) 357 extern int getentropy(void *buffer, size_t length) __attribute__((weak)); 358 359 if (getentropy != NULL) { 360 if (getentropy(buf, buflen) == 0) 361 return (ssize_t)buflen; 362 if (errno != ENOSYS) 363 return -1; 364 } 365 # elif defined(OPENSSL_APPLE_CRYPTO_RANDOM) 366 367 if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess) 368 return (ssize_t)buflen; 369 370 return -1; 371 # else 372 union { 373 void *p; 374 int (*f)(void *buffer, size_t length); 375 } p_getentropy; 376 377 /* 378 * We could cache the result of the lookup, but we normally don't 379 * call this function often. 380 */ 381 ERR_set_mark(); 382 p_getentropy.p = DSO_global_lookup("getentropy"); 383 ERR_pop_to_mark(); 384 if (p_getentropy.p != NULL) 385 return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1; 386 # endif 387 # endif /* !__DragonFly__ && !__NetBSD__ && !__FreeBSD__ */ 388 389 /* Linux supports this since version 3.17 */ 390 # if defined(__linux) && defined(__NR_getrandom) 391 return syscall(__NR_getrandom, buf, buflen, 0); 392 # elif (defined(__DragonFly__) && __DragonFly_version >= 500700) \ 393 || (defined(__NetBSD__) && __NetBSD_Version >= 1000000000) \ 394 || (defined(__FreeBSD__) && __FreeBSD_version >= 1200061) 395 return getrandom(buf, buflen, 0); 396 # elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND) 397 return sysctl_random(buf, buflen); 398 # elif defined(__wasi__) 399 if (getentropy(buf, buflen) == 0) 400 return (ssize_t)buflen; 401 return -1; 402 # else 403 errno = ENOSYS; 404 return -1; 405 # endif 406 } 407 # endif /* defined(OPENSSL_RAND_SEED_GETRANDOM) */ 408 409 # if defined(OPENSSL_RAND_SEED_DEVRANDOM) 410 static const char *random_device_paths[] = { DEVRANDOM }; 411 static struct random_device { 412 int fd; 413 dev_t dev; 414 ino_t ino; 415 mode_t mode; 416 dev_t rdev; 417 } random_devices[OSSL_NELEM(random_device_paths)]; 418 static int keep_random_devices_open = 1; 419 420 # if defined(__linux) && defined(DEVRANDOM_WAIT) \ 421 && defined(OPENSSL_RAND_SEED_GETRANDOM) 422 static void *shm_addr; 423 424 static void cleanup_shm(void) 425 { 426 shmdt(shm_addr); 427 } 428 429 /* 430 * Ensure that the system randomness source has been adequately seeded. 431 * This is done by having the first start of libcrypto, wait until the device 432 * /dev/random becomes able to supply a byte of entropy. Subsequent starts 433 * of the library and later reseedings do not need to do this. 434 */ 435 static int wait_random_seeded(void) 436 { 437 static int seeded = OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID < 0; 438 static const int kernel_version[] = { DEVRANDOM_SAFE_KERNEL }; 439 int kernel[2]; 440 int shm_id, fd, r; 441 char c, *p; 442 struct utsname un; 443 fd_set fds; 444 445 if (!seeded) { 446 /* See if anything has created the global seeded indication */ 447 if ((shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1, 0)) == -1) { 448 /* 449 * Check the kernel's version and fail if it is too recent. 450 * 451 * Linux kernels from 4.8 onwards do not guarantee that 452 * /dev/urandom is properly seeded when /dev/random becomes 453 * readable. However, such kernels support the getentropy(2) 454 * system call and this should always succeed which renders 455 * this alternative but essentially identical source moot. 456 */ 457 if (uname(&un) == 0) { 458 kernel[0] = atoi(un.release); 459 p = strchr(un.release, '.'); 460 kernel[1] = p == NULL ? 0 : atoi(p + 1); 461 if (kernel[0] > kernel_version[0] 462 || (kernel[0] == kernel_version[0] 463 && kernel[1] >= kernel_version[1])) { 464 return 0; 465 } 466 } 467 /* Open /dev/random and wait for it to be readable */ 468 if ((fd = open(DEVRANDOM_WAIT, O_RDONLY)) != -1) { 469 if (DEVRANDM_WAIT_USE_SELECT && fd < FD_SETSIZE) { 470 FD_ZERO(&fds); 471 FD_SET(fd, &fds); 472 while ((r = select(fd + 1, &fds, NULL, NULL, NULL)) < 0 473 && errno == EINTR); 474 } else { 475 while ((r = read(fd, &c, 1)) < 0 && errno == EINTR); 476 } 477 close(fd); 478 if (r == 1) { 479 seeded = 1; 480 /* Create the shared memory indicator */ 481 shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1, 482 IPC_CREAT | S_IRUSR | S_IRGRP | S_IROTH); 483 } 484 } 485 } 486 if (shm_id != -1) { 487 seeded = 1; 488 /* 489 * Map the shared memory to prevent its premature destruction. 490 * If this call fails, it isn't a big problem. 491 */ 492 shm_addr = shmat(shm_id, NULL, SHM_RDONLY); 493 if (shm_addr != (void *)-1) 494 OPENSSL_atexit(&cleanup_shm); 495 } 496 } 497 return seeded; 498 } 499 # else /* defined __linux && DEVRANDOM_WAIT && OPENSSL_RAND_SEED_GETRANDOM */ 500 static int wait_random_seeded(void) 501 { 502 return 1; 503 } 504 # endif 505 506 /* 507 * Verify that the file descriptor associated with the random source is 508 * still valid. The rationale for doing this is the fact that it is not 509 * uncommon for daemons to close all open file handles when daemonizing. 510 * So the handle might have been closed or even reused for opening 511 * another file. 512 */ 513 static int check_random_device(struct random_device *rd) 514 { 515 struct stat st; 516 517 return rd->fd != -1 518 && fstat(rd->fd, &st) != -1 519 && rd->dev == st.st_dev 520 && rd->ino == st.st_ino 521 && ((rd->mode ^ st.st_mode) & ~(S_IRWXU | S_IRWXG | S_IRWXO)) == 0 522 && rd->rdev == st.st_rdev; 523 } 524 525 /* 526 * Open a random device if required and return its file descriptor or -1 on error 527 */ 528 static int get_random_device(size_t n) 529 { 530 struct stat st; 531 struct random_device *rd = &random_devices[n]; 532 533 /* reuse existing file descriptor if it is (still) valid */ 534 if (check_random_device(rd)) 535 return rd->fd; 536 537 /* open the random device ... */ 538 if ((rd->fd = open(random_device_paths[n], O_RDONLY)) == -1) 539 return rd->fd; 540 541 /* ... and cache its relevant stat(2) data */ 542 if (fstat(rd->fd, &st) != -1) { 543 rd->dev = st.st_dev; 544 rd->ino = st.st_ino; 545 rd->mode = st.st_mode; 546 rd->rdev = st.st_rdev; 547 } else { 548 close(rd->fd); 549 rd->fd = -1; 550 } 551 552 return rd->fd; 553 } 554 555 /* 556 * Close a random device making sure it is a random device 557 */ 558 static void close_random_device(size_t n) 559 { 560 struct random_device *rd = &random_devices[n]; 561 562 if (check_random_device(rd)) 563 close(rd->fd); 564 rd->fd = -1; 565 } 566 567 int ossl_rand_pool_init(void) 568 { 569 size_t i; 570 571 for (i = 0; i < OSSL_NELEM(random_devices); i++) 572 random_devices[i].fd = -1; 573 574 return 1; 575 } 576 577 void ossl_rand_pool_cleanup(void) 578 { 579 size_t i; 580 581 for (i = 0; i < OSSL_NELEM(random_devices); i++) 582 close_random_device(i); 583 } 584 585 void ossl_rand_pool_keep_random_devices_open(int keep) 586 { 587 if (!keep) 588 ossl_rand_pool_cleanup(); 589 590 keep_random_devices_open = keep; 591 } 592 593 # else /* !defined(OPENSSL_RAND_SEED_DEVRANDOM) */ 594 595 int ossl_rand_pool_init(void) 596 { 597 return 1; 598 } 599 600 void ossl_rand_pool_cleanup(void) 601 { 602 } 603 604 void ossl_rand_pool_keep_random_devices_open(int keep) 605 { 606 } 607 608 # endif /* defined(OPENSSL_RAND_SEED_DEVRANDOM) */ 609 610 /* 611 * Try the various seeding methods in turn, exit when successful. 612 * 613 * If more than one entropy source is available, is it 614 * preferable to stop as soon as enough entropy has been collected 615 * (as favored by @rsalz) or should one rather be defensive and add 616 * more entropy than requested and/or from different sources? 617 * 618 * Currently, the user can select multiple entropy sources in the 619 * configure step, yet in practice only the first available source 620 * will be used. A more flexible solution has been requested, but 621 * currently it is not clear how this can be achieved without 622 * overengineering the problem. There are many parameters which 623 * could be taken into account when selecting the order and amount 624 * of input from the different entropy sources (trust, quality, 625 * possibility of blocking). 626 */ 627 size_t ossl_pool_acquire_entropy(RAND_POOL *pool) 628 { 629 # if defined(OPENSSL_RAND_SEED_NONE) 630 return ossl_rand_pool_entropy_available(pool); 631 # else 632 size_t entropy_available = 0; 633 634 (void)entropy_available; /* avoid compiler warning */ 635 636 # if defined(OPENSSL_RAND_SEED_GETRANDOM) 637 { 638 size_t bytes_needed; 639 unsigned char *buffer; 640 ssize_t bytes; 641 /* Maximum allowed number of consecutive unsuccessful attempts */ 642 int attempts = 3; 643 644 bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); 645 while (bytes_needed != 0 && attempts-- > 0) { 646 buffer = ossl_rand_pool_add_begin(pool, bytes_needed); 647 bytes = syscall_random(buffer, bytes_needed); 648 if (bytes > 0) { 649 ossl_rand_pool_add_end(pool, bytes, 8 * bytes); 650 bytes_needed -= bytes; 651 attempts = 3; /* reset counter after successful attempt */ 652 } else if (bytes < 0 && errno != EINTR) { 653 break; 654 } 655 } 656 } 657 entropy_available = ossl_rand_pool_entropy_available(pool); 658 if (entropy_available > 0) 659 return entropy_available; 660 # endif 661 662 # if defined(OPENSSL_RAND_SEED_DEVRANDOM) 663 if (wait_random_seeded()) { 664 size_t bytes_needed; 665 unsigned char *buffer; 666 size_t i; 667 668 bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); 669 for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths); 670 i++) { 671 ssize_t bytes = 0; 672 /* Maximum number of consecutive unsuccessful attempts */ 673 int attempts = 3; 674 const int fd = get_random_device(i); 675 676 if (fd == -1) 677 continue; 678 679 while (bytes_needed != 0 && attempts-- > 0) { 680 buffer = ossl_rand_pool_add_begin(pool, bytes_needed); 681 bytes = read(fd, buffer, bytes_needed); 682 683 if (bytes > 0) { 684 ossl_rand_pool_add_end(pool, bytes, 8 * bytes); 685 bytes_needed -= bytes; 686 attempts = 3; /* reset counter on successful attempt */ 687 } else if (bytes < 0 && errno != EINTR) { 688 break; 689 } 690 } 691 if (bytes < 0 || !keep_random_devices_open) 692 close_random_device(i); 693 694 bytes_needed = ossl_rand_pool_bytes_needed(pool, 1); 695 } 696 entropy_available = ossl_rand_pool_entropy_available(pool); 697 if (entropy_available > 0) 698 return entropy_available; 699 } 700 # endif 701 702 # if defined(OPENSSL_RAND_SEED_RDTSC) 703 entropy_available = ossl_prov_acquire_entropy_from_tsc(pool); 704 if (entropy_available > 0) 705 return entropy_available; 706 # endif 707 708 # if defined(OPENSSL_RAND_SEED_RDCPU) 709 entropy_available = ossl_prov_acquire_entropy_from_cpu(pool); 710 if (entropy_available > 0) 711 return entropy_available; 712 # endif 713 714 # if defined(OPENSSL_RAND_SEED_EGD) 715 { 716 static const char *paths[] = { DEVRANDOM_EGD, NULL }; 717 size_t bytes_needed; 718 unsigned char *buffer; 719 int i; 720 721 bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); 722 for (i = 0; bytes_needed > 0 && paths[i] != NULL; i++) { 723 size_t bytes = 0; 724 int num; 725 726 buffer = ossl_rand_pool_add_begin(pool, bytes_needed); 727 num = RAND_query_egd_bytes(paths[i], 728 buffer, (int)bytes_needed); 729 if (num == (int)bytes_needed) 730 bytes = bytes_needed; 731 732 ossl_rand_pool_add_end(pool, bytes, 8 * bytes); 733 bytes_needed = ossl_rand_pool_bytes_needed(pool, 1); 734 } 735 entropy_available = ossl_rand_pool_entropy_available(pool); 736 if (entropy_available > 0) 737 return entropy_available; 738 } 739 # endif 740 741 return ossl_rand_pool_entropy_available(pool); 742 # endif 743 } 744 # endif 745 #endif 746 747 #if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \ 748 || defined(__DJGPP__) 749 int ossl_pool_add_nonce_data(RAND_POOL *pool) 750 { 751 struct { 752 pid_t pid; 753 CRYPTO_THREAD_ID tid; 754 uint64_t time; 755 } data; 756 757 /* Erase the entire structure including any padding */ 758 memset(&data, 0, sizeof(data)); 759 760 /* 761 * Add process id, thread id, and a high resolution timestamp to 762 * ensure that the nonce is unique with high probability for 763 * different process instances. 764 */ 765 data.pid = getpid(); 766 data.tid = CRYPTO_THREAD_get_current_id(); 767 data.time = get_time_stamp(); 768 769 return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); 770 } 771 772 /* 773 * Get the current time with the highest possible resolution 774 * 775 * The time stamp is added to the nonce, so it is optimized for not repeating. 776 * The current time is ideal for this purpose, provided the computer's clock 777 * is synchronized. 778 */ 779 static uint64_t get_time_stamp(void) 780 { 781 # if defined(OSSL_POSIX_TIMER_OKAY) 782 { 783 struct timespec ts; 784 785 if (clock_gettime(CLOCK_REALTIME, &ts) == 0) 786 return TWO32TO64(ts.tv_sec, ts.tv_nsec); 787 } 788 # endif 789 # if defined(__unix__) \ 790 || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) 791 { 792 struct timeval tv; 793 794 if (gettimeofday(&tv, NULL) == 0) 795 return TWO32TO64(tv.tv_sec, tv.tv_usec); 796 } 797 # endif 798 return time(NULL); 799 } 800 801 #endif /* (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) 802 || defined(__DJGPP__) */ 803