Subject: Re: [tcpm] TCP-AO: Text for New_Key Process

From: Joe Touch <[email-masked]>
Date: Sun, 01 Feb 2009 13:49:14 -0800

FYI - there's an important reason not to use a separate flag bit. Doing
so requires parsing the bits of the incoming packet, i.e., this adds
extra processing. It also indicates to everyone on the wire that a key
change is pending; when using only the KeyID, no extra parsing is needed
and the meaning of a changing key is opaque to those on the wire.

Using a key flag means that one side can only ever tell the other end
"ready to use the new key", not which key (if there could be more than
one). That means that if you try it once and it fails and you want to
try it again, you might have to wait MSL (a few minutes) to try it
again, otherwise an old packet might indicate 'ready to receive the new
key" for the wrong key.

Overall, using just the keyID value as the indicator seems much more
flexible to and simple to me.

Joe

Brian Weis wrote:
> The message below summarizes the problem nicely.
> 
> On Jan 28, 2009, at 8:27 AM, Eric Rescorla wrote:
> 
>> At Tue, 27 Jan 2009 13:34:20 -0800,
>> Joe Touch wrote:
>>> I'll kick off discussion on this point on the list.
>>>
>>> IMO, this mechanism is not viable for TCP-AO; it requires generating
>>> (and consuming) TCP segments that a native TCP would not generate. I was
>>> under the assumption that our design space was as close to TCP MD5 as
>>> possible, i.e., augment existing segments with a new option, but neither
>>> generate nor consume new segments.
>>
>> I think it's important to separate two issues:
>>
>> 1. How can an implementation decide when it's safe to use a newly
>> installed
>>    key?
>> 2. How can an implementation help a peer implementation make that
>> decision.
>>
>> I think it's pretty clear that the most natural way to answer question
>> (1) is "when you see a segment protected with that key". Unfortunately,
>> this creates a deadlock problem since both sides are waiting for the
>> other side to use the key. Thus, we need a combination of two
>> methods:
>>
>> 1. If a node has two keys, OLD and NEW, as soon as it sees a segment
>>    from the peer protected with NEW, it starts sending with NEW.
>> 2. If a node has two keys, OLD and NEW, and it's still using OLD
>>    it occasionally experimentally sends a segment with NEW (probing).
>>
>> Taken together, these rules allow a clean transition, since both
>> nodes are in probing state until one node receives a packet with
>> NEW, at which point it switches over and the peer soon follows.
>>
>> The question then becomes how the probing mechanism works. At a
>> high level, there are two options:
>>
>> 1. Probe with packets that the TCP stack would already send.
>> 2. Generate new segments to use explicitly as probes.
>>
>> The advantage of (1) is obviously minimal impact on the stack,
>> but may mean that segments are lost and could unless cere is taken,
>> exert false congestion feedback. The advantage of (2) is that it
>> is less likely to create false congestion feedback, but it requires
>> more changes to the stack and of course creates additional traffic
>> on the wire. Greg's mechanism is of course of type (2).
>>
>> -Ekr
> 
> 
> Probing implies "using a key optimistically", whereby the sender is
> taking a substantial risk that the peer does not yet have knowledge of
> that key. I don't particularly like either option above since they are
> both highly likely to result in significant change to the operation of
> the TCP session.
> 
> Joe mentioned a third approach. Summarizing the discussion, rather than
> "probe" with segments that the TCP stack would already send, his
> approach would add a signal to TCP segments noting that a new master key
> was available. This helps a peer implementation make the decision to
> move to a new key (i.e., the problem we're trying to solve) without
> actually using the new key. This can break the deadlock without the
> actual use of the new key.
> 
> I favor this approach, but not the mechanism. Joe's idea consumes one
> extra KeyID value for each real KeyID. The example given was to allocate
> both KeyID 5 and KeyID 6 when using KeyID 5. Signaling the presence of a
> new key comes by moving to KeyID 6. But overloading KeyIDs is not ideal
> -- in particular, recall that KeyID values are chosen by some external
> entity (e.g., a human or some automated key management system). I'm
> really not confident that a human will always appreciate that they can
> only configure "odd" KeyID values, for example. Furthermore, in order to
> guarantee interoperability I believe that this would have to be
> described in TCP-AO. We would want to avoid different implementations
> have different conventions, and not be able to set the same KeyIDs! This
> could be a fair amount of addition to TCP-AO.
> 
> A better approach is to steal a bit from the KeyID field, and give it
> the meaning "I have a new KeyID". This is an explicit marking with a
> clear meaning. There's no reason the KeyID has to consume 8 bits --
> KeyIDs should be associated with a single peer, and even 7 bits worth of
> simultaneous KeyIDs should be more than enough. A system configured with
> a new KeyID for that peer sets the "new KeyID bit"; a system which also
> has a new KeyID begins use of it when it sees that bit set. As far as I
> can tell, stealing this bit has a negligible effect on the current
> definition of TCP-AO.
> 
> Some further comments addressing other discussion in this thread:
> 
> - No external entity has to be present in this approach.
> 
> - It's true that the two systems could have made an error in stalling a
> new set of policy, and automatically switching to a new KeyID could
> result in peers that cannot communicate. It is a plausible situation
> when the values are manually configured. I'm personally willing to make
> that tradeoff for a simpler TCP stack. This error should rarely occur in
> the presence of a future automated key management method.
> 
> One more thought ... it seems to me that with probe-based approaches a
> man-in-the-middle can prevent the session ever moving to the new key.
> This would be done by dropping frames containing a new KeyID, forcing
> the TCP session continue with an old key. Continued use of the old key
> indefinitely may not be detected by operations staff. On the other hand,
> the presences of a "new KeyID bit" would requires a man-in-the-middle to
> disrupt the TCP session entirely, which is not a new attack on TCP, and
> also immediately visible to operations staff.
> 
> Brian
> 
_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: Caitlin Bestler <[email-masked]>
Date: Sun, 01 Feb 2009 21:15:46 -0800

Gregory M. Lebovitz wrote:
> Folks,
> resend...
> 
> Neither I nor Joe have received ANY feedback on this New_Key process. 
> Can people pls do a quick review and reply to me, Joe, and list with 
> comments? Joe is trying to get a next version out.
> 
> Many thanks,
> Gregory.
> 
> At 01:18 AM 12/19/2008, Gregory M. Lebovitz wrote:
>> Hey Joe, and all.
>> Below is pasted my first crack at the text for the New_Key Process. 
>> All input welcome.
>> Gregory
>>
>> ==New_Key Process:
>>
>> [Suggest you place text about new_key at the end of section 6 in -02]
>>
>> One big difference between TCP-AO and TCP MD5 is that TCP-AO allows 
>> for the change of a TSAD entry -- and thus the corresponding change of 
>> a conn_key -- during a connection, without having to drop the 
>> connection. This allows for an HMAC algorithm or TSAD_key change 
>> without a connection loss. This behavior is very beneficial for the 
>> optimal operation of applications with long lived connections, such as 
>> BGP. The process of moving from one key to another is called "New_Key".
>>

 From the beginning I have been uncomfortable with the abuse of an 
"option" being used to reliably transport something that is not truly
an option.

But as Joe pointed out during a prior round, a simple digest is derived
from the payload. So it is not truly separate payload.

But the "new key process" strikes me as going farther than that. It is
trying to shoe-horn in a second data stream onto one TCP connection.
There are already two ways to do this:

+ At the transport layer with a transport protocol designed to support
   multiple streams, specifically SCTP.
+ Above the transport layer, such as is done with SSH tunneling.

Either of those methods work, so I do not see the justification for
doing major havoc to some of the normal working assumptions with TCP.
Deliberately sending frames that have a substantial chance of being
dropped is just plain wrong.

In fact, I am fairly sure that some of the techniques proposed would
be diagnosed by a current Intrustion Detection System as an attack.

To justify that level of a change there should be something wrong with
the Transport protocol itself, not just an application that doesn't
want to change anything.

Let the current TCP-MD5 applications figure out their own solution on
how to do out-of-band signaling. Using a null encryption and SSH 
wrappers strikes me as one very viable solution that could preserve
existing code. But just find a solution *above* the TCP stack, and
avoid "minor" modifications to TCP that require stacks to do things
that previously would have been an attack.

-- 
Caitlin Bestler
[email-masked] - http://www.asomi.com/CaitlinBestlerResume.html
_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 02 Feb 2009 08:26:02 -0800

At Sun, 01 Feb 2009 13:49:14 -0800,
Joe Touch wrote:
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 

The extra parsing hardly strikes me as a severe burden and I don't
really understand why we would care if an observer knows that a key
change is imminent.

> again, otherwise an old packet might indicate 'ready to receive the new

Well, I don't really favor they ke flag approach, but it occurs to
me that this is easily fixed by replacing the key flag with a 
"ready to use" byte. Recall that the length of the MAC is tied
to the key so if you know the key-id you know the length of the
MAC. This makes the Length byte partly redundant. Accordingly,
you could have the following format:

 - Kind (1)
 - Length (1)
 - Key-ID (1)
 - Ready-keys [variable]
 - MAC

With ready-keys being a variable length field listing any keys which
are ready to use but haven't been used yet. This causes a slight
increase in the option size, but only during the transition period.

> flexible to and simple to me.

It's marginally simpler for the implementor of AO and a huge pain for
everyone else.

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 02 Feb 2009 09:52:25 -0800

At Thu, 29 Jan 2009 21:28:47 -0600,
Eddy, Wesley M. (GRC-RCN0)[VZ] wrote:
> 
> I mostly agree with Joe, and have some brief comments below:
> >My view is that TCP-AO MUST support a mechanism for key coordination -
> >which I believe was consensus in the design team at least.
> >
> >I prefer TCP-AO not to include that mechanism internally, to 
> >keep things
> >simple. That's just a preference, though.
> >
> >I do think that mechanisms that couple tightly to a particular segment
> >exchange should be out of scope, however.
> >
> 
> 
> The direction that we were always heading in was that TCPM will make
> sure the spec for AO permits automated changes of keys and won't be
> breaking other parts of TCP in the meantime.  We understood that
> "permiting" or "supporting" the changeover in AO didn't mean actually
> being responsible for doing it all inside the TCP connection, and that
> the SECDIR would define a separate mechanism (not inside TCP) for this.

Not to put too fine a point on it, that hasn't happened, nor, years
later, is there anything even approaching the beginnings of an effort
towards secdir designing anything (as if secdir could design
anything), or (more realistically) an effort starting up to do so. The
manual keying stuff is it for the foreseeable future.

> To be done timely and without bugs, AO has to stay as simple as the
> needed security properties permit, so I have to agree with Joe.

Well, since the basic security property that people wanted was to be
able to change keys without breaking the connection, it seems to me
that it's important for it to actually work in some useful way.
Certainly, one could claim that having automatic switchover isn't
(e.g., that multiple phone calls to change a key is OK) important or
that Joe's suggestion gets the job done, but I don't think it's
realistic to claim that some putative automatic key management
mechanism is going to suddenly appear and make this problem go away.

-Ekr

---

From: [email-masked]
Date: Mon, 2 Feb 2009 09:43:32 -0800

> you could have the following format:

That is variable length, even when the active key has not changed; that means
conditional parsing is required, which is cumbersome. We wanted to avoid
conditional parsing even to save a single byte (the odd/even mechanism I
suggested in earlier drafts). This seems even more awkward and unnecessary.

> It's marginally simpler for the implementor of AO and a huge pain for

It is simpler for the AO specification, simpler for the implementer, and exactly
the same effort for everyone else (i.e., the user/process changing over the
keys). 

Joe

---

From: Ron Bonica <[email-masked]>
Date: Mon, 2 Feb 2009 17:02:58 -0500

+1

Lars Eggert wrote:
> On 2009-1-27, at 23:34, Joe Touch wrote:
>> I was under the assumption that our design space was as close to TCP
>> MD5 as
> That's my recollection as well, and hopefully it's in the minutes of the
> WG meeting where we adopted the work item. The idea was to be as
> lightweight (in terms of changes to TCP) as possible, and changes to the
> state machine, etc. seem rather heavyweight.
> 
> Lars
>

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 02 Feb 2009 20:10:52 -0800

At Mon,  2 Feb 2009 09:43:32 -0800,
[email-masked] wrote:
> conditional parsing is required, which is cumbersome.

s/cumbersome/trivial/

> We wanted to avoid

I'm not sure what you mean "we". I wanted to avoid the odd/even mechanism
because I thought it was kludgy, but necause I wanted to avoid conditional 
parsing.

> the same effort for everyone else (i.e., the user/process changing over the

Well, obviously people can differ about what's simpler, but
I don't agree with this. 

Either the user has to create bogus keys used solely as a key change
signal or there has to be logic pulled up into some putative (i.e.,
nonexistent) application layer key management logic to do the signally
you suggest. I don't consider that simpler.

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 02 Feb 2009 20:12:29 -0800

As previously noted, you can do automatic switchover without 
changing the TCP state machine at all: you just opportunistically
encrypt the occasional packet that would be sent already.

-Ekr

At Mon, 2 Feb 2009 17:02:58 -0500,

---

From: Joe Touch <[email-masked]>
Date: Mon, 02 Feb 2009 21:07:28 -0800

Eric Rescorla wrote:
...
>> conditional parsing is required, which is cumbersome.

Well, if trivial means the following, sure:

1) get the keyID
2) go to the TSAD to get the MAC length
3) pass the KeyID and the MAC pointer = (option start + length - 
mac_length) to the verification alg

