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

From: Eric Rescorla <[email-masked]>
Date: Sat, 15 Nov 2008 13:33:28 -0800

$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:

OLD ISSUES
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.

NEW TECHNICAL ISSUES
Overall
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
key".

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.

EDITORIAL
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. 

-Ekr

_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: Joe Touch <[email-masked]>
Date: Sat, 15 Nov 2008 14:48:15 -0800

Hi, Eric,

Some clarifying questions below. I think most of these are easy to fix...

Joe

> parameters and not specify (for instance) the signedness or the

These would be good reasons to include the signedness (all are unsigned)
and byte order (network standard). I don't see a reason to indicate bit
order.

> reasoning, I propose it be removed.

We covered this in detail in an extended discussion in Philadelphia; it
is needed to support channel binding. We can't turn on TCP AO after a
connection has started (because TCP has no option handshake after
connection establishment), but we can go from using a null algorithm to
using a real one.

> I remain unconvinced that defining two MACs as MTI does anything but

You noted this before; I'll raise this to both TCPM and SAAG to confirm
that a single algorithm is sufficient.

> so he can switch over. This is a lot of manual coordination.

Agreed; IMO, this is the responsibility of the key management system,
not TCP-AO.

>    knows Key X and start using Key X to transmit with.

We do not require symmetric key changeover. Side A can use key X while
side B uses key Y; there is no requirement that the senders use the same
index.

>    here to decrease the effect, like you only treat ACKs this way

This sounds like a protocol on top of TCP; we're trying to avoid that.
TCP segments have other meanings, and sending such segments just for a
key management reason would impact other TCP properties we're trying to
leave alone.

> without any explicit coordination over when the keys are installed.

The common algorithm is:

a) install key at receiver
b) install key at sender

Since our keys are directional, (b) is taken as implicit permission to
use that key. I don't see a reason for further key coordination.

> which makes it hard to see even where to start. 

We can initialize those as ISN-1.

> Why is 0xffff magic?

Sorry - that's a bug. It had been 0x7fff; I had changed it incorrectly
in this version. I need to debug that code...

...
> Anyway, this algorithm needs much more documentation about why

Agreed.

>    where this is not true. For instance, AES-256-CMAC.

That point was already raised and needs to be addressed.

>    both. However, this is not always the case.

Understood; the question is whether we should be specifying separate
PRFs, or a PRF that can be based on a MAC. I'd prefer the latter, to
allow the PRF to track the addition of new MAC algorithms.

Is there a way to do this?

...
> there is no single conn key. I suggest using the term "traffic

We don't use those terms in the above paragraph. We might use connection
receive key and connection transmit key, but I don't think 'traffic' key
is appropriate in a TCP document.

> it, so why recommend it here.

It helps reduce the overhead of rekeying lost segments. That might be
worth mentioning, and we should determine whether this needs to be a SHOULD.

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

Agreed.

> This seems like a restriction on operators and thus seems inappropriate 

That's an artifact of trying to include deprecation of TCP MD5 in this
doc; operator guidance seemed needed. If that's not the case, we can
remove it...

> This repetition of "locally maintained" is clumsy.

Agreed. Will fix.

> This document should come with a SHOULD for using a strong PRNG

Agreed.

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

Agreed.

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 15 Nov 2008 17:31:46 -0600

At Sat, 15 Nov 2008 14:48:15 -0800,
Joe Touch wrote:
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Hi, Eric,
> 

I want to remove the entire feature, not finish it. I only mention the
fact that it's insufficient in passing.

> connection establishment), but we can go from using a null algorithm to

Well, I wasn't in Philadelphia, but I don't find this to be enough information
to convince me--I can certainly think of ways to make channel binding
work that don't require asymmetric protection.

Perhaps you can point me to something someone has written that describes
the issue?

> Agreed; IMO, this is the responsibility of the key management system,

The key management system is two people at either end of a cell
phone. I'm trying to make their lives easier.

> side B uses key Y; there is no requirement that the senders use the same

Nor did I say otherwise. I'm saying that receiving index X from
the peer is permission to respond with it. It doesn't require you
to do so.

> key management reason would impact other TCP properties we're trying to

I'm sorry if I gave the impression you would send extra segments.
That's not what I meant. I merely meant that every so often instead
of using key X, you use key Y as a probe instead. 

> Since our keys are directional,

The traffic keys are directional. It wasn't my impression from the document
that the master keys were directional. If so, I think that should be
changed.

> (b) is taken as implicit permission to

Well, as it is you effectively need a two phase commit protocol.
I'm trying to remove that.

> in this version. I need to debug that code...

Now I'm even more puzzled. Why should it be 0x7fff?

> Is there a way to do this?

Well, clearly one can do what TLS does and require each algorithm
to specify a PRF. I'm not sure if there is a general transformation
from MACs to PRFs. My intuition is no, however, because you somehow
need to extract the random versus non-random components of the MAC
output.

> is appropriate in a TCP document.

Well, traffic key is the standard comsec terminology. However, I'm fine
with connection receive key and conneciton transmit ke.

-Ekr