Opened 19 months ago

Last modified 7 months ago

#14937 new bug

Tiny chunks of entropy from /dev/urandom

Reported by: kallisti5 Owned by: nobody
Priority: normal Milestone: Unscheduled
Component: Drivers Version: R1/Development
Keywords: urandom Cc:
Blocked By: Blocking:
Platform: All

Description (last modified by kallisti5)

/dev/urandom on Haiku seems to only offer up small 16 byte chunks of entropy. This behaviour differs from other platforms. I saw this while working on WireGuard under Haiku.

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <inttypes.h>


int
main() {
        int len = 128;
        int ret = 0;

        uint8_t key[len];

        int fd = open("/dev/urandom", O_RDONLY);
        if (fd < 0) {
                fprintf(stderr, "Unable to open /dev/urandom!");
                return fd;
        }

        int attempts = 0;
        while (ret < len) {
                ssize_t remaining = len - ret;
                ssize_t got = read(fd, key + ret, remaining);
                ret += got;
                if (attempts > 512) {
                        fprintf(stderr, "Unable to get enough entropy from /dev/urandom!");
                        close(fd);
                        return -1;
                }
                fprintf(stdout, "Attempt %d: Got %d, giving %d total!\n", attempts, got, ret);
                attempts++;
        }
        close(fd);
        return ret;
}

Result on Haiku:

~> ./a.out 
Attempt 0: Got 8, giving 8 total!
Attempt 1: Got 16, giving 24 total!
Attempt 2: Got 16, giving 40 total!
Attempt 3: Got 16, giving 56 total!
Attempt 4: Got 16, giving 72 total!
Attempt 5: Got 16, giving 88 total!
Attempt 6: Got 16, giving 104 total!
Attempt 7: Got 16, giving 120 total!
Attempt 8: Got 8, giving 128 total!

Result on Linux:

$ ./a.out 
Attempt 0: Got 128, giving 128 total!
$ ./a.out 
Attempt 0: Got 128, giving 128 total!
$ ./a.out 
Attempt 0: Got 128, giving 128 total!
$ ./a.out 
Attempt 0: Got 128, giving 128 total!
$ ./a.out 
Attempt 0: Got 128, giving 128 total!
$ ./a.out 
Attempt 0: Got 128, giving 128 total!
$ ./a.out 
Attempt 0: Got 128, giving 128 total!

Change History (5)

comment:1 by kallisti5, 19 months ago

Description: modified (diff)

comment:2 by waddlesplash, 17 months ago

We should probably replace our /dev/random and /dev/urandom with OpenBSD's, or some variant thereof.

comment:3 by pulkomandy, 17 months ago

We need to finish an arc4random implementation (we have a WIP one in Gerrit but it needs to be actually connected to entropy sources) and then we can easily use that for feeding the devices.

comment:4 by waddlesplash, 17 months ago

No, this is only for userland. The kernel random device behaves differently than this in the BSDs for a reason. For one, random and urandom behave the same way, and they both block only during the boot before the pool has been seeded. That way entropy is never "exhausted" like on Linux.

comment:5 by kallisti5, 7 months ago

rng-tools offers some neat test programs for random sources of data's... randomness.

Here are a few examples from my linux machine...

[root@eris ~]# cat /dev/hwrng | rngtest -t 10
rngtest 6.9
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rngtest: starting FIPS tests...
rngtest: bits received from input: 500040032
rngtest: FIPS 140-2 successes: 24987
rngtest: FIPS 140-2 failures: 15
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 3
rngtest: FIPS 140-2(2001-10-10) Runs: 7
rngtest: FIPS 140-2(2001-10-10) Long run: 5
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=992.744; avg=71153.961; max=19531250.000)Kibits/s
rngtest: FIPS tests speed: (min=58.869; avg=152.150; max=185.179)Mibits/s
rngtest: Program run time: 10016917 microseconds
[root@eris ~]# cat /dev/random | rngtest -t 10
rngtest 6.9
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rngtest: starting FIPS tests...
rngtest: bits received from input: 72700032
rngtest: FIPS 140-2 successes: 3632
rngtest: FIPS 140-2 failures: 3
rngtest: FIPS 140-2(2001-10-10) Monobit: 1
rngtest: FIPS 140-2(2001-10-10) Poker: 1
rngtest: FIPS 140-2(2001-10-10) Runs: 1
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=2.064; avg=7.433; max=8.504)Mibits/s
rngtest: FIPS tests speed: (min=56.936; avg=103.244; max=183.399)Mibits/s
rngtest: Program run time: 10000423 microseconds
[root@eris ~]# cat /dev/urandom | rngtest -t 10
rngtest 6.9
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rngtest: starting FIPS tests...
rngtest: bits received from input: 1788660032
rngtest: FIPS 140-2 successes: 89373
rngtest: FIPS 140-2 failures: 60
rngtest: FIPS 140-2(2001-10-10) Monobit: 9
rngtest: FIPS 140-2(2001-10-10) Poker: 12
rngtest: FIPS 140-2(2001-10-10) Runs: 18
rngtest: FIPS 140-2(2001-10-10) Long run: 21
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=476.837; avg=20203.708; max=19073.486)Mibits/s
rngtest: FIPS tests speed: (min=68.857; avg=172.168; max=185.179)Mibits/s
rngtest: Program run time: 10001792 microseconds

And my TrueRNG USB dongle.

[root@eris ~]# cat /dev/TrueRNG | rngtest -t 10
rngtest 6.9
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rngtest: starting FIPS tests...
rngtest: bits received from input: 3360032
rngtest: FIPS 140-2 successes: 168
rngtest: FIPS 140-2 failures: 0
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 0
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=325.570; avg=329.150; max=335.508)Kibits/s
rngtest: FIPS tests speed: (min=70.905; avg=97.157; max=174.986)Mibits/s
rngtest: Program run time: 10003878 microseconds
Note: See TracTickets for help on using tickets.