Compare that with the current option:

1) pass the keyID and the MAC (i.e., option start + 2) to the 
verification algorithm

Joe

---

From: Joe Touch <[email-masked]>
Date: Mon, 02 Feb 2009 23:14:59 -0800

TCP doesn't *need* to send any packets. Whatever mechanism you design 
needs to assume that.

Also, "opportunistically" means that on some systems that packet would 
go through, and on others it wouldn't - depending on when the key was in 
place. So key placement would impact throughput (because TCP interprets 
loss as congestion). While the impact could be reduced by using SACK, 
etc., that's not a great place in the design space to play, IMO.

Joe

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 03 Feb 2009 07:24:49 -0800

At Mon, 02 Feb 2009 23:14:59 -0800,
> TCP doesn't *need* to send any packets. Whatever mechanism you design 

If it doesn't need to send packets, then they don't need to be 
protected, in which case keys don't need to be changed,
so this lines up nicely.

> etc., that's not a great place in the design space to play, IMO.

Once again, I'm having a hard time getting worked up over losing
one packet every 10-30 minutes.

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 03 Feb 2009 07:28:34 -0800

At Mon, 02 Feb 2009 21:07:28 -0800,
> mac_length) to the verification alg

Well, Joe, since you brought it up, this whole architecture
you've invented for the internal structure (TSAD, etc.) is the
source of the clumsiness, not the need for variable parsing.
I've written quite a few crypto stacks, including ones with
MAC length dependent parsing (SSL has it) and if things are
done properly, this isn't clumsy at all.

