Opened 10 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:
Has a Patch: no 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 (4)

comment:1 by kallisti5, 10 months ago

Description: modified (diff)

comment:2 by waddlesplash, 7 months ago

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

comment:3 by pulkomandy, 7 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, 7 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.

Note: See TracTickets for help on using tickets.