Fuzz transmit timestamp

Add random bits below clock precision to the timestamp to make
it less predictable.
This commit is contained in:
Miroslav Lichvar 2012-05-22 17:16:41 +02:00
parent d0acfc2652
commit df6c2a432f
6 changed files with 41 additions and 13 deletions

View file

@ -256,6 +256,7 @@ probe_source(SourceRecord *src)
union sockaddr_in46 his_addr; union sockaddr_in46 his_addr;
int sock_fd; int sock_fd;
socklen_t addrlen; socklen_t addrlen;
uint32_t ts_fuzz;
#if 0 #if 0
printf("Sending probe to %s sent=%d samples=%d\n", UTI_IPToString(&src->ip_addr), src->n_probes_sent, src->n_samples); printf("Sending probe to %s sent=%d samples=%d\n", UTI_IPToString(&src->ip_addr), src->n_probes_sent, src->n_samples);
@ -304,8 +305,9 @@ probe_source(SourceRecord *src)
} }
ts_fuzz = UTI_GetNTPTsFuzz(LCL_GetSysPrecisionAsLog());
LCL_ReadCookedTime(&cooked, NULL); LCL_ReadCookedTime(&cooked, NULL);
UTI_TimevalToInt64(&cooked, &pkt.transmit_ts); UTI_TimevalToInt64(&cooked, &pkt.transmit_ts, ts_fuzz);
if (sendto(sock_fd, (void *) &pkt, NTP_NORMAL_PACKET_SIZE, if (sendto(sock_fd, (void *) &pkt, NTP_NORMAL_PACKET_SIZE,
0, 0,

View file

@ -73,7 +73,7 @@ timeout_handler(void *arbitrary)
int leap; int leap;
int are_we_synchronised, our_stratum; int are_we_synchronised, our_stratum;
NTP_Leap leap_status; NTP_Leap leap_status;
uint32_t our_ref_id; uint32_t our_ref_id, ts_fuzz;
struct timeval our_ref_time; struct timeval our_ref_time;
double our_root_delay, our_root_dispersion; double our_root_delay, our_root_dispersion;
struct timeval local_transmit; struct timeval local_transmit;
@ -107,14 +107,15 @@ timeout_handler(void *arbitrary)
message.reference_id = htonl((NTP_int32) our_ref_id); message.reference_id = htonl((NTP_int32) our_ref_id);
/* Now fill in timestamps */ /* Now fill in timestamps */
UTI_TimevalToInt64(&our_ref_time, &message.reference_ts); UTI_TimevalToInt64(&our_ref_time, &message.reference_ts, 0);
message.originate_ts.hi = 0UL; message.originate_ts.hi = 0UL;
message.originate_ts.lo = 0UL; message.originate_ts.lo = 0UL;
message.receive_ts.hi = 0UL; message.receive_ts.hi = 0UL;
message.receive_ts.lo = 0UL; message.receive_ts.lo = 0UL;
ts_fuzz = UTI_GetNTPTsFuzz(message.precision);
LCL_ReadCookedTime(&local_transmit, NULL); LCL_ReadCookedTime(&local_transmit, NULL);
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts); UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
NIO_SendNormalPacket(&message, &d->addr); NIO_SendNormalPacket(&message, &d->addr);
/* Requeue timeout. Don't care if interval drifts gradually, so just do it /* Requeue timeout. Don't care if interval drifts gradually, so just do it

View file

@ -419,7 +419,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
/* Parameters read from reference module */ /* Parameters read from reference module */
int are_we_synchronised, our_stratum; int are_we_synchronised, our_stratum;
NTP_Leap leap_status; NTP_Leap leap_status;
uint32_t our_ref_id; uint32_t our_ref_id, ts_fuzz;
struct timeval our_ref_time; struct timeval our_ref_time;
double our_root_delay, our_root_dispersion; double our_root_delay, our_root_dispersion;
@ -458,7 +458,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
message.reference_id = htonl((NTP_int32) our_ref_id); message.reference_id = htonl((NTP_int32) our_ref_id);
/* Now fill in timestamps */ /* Now fill in timestamps */
UTI_TimevalToInt64(&our_ref_time, &message.reference_ts); UTI_TimevalToInt64(&our_ref_time, &message.reference_ts, 0);
/* Originate - this comes from the last packet the source sent us */ /* Originate - this comes from the last packet the source sent us */
message.originate_ts = *orig_ts; message.originate_ts = *orig_ts;
@ -467,7 +467,10 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
This timestamp will have been adjusted so that it will now look to This timestamp will have been adjusted so that it will now look to
the source like we have been running on our latest estimate of the source like we have been running on our latest estimate of
frequency all along */ frequency all along */
UTI_TimevalToInt64(local_rx, &message.receive_ts); UTI_TimevalToInt64(local_rx, &message.receive_ts, 0);
/* Prepare random bits which will be added to the transmit timestamp. */
ts_fuzz = UTI_GetNTPTsFuzz(message.precision);
/* Transmit - this our local time right now! Also, we might need to /* Transmit - this our local time right now! Also, we might need to
store this for our own use later, next time we receive a message store this for our own use later, next time we receive a message
@ -481,7 +484,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
take to generate the authentication data. */ take to generate the authentication data. */
local_transmit.tv_usec += KEY_GetAuthDelay(key_id); local_transmit.tv_usec += KEY_GetAuthDelay(key_id);
UTI_NormaliseTimeval(&local_transmit); UTI_NormaliseTimeval(&local_transmit);
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts); UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
auth_len = KEY_GenerateAuth(key_id, (unsigned char *) &message, auth_len = KEY_GenerateAuth(key_id, (unsigned char *) &message,
offsetof(NTP_Packet, auth_keyid), offsetof(NTP_Packet, auth_keyid),
@ -492,7 +495,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
sizeof (message.auth_keyid) + auth_len); sizeof (message.auth_keyid) + auth_len);
} }
} else { } else {
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts); UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
NIO_SendNormalPacket(&message, where_to); NIO_SendNormalPacket(&message, where_to);
} }