So, no, I'm not particularly receptive to arguments about simplicity
that derive from the TSAD architecture, since, as I've said
several times now, I'd remove it entirely.

-Ekr

---

From: Joe Touch <[email-masked]>
Date: Tue, 03 Feb 2009 08:34:53 -0800

> source of the clumsiness, not the need for variable parsing.

OK, let's call the place where the connection info is stored the STORE.
Then the steps still become:

- - get the keyID from the packet
- - go to the STORE to find out how long the MAC is
- - pass the keyID and (optionstart + len - maclen)

Still three steps, vs one:

- - pass the keyID and (optionstart + 2)

Note that the second way doesn't need to go to a separate table of
information to figure out how to finish parsing the packet. Regardless
of what you call it or where you put it, this takes multiple steps and
consulting the STORE before you can pass the required information to the
verification algorithm.

Joe

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 03 Feb 2009 09:09:10 -0800

At Tue, 03 Feb 2009 08:34:53 -0800,
> consulting the STORE before you can pass the required information to the

Again, I wouldn't construct the system this way.

Rather, you hang the information required to process each connection
off the connection itself. This is how pretty much every SSL/TLS stack
works.

-Ekr

---

From: Joe Touch <[email-masked]>
Date: Tue, 03 Feb 2009 08:57:04 -0800

