Hello, list.

Cover letter and reasoning
==========================
This draft suggests improving Babel protocol in the way of packet 
authentication. Packet authentication is an approach, which most other IGPs use 
to ensure, that received protocol packets were originated by the same router, 
which is claimed as packet sender, and were delivered unchanged.

Babel (in the definition of RFC6126) lacks any builtin authentication means, 
but explicitly allows for arbitrary trailing data after the main packet body 
and specifies, that unknown TLVs in the main packet body must be silently 
ignored.

An implementor of an authenticated Babel network is left with the following 
options:
* Authenticate all packetes in the network (e.g. WPA).
* Selectively authenticate Babel packets with IPSec policy.
* Implement Babel packet-level authentication using trailing data.
* Implement Babel packet-level authentication using TLVs.
* Do something else.

The TLV option, to my opinion, makes the most sense. I need to make my reasons, 
which come from several months of studying packet structures of RIP-2, OSPF-2 
and OSPF-3. In partucular, this study involved developing and fixing Quagga 
code to protect it from malformed packets (which may be malformed in a lot of 
ways). In the cases of RIP-2 and OSPF-2 this experience also included 
structures and methods used in packet authentication.

RIP-1 (RFC1058) packets did not have any authentication and contained 
fixed-size data structures (RTEs) with routing information. RIP-2 (RFC2453) 
introduced simple password authentication and reused leading RTE for 
authentication information. Keyed-MD5 hash authentication (RFC2082) was added 
later and used trailing RTE for hash digest data, which did exactly fit, but 
only till Cryptographic (RFC4822) authentication was defined, which allowed for 
longer trailing data.

OSPF-2 (RFC2328) had Keyed-MD5 authentication in the basic specification and 
necessary flexibility in the packet header to allow for hash digests of other 
lengths, which (HMAC-SHA family) were added by RFC5709. However, the hash 
digest never belonged to the main packet body. OSPF-2 did not allow for new 
protocol-scope parameters to be carried in a packet (type-9 opaque LSAs did not 
quite fit for the job), and LLS (RFC5613) was established in the form of 2nd 
(in the case of OSPF-2) trailer, a container for TLVs.

OSPF-3 (RFC5340) removed all support for authentication in favour of IPv6 
AH/ESP means. LLS (RFC5613) was also defined for OSPF-3, which got its own 
(1st) trailer with LLS TLVs. However, AH/ESP did not become a complete 
solution, and (2nd) trailer with HMAC-SHA (RFC6506) authentication data was 
established.

There are lessons, which can be learned from this history.

First, authentication is very likely to appear in a routing protocol at some 
point, even if it is missing in the beginning. Authenticating all packets 
passing a network interface may be impossible, given particular bandwidth 
requirements. IPv6 AH matches the space of the problem only in a part and adds 
to maintenance costs. An optional purpose-builtin authentication is often the 
optimal solution, which leaves the space for every other option.

Second, it is better to keep packet structure pattern as uniform as possible. 
Considering efforts required to develop, audit and debug program code, 
switching from fixed-size structures to TLVs and back is notably more 
expensive, than working within one particular pattern. In the scope of Babel, 
this would mean that TLV-based authentication model would be better, than one 
using trailing data.

Third, modern cryptography tends to replace established hash algorithms with 
those, which are not yet compromised, hence protocol authentication should 
allow for arbitrary hash functions and algorithms. This draft follows 
established best practice in doing this.

Fourth, every protocol described above allows for at most one hash digest per 
protocol packet, although multiple keys may be available, and uses one hash 
algorithm from several available. There are key rollover methods defined, which 
address key selection problem. However, a single digest makes it impossible to 
perform a seamless change of a hash algorithm or authenticate within multiple 
administrative domains. This concern is addressed by this draft.

An essential specification below is likely to include the right amount of key 
ideas required for the solution. Some of the ideas are borrowed from the RFCs 
mentioned above, but a few are original to this specification. An 
implementation of this spec would be completely transparent for all current 
Babel implementations. Transparency with future versions would only require 
permanently reserving two TLV types, which Juliusz can hopefully approve.

