commit 7ce0a3f8a6eead1f1d835f745d23bc4c2ab21bb7
parent e154ae81202e274d51d869d4d4834c96dd6668d4
Author: Christian Grothoff <christian@grothoff.org>
Date: Fri, 21 Nov 2025 20:12:06 +0100
make sure mhd_rng() only provides strictly good entropy, no weaker fallback; leave fallback to the gen_new_nonce logic
Diffstat:
3 files changed, 84 insertions(+), 232 deletions(-)
diff --git a/src/mhd2/auth_digest.c b/src/mhd2/auth_digest.c
@@ -304,11 +304,6 @@ gen_new_nonce (struct MHD_Daemon *restrict d,
uint_fast32_t *restrict expir)
{
uint_fast64_t expiration;
-#define OLD 1
-#if OLD
- size_t gen_num;
- union DigestCtx d_ctx;
-#endif
mhd_assert (! mhd_D_HAS_MASTER (d)); /* only master daemon should be used */
mhd_assert (d == c->daemon);
@@ -317,103 +312,102 @@ gen_new_nonce (struct MHD_Daemon *restrict d,
expiration = mhd_monotonic_msec_counter ()
+ d->auth_dg.cfg.nonce_tmout * (uint_fast64_t) 1000;
- // TODO: replace with pure random number
-
-#if ! OLD
- if (! mhd_rng (d,
- c,
- mhd_AUTH_DIGEST_NONCE_BIN_SIZE,
+ if (! mhd_rng (mhd_AUTH_DIGEST_NONCE_BIN_SIZE,
out_buf))
- return false;
-#else
+ {
+ /* Fallback to generating nonce from application-provided
+ entropy. Note: this should fail if we do not have
+ application-provided entropy. */
+ size_t gen_num;
+ union DigestCtx d_ctx;
- gen_num = mhd_atomic_counter_get_inc_wrap (&(d->auth_dg.num_gen_nonces));
+ gen_num = mhd_atomic_counter_get_inc_wrap (&(d->auth_dg.num_gen_nonces));
#if defined(MHD_SUPPORT_SHA512_256)
- mhd_SHA512_256_init_one_time (&(d_ctx.sha512_256_ctx));
- mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
- d->auth_dg.entropy.size,
- (const uint8_t*) d->auth_dg.entropy.data);
- mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
- sizeof(gen_num),
- (const uint8_t*) &gen_num);
- if (0 != c->sk.addr.size)
+ mhd_SHA512_256_init_one_time (&(d_ctx.sha512_256_ctx));
mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
- c->sk.addr.size,
- (const uint8_t*) c->sk.addr.data);
- mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
- sizeof(expiration),
- (const uint8_t*) &expiration);
- mhd_SHA512_256_finish_deinit (&(d_ctx.sha512_256_ctx), \
- out_buf);
- if (mhd_SHA512_256_has_err (&(d_ctx.sha512_256_ctx)))
- return false;
+ d->auth_dg.entropy.size,
+ (const uint8_t*) d->auth_dg.entropy.data);
+ mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
+ sizeof(gen_num),
+ (const uint8_t*) &gen_num);
+ if (0 != c->sk.addr.size)
+ mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
+ c->sk.addr.size,
+ (const uint8_t*) c->sk.addr.data);
+ mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
+ sizeof(expiration),
+ (const uint8_t*) &expiration);
+ mhd_SHA512_256_finish_deinit (&(d_ctx.sha512_256_ctx), \
+ out_buf);
+ if (mhd_SHA512_256_has_err (&(d_ctx.sha512_256_ctx)))
+ return false;
#elif defined(MHD_SUPPORT_SHA256)
- mhd_SHA256_init_one_time (&(d_ctx.sha256_ctx));
- mhd_SHA256_update (&(d_ctx.sha256_ctx),
- d->auth_dg.entropy.size,
- (const void*) d->auth_dg.entropy.data);
- mhd_SHA256_update (&(d_ctx.sha256_ctx),
- sizeof(gen_num),
- (const void*) &gen_num);
- if (0 != c->sk.addr.size)
+ mhd_SHA256_init_one_time (&(d_ctx.sha256_ctx));
mhd_SHA256_update (&(d_ctx.sha256_ctx),
- c->sk.addr.size,
- (const void*) c->sk.addr.data);
- mhd_SHA256_update (&(d_ctx.sha256_ctx),
- sizeof(expiration),
- (const void*) &expiration);
- mhd_SHA256_finish_deinit (&(d_ctx.sha256_ctx), \
- out_buf);
- if (mhd_SHA256_has_err (&(d_ctx.sha256_ctx)))
- return false;
+ d->auth_dg.entropy.size,
+ (const void*) d->auth_dg.entropy.data);
+ mhd_SHA256_update (&(d_ctx.sha256_ctx),
+ sizeof(gen_num),
+ (const void*) &gen_num);
+ if (0 != c->sk.addr.size)
+ mhd_SHA256_update (&(d_ctx.sha256_ctx),
+ c->sk.addr.size,
+ (const void*) c->sk.addr.data);
+ mhd_SHA256_update (&(d_ctx.sha256_ctx),
+ sizeof(expiration),
+ (const void*) &expiration);
+ mhd_SHA256_finish_deinit (&(d_ctx.sha256_ctx), \
+ out_buf);
+ if (mhd_SHA256_has_err (&(d_ctx.sha256_ctx)))
+ return false;
#else /* MHD_SUPPORT_MD5 */
#ifndef MHD_SUPPORT_MD5
#error At least one hashing algorithm must be enabled
#endif
- mhd_MD5_init_one_time (&(d_ctx.md5_ctx));
- mhd_MD5_update (&(d_ctx.md5_ctx),
- d->auth_dg.entropy.size,
- (const void*) d->auth_dg.entropy.data);
- mhd_MD5_update (&(d_ctx.md5_ctx),
- sizeof(gen_num),
- (const void*) &gen_num);
- if (0 != c->sk.addr.size)
+ mhd_MD5_init_one_time (&(d_ctx.md5_ctx));
mhd_MD5_update (&(d_ctx.md5_ctx),
- c->sk.addr.size,
- (const void*) c->sk.addr.data);
- mhd_MD5_update (&(d_ctx.md5_ctx),
- sizeof(expiration),
- (const void*) &expiration);
- mhd_MD5_finish_deinit (&(d_ctx.md5_ctx), \
- out_buf);
- if (mhd_MD5_has_err (&(d_ctx.md5_ctx)))
- return false;
+ d->auth_dg.entropy.size,
+ (const void*) d->auth_dg.entropy.data);
+ mhd_MD5_update (&(d_ctx.md5_ctx),
+ sizeof(gen_num),
+ (const void*) &gen_num);
+ if (0 != c->sk.addr.size)
+ mhd_MD5_update (&(d_ctx.md5_ctx),
+ c->sk.addr.size,
+ (const void*) c->sk.addr.data);
+ mhd_MD5_update (&(d_ctx.md5_ctx),
+ sizeof(expiration),
+ (const void*) &expiration);
+ mhd_MD5_finish_deinit (&(d_ctx.md5_ctx), \
+ out_buf);
+ if (mhd_MD5_has_err (&(d_ctx.md5_ctx)))
+ return false;
- /* One more hash, for the second part */
- gen_num = mhd_atomic_counter_get_inc_wrap (&(d->auth_dg.num_gen_nonces));
-
- mhd_MD5_init_one_time (&(d_ctx.md5_ctx));
- mhd_MD5_update (&(d_ctx.md5_ctx),
- d->auth_dg.entropy.size,
- (const void*) d->auth_dg.entropy.data);
- mhd_MD5_update (&(d_ctx.md5_ctx),
- sizeof(gen_num),
- (const void*) &gen_num);
- if (0 != c->sk.addr.size)
+ /* One more hash, for the second part */
+ gen_num = mhd_atomic_counter_get_inc_wrap (&(d->auth_dg.num_gen_nonces));
+
+ mhd_MD5_init_one_time (&(d_ctx.md5_ctx));
mhd_MD5_update (&(d_ctx.md5_ctx),
- c->sk.addr.size,
- (const void*) c->sk.addr.data);
- mhd_MD5_update (&(d_ctx.md5_ctx),
- sizeof(expiration),
- (const void*) &expiration);
- mhd_MD5_finish_deinit (&(d_ctx.md5_ctx), \
- out_buf + mhd_MD5_DIGEST_SIZE);
- if (mhd_MD5_has_err (&(d_ctx.md5_ctx)))
- return false;
+ d->auth_dg.entropy.size,
+ (const void*) d->auth_dg.entropy.data);
+ mhd_MD5_update (&(d_ctx.md5_ctx),
+ sizeof(gen_num),
+ (const void*) &gen_num);
+ if (0 != c->sk.addr.size)
+ mhd_MD5_update (&(d_ctx.md5_ctx),
+ c->sk.addr.size,
+ (const void*) c->sk.addr.data);
+ mhd_MD5_update (&(d_ctx.md5_ctx),
+ sizeof(expiration),
+ (const void*) &expiration);
+ mhd_MD5_finish_deinit (&(d_ctx.md5_ctx), \
+ out_buf + mhd_MD5_DIGEST_SIZE);
+ if (mhd_MD5_has_err (&(d_ctx.md5_ctx)))
+ return false;
#endif /* MHD_SUPPORT_MD5 */
-#endif /* old code */
+ }
*expir = (uint_fast32_t) (expiration / 1000u);
mhd_PUT_32BIT_LE_UNALIGN (out_buf + mhd_AUTH_DIGEST_NONCE_RAND_BIN_SIZE, \
diff --git a/src/mhd2/mhd_rng.c b/src/mhd2/mhd_rng.c
@@ -87,34 +87,14 @@
# include "mhd_md5.h"
#endif
-#include "mhd_daemon.h"
-#include "mhd_connection.h"
#include "mhd_mono_clock.h"
#include "mhd_atomic_counter.h"
#include "mhd_rng.h"
-/**
- * Digest context data
- */
-union DigestCtx
-{
-#ifdef MHD_SUPPORT_SHA512_256
- struct mhd_Sha512_256Ctx sha512_256_ctx;
-#endif /* MHD_SUPPORT_SHA512_256 */
-#ifdef MHD_SUPPORT_SHA256
- struct mhd_Sha256Ctx sha256_ctx;
-#endif /* MHD_SUPPORT_SHA256 */
-#ifdef MHD_SUPPORT_MD5
- struct mhd_Md5Ctx md5_ctx;
-#endif /* MHD_SUPPORT_MD5 */
-};
-
MHD_INTERNAL bool
-mhd_rng (struct MHD_Daemon *restrict d,
- struct MHD_Connection *restrict c,
- size_t buf_size,
+mhd_rng (size_t buf_size,
uint8_t buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)])
{
#if defined(MHD_SUPPORT_OPENSSL)
@@ -237,121 +217,5 @@ mhd_rng (struct MHD_Daemon *restrict d,
}
}
#endif
- /* Nothing worked, use hash functions and our entropy pool and
- combine it with current time, generation counter and (if
- available) client address to make the inputs as unique as
- possible. */
- {
- size_t off = 0;
-
- while (off < buf_size)
- {
- size_t gen_num;
- union DigestCtx d_ctx;
- uint_fast64_t now;
- /* size of the output buffer, same for all of our hash functions */
- uint8_t out_buf[mhd_AUTH_DIGEST_NONCE_BIN_SIZE];
- size_t left;
-
- gen_num = mhd_atomic_counter_get_inc_wrap (&(d->auth_dg.num_gen_nonces));
- now = mhd_monotonic_msec_counter ();
-
-#if defined(MHD_SUPPORT_SHA512_256)
- mhd_SHA512_256_init_one_time (&(d_ctx.sha512_256_ctx));
- mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
- d->auth_dg.entropy.size,
- (const uint8_t*) d->auth_dg.entropy.data);
- mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
- sizeof(gen_num),
- (const uint8_t*) &gen_num);
- if ( (NULL != c) &&
- (0 != c->sk.addr.size) )
- mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
- c->sk.addr.size,
- (const uint8_t*) c->sk.addr.data);
- mhd_SHA512_256_update (&(d_ctx.sha512_256_ctx),
- sizeof(now),
- (const uint8_t*) &now);
- mhd_SHA512_256_finish_deinit (&(d_ctx.sha512_256_ctx), \
- out_buf);
- if (mhd_SHA512_256_has_err (&(d_ctx.sha512_256_ctx)))
- return false;
-#elif defined(MHD_SUPPORT_SHA256)
- mhd_SHA256_init_one_time (&(d_ctx.sha256_ctx));
- mhd_SHA256_update (&(d_ctx.sha256_ctx),
- d->auth_dg.entropy.size,
- (const void*) d->auth_dg.entropy.data);
- mhd_SHA256_update (&(d_ctx.sha256_ctx),
- sizeof(gen_num),
- (const void*) &gen_num);
- if ( (NULL != c) &&
- (0 != c->sk.addr.size) )
- mhd_SHA256_update (&(d_ctx.sha256_ctx),
- c->sk.addr.size,
- (const void*) c->sk.addr.data);
- mhd_SHA256_update (&(d_ctx.sha256_ctx),
- sizeof(now),
- (const void*) &now);
- mhd_SHA256_finish_deinit (&(d_ctx.sha256_ctx), \
- out_buf);
- if (mhd_SHA256_has_err (&(d_ctx.sha256_ctx)))
- return false;
-#else /* MHD_SUPPORT_MD5 */
-#ifndef MHD_SUPPORT_MD5
-#error At least one hashing algorithm must be enabled
-#endif
- mhd_MD5_init_one_time (&(d_ctx.md5_ctx));
- mhd_MD5_update (&(d_ctx.md5_ctx),
- d->auth_dg.entropy.size,
- (const void*) d->auth_dg.entropy.data);
- mhd_MD5_update (&(d_ctx.md5_ctx),
- sizeof(gen_num),
- (const void*) &gen_num);
- if ( (NULL != c) &&
- (0 != c->sk.addr.size) )
- mhd_MD5_update (&(d_ctx.md5_ctx),
- c->sk.addr.size,
- (const void*) c->sk.addr.data);
- mhd_MD5_update (&(d_ctx.md5_ctx),
- sizeof(now),
- (const void*) &now);
- mhd_MD5_finish_deinit (&(d_ctx.md5_ctx), \
- out_buf);
- if (mhd_MD5_has_err (&(d_ctx.md5_ctx)))
- return false;
-
- /* One more hash, for the second part */
- gen_num = mhd_atomic_counter_get_inc_wrap (&(d->auth_dg.num_gen_nonces));
-
- mhd_MD5_init_one_time (&(d_ctx.md5_ctx));
- mhd_MD5_update (&(d_ctx.md5_ctx),
- d->auth_dg.entropy.size,
- (const void*) d->auth_dg.entropy.data);
- mhd_MD5_update (&(d_ctx.md5_ctx),
- sizeof(gen_num),
- (const void*) &gen_num);
- if ( (NULL != c) &&
- (0 != c->sk.addr.size) )
- mhd_MD5_update (&(d_ctx.md5_ctx),
- c->sk.addr.size,
- (const void*) c->sk.addr.data);
- mhd_MD5_update (&(d_ctx.md5_ctx),
- sizeof(now),
- (const void*) &now);
- mhd_MD5_finish_deinit (&(d_ctx.md5_ctx), \
- out_buf + mhd_MD5_DIGEST_SIZE);
- if (mhd_MD5_has_err (&(d_ctx.md5_ctx)))
- return false;
-#endif /* MHD_SUPPORT_MD5 */
-
- left = mhd_AUTH_DIGEST_NONCE_BIN_SIZE < (buf_size - off)
- ? mhd_AUTH_DIGEST_NONCE_BIN_SIZE
- : (buf_size - off);
- memcpy (buf + off,
- out_buf,
- left);
- off += left;
- } /* end while off < buf_size */
- } /* end hash-based approach scope */
- return true;
+ return false;
}
diff --git a/src/mhd2/mhd_rng.h b/src/mhd2/mhd_rng.h
@@ -51,23 +51,17 @@
#include "sys_base_types.h"
#include "mhd_socket_error.h"
-struct MHD_Daemon; /* forward declaration */
-struct MHD_Connection; /* forward declaration */
/**
* Initialize @a buf with random data.
*
- * @param d the daemon to use
- * @param c client to create entropy for, can be NULL
* @param buf_size the size of the @a buf buffer
* @param[out] buf the buffer to fill with the random bytes
* @return true on success
*/
MHD_INTERNAL bool
-mhd_rng (struct MHD_Daemon *restrict d,
- struct MHD_Connection *restrict c,
- size_t buf_size,
+mhd_rng (size_t buf_size,
uint8_t buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)])
-MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_OUT_SIZE_ (4,3);
+MHD_FN_PAR_OUT_SIZE_ (2,1);
#endif