View file

@ -147,7 +147,7 @@ SCH_Initialise(void)
LCL_AddParameterChangeHandler(handle_slew, NULL); LCL_AddParameterChangeHandler(handle_slew, NULL);
LCL_ReadRawTime(&tv); LCL_ReadRawTime(&tv);
srandom(tv.tv_sec * tv.tv_usec); srandom(tv.tv_sec << 16 ^ tv.tv_usec);
initialised = 1; initialised = 1;

24
util.c
View file

@ -459,16 +459,31 @@ UTI_AdjustTimeval(struct timeval *old_tv, struct timeval *when, struct timeval *
/* ================================================== */ /* ================================================== */
uint32_t
UTI_GetNTPTsFuzz(int precision)
{
uint32_t fuzz;
int fuzz_bits;
fuzz_bits = 32 - 1 + precision;
fuzz = random() % (1 << fuzz_bits);
return fuzz;
}
/* ================================================== */
/* Seconds part of RFC1305 timestamp correponding to the origin of the /* Seconds part of RFC1305 timestamp correponding to the origin of the
struct timeval format. */ struct timeval format. */
#define JAN_1970 0x83aa7e80UL #define JAN_1970 0x83aa7e80UL
void void
UTI_TimevalToInt64(struct timeval *src, UTI_TimevalToInt64(struct timeval *src,
NTP_int64 *dest) NTP_int64 *dest, uint32_t fuzz)
{ {
unsigned long usec = src->tv_usec; unsigned long usec = src->tv_usec;
unsigned long sec = src->tv_sec; unsigned long sec = src->tv_sec;
uint32_t lo;
/* Recognize zero as a special case - it always signifies /* Recognize zero as a special case - it always signifies
an 'unknown' value */ an 'unknown' value */
@ -478,7 +493,12 @@ UTI_TimevalToInt64(struct timeval *src,
dest->hi = htonl(src->tv_sec + JAN_1970); dest->hi = htonl(src->tv_sec + JAN_1970);
/* This formula gives an error of about 0.1us worst case */ /* This formula gives an error of about 0.1us worst case */
dest->lo = htonl(4295 * usec - (usec>>5) - (usec>>9)); lo = 4295 * usec - (usec>>5) - (usec>>9);
/* Add the fuzz */
lo ^= fuzz;
dest->lo = htonl(lo);
} }
} }

4
util.h
View file

@ -88,8 +88,10 @@ extern char *UTI_TimeToLogForm(time_t t);
/* Adjust time following a frequency/offset change */ /* Adjust time following a frequency/offset change */
extern void UTI_AdjustTimeval(struct timeval *old_tv, struct timeval *when, struct timeval *new_tv, double *delta, double dfreq, double doffset); extern void UTI_AdjustTimeval(struct timeval *old_tv, struct timeval *when, struct timeval *new_tv, double *delta, double dfreq, double doffset);
/* Get a random value to fuzz an NTP timestamp in the given precision */
extern uint32_t UTI_GetNTPTsFuzz(int precision);
extern void UTI_TimevalToInt64(struct timeval *src, NTP_int64 *dest); extern void UTI_TimevalToInt64(struct timeval *src, NTP_int64 *dest, uint32_t fuzz);
extern void UTI_Int64ToTimeval(NTP_int64 *src, struct timeval *dest); extern void UTI_Int64ToTimeval(NTP_int64 *src, struct timeval *dest);