[Git][NTPsec/ntpsec][master] 2 commits: Replace random() calls in daemon w/ new shim

Hal Murray (@hal.murray) gitlab at mg.gitlab.com
Mon Jun 9 20:43:43 UTC 2025



Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
33ce37b2 by James Browning at 2025-06-01T06:20:32-07:00
Replace random() calls in daemon w/ new shim

Leaks 75% of entropy to poll adjustment,
and 50% of the associd initializer.

Does not use a pool yet.

- - - - -
b71da3bb by James Browning at 2025-06-09T03:09:27-07:00
Add & use pseudorandom pool w/o refresh logging

- - - - -


5 changed files:

- include/ntp.h
- libntp/ntp_random.c
- ntpd/ntp_control.c
- ntpd/ntp_peer.c
- ntpd/ntp_proto.c


Changes:

=====================================
include/ntp.h
=====================================
@@ -19,6 +19,7 @@
 /* common place to check/crash on unlikely error return */
 void ntp_RAND_bytes(unsigned char *buf, int num);
 void ntp_RAND_priv_bytes(unsigned char *buf, int num);
+uint32_t ntp_random(void);
 
 
 /*


=====================================
libntp/ntp_random.c
=====================================
@@ -4,12 +4,21 @@
  */
 
 #include <stdint.h>
+#include <string.h>
 
 #include <openssl/opensslv.h>
 #include <openssl/rand.h>
 
 #include "config.h"
 #include "ntp.h"
+#include "ntp_stdlib.h"
+#include "ntp_syslog.h"
+
+#ifndef PRAND_BUF_LEN
+#define PRAND_BUF_LEN 4096l
+#endif
+static uint8_t prand_buffer[PRAND_BUF_LEN];
+static size_t prand_burned = PRAND_BUF_LEN;
 
 /* NB: RAND_bytes comes from OpenSSL
  * Starting in version 1.1.1, it reseeds itself occasionally.
@@ -18,15 +27,32 @@
  * so this won't be a problem on newer Linux systems.
  */
 
-void ntp_RAND_bytes(unsigned char *buf, int num) {
-	int err;
-	err = RAND_bytes(buf, num);
-	if (1 != err) {
+/* Use psuedorandom pool to get entropy from */
+static void ntp_pool_rand_fill(uint8_t *buf, int num) {
+	if (0 > num) {
+		return;
+	}
+	if (1 != RAND_bytes(buf, num)) {
 		msyslog(LOG_ERR, "ERR: RAND_bytes failed");
 		exit(1);
 	}
 }
 
+void ntp_RAND_bytes(unsigned char *buf, int num) {
+	if (0 > num) {
+		return;
+	}
+	if (PRAND_BUF_LEN < num) {  // This should never happen
+		return ntp_pool_rand_fill(buf, num);
+	}
+	if (PRAND_BUF_LEN < num + prand_burned) {
+		ntp_pool_rand_fill(&prand_buffer[0], prand_burned);
+		prand_burned = 0;
+	}
+	memcpy(buf, &prand_buffer[0] + prand_burned, num);
+	prand_burned += num;
+}
+
 void ntp_RAND_priv_bytes(unsigned char *buf, int num) {
 	int err;
 #if (OPENSSL_VERSION_NUMBER > 0x1010100fL) && !defined(LIBRESSL_VERSION_NUMBER)
@@ -39,3 +65,11 @@ void ntp_RAND_priv_bytes(unsigned char *buf, int num) {
 		exit(1);
 	}
 }
+
+/* Return four byes of entropy. This differs from the ~31bits from random() */
+
+uint32_t ntp_random(void) {
+	uint32_t ret;
+	ntp_RAND_bytes((uint8_t*)&ret, sizeof(ret));
+	return ret;
+}


=====================================
ntpd/ntp_control.c
=====================================
@@ -2725,8 +2725,7 @@ send_random_tag_value(
 	int	noise;
 	char	buf[32];
 
-	/* coverity[DC.WEAK_CRYPTO] */
-	noise = random();
+	noise = ntp_random();
 	buf[0] = 'a' + noise % 26;
 	noise >>= 5;
 	buf[1] = 'a' + noise % 26;
@@ -2769,8 +2768,7 @@ send_mru_entry(
 
 	remaining = COUNTOF(sent);
 	ZERO(sent);
-	/* coverity[DC.WEAK_CRYPTO] */
-	noise = (uint32_t)random();
+	noise = (uint32_t)ntp_random();
 	while (remaining > 0) {
 #ifdef USE_RANDOMIZE_RESPONSES
 	 	which = (noise & 7) % COUNTOF(sent);
@@ -3312,8 +3310,7 @@ send_ifstats_entry(
 	noisebits = 0;
 	while (remaining > 0) {
 		if (noisebits < 4) {
-			/* coverity[DC.WEAK_CRYPTO] */
-			noise = (uint32_t)random();
+			noise = (uint32_t)ntp_random();
 			noisebits = 31;
 		}
 #ifdef USE_RANDOMIZE_RESPONSES
@@ -3481,8 +3478,7 @@ send_restrict_entry(
 	noisebits = 0;
 	while (remaining > 0) {
 		if (noisebits < 2) {
-			/* coverity[DC.WEAK_CRYPTO] */
-			noise = (uint32_t)random();
+			noise = (uint32_t)ntp_random();
 			noisebits = 31;
 		}
 #ifdef USE_RANDOMIZE_RESPONSES


=====================================
ntpd/ntp_peer.c
=====================================
@@ -98,7 +98,7 @@ init_peer(void)
 	 * Initialize our first association ID
 	 */
 	do
-		current_association_ID = random() & ASSOCID_MAX;
+		current_association_ID = ntp_random() & ASSOCID_MAX;
 	while (!current_association_ID);
 	initial_association_ID = current_association_ID;
 }


=====================================
ntpd/ntp_proto.c
=====================================
@@ -13,6 +13,7 @@
 #include "ntp_auth.h"
 #include "timespecops.h"
 
+#include <stdint.h>
 #include <string.h>
 #include <stdio.h>
 #ifdef HAVE_LIBSCF_H
@@ -457,7 +458,7 @@ static bool check_early_restrictions(
 	int mode = PKT_MODE(rbufp->recv_buffer[0]);
 	return (
 	  (restrict_mask & RES_IGNORE) ||
-	  ((restrict_mask & RES_FLAKE) && (double)random() / RAND_MAX < .1) ||
+	  ((restrict_mask & RES_FLAKE) && (double)ntp_random() / UINT32_MAX < .1) ||
 	  ((restrict_mask & RES_NOQUERY) && (MODE_CONTROL == mode)) ||
 	  ((restrict_mask & RES_NOSERVE) && (MODE_CONTROL != mode)) ||
 	  ((restrict_mask & RES_VERSION) &&
@@ -1259,7 +1260,7 @@ poll_update(
 #endif /* REFCLOCK */
 			/* add a bit of randomess to next polling time
 			 * to disperse traffic */
-			next = ((0x1000UL | (random() & 0x0ff)) <<
+			next = ((0x1000UL | (ntp_random() & 0x0ff)) <<
 			    hpoll) >> 12;
 		next += peer->outdate;
 		if (next > utemp)



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/b8f66ec4189188f63c00faf1fc625af541292c84...b71da3bb2aeb3a5c618a1491ab174a45165afccd

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/b8f66ec4189188f63c00faf1fc625af541292c84...b71da3bb2aeb3a5c618a1491ab174a45165afccd
You're receiving this email because of your account on gitlab.com.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20250609/97a8195f/attachment-0001.htm>


More information about the vc mailing list