double stir_from_programs(void) { int c; double entropy, total_entropy; unsigned char hash[SHA_DIGEST_LENGTH]; total_entropy = 0; for(c = 0; entropy_cmds[c].path != NULL; c++) { if (!entropy_cmds[c].badness) { /* Hash output from command */ entropy = hash_command_output(&entropy_cmds[c], hash); /* Scale back estimate by command's rate */ entropy *= entropy_cmds[c].rate; /* Upper bound of entropy is SHA_DIGEST_LENGTH */ if (entropy > SHA_DIGEST_LENGTH) entropy = SHA_DIGEST_LENGTH; /* Stir it in */ RAND_add(hash, sizeof(hash), entropy); debug3("Got %0.2f bytes of entropy from '%s'", entropy, entropy_cmds[c].cmdstring); total_entropy += entropy; /* Execution time should be a bit unpredictable */ total_entropy += stir_gettimeofday(0.05); total_entropy += stir_clock(0.05); total_entropy += stir_rusage(RUSAGE_SELF, 0.1); total_entropy += stir_rusage(RUSAGE_CHILDREN, 0.1); } else { debug2("Command '%s' disabled (badness %d)", entropy_cmds[c].cmdstring, entropy_cmds[c].badness); if (entropy_cmds[c].badness > 0) entropy_cmds[c].badness--; } } return total_entropy; }
bool hash_multicommand_output(struct mdfour *hash, const char *commands, const char *compiler) { char *command_string, *command, *p, *saveptr = NULL; bool ok = true; command_string = x_strdup(commands); p = command_string; while ((command = strtok_r(p, ";", &saveptr))) { if (!hash_command_output(hash, command, compiler)) { ok = false; } p = NULL; } free(command_string); return ok; }