static int seed_something(void) { #ifndef NO_RANDFILE char buf[1024], seedfile[256]; /* If there is a seed file, load it. But such a file cannot be trusted, so use 0 for the entropy estimate */ if (RAND_file_name(seedfile, sizeof(seedfile))) { int fd; fd = open(seedfile, O_RDONLY | O_BINARY | O_CLOEXEC); if (fd >= 0) { ssize_t ret; rk_cloexec(fd); ret = read(fd, buf, sizeof(buf)); if (ret > 0) RAND_add(buf, ret, 0.0); close(fd); } else seedfile[0] = '\0'; } else seedfile[0] = '\0'; #endif /* Calling RAND_status() will try to use /dev/urandom if it exists so we do not have to deal with it. */ if (RAND_status() != 1) { #if defined(HAVE_RAND_EGD) krb5_context context; const char *p; #ifndef OPENSSL_NO_EGD /* Try using egd */ if (!krb5_init_context(&context)) { p = krb5_config_get_string(context, NULL, "libdefaults", "egd_socket", NULL); if (p != NULL) RAND_egd_bytes(p, ENTROPY_NEEDED); krb5_free_context(context); } #endif #else /* TODO: Once a Windows CryptoAPI RAND method is defined, we can use that and failover to another method. */ #endif } if (RAND_status() == 1) { #ifndef NO_RANDFILE /* Update the seed file */ if (seedfile[0]) RAND_write_file(seedfile); #endif return 0; } else return -1; }
/* * call-seq: * egd_bytes(filename, length) -> true * */ static VALUE ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len) { SafeStringValue(filename); if (!RAND_egd_bytes(RSTRING_PTR(filename), FIX2INT(len))) { ossl_raise(eRandomError, NULL); } return Qtrue; }
int SslContext::seedRand(int len) { static int fd = open("/dev/urandom", O_RDONLY | O_NONBLOCK); char achBuf[2048]; int ret; if (fd >= 0) { int toRead; do { toRead = sizeof(achBuf); if (len < toRead) toRead = len; ret = read(fd, achBuf, toRead); if (ret > 0) { RAND_seed(achBuf, ret); len -= ret; } } while ((len > 0) && (ret == toRead)); fcntl(fd, F_SETFD, FD_CLOEXEC); //close( fd ); } else { #ifdef DEVRANDOM_EGD /* Use an EGD socket to read entropy from an EGD or PRNGD entropy * collecting daemon. */ static const char *egdsockets[] = { "/var/run/egd-pool", "/dev/egd-pool", "/etc/egd-pool" }; for (egdsocket = egdsockets; *egdsocket && n < len; egdsocket++) { ret = RAND_egd_bytes(*egdsocket, len); if (ret > 0) len -= ret; } #endif } if (len == 0) return 0; if (len > (int)sizeof(achBuf)) len = (int)sizeof(achBuf); gettimeofday((timeval *)achBuf, NULL); ret = sizeof(timeval); *(pid_t *)(achBuf + ret) = getpid(); ret += sizeof(pid_t); *(uid_t *)(achBuf + ret) = getuid(); ret += sizeof(uid_t); if (len > ret) memmove(achBuf + ret, achBuf + sizeof(achBuf) - len + ret, len - ret); RAND_seed(achBuf, len); return 0; }
int RAND_egd(const char *filename) { return RAND_egd_bytes(filename, 128); }