Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linux: add forced CRNG reseed option for newer kernels #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions software/infnoise.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void term(int signum)
static void initOpts(struct opt_struct *opts) {
opts->outputMultiplier = 0u;
opts->feedFreq = 30u;
opts->forceReseed = false;
opts->daemon = false;
opts->debug = false;
opts->devRandom = false;
Expand All @@ -50,6 +51,7 @@ static struct option longopts[] = {
{"raw", no_argument, NULL, 'r'},
{"debug", no_argument, NULL, 'D'},
{"dev-random", no_argument, NULL, 'R'},
{"reseed-crng", no_argument, NULL, 'C'},
{"no-output", no_argument, NULL, 'n'},
{"feed-frequency", required_argument, NULL, 'f'},
{"multiplier", required_argument, NULL, 'm'},
Expand All @@ -62,7 +64,7 @@ static struct option longopts[] = {
{NULL, 0, NULL, 0}};

// Write the bytes to either stdout, or /dev/random.
bool outputBytes(uint8_t *bytes, uint32_t length, uint32_t entropy, bool writeDevRandom, uint32_t feedFrequency, const char **message) {
bool outputBytes(uint8_t *bytes, uint32_t length, uint32_t entropy, bool writeDevRandom, bool forceKernelReseed, uint32_t feedFrequency, const char **message) {
if (!writeDevRandom) {
if (fwrite(bytes, 1, length, stdout) != length) {
*message = "Unable to write output from Infinite Noise Multiplier";
Expand Down Expand Up @@ -99,6 +101,9 @@ bool outputBytes(uint8_t *bytes, uint32_t length, uint32_t entropy, bool writeDe
#ifdef LINUX
inmWaitForPoolToHaveRoom(feedFrequency);
inmWriteEntropyToPool(bytes, length, entropy);
if(forceKernelReseed) {
inmForceKernelRngReseed();
}
#endif
}
return true;
Expand All @@ -113,7 +118,7 @@ int main(int argc, char **argv) {
initOpts(&opts);

// Process arguments
while ((ch = getopt_long(argc, argv, "rDRnf:m:p:s:dlvh", longopts, NULL)) !=
while ((ch = getopt_long(argc, argv, "rDRCnf:m:p:s:dlvh", longopts, NULL)) !=
-1) {
switch (ch) {
case 'r':
Expand All @@ -125,6 +130,9 @@ int main(int argc, char **argv) {
case 'R':
opts.devRandom = true;
break;
case 'C':
opts.forceReseed = true;
break;
case 'n':
opts.noOutput = true;
break;
Expand Down Expand Up @@ -183,6 +191,7 @@ int main(int argc, char **argv) {
" -D, --debug - turn on some debug output\n"
" -R, --dev-random - write entropy to /dev/random instead of "
"stdout\n"
" -C, --reseed-crng - force reseed of /dev/random on write\n"
" -r, --raw - do not whiten the output\n"
" -m, --multiplier <value> - write 256 bits * value for each 512 bits written to\n"
" the Keccak sponge. Default of 0 means write all the entropy.\n"
Expand Down Expand Up @@ -311,7 +320,7 @@ int main(int argc, char **argv) {
}

if (!opts.noOutput
&& !outputBytes(result, bytesWritten, context.entropyThisTime, opts.devRandom, opts.feedFreq, &context.message)) {
&& !outputBytes(result, bytesWritten, context.entropyThisTime, opts.devRandom, opts.forceReseed, opts.feedFreq, &context.message)) {
fprintf(stderr, "Error: %s\n", context.message);
return 1;
}
Expand Down
2 changes: 2 additions & 0 deletions software/infnoise.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct opt_struct {
bool daemon; // Run as daemon?
bool debug; // Print debugging info?
bool devRandom; // Feed /dev/random?
bool forceReseed; // Force reseed when feeding /dev/random?
bool noOutput; // Supress output?
bool listDevices; // List possible USB-devices?
bool help; // Show help
Expand All @@ -28,6 +29,7 @@ struct opt_struct {
void inmWriteEntropyStart(uint32_t bufLen, bool debug);
void inmWriteEntropyEnd();
void inmWriteEntropyToPool(uint8_t *bytes, uint32_t length, uint32_t entropy);
void inmForceKernelRngReseed();
void inmWaitForPoolToHaveRoom(uint32_t feedFreq);

void startDaemon(struct opt_struct *opts);
14 changes: 14 additions & 0 deletions software/writeentropy.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// This writes entropy to the Linux /dev/random pool using ioctl, so that entropy increases.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -59,6 +60,19 @@ void inmWriteEntropyEnd() {
free( inmPoolInfo );
}

// recent Linux kernels seldomly reseed from the input pool (60s),
// this call can be used to force faster reseeds
void inmForceKernelRngReseed() {
#ifdef RNDRESEEDCRNG
// printf("force CRNG reseed\n");
if(ioctl(pfd.fd, RNDRESEEDCRNG) < 0 && errno != EINVAL) {
fprintf(stderr, "RNDRESEEDCRNG on /dev/random failed.\n");
}
#else
fprintf(stderr, "/dev/random does not support RNDRESEEDCRNG\n");
#endif
}

// Block until either the entropy pool has room, or 1 minute has passed.
void inmWaitForPoolToHaveRoom(uint32_t feed_frequency) {
int ent_count;
Expand Down