Do not seed PRNG with uninitialised stack buffer.

Use instead some rand() filled buffer, only if OpenSSL has failed to find other source of entropy (in which case we complain at LOG_LEVEL_INFO). An example is a chroot missing ```/dev/urandom```. Even then, the sysadmin can alleviate the problem by writing random bytes to ```WORKDIR/randseed``` file.

Resolves [redmine 6468](https://dev.cfengine.com/issues/6468), [redmine 6476](https://dev.cfengine.com/issues/6476), superseeds [pull request 1887](https://github.com/cfengine/core/pull/1887), [pull request 1888](https://github.com/cfengine/core/pull/1888).
And still what you wrote does not guarantee that the random number is not
biased, so it's still flawed! But remember, this whole discussion is about
perfecting the *fallback* seeding routine, which should not happen anyway
if the sysadmin fixes the previous INFO message. So why is this an issue?


On Mon, Sep 1, 2014 at 4:37 PM, Edward Welbourne <notifications@github.com>
wrote:

> In libpromises/crypto.c:
>
> > -        RAND_seed(&now, sizeof(time_t));
> > -        char uninitbuffer[100];
> > -        RAND_seed(uninitbuffer, sizeof(uninitbuffer));
> > +        /* TODO raise to LOG_LEVEL_WARNING? */
> > +        Log(LOG_LEVEL_INFO,
> > +            "PRNG hasn't been seeded enough, using some pseudo-random bytes for seed!");
> > +        Log(LOG_LEVEL_INFO,
> > +            "A workaround is to copy 1KB of random bytes to '%s'",
> > +            randfile);
> > +
> > +        unsigned char rand_buf[128];
> > +        for (size_t i = 0; i < sizeof(rand_buf); i++)
> > +        {
> > +            rand_buf[i] = rand() % 256;
> > +        }
> > +        RAND_seed(rand_buf, sizeof(rand_buf));
>
> ... and RAND_MAX is guaranteed to be at least 32767 = 0x7fff, so you could
> at least use a uint16_t [64]; that might leave one clear bit per sixteen,
> but bumping the buffer size up to [69] would ensure you get as much noise
> as before.
>
> To use all bits and nothing else (probably more hassle than it's worth):
>
> unsigned char noise[128];
> size_t i = sizeof(noise);
> unsigned int word = RAND_MAX;
> int rmbits = 0, live = 0;
> while (word) { rmbits += 1; word >>= 1; } /* rmbits = number of bits in RAND_MAX */
> /* The least significant 'live' bits of 'word' are entropic. */
> while (i > 0)
> {
>     i--;
>     if (live < CHAR_BIT) { word |= rand() << live; live += rmbits; }
>     noise[i] = word; /* let type-coercion handle the reduction modulo 1<<CHAR_BIT */
>     word >>= CHAR_BIT;
>     live -= CHAR_BIT;
> }
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/cfengine/core/pull/1944/files#r16956691>.
>