aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2023-02-11 23:21:00 +0000
committerrodri <rgl@antares-labs.eu>2023-02-11 23:21:00 +0000
commit62e75d8830eb56ab03bd4689d51ffd6d4150f461 (patch)
tree5c84e92fbb3df890adeed7ba5f06ecda95b6e83e
parent775309861b51dd1f340d82074b7e9234f3e0675e (diff)
downloadmusw-62e75d8830eb56ab03bd4689d51ffd6d4150f461.tar.gz
musw-62e75d8830eb56ab03bd4689d51ffd6d4150f461.tar.bz2
musw-62e75d8830eb56ab03bd4689d51ffd6d4150f461.zip
implemented per-packet HMAC to avoid MITM tampering.
-rw-r--r--dat.h5
-rw-r--r--fmt.c25
-rw-r--r--fns.h7
-rw-r--r--mkfile1
-rw-r--r--musw.c29
-rw-r--r--muswd.c35
-rw-r--r--net.c37
-rw-r--r--pack.c4
-rw-r--r--party.c2
-rw-r--r--physics.c2
-rw-r--r--sprite.c2
-rw-r--r--universe.c2
12 files changed, 126 insertions, 25 deletions
diff --git a/dat.h b/dat.h
index 89554bc..566c248 100644
--- a/dat.h
+++ b/dat.h
@@ -46,7 +46,7 @@ enum {
enum {
ProtocolID = 0x5753554d, /* MUSW */
- Framehdrsize = 4+1+4+4+2,
+ Framehdrsize = 4+1+4+4+2+MD5dlen,
MTU = 1024
};
@@ -147,6 +147,7 @@ struct Frame
u32int seq;
u32int ack;
u16int len;
+ uchar sig[MD5dlen];
uchar data[];
};
@@ -177,3 +178,5 @@ struct Party
Universe *u;
Party *prev, *next;
};
+
+#pragma varargck type "Φ" Frame*
diff --git a/fmt.c b/fmt.c
new file mode 100644
index 0000000..7d33e57
--- /dev/null
+++ b/fmt.c
@@ -0,0 +1,25 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include <mp.h>
+#include <libsec.h>
+#include <thread.h>
+#include <draw.h>
+#include <geometry.h>
+#include "dat.h"
+#include "fns.h"
+
+int
+Φfmt(Fmt *f)
+{
+ int n, i;
+ Frame *frame;
+
+ frame = va_arg(f->args, Frame*);
+
+ n = fmtprint(f, "id %x type %ud seq %ud ack %ud len %ud sig ",
+ frame->id, frame->type, frame->seq, frame->ack, frame->len);
+ for(i = 0; i < MD5dlen; i++)
+ n += fmtprint(f, "%2.2x", frame->sig[i]);
+ return n;
+}
diff --git a/fns.h b/fns.h
index b4059ce..6ec3b0d 100644
--- a/fns.h
+++ b/fns.h
@@ -53,4 +53,11 @@ ulong dhgenkey(ulong, ulong, ulong);
NetConn *newnetconn(NCState, Udphdr*);
void delnetconn(NetConn*);
Frame *newframe(Frame*, u8int, u32int, u32int, u16int, uchar*);
+void signframe(Frame*, ulong);
+int verifyframe(Frame*, ulong);
void delframe(Frame*);
+
+/*
+ * fmt
+ */
+int Φfmt(Fmt*);
diff --git a/mkfile b/mkfile
index 3d7da33..123c050 100644
--- a/mkfile
+++ b/mkfile
@@ -15,6 +15,7 @@ OFILES=\
universe.$O\
sprite.$O\
net.$O\
+ fmt.$O\
HFILES=\
dat.h\
diff --git a/musw.c b/musw.c
index ca428bf..039f7b6 100644
--- a/musw.c
+++ b/musw.c
@@ -1,6 +1,8 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
+#include <mp.h>
+#include <libsec.h>
#include <bio.h>
#include <thread.h>
#include <draw.h>
@@ -164,6 +166,7 @@ sendkeys(ulong kdown)
frame = newframe(nil, NCinput, 0, 0, sizeof(kdown), nil);
pack(frame->data, frame->len, "k", kdown);
+ signframe(frame, netconn.dh.priv);
sendp(egress, frame);
}
@@ -241,9 +244,8 @@ threadnetrecv(void *arg)
if(debug){
rport = frame->udp.rport[0]<<8 | frame->udp.rport[1];
lport = frame->udp.lport[0]<<8 | frame->udp.lport[1];
- fprint(2, "%I!%ud ← %I!%ud | rcvd type %ud seq %ud ack %ud len %ud\n",
- frame->udp.laddr, lport, frame->udp.raddr, rport,
- frame->type, frame->seq, frame->ack, frame->len);
+ fprint(2, "%I!%ud → %I!%ud | rcvd %Φ\n",
+ frame->udp.laddr, lport, frame->udp.raddr, rport, frame);
}
}
closeioproc(io);
@@ -267,27 +269,33 @@ threadnetppu(void *)
unpack(frame->data, frame->len, "kk", &netconn.dh.p, &netconn.dh.g);
newf = newframe(frame, NCdhx, 0, 0, sizeof(ulong), nil);
-
+
netconn.dh.sec = truerand();
pack(newf->data, newf->len, "k", dhgenkey(netconn.dh.g, netconn.dh.sec, netconn.dh.p));
sendp(egress, newf);
if(debug)
fprint(2, "\tsent pubkey %ld\n", dhgenkey(netconn.dh.g, netconn.dh.sec, netconn.dh.p));
-
+
break;
case NSdhx:
unpack(frame->data, frame->len, "k", &netconn.dh.pub);
netconn.state = NCSConnected;
if(debug)
- fprint(2, "\trecvd pubkey %ld\n", netconn.dh.pub);
+ fprint(2, "\trcvd pubkey %ld\n", netconn.dh.pub);
netconn.dh.priv = dhgenkey(netconn.dh.pub, netconn.dh.sec, netconn.dh.p);
break;
}
break;
case NCSConnected:
+ if(verifyframe(frame, netconn.dh.priv) != 0){
+ if(debug)
+ fprint(2, "\tbad signature\n");
+ goto discard;
+ }
+
switch(frame->type){
case NSsimstate:
unpack(frame->data, frame->len, "PdPdP",
@@ -297,6 +305,7 @@ threadnetppu(void *)
break;
case NSnudge:
newf = newframe(frame, NCnudge, 0, 0, 0, nil);
+ signframe(newf, netconn.dh.priv);
sendp(egress, newf);
@@ -308,7 +317,7 @@ threadnetppu(void *)
break;
}
discard:
- free(frame);
+ delframe(frame);
}
}
@@ -332,9 +341,8 @@ threadnetsend(void *arg)
if(debug){
rport = frame->udp.rport[0]<<8 | frame->udp.rport[1];
lport = frame->udp.lport[0]<<8 | frame->udp.lport[1];
- fprint(2, "%I!%ud → %I!%ud | sent type %ud seq %ud ack %ud len %ud\n",
- frame->udp.laddr, lport, frame->udp.raddr, rport,
- frame->type, frame->seq, frame->ack, frame->len);
+ fprint(2, "%I!%ud → %I!%ud | sent %Φ\n",
+ frame->udp.laddr, lport, frame->udp.raddr, rport, frame);
}
free(frame);
@@ -438,6 +446,7 @@ threadmain(int argc, char *argv[])
GEOMfmtinstall();
fmtinstall('I', eipfmt);
+ fmtinstall(L'Φ', Φfmt);
ARGBEGIN{
case 'd':
debug++;
diff --git a/muswd.c b/muswd.c
index 9329545..d2f1f01 100644
--- a/muswd.c
+++ b/muswd.c
@@ -1,6 +1,8 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
+#include <mp.h>
+#include <libsec.h>
#include <thread.h>
#include <draw.h>
#include <geometry.h>
@@ -46,7 +48,7 @@ popconn(NetConn *nc)
ncpe = conns+nconns;
- for(ncp = conns; ncp < conns+nconns; ncp++)
+ for(ncp = conns; ncp < ncpe; ncp++)
if(*ncp == nc){
memmove(ncp, ncp+1, sizeof(NetConn*)*(ncpe-ncp-1));
nconns--;
@@ -77,9 +79,8 @@ threadnetrecv(void *arg)
if(debug){
rport = frame->udp.rport[0]<<8 | frame->udp.rport[1];
lport = frame->udp.lport[0]<<8 | frame->udp.lport[1];
- fprint(2, "%I!%ud ← %I!%ud | rcvd type %ud seq %ud ack %ud len %ud\n",
- frame->udp.laddr, lport, frame->udp.raddr, rport,
- frame->type, frame->seq, frame->ack, frame->len);
+ fprint(2, "%I!%ud → %I!%ud | rcvd %Φ\n",
+ frame->udp.laddr, lport, frame->udp.raddr, rport, frame);
}
}
closeioproc(io);
@@ -103,13 +104,13 @@ threadnetppu(void *)
if(frame->type == NChi){
nc = newnetconn(NCSConnecting, &frame->udp);
putconn(nc);
-
+
newf = newframe(frame, NShi, 0, 0, 2*sizeof(ulong), nil);
-
+
dhgenpg(&nc->dh.p, &nc->dh.g);
pack(newf->data, newf->len, "kk", nc->dh.p, nc->dh.g);
sendp(egress, newf);
-
+
if(debug)
fprint(2, "\tsent p %ld g %ld\n", nc->dh.p, nc->dh.g);
}else
@@ -124,10 +125,10 @@ threadnetppu(void *)
nc->state = NCSConnected;
if(debug)
- fprint(2, "\trecvd pubkey %ld\n", nc->dh.pub);
+ fprint(2, "\trcvd pubkey %ld\n", nc->dh.pub);
newf = newframe(frame, NSdhx, 0, 0, sizeof(ulong), nil);
-
+
nc->dh.sec = truerand();
nc->dh.priv = dhgenkey(nc->dh.pub, nc->dh.sec, nc->dh.p);
pack(newf->data, newf->len, "k", dhgenkey(nc->dh.g, nc->dh.sec, nc->dh.p));
@@ -140,6 +141,12 @@ threadnetppu(void *)
}
break;
case NCSConnected:
+ if(verifyframe(frame, nc->dh.priv) != 0){
+ if(debug)
+ fprint(2, "\tbad signature\n");
+ goto discard;
+ }
+
switch(frame->type){
case NCinput:
unpack(frame->data, frame->len, "k", &kdown);
@@ -150,13 +157,13 @@ threadnetppu(void *)
break;
case NCbuhbye:
popconn(nc);
- free(nc);
+ delnetconn(nc);
break;
}
break;
}
discard:
- free(frame);
+ delframe(frame);
}
}
@@ -180,9 +187,8 @@ threadnetsend(void *arg)
if(debug){
rport = frame->udp.rport[0]<<8 | frame->udp.rport[1];
lport = frame->udp.lport[0]<<8 | frame->udp.lport[1];
- fprint(2, "%I!%ud → %I!%ud | sent type %ud seq %ud ack %ud len %ud\n",
- frame->udp.laddr, lport, frame->udp.raddr, rport,
- frame->type, frame->seq, frame->ack, frame->len);
+ fprint(2, "%I!%ud → %I!%ud | sent %Φ\n",
+ frame->udp.laddr, lport, frame->udp.raddr, rport, frame);
}
free(frame);
@@ -334,6 +340,7 @@ threadmain(int argc, char *argv[])
GEOMfmtinstall();
fmtinstall('I', eipfmt);
+ fmtinstall(L'Φ', Φfmt);
addr = "udp!*!112";
ARGBEGIN{
case 'a':
diff --git a/net.c b/net.c
index d645eb4..12c2c5b 100644
--- a/net.c
+++ b/net.c
@@ -1,6 +1,8 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
+#include <mp.h>
+#include <libsec.h>
#include <thread.h>
#include <draw.h>
#include <geometry.h>
@@ -69,6 +71,7 @@ newframe(Frame *pf, u8int type, u32int seq, u32int ack, u16int len, uchar *data)
Frame *f;
f = emalloc(sizeof(Frame)+len);
+ memset(f, 0, sizeof(Frame));
f->id = ProtocolID;
f->type = type;
if(pf != nil){
@@ -88,6 +91,40 @@ newframe(Frame *pf, u8int type, u32int seq, u32int ack, u16int len, uchar *data)
}
void
+signframe(Frame *f, ulong key)
+{
+ uchar k[sizeof(ulong)];
+ uchar h[MD5dlen];
+ uchar msg[MTU];
+ int n;
+
+ k[0] = key; k[1] = key>>8; k[2] = key>>16; k[3] = key>>24;
+
+ memset(f->sig, 0, MD5dlen);
+ n = pack(msg, sizeof msg, "f", f);
+ hmac_md5(msg, n, k, sizeof k, h, nil);
+ memmove(f->sig, h, MD5dlen);
+}
+
+int
+verifyframe(Frame *f, ulong key)
+{
+ uchar k[sizeof(ulong)];
+ uchar h0[MD5dlen], h1[MD5dlen];
+ uchar msg[MTU];
+ int n;
+
+ k[0] = key; k[1] = key>>8; k[2] = key>>16; k[3] = key>>24;
+
+ memmove(h0, f->sig, MD5dlen);
+ memset(f->sig, 0, MD5dlen);
+ n = pack(msg, sizeof msg, "f", f);
+ hmac_md5(msg, n, k, sizeof k, h1, nil);
+ memmove(f->sig, h0, MD5dlen);
+ return memcmp(h0, h1, MD5dlen);
+}
+
+void
delframe(Frame *f)
{
free(f);
diff --git a/pack.c b/pack.c
index 4680d73..f1a9a0a 100644
--- a/pack.c
+++ b/pack.c
@@ -1,6 +1,8 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
+#include <mp.h>
+#include <libsec.h>
#include <draw.h>
#include <geometry.h>
#include "dat.h"
@@ -91,6 +93,7 @@ vpack(uchar *p, int n, char *fmt, va_list a)
put4(p, F->seq), p += 4;
put4(p, F->ack), p += 4;
put2(p, F->len), p += 2;
+ memmove(p, F->sig, MD5dlen), p += MD5dlen;
if(p+F->len > e)
goto err;
@@ -161,6 +164,7 @@ vunpack(uchar *p, int n, char *fmt, va_list a)
F->seq = get4(p), p += 4;
F->ack = get4(p), p += 4;
F->len = get2(p), p += 2;
+ memmove(F->sig, p, MD5dlen), p += MD5dlen;
if(p+F->len > e)
goto err;
diff --git a/party.c b/party.c
index ad3cd9b..6199b87 100644
--- a/party.c
+++ b/party.c
@@ -1,6 +1,8 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
+#include <mp.h>
+#include <libsec.h>
#include <draw.h>
#include <geometry.h>
#include "dat.h"
diff --git a/physics.c b/physics.c
index 0fafea4..b588a4d 100644
--- a/physics.c
+++ b/physics.c
@@ -1,6 +1,8 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
+#include <mp.h>
+#include <libsec.h>
#include <draw.h>
#include <geometry.h>
#include "dat.h"
diff --git a/sprite.c b/sprite.c
index aceceed..22dd00b 100644
--- a/sprite.c
+++ b/sprite.c
@@ -1,6 +1,8 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
+#include <mp.h>
+#include <libsec.h>
#include <draw.h>
#include <geometry.h>
#include "dat.h"
diff --git a/universe.c b/universe.c
index 7a17b56..eea95a8 100644
--- a/universe.c
+++ b/universe.c
@@ -1,6 +1,8 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
+#include <mp.h>
+#include <libsec.h>
#include <draw.h>
#include <geometry.h>
#include "dat.h"