[tcpm] Review of draft-ietf-tcpm-tcp-auth-opt-05

Eric Rescorla <ekr@networkresonance.com> Sat, 15 November 2008 22:03 UTC

Return-Path: <tcpm-bounces@ietf.org>
X-Original-To: tcpm-archive@megatron.ietf.org
Delivered-To: ietfarch-tcpm-archive@core3.amsl.com
Received: from [] (localhost []) by core3.amsl.com (Postfix) with ESMTP id 1BDF33A680F; Sat, 15 Nov 2008 14:03:20 -0800 (PST)
X-Original-To: tcpm@core3.amsl.com
Delivered-To: tcpm@core3.amsl.com
Received: from localhost (localhost []) by core3.amsl.com (Postfix) with ESMTP id 3D4B03A680F for <tcpm@core3.amsl.com>; Sat, 15 Nov 2008 14:03:19 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.399
X-Spam-Status: No, score=-1.399 tagged_above=-999 required=5 tests=[BAYES_00=-2.599, J_CHICKENPOX_33=0.6, J_CHICKENPOX_43=0.6]
Received: from mail.ietf.org ([]) by localhost (core3.amsl.com []) (amavisd-new, port 10024) with ESMTP id Vx6LPeIkNAfZ for <tcpm@core3.amsl.com>; Sat, 15 Nov 2008 14:03:17 -0800 (PST)
Received: from s-utl01-dcpop.stsn.net (s-utl01-dcpop.stsn.net []) by core3.amsl.com (Postfix) with SMTP id 94A4C3A67F5 for <tcpm@ietf.org>; Sat, 15 Nov 2008 14:03:17 -0800 (PST)
Received: from s-utl01-dcpop.stsn.net ([]) by s-utl01-dcpop.stsn.net (SMSSMTP with SMTP id M2008111517031722929 for <tcpm@ietf.org>; Sat, 15 Nov 2008 17:03:17 -0500
Received: from kilo.rtfm.com ([]) by s-utl01-dcpop.stsn.net for tcpm@ietf.org; Sat, 15 Nov 2008 17:03:05 -0500
Received: from kilo-2.local (localhost []) by kilo.rtfm.com (Postfix) with ESMTP id DD4F57575BD for <tcpm@ietf.org>; Sat, 15 Nov 2008 13:33:38 -0800 (PST)
Date: Sat, 15 Nov 2008 13:33:28 -0800
From: Eric Rescorla <ekr@networkresonance.com>
To: tcpm@ietf.org
User-Agent: Wanderlust/2.15.5 (Almost Unreal) Emacs/22.1 Mule/5.0 (SAKAKI)
MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka")
Message-Id: <20081115213338.DD4F57575BD@kilo.rtfm.com>
Subject: [tcpm] Review of draft-ietf-tcpm-tcp-auth-opt-05
X-BeenThere: tcpm@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: TCP Maintenance and Minor Extensions Working Group <tcpm.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/tcpm>, <mailto:tcpm-request@ietf.org?subject=unsubscribe>
List-Archive: <https://www.ietf.org/mailman/private/tcpm>
List-Post: <mailto:tcpm@ietf.org>
List-Help: <mailto:tcpm-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tcpm>, <mailto:tcpm-request@ietf.org?subject=subscribe>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Sender: tcpm-bounces@ietf.org
Errors-To: tcpm-bounces@ietf.org

$Id: draft-ietf-tcpm-tcp-auth-opt-05-rev.txt,v 1.1 2008/11/15 20:50:05 ekr Exp $

Overall, this document is substantially improved. However, 
a number of the issues I raised in previous reviews remain:

In particular, I wrote:

    I don't think this API, specification of the TSAD, etc., is
    particularly helpful. IPsec needed the concept of an association
    database because packets corresponding to multiple associations
    got similar treatment. However, TCP has an explicit notion
    of connection so it would be far more convenient to simply
    refer to keys as tied to connections, and then have a set
    of rules for mapping which connections get which keys.
    Even if some TSAD-type abstraction is useful, I don't think
    it's appropriate to define things like the size of each
    parameter in the TSAD as opposed to on the wire, or to
    describe the default values of various parameters as in
    S 3. For instance:
             iii. Key length. A byte indicating the length of the 
                   connection key in bytes.  
    Those are internal implementation issues. Certainly, I might
    want to use a native int in my implementation. Why should
    this document tell me otherwise?

In response to my previous review, Joe indicated that:

    The TSAD API needs to be specified in detail because the key management 
    solution needs to rely on that information.

I don't agree that it's necessary to define *any* API. What's
necessary is to define clear boundaries between the packet processing
system and the key management system (if any). I don't see that it's
necessary to be specified at the level of "this parameter is a byte".
If you want enough specificity that uncooperating implementors could
independently develop these components and have them work together out
of the box, then you need to explicitly define much more material,
i.e., argument order, struct packing, error formats, calling sequences
etc. In other words, you should either be defining language bindings
or a formal language like IDL. Absent that, I don't agree that 
defining the length of the fields containing these parameters is of
any value. It's particularly odd to focus on the length of the
parameters and not specify (for instance) the signedness or the
bit order.

WRT to S 3 (now in S 6) I wrote:

               >> At least one direction (inbound/outbound) SHOULD have 
               a non-"NONE" MAC in practice, but this MUST NOT be 
               strictly required by an implementation.  

     1. This seems like a bad idea. It's very hard to analyze the security
     properties of a connection when only one side is protected. To take
     one case that is obviously bad, if you're worried about DoS attacks
     and you use TCP-AO, then forging packets in either direction can
     bring it down. I would reverse this and require MACs in both directions.
     2. Even if we stipulate that this might be an OK idea, it's not
     appropriate to require implementations to support it.

No good reason has ever been offered for this feature. Given the above
reasoning, I propose it be removed.

S 1.1.
   o  TCP-AO replaces MD5's single MAC algorithm with two prespecified 
      MACs (TBD-WG-MACS), and allows extension to include other MACs. 

I remain unconvinced that defining two MACs as MTI does anything but
add complexity.

I'm wondering if we should specify heuristics or algorithms for
key changeover. Here's what I mean: Alice and Bob are currently
using Key 1 and they want to change over to Key 2. At time 
T0, Alice installs Key 2, but she can't start transmitting with
it until she knows that Bob has installed it. At time T1,
Bob installs Key 2. Now, if he knows that Alice installed first,
he can start using it, but if he does and Alice hasn't, then
packets start getting dropped. Finally, once Bob has installed
Key 2, he needs to tell Alice that he has installed Key 2
so he can switch over. This is a lot of manual coordination.

Lebovitz and I spent some time the other day trying to make this
problem easier and here's what we came up with. 

1. As soon as a node receives a segment protected with Key X
   (and verifies it, of course) it can conclude that the peer
   knows Key X and start using Key X to transmit with.
2. Once a peer has had a new key installed, it should periodically
   send a segment protected with that key. Note that the interval
   here should be low enough that if the verification fails it
   doesn't cause TCP to back off really far. But other than that,
   it doesn't matter how it's set. [Maybe there's some TCP wizardry
   here to decrease the effect, like you only treat ACKs this way
   or something...]

I'm assuming there's some concept of ordering or priority where key
X is assumed to be better (newer) than Y. That seems easy to have.

Anyway, the point of this algorithm is that Alice and Bob can 
independently configure new keys and then the system will automatically
detect when they both have them configured and start using them
without any explicit coordination over when the keys are installed.

S 4.
I found this ESN management algorithm extremely hard to follow.
For starters, no initial values are provided for {SND,RCV}.PREV_SEQ,
which makes it hard to see even where to start. 

Aside from that, let's look at the first line:

         ROLL = (RCV.PREV_SEQ > 0xffff) && (SEG.SEQ < 0xffff); 

Why is 0xffff magic? I'm inferring that no TCP datagram can ever
exceed 2^16 bytes of data, but actually the maximum is somewhat
less because it's bounded by the maximum length of an IP datagram
minus the various headers, so it's more like 2^16 - 40 plus
options, and of course this option consumes space.

Anyway, this algorithm needs much more documentation about why
it's supposed to work.

I would also note that despite the statement that hte algorithm
is "written in C", this is not valid C source code, because
you're using # as a comment character.

S 5.
      Conn_key = TALG(TSAD_key, connblock) 

This is not a good method of generating traffic keys:

1. There is no guarantee that the TALG will generate a value as
   long as the required key. Indeed, it's easy to design a MAC
   where this is not true. For instance, AES-256-CMAC.

2. What you want to generate a key is a pseudorandom function (PRF)
   Not all MACs are PRFs. This is easy to forget because HMAC is
   both. However, this is not always the case.

   For example, consider the following MAC, which is designed for the
   rapid detection of errored packets:

   MAC(Key, Data) = CRC32(Data) || HMAC(Key, Data)

   This is a perfectly fine MAC because forging it is intractable.
   However, it is a lousy PRF because the first 32 bits are
   extremely predictable. Note that this isn't at all a hypothetical
   example. Indeed, S 7.5 considers a MAC that is an even weaker
   PRF, with the initial values fixed!

      Additional reductions in MAC validation can be supported by using a 
      MAC algorithm that partitions the MAC field into fixed and computed 
      portions, where the fixed value is validated before investing in the 
      computed portion. This optimization would be contained in the MAC 
      algorithm specification. Note that the KeyID cannot be used for 
      connection validation per se, because it is not assumed random. 

The use of the term "connection key" and "connection block" are
confusing here because the keys are different in each direction, so
there is no single conn key. I suggest using the term "traffic

S 8.
   >> TCP-AO SHOULD be deployed in conjunction with support for 
   selective acknowledgement (SACK), including support for multiple lost 
   segments in the same round trip [RFC2018][RFC3517]. 

I get that SACK would be nice, but this should work fine without
it, so why recommend it here.

S 8.3
   o  TCP connection identifier (ID) (The socket pair, sent as 4 byte IP 
      source address, 4 byte IP destination address, 2 byte TCP source 
      port, 2 byte TCP destination port). 

This is incompatible with IPv6--a result of overspecification here.

S 9.
   >> A system that supports both TCP-AO and TCP MD5 MUST use TCP-AO for 
   connections unless not supported by its peer, at which point it MAY 
   use TCP MD5 instead.  

This seems like a restriction on operators and thus seems inappropriate 
to me.

S 3.2.

      The ESN for transmitted segments is locally maintained from a 
      locally maintained SND.ESN value, for received segments, a local 

This repetition of "locally maintained" is clumsy.

S 5
   Once a connection is established, a connection key would typically be 
   cached to avoid recomputing it on a per-segment basis. The use of 
   both ISNs in the connection key computation ensures that segments 
   cannot be replayed across repeated connections reusing the same 
   socket pair (provided the ISN pair does not repeat, which is 
   extremely unlikely). 

This is only true if strong ISN generation algorithms are used.
This document should come with a SHOULD for using a strong PRNG
for ISN generation.

S 8.1.
   Keys reused across different socket pairs cannot enable replay 
   attacks because the TCP socket pair is included in the MAC, as well 
   as in the generation of the connection key. Keys reused across 

I would use "connnection id" instead of socket pair here. 


tcpm mailing list