[openssl-users] RNG behavior by default

Steffen Nurpmeso steffen at sdaoden.eu
Sat Jan 5 19:33:18 UTC 2019


Good evening.

Please excuse the late reply.

Kurt Roeckx wrote in <20190104180735.GA25041 at roeckx.be>:
 |On Fri, Jan 04, 2019 at 02:48:48PM +0100, Steffen Nurpmeso wrote:
 |> Dr. Matthias St. Pierre wrote in <450169f8ca7c43d1841c4c8052e78c72 at Ex13.\
 |> ncp.local>:
 ...
 |>|2. If something goes wrong with PRNG initialization, that it will fail \
 |>|hard rather than fall back to something less secure. And if so how \
 |>|I detect such a failure.
 |>|
 |>|If the (re-)seeding fails, the DRBG enters an error state. When you \
 |>|try to generate random bytes it will detect the error state and try
 |>|automatically to heal the error state by reinstantiating. But if \
 |>|reseeding \
 |>|fails, it will return and error code and not generate any pseudo random \
 |>|bytes.
 |>|
 |>|Citing from the manual pages:
 |>  ...
 |>| As a normal application developer, you do not have to worry about \
 |>| any details, just use RAND_bytes(3)
 |>| to obtain random data. Having said that, there is one important rule \
 |>| to obey: Always check the error
 |>| return value of RAND_bytes(3) and do not take randomness for granted.
 |>|
 |>| https://www.openssl.org/docs/man1.1.1/man7/RAND.html
 |> 
 |> That is new however, _imho_.  The wording of RAND_bytes(3) (still)
 |> says that "an error occurs [.if.] not [been] seeded with enough
 |> [data]", and RAND_status(3) returns 1 if the PRNG "has been seeded
 |> with enough data".  So if it is seeded it is seeded, in my
 |> understanding anything further on up the road only mixes in noise
 |> (which likely will undergo further maths and be stirred into the
 |> pool, i have not looked, actually).  I do not test RAND_bytes(3)
 |> return (yet), because i have ensured the PRNG is sufficiently
 |> seeded, and RAND_status(3) returns success, before RAND_bytes(3)
 |> is used the first time.
 |
 |For 1.1.0 and older that works, because they do not reseed. Since
 |1.1.1 it does reseed, and if the reseed fails, it will go to an
 |error state. So yes, this is new behavior.

Thanks.  Well this is good to know, i have to think about how
i will deal with this.

(I am also really interested and will look into OpenSSL to see if
the abort() that seems to happen if the initial seed fails is in
a linker-resolved constructor, and if not, why later failures do
not also abort.  Yes, while i am going, the full truth is that
i do not like it, i do not like that possibly a constructor call
is made for something that is possibly not needed, if it is done
like that, that someone simply aborts because of a some internal
PRNG, especially so if it is not in a constructor call and if
errors can and are expected to be handled by PRNG users anyway,
i do not like that the stuff is instantiated in all threads, which
in addition requires forks handlers to be installed all over the
place.  Now, on NetBSD for example, and because of libraries i am
linking in, i do have two complete sets of fork handlers and PRNG
buffers all over the place, one for NetBSD LibC, one for OpenSSL.
In my unfortunately not so humble opinion this looks like a modern
white first world child.  Including the postural defect.

I am sorry for this rant.  Yeah, i think OpenSSL even offers PRNG
objects which i can use and control directly, and through this
i regain a bit control of resource usage etc.  Without rewriting
software in order to pregenerate randoms in the main( manager)
thread to pass them through to jobs in thread pools.  Just look
for those and do not use the TSD/fork-aware RAND_bytes().
But before i become a total troll.. the Linux kernel that drives
the world from smallest to hugest has one internal entropy pool
that feeds two public pools, whereas i the lucent little hobby
server from user space get an armada of these.  Wow.

It is not your fault of course.  I am sorry for this rant.
Thanks for your answer.)

How do i deal with this?  Maybe i simply always use my builtin
ARC4, it is so small, or upgrade to ChaCha20 or so, and add
something like a Blake2 filter to protect that pool, and only
serve the output of it.  Or something.

 |The RAND_bytes and RAND_status manpages can clearly be improved.
 |Since you always have to check RAND_bytes's return value now,
 |RAND_status is mostly useless.

Yes, in my opinion good documentation is hard, almost impossible.
I am not using it, but i always enjoy reading the concise
(concise!  Says Mr. McIlroy.) yet helpful manuals from the really
great guys, for example the Plan9 manuals regarding programming.
Maybe a bit too concise for end-users, except academics.

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)


More information about the openssl-users mailing list