Arc4random – randomization for all occasions
openbsd.org
openbsd.org
https://www.youtube.com/watch?v=aWmLWx8ut20
via http://www.bsdnow.tv/episodes/ a great podcast with ep 64 talking about the presentation and whole lot more.
http://www.openbsd.org/papers/hackfest2014-arc4random/mgp000...
rc4random cannot fail
Look at the function definitions:
uint32_t
arc4random(void);
void
arc4random_buf(void *buf, size_t nbytes);
uint32_t
arc4random_uniform(uint32_t upper_bound);
All 3 functions guarantee a result. They will not fail, and cannot
return an error.
http://www.openbsd.org/papers/hackfest2014-arc4random/mgp000... Linux?
We have encouraged Ted Ts'o to create a getentropy-like interface
for Linux; getrandom()
Too many options, too easy to misuse
Interactions with signal handlers (EINTR)
Hope applications do not directly call getrandom()...
Bit worrying
Really feels like there is pressure against easy-access random..
"Use /dev/random" meme continues damaging effects
Linux's getrandom really has a bunch of error codes:http://lwn.net/Articles/606202/
EINVAL An invalid flag was passed to getrandom(2)
EFAULT buf is outside the accessible address space.
EAGAIN The requested entropy was not available, and the
getentropy(2) would have blocked if GRND_BLOCK flag
was set.
EINTR While blocked waiting for entropy, the call was
interrupted by a signal handler; see the description
of how interrupted read(2) calls on "slow" devices
are handled with and without the SA_RESTART flag
in the signal(7) man page.
And a few flags: GRND_NONBLOCK Don't block and return EAGAIN instead
GRND_RANDOM Use the /dev/random pool instead of /dev/urandom
I agree that the best interface is the one that can't fail.From the OpenBSD Manpage:
getentropy() will succeed unless:
[EFAULT]
The buf parameter points to an invalid address.
[EIO]
Too many bytes requested, or some other fatal error occurred.
See: http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/...http://lwn.net/Articles/606552/
int getentropy(void *buf, size_t buflen)
{
int ret;
if (buflen > 256)
goto failure;
ret = getrandom(buf, buflen, 0);
if (ret < 0)
return ret;
if (ret == buflen)
return 0;
failure:
errno = EIO;
return -1;
}
Note the magical 256 number. It's important.I wonder how arc4random_buf(NULL, 42) behaves. Or what happens if you pass it a pointer to an invalid memory location. Yeah, can't fail, right...
Not a "failure" of the libc call per se and it terminates the caller app which, frankly, is the only safe thing to do.
The Linux equivalent, while it can fail could be wrapped in a libc version that emulates arc4random behaviour (provide random or kill the app really.)
For example to choose a pseudorandom entry from a (reasonably short) list and set it as an environmental variable:
echo "main(){ arc4random();}" |gcc -x c -pipe -o arc4random -static -
b1=$(sed -n '$!D;=' .list); c1=$((b1/255)); arc4random; d1=$(($?*c1)); VARIABLE=$( sed ''"$d1"'!d;'"$d1"'q' .list ); echo $VARIABLE
echo $(( $RANDOM << 15 | $RANDOM ))
to get 30 bits?I am not sure I understand the gcc comment. Can you explain?
Assuming I cannot get a random number from dd'ing /dev/urandom then I needed a utility to do it where the system only has a small base and does not have gcc.
Unangst's suggestion to use sysctl is better (although it means I have to crunch the sysctl utility). I will be using that from now on. Thank you for the tip!
As for $RANDOM, that may be OpenBSD-specific. For example, does NetBSD have it?
dd if=/dev/random count=1 bs=4
On Linux, you'd use /dev/urandom cause /dev/random blocks stupidly.
I gave your solution a try.
a=$(dd if=/dev/urandom bs=4 count=1|od -An -tx1|sed 's/ //g')
printf %d\\n 0x$a[1] http://www.openbsd.org/papers/hackfest2014-arc4random/mgp000... [2] http://www.openbsd.org/papers/hackfest2014-arc4random/mgp000...
Framing this as a general rejection of APIs because they are from OpenBSD is highly disingenuous.
More discussion here: http://stackoverflow.com/q/2114896/67591
Now, if reading a piece of code that does strlcat(dst, src, SIZE_MAX) would make you feel uncomfortable, the question is how should you feel reading code that uses strcat?