> off the connection itself. This is how pretty much every SSL/TLS stack

I don't think you're seeing the extra work; you're focusing too much on
the assumption that the STORE is in a single place. OK, so let's call
the place where the properties of a connection are in TCB++ (note that
the TSAD isn't the place you go for every packet; you can easily keep
connection info in the TCB++, and an implementation probably will, and
we already note that in the ID).

So the steps are still:

- - get the keyID from the packet
- - check the TCB++ to figure out where the MAC is
- - pass the keyID and (optionstart + len - maclen) to the algorithm

The point is that you can't parse the option without extra info that is
stored elsewhere - i.e., not in the packet. Whether it's central or in
the TCB++ is not the point.

Joe

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 03 Feb 2009 09:25:46 -0800

At Tue, 03 Feb 2009 08:57:04 -0800,
Joe Touch wrote:
> I don't think you're seeing the extra work;

You're right, I'm not.

> you're focusing too much on

And again, so what? You can't *verify* the option without having the
key that corresponds to the key-id. The problem here is that you're

> - - pass the keyID and (optionstart + len - maclen) to the algorithm

But this is not how I would build things, because it's more helpful to
have the key-id->MAC mapping in a common place rather, I would do this:

1. Get the key-id from the packet.
2. Look up the key-id in XXX to get the relevant algorithm info, namely:
   - algorithm 
   - key
   - MAC length
3. Pass (key, <MAC input>) to the MAC function.
4. Compare the result to the MAC

With this design, it's trivial to add a step 2(b):

2(b): strip off the extra key-ids.

That said, I consider this discussion basically irrelevant: the right
question is whether it's important for this protocol to offer some
automatic mechanism for key switchover [and no, I don't think your
mechanism qualifies because it requires some external intervention
either from users or from some (nonexistent) key management system].
If the answer is yes, then we need to figure out what the best way
to do that is [and as it happens, I'm not that enamored of this
approach.] Certainly implementation complexity factors into what
the best way to do it is, but given the scale of complexity we're
talking about, I don't think it's a meaningful consideration for
whether we should add this type of functionality at all.

-Ekr