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