I would be glad to have this draft eventually developed into a formal RFC. 
Talking about a proof of concept, I guess it's possible to add required 
functionality to Quagga babeld in a reasonable time.

Changes in data structures
==========================
1. Three variables are added to the structure representing a Babel protocol.
1.1 PC (16-bit unsigned integer)
1.2 TS (32-bit unsigned integer)
1.3 MaxDigests (unsigned integer of an arbitrary size, which may remain "unset")

2. The structure representing a Babel neighbor is also extended with PC and TS 
variables of the same type and size.

3. The structure representing a Babel interface is extended to allow for a list 
of Security Associations (defined below).

4. Two additional TLVs are defined: Packet Counter/Timestamp (PC/TS) and 
HashDigest (HD).

4.1. PC/TS TLV

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Type = 11  |    Length     |        Packet Counter         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                           Timestamp                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   Fields :

   Type            Set to 11 to indicate a PC/TS TLV.

   Length          The length of the body, exclusive of the Type and
                   Length fields.

   Packet Counter  A 16-bit unsigned integer in network byte order.

   Timestamp       A 32-bit unsigned integer in network byte order.


4.2. Hash Digest TLV

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Type = 12  |    Length     |             Key ID            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |       Digest...
   +-+-+-+-+-+-+-+-+-+-+-+-

   Fields :

   Type            Set to 12 to indicate an HD TLV.

   Length          The length of the body, exclusive of the Type and
                   Length fields.

   Key ID          A 16-bit unsigned integer in network byte order.

   Digest          A variable-length sequence of octets, typically 20
                   or more octets long.


Semantics of PC/TS data structure
=================================
PC and TS are essentially two parts of a strictly increasing 48-bit unsigned 
integer number, which is typically referred to as "crypto sequence number" in 
several other specifications.

This specification does not call it a "crypto sequence number" (to avoid 
confusion with Babel sequence numbers) and defines different handling for each 
part of PC/TS.

The "Packet Counter" field is intended to hold the value of a counter, which 
belongs to the whole Babel protocol instance and is incremented with each 
protocol packet being sent. The counter will wrap (reset to 0) upon reaching 
maximum value.

The "Timestamp" field is used as a PC wrap counter: when PC reaches the maximum 
value and wraps, TS is incremented.

When TS reaches the maximum value, it wraps (resets to the "initial" value 
defined below).

It is also possible for TS to be incremented before PC wraps, in this case PC 
must be set to 0.

There are several ways possible to initialize and update TS, so that PC/TS 
number may have additional properties besides being strictly increasing.

1. The most basic approach is to assign TS := 0 on Babel protocol instance 
start and increment it only on PC wrap. PC/TS numbers would repeat after each 
protocol restart and induce a PC/TS quarantine period, if the neighboring 
routers have not aged the previous protocol instance out by the time new 
instance is started.

2. Use TS as a "wrap/boot counter" and store it in NVRAM each time it changes 
(see RFC6506 4.1). This would allow for unique PC/TS across router's deployed 
life.

3. Use UNIX timestamp as TS source. That is, if current UNIX timestamp is 
greater than current TS value, the latter must be set to the former and PC 
reset to 0. This also allows for lifetime-unique PC/TS number, but without 
NVRAM.

All these approaches are compatible with this specification. Implementors of 
this specification and operators of the implementations are free to decide, 
which particular approach is used by which particular Babel router. There are 
some additional notes concerning use of UNIX timestamp.

3.1. Using UNIX timestamp as TS source is appropriate only if router's local 
clock is never adjusted backwards, otherwise each such adjustment will place 
the router into a PC/TS quarantine.

3.2. If a router is sending more than 64K Babel packets per second for a 
limited period of time, PC will wrap more often, than once per second, and TS 
will exceed UNIX timestamp. Once the packet rate drops, UNIX timestamp will 
eventually reach the value of then-current TS. Babel routers permanently 
sending more than 64K protocol packets per second will suffer periodic PC/TS 
quarantines. This is not viewed as a problem of practical significance.

