[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] Re: [RFC] ra_svn::make_nonce: how to cope with entropy shortages?

From: Jonathan Nieder <jrnieder_at_gmail.com>
Date: Thu, 3 Nov 2011 15:53:28 -0500

Daniel Shahaf wrote:
> On Thursday, November 03, 2011 12:44 AM, "Jonathan Nieder" <jrnieder_at_gmail.com> wrote:

>> Another possibility would be to enhance
>> apr's random number source API to allow requesting random bytes
>> without so much entropy (erandom/frandom) or without blocking on lack
>> of entropy (urandom).
>
> Fixing this by extending APR's API sounds good. Would the change be
> backportable to APR 1.4.x too?

I think a proper fix is possible without changing APR's API.
The calling sequence is something like this:

        state = apr_random_standard_new(pool);

        for (;;) {
                while (apr_random_secure_ready(state) == APR_ENOTENOUGHENTROPY) {
                        apr_generate_random_bytes(buf, sizeof(buf));
                        apr_random_add_entropy(state, buf, sizeof(buf));
                }

                apr_random_secure_bytes(state, ret, n);
                yield;
        }

Justification: that is how /dev/random seems to be meant to be used
(as source for a random seed, with userspace taking over after that).

Actually, using apr_random_insecure_bytes without seeding the
generator would be about as good, as far as I can tell. What is
important is that a given <nonce, timestamp> pair is not likely to be
repeated.

Complications:

 - This involves application-local state. Making the PRNG state
   per-thread would be fussy. And on the other hand if it's global,
   synchronizing between threads could hurt performance.

 - Could be controversial on platforms "where the built-in strong
   random number generator works just fine without blocking
   applications all the time" (but aren't good random numbers a scarce
   resource almost everywhere?).

[...]
> Something tells me that when a cryptographic protocol calls for random
> numbers then a quasiconstant or known value wouldn't do instead.

Right. It's not as bad as it sounds because abusing this requires

 (1) intercepting and replaying challenge responses in real time
 (2) getting your <nonce, timestamp, hostname> tuple to match the one
     from the challenge you intercepted. On affected installations,
     both the nonce and timestamp are timestamps with 1-microsecond
     resolution.

but it certainly looks like a problem to me.

So how about this to start, to avoid providing people on platforms
with !APR_HAS_RANDOM with a false sense of security?

[[[
* subversion/libsvn_ra_svn/cram.c (make_nonce): Refuse to build if
    APR_HAS_RANDOM is unset, instead of falling back to using a
    timestamp as nonce.
]]]

Index: subversion/libsvn_ra_svn/cram.c
===================================================================
--- subversion/libsvn_ra_svn/cram.c (revision 1197294)
+++ subversion/libsvn_ra_svn/cram.c (working copy)
@@ -117,18 +117,10 @@
   return svn_ra_svn_flush(conn, pool);
 }
 
-/* If we can, make the nonce with random bytes. If we can't... well,
- * it just has to be different each time. The current time isn't
- * absolutely guaranteed to be different for each connection, but it
- * should prevent replay attacks in practice. */
+/* Make the nonce with random bytes. */
 static apr_status_t make_nonce(apr_uint64_t *nonce)
 {
-#if APR_HAS_RANDOM
   return apr_generate_random_bytes((unsigned char *) nonce, sizeof(*nonce));
-#else
- *nonce = apr_time_now();
- return APR_SUCCESS;
-#endif
 }
 
 svn_error_t *svn_ra_svn_cram_server(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
Received on 2011-11-03 22:10:53 CET

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.