Subject: [babel] ANNOUNCE: hmac authentication for Babel, first prototype

From: Juliusz Chroboczek <[email-masked]>
Date: Fri, 22 Jun 2018 23:18:25 +0200

Dear all,

Clara Dô et Weronika Kołodziejak (in copy of this mail) have just pushed
their work on HMAC authentication for babeld to Github:

  https://github.com/wkolod/babeld  branch hmac

It's a very early prototype, and has received almost no testing.  To use,
checkout and compile the hmac branch, and say in your config file:

  key id key1 type sha1 value deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
  interface wlan0 hmac key1

The following features are planned but not implemented yet:

  - multiple keys on a single interface;
  - key rotation;
  - restart with loss of state in the absence of a hardware clock.

There's a minor bug that we plan to fix next week:

  - all keys known to babeld are accepted, not just the keys assigned to
    a given interface.

We also need to carefully check the error-handling behaviour, especially
for TLV truncation.

The protocol
============

The protocol is closely based on the work of Denis Ovsienko (RFC 7298,
draft-ovsienko-babel-rfc7298bis-00.  The main differences are as follows:

  (1) rather than inserting the source address into the HMAC TLV before
      hashing, we use a pseudo-header consisting of the source and
      destination addresses (suggested by David Schinazi, to whom thanks);
  (2) the HMAC TLV does not carry an explicit key-ID; instead, we test the
      received HMAC against all provisioned keys (just one in the normal
      case, just two during key rotation);
  (3) the HMAC TLV carries a single opaque field "TS/PC" of size 6 octets;
      it is not structured into TS and PC, since the distinction is not
      necessary;
  (4) the HMAC TLV lives in the packet trailer, which makes it clear what
      is covered by the HMAC and what isn't;
  (5) replay protection is slightly different, to avoid the flaw described
      in my posting of 10 May 2018 to babel@ietf.  A neighbour is
      considered authentic if we received a fresh TS/PC echo from it in
      the last 30 seconds.  Details are likely to change (I think we'll
      make that 4 * IHU interval).

We're pretty sure of ourselves for points 1, 2, and 3.  Point 4 is open
for discussion -- it makes implementation simpler, but complicates the
description of the protocol.  Point 5 is likely to change.

We are open to suggestions about how to achieve restart with loss of
state.  Be aware that the internship officially ends by the end of the
month, so earlier comments will be even more welcome than later ones.

The code
========

A quick guide to the code:

  - keys live in struct interface and struct buffered; all known keys are
    in the key table, which is reference counted;
  - the packet trailer is checked in check_hmac, which is called early in
    parse_packet; if the HMAC check fails, the packet is dropped straight
    away, with no further parsing;
  - a first pass is made over the packet to check for TS/PC and update
    neighbour authenticity; this is preparse_tspc, called from
    parse_packet; if the neighbour is not fresh, the packet is dropped
    straight away;
  - the packet is then parsed as usual.

All together, some 850 lines of code, 730 not counting the configuration
parser.

 Makefile        |  10 +-
 anm.c           |  81 +++++++++++++++
 anm.h           |  31 ++++++
 babeld.c        |   5 +-
 configuration.c | 121 ++++++++++++++++++++++-
 configuration.h |   4 +
 hmac.c          | 300 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hmac.h          |  36 +++++++
 interface.c     |  12 ++-
 interface.h     |  10 ++
 message.c       | 178 ++++++++++++++++++++++++++++++---
 message.h       |  10 +-
 neighbour.c     |   5 +
 neighbour.h     |   1 +
 net.c           |  40 +++++++-
 net.h           |   3 +-
 util.c          |  32 ++++++
 util.h          |   2 +
 18 files changed, 851 insertions(+), 30 deletions(-)

Enjoy,

-- Juliusz