static int seed_from_prngd(unsigned char *buf, size_t bytes) { #ifdef PRNGD_PORT debug("trying egd/prngd port %d", PRNGD_PORT); if (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == 0) return 0; #endif #ifdef PRNGD_SOCKET debug("trying egd/prngd socket %s", PRNGD_SOCKET); if (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == 0) return 0; #endif return -1; }
int main(int argc, char **argv) { unsigned char *buf; int ret, ch, debug_level, output_hex, bytes; extern char *optarg; LogLevel ll; __progname = get_progname(argv[0]); log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); ll = SYSLOG_LEVEL_INFO; debug_level = output_hex = 0; bytes = OUTPUT_SEED_SIZE; /* Don't write binary data to a tty, unless we are forced to */ if (isatty(STDOUT_FILENO)) output_hex = 1; while ((ch = getopt(argc, argv, "vxXhb:")) != -1) { switch (ch) { case 'v': if (debug_level < 3) ll = SYSLOG_LEVEL_DEBUG1 + debug_level++; break; case 'x': output_hex = 1; break; case 'X': output_hex = 0; break; case 'b': if ((bytes = atoi(optarg)) <= 0) fatal("Invalid number of output bytes"); break; case 'h': usage(); exit(0); default: error("Invalid commandline option"); usage(); } } log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1); #ifdef USE_SEED_FILES prng_read_seedfile(); #endif buf = xmalloc(bytes); /* * Seed the RNG from wherever we can */ /* Take whatever is on the stack, but don't credit it */ RAND_add(buf, bytes, 0); debug("Seeded RNG with %i bytes from system calls", (int)stir_from_system()); #ifdef PRNGD_PORT if (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == -1) fatal("Entropy collection failed"); RAND_add(buf, bytes, bytes); #elif defined(PRNGD_SOCKET) if (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == -1) fatal("Entropy collection failed"); RAND_add(buf, bytes, bytes); #else /* Read in collection commands */ if (prng_read_commands(SSH_PRNG_COMMAND_FILE) == -1) fatal("PRNG initialisation failed -- exiting."); debug("Seeded RNG with %i bytes from programs", (int)stir_from_programs()); #endif #ifdef USE_SEED_FILES prng_write_seedfile(); #endif /* * Write the seed to stdout */ if (!RAND_status()) fatal("Not enough entropy in RNG"); if (RAND_bytes(buf, bytes) <= 0) fatal("Couldn't extract entropy from PRNG"); if (output_hex) { for(ret = 0; ret < bytes; ret++) printf("%02x", (unsigned char)(buf[ret])); printf("\n"); } else ret = atomicio(write, STDOUT_FILENO, buf, bytes); memset(buf, '\0', bytes); xfree(buf); return ret == bytes ? 0 : 1; }