--- dhcp-3.0.5/client/dhclient.c.bak 2007-05-23 22:13:04.600575000 +0300 +++ dhcp-3.0.5/client/dhclient.c 2007-05-23 23:03:39.079642466 +0300 @@ -35,6 +35,12 @@ static char ocopyright[] = "$Id: dhclient.c,v 1.129.2.34 2006/08/22 15:13:57 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ +#include +#include +#include +#include +#include + #include "dhcpd.h" #include "version.h" @@ -95,6 +101,86 @@ static void usage PROTO ((void)); void do_release(struct client_state *); +#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) +static void salsa20(void * __out, void *__in) +{ + int i; + uint32_t x[16]; + uint32_t *in = __in; + uint32_t *out = __out; + + for (i = 0; i < 16; ++i) x[i] = in[i]; + + for (i = 20;i > 0;i -= 2) { + x[ 4] ^= R(x[ 0]+x[12], 7); + x[ 8] ^= R(x[ 4]+x[ 0], 9); + x[12] ^= R(x[ 8]+x[ 4],13); + x[ 0] ^= R(x[12]+x[ 8],18); + x[ 9] ^= R(x[ 5]+x[ 1], 7); + x[13] ^= R(x[ 9]+x[ 5], 9); + x[ 1] ^= R(x[13]+x[ 9],13); + x[ 5] ^= R(x[ 1]+x[13],18); + x[14] ^= R(x[10]+x[ 6], 7); + x[ 2] ^= R(x[14]+x[10], 9); + x[ 6] ^= R(x[ 2]+x[14],13); + x[10] ^= R(x[ 6]+x[ 2],18); + x[ 3] ^= R(x[15]+x[11], 7); + x[ 7] ^= R(x[ 3]+x[15], 9); + x[11] ^= R(x[ 7]+x[ 3],13); + x[15] ^= R(x[11]+x[ 7],18); + x[ 1] ^= R(x[ 0]+x[ 3], 7); + x[ 2] ^= R(x[ 1]+x[ 0], 9); + x[ 3] ^= R(x[ 2]+x[ 1],13); + x[ 0] ^= R(x[ 3]+x[ 2],18); + x[ 6] ^= R(x[ 5]+x[ 4], 7); + x[ 7] ^= R(x[ 6]+x[ 5], 9); + x[ 4] ^= R(x[ 7]+x[ 6],13); + x[ 5] ^= R(x[ 4]+x[ 7],18); + x[11] ^= R(x[10]+x[ 9], 7); + x[ 8] ^= R(x[11]+x[10], 9); + x[ 9] ^= R(x[ 8]+x[11],13); + x[10] ^= R(x[ 9]+x[ 8],18); + x[12] ^= R(x[15]+x[14], 7); + x[13] ^= R(x[12]+x[15], 9); + x[14] ^= R(x[13]+x[12],13); + x[15] ^= R(x[14]+x[13],18); + } + for (i = 0;i < 16;++i) out[i] = x[i] + in[i]; +} + +uint32_t salsa_rand(void) +{ + static uint32_t salsa20_out[16]; + static uint32_t salsa20_in[16]; + static int nrints; + static int rndinit; + + if (!rndinit) { + int fd; + + rndinit = 1; + salsa20_in[0] = time(NULL); + salsa20_in[1] = getpid(); + fd = open("/dev/urandom", O_RDONLY); + if (fd != -1) { + read(fd, salsa20_in, sizeof(salsa20_in)); + close(fd); + } + } + + if (nrints == 0) { + if (!++salsa20_in[0]) if (!++salsa20_in[1]) if (!++salsa20_in[2]) if (!++salsa20_in[3]) + if (!++salsa20_in[4]) if (!++salsa20_in[5]) if (!++salsa20_in[6]) if (!++salsa20_in[7]) + if (!++salsa20_in[8]) if (!++salsa20_in[9]) if (!++salsa20_in[10]) if (!++salsa20_in[11]) + if (!++salsa20_in[12]) if (!++salsa20_in[13]) if (!++salsa20_in[14]) ++salsa20_in[15]; + salsa20(salsa20_out, salsa20_in); + nrints = 16; + } + + return salsa20_out[--nrints]; +} + + #ifdef LIBDHCP #include "libdhcp_control.h" LIBDHCP_Control *libdhcp_control; @@ -135,7 +221,6 @@ int main (argc, argv, envp) struct servent *ent; struct interface_info *ip; struct client_state *client; - unsigned seed; char *server = (char *)0; char *relay = (char *)0; isc_result_t status; @@ -792,21 +877,6 @@ int main (argc, argv, envp) ? DISCOVER_REQUESTED : DISCOVER_RUNNING); - /* Make up a seed for the random number generator from current - time plus the sum of the last four bytes of each - interface's hardware address interpreted as an integer. - Not much entropy, but we're booting, so we're not likely to - find anything better. */ - seed = 0; - for (ip = interfaces; ip; ip = ip -> next) { - int junk; - memcpy (&junk, - &ip -> hw_address.hbuf [ip -> hw_address.hlen - - sizeof seed], sizeof seed); - seed += junk; - } - srandom (seed + cur_time); - /* Start a configuration state machine for each interface. */ for (ip = interfaces; ip; ip = ip -> next) { ip -> flags |= INTERFACE_RUNNING; @@ -1097,7 +1167,7 @@ void state_reboot (cpp) /* make_request doesn't initialize xid because it normally comes from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER, so pick an xid now. */ - client -> xid = random (); + client -> xid = salsa_rand(); /* Make a DHCPREQUEST packet, and set appropriate per-interface flags. */ @@ -1141,7 +1211,7 @@ void state_init (cpp) /* We've received an OFFER and it has been DECLINEd by dhclient-script. * wait for a random time between 1 and backoff_cutoff seconds before * trying again. */ - add_timeout(cur_time + ((1 + (random() >> 2)) % client->config->backoff_cutoff), send_discover, client, 0, 0); + add_timeout(cur_time + ((1 + (salsa_rand() >> 2)) % client->config->backoff_cutoff), send_discover, client, 0, 0); } } @@ -1330,7 +1400,7 @@ void dhcpack (packet) /* Now introduce some randomness to the renewal time: */ if (client->new->renewal <= ((TIME_MAX / 3) - 3)) client->new->renewal = (((client->new->renewal * 3) + 3) / 4) + - (((random() % client->new->renewal) + 3) / 4); + (((salsa_rand() % client->new->renewal) + 3) / 4); /* Same deal with the rebind time. */ oc = lookup_option (&dhcp_universe, client -> new -> options, @@ -1978,12 +2048,12 @@ void send_discover (cpp) if (!client->interval) client->interval = client->config->initial_interval; else - client->interval += random() % (2 * client->interval); + client->interval += salsa_rand() % (2 * client->interval); /* Don't backoff past cutoff. */ if (client->interval > client->config->backoff_cutoff) client->interval = (client->config->backoff_cutoff / 2) - + (random() % client->config->backoff_cutoff); + + (salsa_rand() % client->config->backoff_cutoff); } else if (!client->interval) client->interval = client->config->initial_interval; @@ -2125,7 +2195,7 @@ void state_panic (cpp) client -> state = S_INIT; add_timeout (cur_time + ((client -> config -> retry_interval + 1) / 2 + - (random () % client -> config -> retry_interval)), + (salsa_rand() % client -> config -> retry_interval)), state_init, client, 0, 0); go_daemon (); } @@ -2207,7 +2277,7 @@ void send_request (cpp) if (!client -> interval) client -> interval = client -> config -> initial_interval; else { - client -> interval += ((random () >> 2) % + client -> interval += ((salsa_rand() >> 2) % (2 * client -> interval)); } @@ -2216,7 +2286,7 @@ void send_request (cpp) client -> config -> backoff_cutoff) client -> interval = ((client -> config -> backoff_cutoff / 2) - + ((random () >> 2) % + + ((salsa_rand() >> 2) % client -> config -> backoff_cutoff)); /* If the backoff would take us to the expiry time, just set the @@ -2474,7 +2544,7 @@ void make_discover (client, lease) client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; - client -> packet.xid = random (); + client -> packet.xid = salsa_rand(); client -> packet.secs = 0; /* filled in by send_discover. */ if ((!(bootp_broadcast_always || client->config->bootp_broadcast_always)) @@ -2685,7 +2755,7 @@ void make_release (client, lease) client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; - client -> packet.xid = random (); + client -> packet.xid = salsa_rand(); client -> packet.secs = 0; client -> packet.flags = 0; memcpy (&client -> packet.ciaddr, @@ -3477,7 +3547,7 @@ void do_release(client) struct option_cache *oc; /* Pick a random xid. */ - client -> xid = random (); + client -> xid = salsa_rand(); /* is there even a lease to release? */ if (client -> active) { @@ -3628,7 +3698,7 @@ isc_result_t dhclient_interface_startup_ client -> state = S_INIT; /* Set up a timeout to start the initialization process. */ - add_timeout (cur_time + random () % 5, + add_timeout (cur_time + salsa_rand() % 5, state_reboot, client, 0, 0); } } --- dhcp-3.0.5/common/ctrace.c.bak 2004-09-30 23:23:06.000000000 +0300 +++ dhcp-3.0.5/common/ctrace.c 2007-05-23 23:05:42.743717918 +0300 @@ -270,26 +270,4 @@ void trace_outpacket_input (trace_type_t void trace_outpacket_stop (trace_type_t *ttype) { } -void trace_seed_stash (trace_type_t *ttype, unsigned seed) -{ - u_int32_t outseed; - if (!trace_record ()) - return; - outseed = htonl (seed); - trace_write_packet (ttype, sizeof outseed, (char *)&outseed, MDL); - return; -} - -void trace_seed_input (trace_type_t *ttype, unsigned length, char *buf) -{ - u_int32_t *seed; - - if (length != sizeof seed) { - log_error ("trace_seed_input: wrong size (%d)", length); - } - seed = (u_int32_t *)buf; - srandom (ntohl (*seed)); -} - -void trace_seed_stop (trace_type_t *ttype) { } #endif /* TRACING */ --- dhcp-3.0.5/includes/ctrace.h.bak 2004-06-10 20:59:29.000000000 +0300 +++ dhcp-3.0.5/includes/ctrace.h 2007-05-23 23:05:56.157075349 +0300 @@ -72,6 +72,3 @@ void trace_icmp_input_input (trace_type_ void trace_icmp_input_stop (trace_type_t *); void trace_icmp_output_input (trace_type_t *, unsigned, char *); void trace_icmp_output_stop (trace_type_t *); -void trace_seed_stash (trace_type_t *, unsigned); -void trace_seed_input (trace_type_t *, unsigned, char *); -void trace_seed_stop (trace_type_t *); --- dhcp-3.0.5/omapip/protocol.c.bak 2007-05-23 22:13:00.768747000 +0300 +++ dhcp-3.0.5/omapip/protocol.c 2007-05-23 23:10:33.517790265 +0300 @@ -39,6 +39,92 @@ static char ocopyright[] = #include +#include +#include +#include +#include +#include + +#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) +static void salsa20(void * __out, void *__in) +{ + int i; + uint32_t x[16]; + uint32_t *in = __in; + uint32_t *out = __out; + + for (i = 0; i < 16; ++i) x[i] = in[i]; + + for (i = 20;i > 0;i -= 2) { + x[ 4] ^= R(x[ 0]+x[12], 7); + x[ 8] ^= R(x[ 4]+x[ 0], 9); + x[12] ^= R(x[ 8]+x[ 4],13); + x[ 0] ^= R(x[12]+x[ 8],18); + x[ 9] ^= R(x[ 5]+x[ 1], 7); + x[13] ^= R(x[ 9]+x[ 5], 9); + x[ 1] ^= R(x[13]+x[ 9],13); + x[ 5] ^= R(x[ 1]+x[13],18); + x[14] ^= R(x[10]+x[ 6], 7); + x[ 2] ^= R(x[14]+x[10], 9); + x[ 6] ^= R(x[ 2]+x[14],13); + x[10] ^= R(x[ 6]+x[ 2],18); + x[ 3] ^= R(x[15]+x[11], 7); + x[ 7] ^= R(x[ 3]+x[15], 9); + x[11] ^= R(x[ 7]+x[ 3],13); + x[15] ^= R(x[11]+x[ 7],18); + x[ 1] ^= R(x[ 0]+x[ 3], 7); + x[ 2] ^= R(x[ 1]+x[ 0], 9); + x[ 3] ^= R(x[ 2]+x[ 1],13); + x[ 0] ^= R(x[ 3]+x[ 2],18); + x[ 6] ^= R(x[ 5]+x[ 4], 7); + x[ 7] ^= R(x[ 6]+x[ 5], 9); + x[ 4] ^= R(x[ 7]+x[ 6],13); + x[ 5] ^= R(x[ 4]+x[ 7],18); + x[11] ^= R(x[10]+x[ 9], 7); + x[ 8] ^= R(x[11]+x[10], 9); + x[ 9] ^= R(x[ 8]+x[11],13); + x[10] ^= R(x[ 9]+x[ 8],18); + x[12] ^= R(x[15]+x[14], 7); + x[13] ^= R(x[12]+x[15], 9); + x[14] ^= R(x[13]+x[12],13); + x[15] ^= R(x[14]+x[13],18); + } + for (i = 0;i < 16;++i) out[i] = x[i] + in[i]; +} + +uint32_t salsa_rand2(void) +{ + static uint32_t salsa20_out[16]; + static uint32_t salsa20_in[16]; + static int nrints; + static int rndinit; + + if (!rndinit) { + int fd; + + rndinit = 1; + salsa20_in[0] = time(NULL); + salsa20_in[1] = getpid(); + fd = open("/dev/urandom", O_RDONLY); + if (fd != -1) { + read(fd, salsa20_in, sizeof(salsa20_in)); + close(fd); + } + } + + if (nrints == 0) { + if (!++salsa20_in[0]) if (!++salsa20_in[1]) if (!++salsa20_in[2]) if (!++salsa20_in[3]) + if (!++salsa20_in[4]) if (!++salsa20_in[5]) if (!++salsa20_in[6]) if (!++salsa20_in[7]) + if (!++salsa20_in[8]) if (!++salsa20_in[9]) if (!++salsa20_in[10]) if (!++salsa20_in[11]) + if (!++salsa20_in[12]) if (!++salsa20_in[13]) if (!++salsa20_in[14]) ++salsa20_in[15]; + salsa20(salsa20_out, salsa20_in); + nrints = 16; + } + + return salsa20_out[--nrints]; +} + + OMAPI_OBJECT_ALLOC (omapi_protocol, omapi_protocol_object_t, omapi_type_protocol) OMAPI_OBJECT_ALLOC (omapi_protocol_listener, omapi_protocol_listener_object_t, @@ -146,7 +232,7 @@ isc_result_t omapi_protocol_send_intro ( return status; /* Make up an initial transaction ID for this connection. */ - p -> next_xid = random (); + p -> next_xid = salsa_rand2(); return ISC_R_SUCCESS; } --- dhcp-3.0.5/server/dhcpd.c.bak 2007-05-23 22:13:02.777657000 +0300 +++ dhcp-3.0.5/server/dhcpd.c 2007-05-23 23:06:54.617274907 +0300 @@ -156,10 +156,6 @@ int dhcp_max_agent_option_packet_length static omapi_auth_key_t *omapi_key = (omapi_auth_key_t *)0; int omapi_port; -#if defined (TRACING) -trace_type_t *trace_srandom; -#endif - static isc_result_t verify_addr (omapi_object_t *l, omapi_addr_t *addr) { return ISC_R_SUCCESS; } @@ -211,7 +207,6 @@ int main (argc, argv, envp) int quiet = 0; char *server = (char *)0; isc_result_t result; - unsigned seed; struct interface_info *ip; struct parse *parse; int lose; @@ -382,9 +377,6 @@ int main (argc, argv, envp) } interface_trace_setup (); parse_trace_setup (); - trace_srandom = trace_type_register ("random-seed", (void *)0, - trace_seed_input, - trace_seed_stop, MDL); #endif /* Default to the DHCP/BOOTP port. */ @@ -508,23 +500,6 @@ int main (argc, argv, envp) /* Discover all the network interfaces and initialize them. */ discover_interfaces (DISCOVER_SERVER); - /* Make up a seed for the random number generator from current - time plus the sum of the last four bytes of each - interface's hardware address interpreted as an integer. - Not much entropy, but we're booting, so we're not likely to - find anything better. */ - seed = 0; - for (ip = interfaces; ip; ip = ip -> next) { - int junk; - memcpy (&junk, - &ip -> hw_address.hbuf [ip -> hw_address.hlen - - sizeof seed], sizeof seed); - seed += junk; - } - srandom (seed + cur_time); -#if defined (TRACING) - trace_seed_stash (trace_srandom, seed + cur_time); -#endif postdb_startup (); #ifndef DEBUG