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

Disconnect between docs and source - entropy every 60 or 600 seconds? #82

Open
VA1DER opened this issue Sep 15, 2024 · 6 comments
Open

Comments

@VA1DER
Copy link

VA1DER commented Sep 15, 2024

There is a disconnect between the documentation, where the README states:

HAVEGED now inserts entropy into the kernel every 60 seconds, regardless of the entropy level reported by Linux Kernel.

...and the source code, which reads:

      if (t[1] - t[0] > 600) {
        /* add entropy on daemon start and then every 600 seconds unconditionally */
        nbytes = poolSize;
        ...

Every ten minutes is far too long to be useful in any real sense. Recommend this be reduced to the stated 60 seconds. It could actually be useful to further reduce this, and/or make it settable on the command-line.

Just by way of explanation of my use case, I employ several VPSes which produce CPUs that report having "rdrand", but which I have verified that "rdrand" is not actually being passed on to the host CPU. Where it's going, I don't know, but I want to employ haveged to salt my entropy pool regularly. I think it would be useful on such systems to use haveged inject entropy at much lower intervals, perhaps as low as every 5 seconds.

@jirka-h
Copy link
Owner

jirka-h commented Oct 1, 2024

Good point!

I have set the default to 60 seconds and added a new command-line parameter, --time-interval or -T, to set the value from the command line. Please note that the check is done every ~ 2 seconds.

haveged --Foreground --verbose -w 1024 -T 5
strace -p 675656
strace: Process 675656 attached
pselect6(5, [3], [4], NULL, {tv_sec=1, tv_nsec=664107551}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
ioctl(4, RNDADDENTROPY, {entropy_count=2048, buf_size=256, buf="\342up3q\352\rbR\275=^\204\313p\250\310r/.\362hg8\20\2267\334\311U\234\324"...}) = 0
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
ioctl(4, RNDADDENTROPY, {entropy_count=2048, buf_size=256, buf=";\347/\332o\245x\365\254\265O\366\206\313w\260\245\310\27e\267\345E<\204\214\375\315\326U60"...}) = 0
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
ioctl(4, RNDADDENTROPY, {entropy_count=2048, buf_size=256, buf="\31\21\240\206\256d\316?\336\37ZG\314\26N\244\343\300\177\226\234\351\356K=\327^\1\366\336\32\353"...}) = 0
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
ioctl(4, RNDADDENTROPY, {entropy_count=2048, buf_size=256, buf=";/~7?E:Y\345-\356\241&g\370\344\300\211\3229\5\2G\355o\240Bg\244:\320n"...}) = 0
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
pselect6(5, [3], [4], NULL, {tv_sec=2, tv_nsec=0}, {sigmask=[], sigsetsize=8}) = 0 (Timeout)
ioctl(4, RNDADDENTROPY, {entropy_count=2048, buf_size=256, buf="\0261\232\211\305\346.9\3460o\261\211S\275\200z,\33Y\362\24\204\246\307\26\332\312\346\t(."...}) = 0

Please let me know if it works for you. I will then release the new version.

deff543#diff-043ded6506fb937c60ed15d0e9cfe02d6de6c72bcbd0bb14b7ad5e64ee7a6713R168

@VA1DER
Copy link
Author

VA1DER commented Oct 1, 2024

That's perfect. Thanks so much for looking at this so quickly.

BTW, do you happen to have any relationship with the Debian package maintainers for this? I would like to convince them this is a bug fix worthy of getting a package update for into Debian 12 rather than wait for 13 (just to cut down on manually tweaked services).

@jirka-h
Copy link
Owner

jirka-h commented Oct 2, 2024

OK, I have released a new version:
https://github.com/jirka-h/haveged/releases/tag/v1.9.19

I'm sorry, I have no contact with Debian package maintainers. I manage Fedora packages.

@VA1DER
Copy link
Author

VA1DER commented Oct 15, 2024

Both Debian package maintainers retired. I'm considering volunteering for the post myself.

I'm looking more closely at the timed injections. I wasn't sure the timed entropy injections were happening because they weren't logged and weren't affecting the numbers when haveged terminated. I now think it's just a stats/logging bug in the timed injection code:

+++ haveged-1.9.19_test/src/haveged.c   2024-10-15 14:17:10.264256154 -0300
@@ -697,10 +697,11 @@
         /* entropy is 8 bits per byte */
         output->entropy_count = nbytes * 8;
         if (ioctl(random_fd, RNDADDENTROPY, output) == -1)
           error_exit("RNDADDENTROPY failed!");
         h->n_entropy_bytes += nbytes;
+        h->n_fills += 1;
         if (params->once == 1) {
           params->exit_code = 0;
           error_exit("Entropy refilled once (%d bytes), exiting.", nbytes);
         }
         if (0 != (params->verbose & H_RNDADDENTROPY_INFO) && h->n_fills > fills) {

Sorry I didn't catch this earlier.

Timed injections are happening on time, they just aren't getting printed when logging is enabled, and don't affect the stats at termination.

@jirka-h
Copy link
Owner

jirka-h commented Oct 15, 2024

Both Debian package maintainers retired.
I'm sorry to hear that. I maintain a couple of Fedora packages, and we have to deal with orphaned packages as well.

I'm considering volunteering for the post myself.
Go for it - from my experience, it won’t take much of your time.

Regarding h->n_fills , I have reviewed the code, and it represents how many times the internal haveged buffer was refilled. See https://github.com/jirka-h/haveged/blob/master/src/havegecollect.c#L273

I think you are looking for another counter - how many times entropy was added to kernel. There is currently no variable for that but we can certainly add one.

@VA1DER
Copy link
Author

VA1DER commented Oct 18, 2024

I can't speak to the rest of haveged, but the code above is clearly set up to log if an only if h->n_fills > fill. It first sets fill = n_fills in line 693, does the injection into the kernel, updates the number of bytes in another counter, h->n_entropy_bytes then tests if h->n_fills > fills and then logs based on n_entropy_bytes and n_fills. If the intention is for h->n_fills NOT to be the counter for this section, then the logging code is all wrong. If this log is supposed to tell you how many bytes are added to the internal pool, it's not doing that.

It looks to me like whomever wrote this section either also didn't understand what n_fills is for, or else n_fills was for this purpose originally and got co-opted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants