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