summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2015-04-19 12:56:43 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2015-04-19 12:56:43 +0000
commit3bb597daa5c36e58b3fb92cc6c2dbad08cb1f268 (patch)
tree09222c4f047211abb398cbe4ee5903139aa357a1
parent8c0dcfd9d17bdc44d9db4784d525141b45f36b35 (diff)
by default fill the ping payload with a chacha stream instead of
an unvarying payload. each ping process generates a random key, and each packet then uses the timestamps mac as the IV for the stream. this allows us to have a different payload per packet that we can recalculate and compare in the same was as the static payload was checked before. by aggressively varying the payload we hope to generate more opportunities for dodgy network equipment to show errors. note that we do siphash before chacha because we want to be strict about the timestamp payload, but we want to be able to recognise errors in the rest of the payload and where those errors were. doing chacha before siphash would have us than fail the whole packet if a checksum doesnt match. discussed with jp aumasson ok florian@
-rw-r--r--sbin/ping/ping.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c
index 7485cfafddf..7ce9b4bbb07 100644
--- a/sbin/ping/ping.c
+++ b/sbin/ping/ping.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ping.c,v 1.119 2015/04/19 12:45:37 dlg Exp $ */
+/* $OpenBSD: ping.c,v 1.120 2015/04/19 12:56:42 dlg Exp $ */
/* $NetBSD: ping.c,v 1.20 1995/08/11 22:37:58 cgd Exp $ */
/*
@@ -72,7 +72,10 @@
#include <string.h>
#include <limits.h>
#include <stdlib.h>
+
#include <siphash.h>
+#define KEYSTREAM_ONLY
+#include <crypto/chacha_private.h>
struct tv64 {
u_int64_t tv64_sec;
@@ -162,6 +165,7 @@ int bufspace = IP_MAXPACKET;
struct tv64 tv64_offset;
SIPHASH_KEY mac_key;
+chacha_ctx fill_stream;
void fill(char *, char *);
void catcher(int signo);
@@ -188,7 +192,7 @@ main(int argc, char *argv[])
struct hostent *hp;
struct sockaddr_in *to;
struct in_addr saddr;
- int ch, i, optval = 1, packlen, preload, maxsize, df = 0, tos = 0;
+ int ch, optval = 1, packlen, preload, maxsize, df = 0, tos = 0;
u_char *datap, *packet, ttl = MAXTTL, loop = 1;
char *target, hnamebuf[HOST_NAME_MAX+1];
char rspace[3 + 4 * NROUTES + 1]; /* record route space */
@@ -385,9 +389,11 @@ main(int argc, char *argv[])
packlen = datalen + MAXIPLEN + MAXICMPLEN;
if (!(packet = malloc((size_t)packlen)))
err(1, "malloc");
- if (!(options & F_PINGFILLED))
- for (i = sizeof(struct payload); i < datalen; ++i)
- *datap++ = i;
+ if (!(options & F_PINGFILLED) && datalen > sizeof(struct payload)) {
+ u_int8_t key[32];
+ arc4random_buf(key, sizeof(key));
+ chacha_keysetup(&fill_stream, key, sizeof(key) * 8, 0);
+ }
ident = getpid() & 0xFFFF;
@@ -647,6 +653,14 @@ pinger(void)
SipHash24_Final(&payload.mac, &ctx);
memcpy(&outpack[8], &payload, sizeof(payload));
+
+ if (!(options & F_PINGFILLED) && datalen > sizeof(payload)) {
+ u_int8_t *dp = &outpack[8 + sizeof(payload)];
+
+ chacha_ivsetup(&fill_stream, payload.mac);
+ chacha_encrypt_bytes(&fill_stream, dp, dp,
+ datalen - sizeof(payload));
+ }
}
cc = datalen + 8; /* skips ICMP portion */
@@ -700,6 +714,7 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from)
char *pkttime;
quad_t triptime = 0;
int hlen, hlen2, dupflag;
+ struct payload payload;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
err(1, "clock_gettime(CLOCK_MONOTONIC)");
@@ -723,7 +738,6 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from)
++nreceived;
if (cc >= 8 + sizeof(struct payload)) {
SIPHASH_CTX ctx;
- struct payload payload;
struct tv64 *tv64 = &payload.tv64;
u_int8_t mac[SIPHASH_DIGEST_LENGTH];
@@ -790,6 +804,11 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from)
(void)printf(" (TRUNC!)");
cp = (u_char *)&icp->icmp_data[sizeof(struct payload)];
dp = &outpack[8 + sizeof(struct payload)];
+ if (!(options & F_PINGFILLED)) {
+ chacha_ivsetup(&fill_stream, payload.mac);
+ chacha_encrypt_bytes(&fill_stream, dp, dp,
+ datalen - sizeof(payload));
+ }
for (i = 8 + sizeof(struct payload);
i < cc && i < datalen;
++i, ++cp, ++dp) {