seedrng: simplify read_new_seed() to not have error return
gcc in fact detects this and does this transformation when generating code - no object code changes. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
282b61a649
commit
52f3cf7e5f
@ -75,31 +75,38 @@ static size_t determine_optimal_seed_len(void)
|
|||||||
return MAX(MIN(poolsize, MAX_SEED_LEN), MIN_SEED_LEN);
|
return MAX(MIN(poolsize, MAX_SEED_LEN), MIN_SEED_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable)
|
static bool read_new_seed(uint8_t *seed, size_t len)
|
||||||
{
|
{
|
||||||
|
bool is_creditable;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
ret = getrandom(seed, len, GRND_NONBLOCK);
|
ret = getrandom(seed, len, GRND_NONBLOCK);
|
||||||
if (ret == (ssize_t)len) {
|
if (ret == (ssize_t)len) {
|
||||||
*is_creditable = true;
|
return true;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (ret < 0 && errno == ENOSYS) {
|
if (ret < 0 && errno == ENOSYS) {
|
||||||
struct pollfd random_fd = {
|
struct pollfd random_fd = {
|
||||||
.fd = xopen("/dev/random", O_RDONLY),
|
.fd = xopen("/dev/random", O_RDONLY),
|
||||||
.events = POLLIN
|
.events = POLLIN
|
||||||
};
|
};
|
||||||
*is_creditable = poll(&random_fd, 1, 0) == 1;
|
is_creditable = poll(&random_fd, 1, 0) == 1;
|
||||||
|
//This is racy. is_creditable can be set to true here, but other process
|
||||||
|
//can consume "good" random data from /dev/urandom before we do it below.
|
||||||
close(random_fd.fd);
|
close(random_fd.fd);
|
||||||
} else {
|
} else {
|
||||||
*is_creditable = false;
|
|
||||||
if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len)
|
if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len)
|
||||||
return 0;
|
return false;
|
||||||
|
is_creditable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Either getrandom() is not implemented, or
|
||||||
|
* getrandom(GRND_INSECURE) did not give us LEN bytes.
|
||||||
|
* Fallback to reading /dev/urandom.
|
||||||
|
*/
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (open_read_close("/dev/urandom", seed, len) != (ssize_t)len)
|
if (open_read_close("/dev/urandom", seed, len) != (ssize_t)len)
|
||||||
bb_perror_msg_and_die("can't read '%s'", "/dev/urandom");
|
bb_perror_msg_and_die("can't read '%s'", "/dev/urandom");
|
||||||
return 0;
|
return is_creditable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void seed_rng(uint8_t *seed, size_t len, bool credit)
|
static void seed_rng(uint8_t *seed, size_t len, bool credit)
|
||||||
@ -190,17 +197,13 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
new_seed_len = determine_optimal_seed_len();
|
new_seed_len = determine_optimal_seed_len();
|
||||||
if (read_new_seed(new_seed, new_seed_len, &new_seed_creditable) < 0) {
|
new_seed_creditable = read_new_seed(new_seed, new_seed_len);
|
||||||
bb_perror_msg("can't%s seed", " read new");
|
|
||||||
new_seed_len = SHA256_OUTSIZE;
|
|
||||||
memset(new_seed, 0, SHA256_OUTSIZE);
|
|
||||||
program_ret |= 1 << 3;
|
|
||||||
}
|
|
||||||
sha256_hash(&hash, &new_seed_len, sizeof(new_seed_len));
|
sha256_hash(&hash, &new_seed_len, sizeof(new_seed_len));
|
||||||
sha256_hash(&hash, new_seed, new_seed_len);
|
sha256_hash(&hash, new_seed, new_seed_len);
|
||||||
sha256_end(&hash, new_seed + new_seed_len - SHA256_OUTSIZE);
|
sha256_end(&hash, new_seed + new_seed_len - SHA256_OUTSIZE);
|
||||||
|
|
||||||
printf("Saving %u bits of %screditable seed for next boot\n", (unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-");
|
printf("Saving %u bits of %screditable seed for next boot\n",
|
||||||
|
(unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-");
|
||||||
fd = open(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400);
|
fd = open(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400);
|
||||||
if (fd < 0 || full_write(fd, new_seed, new_seed_len) != (ssize_t)new_seed_len || fsync(fd) < 0) {
|
if (fd < 0 || full_write(fd, new_seed, new_seed_len) != (ssize_t)new_seed_len || fsync(fd) < 0) {
|
||||||
bb_perror_msg("can't%s seed", " write");
|
bb_perror_msg("can't%s seed", " write");
|
||||||
|
Loading…
Reference in New Issue
Block a user