static void do_save(const char *const filename) { int est1, est2; rndpoolstat_t rp; rndsave_t rs; SHA1_CTX s; int fd; fd = open(_PATH_URANDOM, O_RDONLY, 0644); if (fd < 0) { err(1, "device open"); } if (ioctl(fd, RNDGETPOOLSTAT, &rp) < 0) { err(1, "ioctl(RNDGETPOOLSTAT)"); } est1 = rp.curentropy; if (read(fd, rs.data, sizeof(rs.data)) != sizeof(rs.data)) { err(1, "entropy read"); } if (ioctl(fd, RNDGETPOOLSTAT, &rp) < 0) { err(1, "ioctl(RNDGETPOOLSTAT)"); } est2 = rp.curentropy; if (est1 - est2 < 0) { rs.entropy = 0; } else { rs.entropy = est1 - est2; } SHA1Init(&s); SHA1Update(&s, (uint8_t *)&rs.entropy, sizeof(rs.entropy)); SHA1Update(&s, rs.data, sizeof(rs.data)); SHA1Final(rs.digest, &s); close(fd); unlink(filename); fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, 0600); if (fd < 0) { err(1, "output open"); } if (write(fd, &rs, sizeof(rs)) != sizeof(rs)) { unlink(filename); fsync_range(fd, FDATASYNC|FDISKSYNC, (off_t)0, (off_t)0); err(1, "write"); } fsync_range(fd, FDATASYNC|FDISKSYNC, (off_t)0, (off_t)0); close(fd); }
static void do_load(const char *const filename) { int fd; rndsave_t rs, rszero; rnddata_t rd; SHA1_CTX s; uint8_t digest[SHA1_DIGEST_LENGTH]; fd = open(filename, O_RDWR, 0600); if (fd < 0) { err(1, "input open"); } unlink(filename); if (read(fd, &rs, sizeof(rs)) != sizeof(rs)) { err(1, "read"); } memset(&rszero, 0, sizeof(rszero)); if (pwrite(fd, &rszero, sizeof(rszero), (off_t)0) != sizeof(rszero)) err(1, "overwrite"); fsync_range(fd, FDATASYNC|FDISKSYNC, (off_t)0, (off_t)0); close(fd); SHA1Init(&s); SHA1Update(&s, (uint8_t *)&rs.entropy, sizeof(rs.entropy)); SHA1Update(&s, rs.data, sizeof(rs.data)); SHA1Final(digest, &s); if (memcmp(digest, rs.digest, sizeof(digest))) { errx(1, "bad digest"); } rd.len = MIN(sizeof(rd.data), sizeof(rs.data)); rd.entropy = rs.entropy; memcpy(rd.data, rs.data, MIN(sizeof(rd.data), sizeof(rs.data))); fd = open(_PATH_URANDOM, O_RDWR, 0644); if (fd < 0) { err(1, "device open"); } if (ioctl(fd, RNDADDDATA, &rd) < 0) { err(1, "ioctl"); } close(fd); }
int rumpuser_syncfd(int fd, int flags, uint64_t start, uint64_t len) { int rv = 0; /* * For now, assume fd is regular file and does not care * about read syncing */ if ((flags & RUMPUSER_SYNCFD_BOTH) == 0) { rv = EINVAL; goto out; } if ((flags & RUMPUSER_SYNCFD_WRITE) == 0) { rv = 0; goto out; } #ifdef __NetBSD__ { int fsflags = FDATASYNC; if (fsflags & RUMPUSER_SYNCFD_SYNC) fsflags |= FDISKSYNC; if (fsync_range(fd, fsflags, start, len) == -1) rv = errno; } #else /* el-simplo */ if (fsync(fd) == -1) rv = errno; #endif out: ET(rv); }