ec-field-test.c: Make the field-element type use internal format.
[secnet] / secnet-wireshark.lua
index c9b25d2..b9c42b8 100644 (file)
@@ -162,7 +162,7 @@ end
 local function dump_algs(algs)
   -- Dump the algorithms selection ALGS from a site structure.
 
-  return "xform=" .. algs.transform
+  return "xform=" .. algs.transform .. "; dh=" .. algs.dhgroup
 end
 
 local function dump_str(str) return str end
@@ -224,6 +224,12 @@ local CAPTAB = {
          desc = "Deprecated Serpent256-CBC transform" },
   [9] = { name = "eaxserpent", kind = "transform",
          desc = "Serpent256-EAX transform" },
+  [10] = { name = "tradzp", kind = "dhgroup",
+          desc = "Traditional Z_p Diffie--Hellman key agreement" },
+  [11] = { name = "x25519", kind = "dhgroup",
+          desc = "X25519 elliptic curve Diffie--Hellman key agreement" },
+  [12] = { name = "x448", kind = "dhgroup",
+          desc = "X448 elliptic curve Diffie--Hellman key agreement" },
   [31] = { name = "mobile-priority", kind = "early",
           desc = "Mobile site takes priority in case of MSG1 crossing" }
 }
@@ -248,10 +254,11 @@ local function notice_alg_selection(st)
   -- Record the algorithm selections declared in the packet described by ST.
 
   local transform = get_algname("transform", st.transform, "serpent256cbc")
+  local dhgroup = get_algname("dhgroup", st.dhgroup, "tradzp")
   local site = get_site_create(st.sndname)
   local peer = get_site_create(st.rcvname)
   local now = st.pinfo.rel_ts
-  local algs = { transform = transform }
+  local algs = { transform = transform, dhgroup = dhgroup }
   tl_add(get_timeline_create(site.algs, st.rcvname), now, algs)
   tl_add(get_timeline_create(peer.algs, st.sndname), now, algs)
 end
@@ -262,20 +269,54 @@ end
 local PF = { } -- The table of protocol fields, filled in later.
 local F = { } -- A table of field values, also filled in later.
 
+local function msgcode(major, minor)
+  -- Construct a Secnet message number according to the complicated rules.
+
+  local majlo = bit.band(major, 0x000f)
+  local majhi = bit.band(major, 0xfff0)
+  local minlo = bit.band(minor, 0x000f)
+  local minhi = bit.band(minor, 0xfff0)
+  return bit.bxor(bit.lshift(majlo,  0),
+                 bit.lshift(majlo,  8),
+                 bit.lshift(majlo, 16),
+                 bit.lshift(majlo, 24),
+                 bit.lshift(majhi,  4),
+                 bit.lshift(minlo,  4),
+                 bit.lshift(minlo, 28),
+                 bit.lshift(minhi, 16))
+end
+
+local function msgmajor(label)
+  -- Return the major message number from a LABEL.
+
+  local lo = bit.band(label, 0x000f)
+  local hi = bit.band(bit.rshift(label, 4), 0xfff0)
+  return bit.bxor(lo, bit.lshift(lo, 4), bit.lshift(lo, 12), hi)
+end
+
+local function msgminor(label)
+  -- Return the minor message number from a LABEL.
+
+  return bit.bxor(bit.lshift(bit.band(label, 0x00ff), 8),
+                 bit.band(bit.rshift(label, 4), 0x000f),
+                 bit.band(bit.rshift(label, 16), 0xfff0))
+end
+
 -- Main message-number table.
-local M = { NAK                = 0x00000000
-           MSG0        = 0x00020200
-           MSG1        = 0x01010101
-           MSG2        = 0x02020202
-           MSG3        = 0x03030303
-           MSG3BIS     = 0x13030313
-           MSG4        = 0x04040404
-           MSG5        = 0x05050505
-           MSG6        = 0x06060606
-           MSG7        = 0x07070707
-           MSG8        = 0x08080808
-           MSG9        = 0x09090909
-           PROD        = 0x0a0a0a0a }
+local M = { NAK                = msgcode(     0, 0),
+           MSG0        = msgcode(0x2020, 0), -- !
+           MSG1        = msgcode(     1, 0),
+           MSG2        = msgcode(     2, 0),
+           MSG3        = msgcode(     3, 0),
+           MSG3BIS     = msgcode(     3, 1),
+           MSG3TER     = msgcode(     3, 2),
+           MSG4        = msgcode(     4, 0),
+           MSG5        = msgcode(     5, 0),
+           MSG6        = msgcode(     6, 0),
+           MSG7        = msgcode(     7, 0),
+           MSG8        = msgcode(     8, 0),
+           MSG9        = msgcode(     9, 0),
+           PROD        = msgcode(    10, 0)}
 
 -- The `dissect_*' functions follow a common protocol.  They parse a thing
 -- from a packet buffer BUF, of size SZ, starting from POS, and store
@@ -313,6 +354,7 @@ do
     -- Firstly, build, in `caps', a list of the capability names and their
     -- numbers.
     local i = 1
