[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