9

I have a device which generates some noise that I want to add to the entropy pool for the /dev/random device in an embedded Linux system.

I'm reading the man page on /dev/random and I don't really understand the structure that you pass into the RNDADDENTROPY ioctl call.

   RNDADDENTROPY
          Add some additional entropy to the input pool, incrementing
          the entropy count.  This differs from writing to /dev/random
          or /dev/urandom, which only adds some data but does not
          increment the entropy count.  The following structure is used:

              struct rand_pool_info {
                  int    entropy_count;
                  int    buf_size;
                  __u32  buf[0];
              };

          Here entropy_count is the value added to (or subtracted from)
          the entropy count, and buf is the buffer of size buf_size
          which gets added to the entropy pool.

Is entropy_count in this structure the number of bits that I am adding? Why wouldn't this just always be buf_size * 8 (assuming that buf_size is in terms of bytes)?

Additionally why is buf a zero size array? How am I supposed to assign a value to it?

Thanks for any help here!

Benjamin Leinweber
  • 2,774
  • 1
  • 24
  • 41

3 Answers3

4

I am using a hardware RNG to stock my entropy pool. My struct is a static size and looks like this (my kernel has a slightly different random.h; just copy what you find in yours and increase the array size to whatever you want):

#define BUFSIZE 256
/* WARNING - this struct must match random.h's struct rand_pool_info */
typedef struct {
    int bit_count;               /* number of bits of entropy in data */
    int byte_count;              /* number of bytes of data in array */
    unsigned char buf[BUFSIZ];
} entropy_t;

Whatever you pass in buf will be hashed and will stir the entropy pool. If you are using /dev/urandom, it does not matter what you pass for bit_count because /dev/urandom ignores it equaling zero and just keeps on going.

What bit_count does is push the point out at which /dev/random will block and wait for something to add more entropy from a physical RNG source. Thus, it's okay to guesstimate on bit_count. If you guess low, the worst that will happen is that /dev/random will block sooner than it otherwise would have. If you guess high, /dev/random will operate like /dev/urandom for a little bit longer than it otherwise would have before it blocks.

You can guesstimate based on the "quality" of your entropy source. If it's low, like characters typed by humans, you can set it to 1 or 2 per byte. If it's high, like values read from a dedicated hardware RNG, you can set it to 8 bits per byte.

  • This is a great explanation to a question that has been in the back of my mind for months now. – Benjamin Leinweber Sep 21 '13 at 15:24
  • 1
    According to my reading of the source code, the `ioctl()` on `/dev/urandom` *will* increase the entropy estimate. If you don't care to increase the entropy estimate, just use `write()`. Overestimating your entropy is harmful for things which use `/dev/random` because they *need* strong entropy (whether anything actually does is a source of plenty of debate). – tc. Dec 10 '13 at 10:41
1

If your data is perfectly random, then I believe it would be appropriate for entropy_count to be the number of bits in the buffer you provide. However, many (most?) sources of randomness aren't perfect, and so it makes sense for the buffer size and amount of entropy to be kept as separate parameters.

buf being declared to be size zero is a standard C idiom. The deal is that when you actually allocate a rand_pool_info, you do malloc(sizeof(rand_pool_info) + size_of_desired_buf), and then you refer to the buffer using the buf member. Note: With some C compilers, you can declare buf[*] instead of buf[0] to be explicit that in reality buf is "stretchy".

danfuzz
  • 4,253
  • 24
  • 34
  • Interesting. So let's say that my data is not totally random. What does it mean to have the entropy_count less than buf_size * 8. For instance what if I have two words of random data and pass in 16 into entropy_count. Does it use the most significant 16-bits of the entire buffer? The least significant bits? Something else? What does it mean to pass more data than entropy_count? – Benjamin Leinweber Jun 15 '13 at 07:35
  • The idea is that the entropy is spread through the entire buffer, not just limited to one end or the other. As such, what I'd expect is that the kernel does some sort of processing on the entire given buffer plus the pre-existing entropy state (e.g., taking a combined SHA hash of some sort). As an example of what it might mean to have entropy spread throughout: Perhaps your random source produces 99 bits of value 0 for every one of value 1. In that case, a given bit isn't great as a random bit, but when combined in some way each bit adds *some* entropy (though less than a bit per bit). – danfuzz Jun 15 '13 at 17:17
  • Hmm, looks like my comment yesterday didn't get posted. Ok, your answer makes a certain amount of sense to me, but it doesn't really tell me what to set entropy_count to. Taking your example, lets say I add 100 bits of data which statistically only one of those hundred bits is a 1. Does that mean I should set entropy_count to 1? Or is the relationship more complicated than that? – Benjamin Leinweber Jun 16 '13 at 16:39
  • Sorry, you've hit the limit of my knowledge on the topic. I bet you can find more authoritative info in the excellent book _Applied Cryptography_. – danfuzz Jun 16 '13 at 18:28
0

The number of bytes you have in the buffer correlates to the entropy of the data but the entropy can not be calculated only from that data or its length.

Sure, if the data came from a good, unpredictable and equal-distributed hardware random noise generatr the entropy (in bits) is 8*size of the buffer (in bytes).

But if the bits are not equally distributed or are somehow predictable the entropy becomes less.

See https://en.wikipedia.org/wiki/Entropy_(information_theory)

I hope that helps.

Roker
  • 1