
Arc4random – randomization for all occasions - edwintorok
http://www.openbsd.org/papers/hackfest2014-arc4random/index.html
======
protomyth
Link to Hackfest 2014: Theo de Raadt presented "arc4random - randomization for
all occasions" video

[https://www.youtube.com/watch?v=aWmLWx8ut20](https://www.youtube.com/watch?v=aWmLWx8ut20)

via [http://www.bsdnow.tv/episodes/](http://www.bsdnow.tv/episodes/) a great
podcast with ep 64 talking about the presentation and whole lot more.

------
acqq
The two (for me) important slides:

[http://www.openbsd.org/papers/hackfest2014-arc4random/mgp000...](http://www.openbsd.org/papers/hackfest2014-arc4random/mgp00016.html)

    
    
        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...](http://www.openbsd.org/papers/hackfest2014-arc4random/mgp00041.html)

    
    
        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/](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.

~~~
wereHamster
> EFAULT buf is outside the accessible address space.

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...

~~~
acqq
Once we commit ourselves to write some C code some kinds of failures are
expected and the ones you point to are of that kind. The topic here are
actually the ones not expected by a C programmer who wishes to use the API
function. I don't want this discussion to digress to talking about some other
languages even if we all know they exist and can avoid the kind of errors you
describe. That's still off topic.

------
101914
All occasions, even shell scripts.

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

~~~
acveilleux
It's simpler to dd from /dev/[u]random however and in OpenBSD, you'll get
exactly the same quality result. Most of the benefits of arc4random() are
nullified by invoking gcc...

~~~
101914
OK, I feel stupid. How would I get a random number using dd and /dev/urandom?

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?

~~~
acveilleux
This dd(1) command line would get 1 block of 4 bytes from the /dev/random file
and output it to stdout. Effectively the same as a call to arc4random():

dd if=/dev/random count=1 bs=4

On Linux, you'd use /dev/urandom cause /dev/random blocks stupidly.

~~~
101914
Agreed. But I want a pseudorandom real _number_ in decimal, to use in a shell
script, not just random bytes.

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

------
edwintorok
Shouldn't glibc provide an arc4random? Apparently the new syscall is not for
direct use [1], and you might not want to link with LibreSSL just to get
arc4random [2]

[1]
[http://www.openbsd.org/papers/hackfest2014-arc4random/mgp000...](http://www.openbsd.org/papers/hackfest2014-arc4random/mgp00041.html)
[2]
[http://www.openbsd.org/papers/hackfest2014-arc4random/mgp000...](http://www.openbsd.org/papers/hackfest2014-arc4random/mgp00040.html)

~~~
throwaway2048
The chances of glibc importing openbsd derived functions are practically nil
unfortunately, as we saw with the strlcat saga. With the departure of Drepper,
things might have changed, but strlcat is still not imported.

~~~
sarciszewski
What is the reason for that? :(

~~~
IvyMike
Drepper's caustic style aside, his point ultimately was that truncation is
still a problem. Whether or not you think glibc should include strlcat, this
is an important point to understand.

More discussion here:
[http://stackoverflow.com/q/2114896/67591](http://stackoverflow.com/q/2114896/67591)

~~~
tedunangst
Note that you can mechanically translate strcat(dst, src) to strlcat(dst, src,
SIZE_MAX) with no loss of functionality or change in behavior. No worries
about truncation, either. Exactly the same thing.

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?