3.3. A seamless switch from "basic" to "UNIX" TS approach is possible, but not 
the other way. This allows for a case, where a freshly deployed Babel router 
would use "basic" PC/TS approach until it has acquired necessary routes and 
completed initial network clock synchronization. Once this is done, it can be 
permanently reconfigured to use the "UNIX" approach without any interruption to 
Babel protocol exchange.

Definitions of Security Associations
====================================
An authentication key (AK) is defined as a secret data with associated ID (a 
16-bit unsigned integer) and a set of lifetime attributes.

Depending on the current date and time (which change), each AK may be 
distinguished as active or inactive according to its lifetime attributes (which 
do not change between configuration changes).

A configured security association (CSA) is defined as an interface-specific 
unique combination of one particular hash algorithm (HMAC-SHA-1, HMAC-SHA-256, 
HMAC-SHA-384, HMAC-SHA-512) and one set of 1 or more AKs.

Key IDs must be unique within the scope of one given CSA.

A Babel interface may have any number of CSAs (including 0) at operator's 
discretion.

An effective security association (ESA) is a CSA with inactive AKs excluded, as 
evaluated against current date and time.

A valid ESA can have 0 or more AKs.

Changes in packet sending
=========================
If the current outgoing interface has no CSAs, the current packet is processed 
without any changes to the original sending process.

Otherwise, the following steps are taken.

1. A PC/TS TLV is appended to the main packet body. PC and TS values are 
assigned as described above.

2. For each of the interface ESAs, for each AK of the current ESA an HD TLV is 
appended to the main packet body. This TLV must have "Length" field set to L+2, 
"Key ID" field set to ID of the current AK and "Digest" field (L bytes long) 
set to source address of the current packet, zero-padded to L bytes. Generation 
process may be stopped, if MaxDigests is set and number of HD TLVs reaches 
MaxDigests value.

3. The current packet (Pout) is then copied and the copy (Pout') set aside.

4. For each of the interface ESAs, for each AK of the current ESA (in the same 
very order as in step 2, and respectively for each of the HD TLVs generated) a 
HMAC procedure is performed, using Pout' as "m" input and AK as "Ko" input, 
with hash digest output written to "Digest" field of the current HD TLV of Pout 
(this way, "m" remains constant for every HMAC round, but "H" and "Ko" may 
change). If HD TLVs generation process was limited due to MaxDigests threshold, 
this process must also be terminated at the same threshold.

5. Pout' is discarded, Pout is treated as the current packet. Since this point, 
no more changes are allowed to the packet, which is now ready for remaining 
transmission procedures.

Changes in packet reception
===========================
If the current incoming interface has no CSAs, the current packet is processed 
without any changes to the original receiving process. 

Otherwise, the following steps are taken.

1. PC/TS TLV of the packet (PCr, TSr) is verified against stored PC and TS 
values of the Babel neighbor originating the packet (PCs, TSs). If TSr < TSs, 
the packet is discarded and processing stops. Otherwise, if TSr > TSs, 
processing proceeds to step 2. Otherwise, if PCr > PCs, processing proceeds to 
step 2. Otherwise the packet is discarded and processing stops.

2. A copy (Pin') of the current packet (Pin) is made and set aside.

3. For each of the HD TLVs present in Pin' the "Digest" field is set to source 
address of the current packet and zero-padded up to length of the current HD 
TLV.

4. For each of the HD TLVs present in Pin all ESAs are looked up, which have 
hash digest length = "Length" field of the current TLV minus 2 and an AK with 
ID = "Key ID" field. For each of the ESA-AK pairs found a HMAC procedure is 
performed with m = Pin', Ko = KA and H = hash function of the current ESA. If 
HMAC output matches the "Digest" field of the current TLV, processing proceeds 
to step 6.

5. Apparently, none of the HD TLVs matched any of the ESAs. Pin and Pin' are 
discarded and processing stops.

6. PC and TS value of the current Babel neighbor are updated to the PC and TS 
values of the current packet PC/TS TLV (PCs := PCr; TSs := TSr).

7. Pin' is discarded, Pin is accepted for remaining receiving procedures.


-- 
    Denis Ovsienko

_______________________________________________
Babel-users mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/babel-users

Reply via email to