+    caps[i] = { i = 15, cap = "explicit" }; i = 1 + 1
     for j, cap in pairs(CAPTAB) do
       caps[i] = { i = j, cap = cap.name }
       i = i + 1
@@ -418,6 +460,14 @@ local function dissect_transform(st, buf, tree, pos, sz)
   return pos
 end
 
+local function dissect_dhgroup(st, buf, tree, pos, sz)
+  -- Dissect the selected DH group.  Note this in the packet state for later.
+
+  st.dhgroup = buf(pos, 1):uint()
+  tree:add(PF["secnet.kx.dhgroup"], buf(pos, 1)); pos = pos + 1
+  return pos
+end
+
 local function dissect_lenstr(st, buf, tree, label, pos, sz)
   -- Dissect a simple string given its length.
   local len = buf(pos, 2):uint()
@@ -430,7 +480,11 @@ end
 local function dissect_dhval(st, buf, tree, pos, sz)
   -- Dissect a Diffie--Hellman public value.
 
-  return dissect_lenstr(st, buf, tree, "secnet.kx.dhval", pos, sz)
+  local len = buf(pos, 2):uint()
+  local sub = tree:add(PF["secnet.kx.dhval"], buf(pos, len + 2))
+  sub:add(PF["secnet.kx.dhval.len"], buf(pos, 2)); pos = pos + 2
+  sub:add(PF["secnet.kx.dhval.bytes"], buf(pos, len)); pos = pos + len
+  return pos
 end
 
 local function dissect_sig(st, buf, tree, pos, sz)
@@ -587,6 +641,23 @@ local PKTINFO = {
                dissect_wtf },
     hook = notice_alg_selection
   },
+  [M.MSG3TER] = {
+    label = "MSG3TER",
+    info = "MSG3TER",
+    dissect = { make_dissect_name_xinfo("secnet.kx.sndname",
+                                       { dissect_caps,
+                                         dissect_mtu,
+                                         dissect_wtf },
+                                       notice_sndname),
+               make_dissect_name_xinfo("secnet.kx.rcvname",
+                                       { dissect_wtf },
+                                       notice_rcvname),
+               dissect_sndnonce, dissect_rcvnonce,
+               dissect_transform, dissect_dhgroup,
+               dissect_dhval, dissect_sig,
+               dissect_wtf },
+    hook = notice_alg_selection
+  },
   [M.MSG4] = {
     label = "MSG4",
     info = "MSG4",
@@ -632,7 +703,7 @@ do
   local msgtab = { }
   for i, v in pairs(PKTINFO) do msgtab[i] = v.label end
 
-  local capmap = { transform = { }, early = { } }
+  local capmap = { transform = { }, dhgroup = { }, early = { } }
   for i, v in pairs(CAPTAB) do capmap[v.kind][i] = v.desc end
 
   local ftab = {
@@ -693,6 +764,10 @@ do
       name = "User-assigned capability bits",
       type = ftypes.UINT32, mask = 0x000000ff, base = base.HEX
     },
+    ["secnet.cap.explicit"] = {
+      name = "Transforms listed explicitly; all capability bits used",
+      type = ftypes.BOOLEAN, mask = 0x00008000, base = 32
+    },
     ["secnet.mtu"] = {
       name = "Sender's requested MTU", type = ftypes.UINT16, base = base.DEC
     },
@@ -706,6 +781,10 @@ do
       name = "Selected bulk-crypto transform", type = ftypes.UINT8,
       base = base.DEC, tab = capmap.transform
     },
+    ["secnet.kx.dhgroup"] = {
+      name = "Selected Diffie--Hellman group kind", type = ftypes.UINT8,
+      base = base.DEC, tab = capmap.dhgroup
+    },
     ["secnet.kx.dhval"] = {
       name = "Sender's public Diffie--Hellman value", type = ftypes.NONE
     },
@@ -713,9 +792,9 @@ do
       name = "Sender's public Diffie--Hellman length",
       type = ftypes.UINT16, base = base.DEC
     },
-    ["secnet.kx.dhval.text"] = {
-      name = "Sender's public Diffie--Hellman text", type = ftypes.STRING,
-      base = base.ASCII
+    ["secnet.kx.dhval.bytes"] = {
+      name = "Sender's public Diffie--Hellman value bytes",
+      type = ftypes.BYTES, base = base.SPACE
     },
     ["secnet.kx.sig"] = {
       name = "Sender's signature", type = ftypes.NONE