Hi,

upfront: sorry for double posting!! Some people told me, that I should send
my findings directly to the list instead of a link. Sorry if I  violated the
netiquette on the list!

So, here we go again (text from the forum where I posted it).

regarding the allegations about a backdoor beeing planted into OpenBSD, I
did a code review myself and I believe that I've found two bugs in the PRNG
code. I'm NOT saying that this is the backdoor or even part of the backdoor.
I'm not even saying, that these two bugs create a weakness in the PRNG
itself, however the two bugs just don't look good and possibly need more
investigation!!

Here we go...

OpenBSD uses arc4random() and arc4random_buf() all over the code to generate
random numbers. This code is defined in src/sys/dev/rnd.c.

Within arc4random() and arc4random_buf() the code flow is like this:

arc4random -> arc4maybeinit -> arc4_stir

arc4_stir() will be called at least every 10 minutes, as a timer is set
within arc4maybeinit() that resets the variable 'arc4random_initialized'
(see below).

> static void
> arc4maybeinit(void)
> {
>
>         if (!arc4random_initialized) {
> #ifdef DIAGNOSTIC
>                 if (!rnd_attached)
>                         panic("arc4maybeinit: premature");
> #endif
>                 arc4random_initialized++;
>                 arc4_stir();
>                 /* 10 minutes, per dm@'s suggestion */
>                 timeout_add_sec(&arc4_timeout, 10 * 60);
>         }
> }

Now, let's have a look at arc4_stir().

> arc4_stir(void)
> {
>         u_int8_t buf[256];
>         int len;
>
>         nanotime((struct timespec *) buf);
>         len = sizeof(buf) - sizeof(struct timespec);
>         get_random_bytes(buf + sizeof (struct timespec), len);
>         len += sizeof(struct timespec);
>
>         mtx_enter(&rndlock);
>        if (rndstats.arc4_nstirs > 0)
>                rc4_crypt(&arc4random_state, buf, buf, sizeof(buf));
>
>        rc4_keysetup(&arc4random_state, buf, sizeof(buf));
>        arc4random_count = 0;
>       rndstats.arc4_stirs += len;
>         rndstats.arc4_nstirs++;
>
>        /*
>         * Throw away the first N words of output, as suggested in the
>         * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
>         * by Fluher, Mantin, and Shamir.  (N = 256 in our case.)
>         */
>        rc4_skip(&arc4random_state, 256 * 4);
>        mtx_leave(&rndlock);
>
> }

This initializes the RC4 context with some random data, gathered by system
enthropy, that is mainly done by get_random_bytes().

==> Bug #1

HOWEVER: Have a look at the buffer that's beeing used as a seed for the RC4
key setup. It's beeing filled with the random data, BUT at the beginning it
will be filled with just the value of nanotime().

>        nanotime((struct timespec *) buf);
>        len = sizeof(buf) - sizeof(struct timespec);
>        get_random_bytes(buf + sizeof (struct timespec), len);
>        len += sizeof(struct timespec);


So, there is a lot of effort in get_random_bytes() to get "real random" data
for the buffer and then the value of nanotime() is prepended to the buffer?
That does not look right. Please consider: this buffer will be used as key
for  rc4_keysetup() and thus it should contain unrelated and unpredictable
data.

==> Bug #2

The function rc4_crypt() get's called as soon as rndstats.arc4_nstirs > 0.
This will be the case whenever arc4_stir get's called the second time (by
the timer reset - see above).

>        if (rndstats.arc4_nstirs > 0)
>                rc4_crypt(&arc4random_state, buf, buf, sizeof(buf));

>        rc4_keysetup(&arc4random_state, buf, sizeof(buf));
>        arc4random_count = 0;
>        rndstats.arc4_stirs += len;
>        rndstats.arc4_nstirs++;

HOWEVER, right after the call of rc4_crypt(), we call rc4_keysetup() with
the same 'arc4random_state'. This makes the call to rc4_crypt() useless, as
the data structure will be overwritten again with the init data of the RC4
function.

AGAIN: I'm not saying that this is part of the backdoor nor that it weakens
the PRNG. HOWEVER, this does not look right and leaves some bad feeling for
me!

I think we will need some investigation on the effect of PRNG quality caused
by these two bugs.

Regards
Kurt Knochner

http://knochner.com/

Reply via email to