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

From: Eric Rescorla <[email-masked]>
Date: Sun, 27 Jul 2008 21:24:51 -0700

$Id: draft-ietf-tcpm-tcp-auth-01-rev.txt,v 1.1 2008/07/28 03:06:22 ekr Exp $

I've reviewed the latest version of this document and while it 
seems to incorporate some improvements over the -00 version,
I still have a number of concerns:

- The document seems to assume an (unspecified) external key management
mechanism. That seems less than maximally useful

- There's discussion of a "per-connection nonce" in S 3.2,
but it's non-normative and does not completely specify how
the nonce is to be used:

     MACs typically benefit from a per-connection nonce, notably in 
     avoiding the impact of key reuse. The presence of TCP's pair of 
     Initial Sequence Numbers presents a nonce that may be useful in that 
     case. Such a nonce could be computed as the concatenation of the ISNs 
     (initiator, responder), and the socket pair (addresses, ports): 
  
     o  Nonce = ISN_i, ISN_r, IP_address_i, IP_address_r, port_i, port_r 
  
     The initial SYN would not know ISN_r, so that packet's nonce would 
     use ISN_r = 0. Use of these nonces avoids the need to avoid key reuse 
     on a per connection basis. 

     >> ISN and socket pair nonces MUST be used to generate unique per-
     session keys. 

   I don't see in the draft where it actually describes how this is 
   intended to work.

- The discussion of key rollover seems incomplete

      >> TCP-AO implementations SHOULD change keys for a connection at 
      least every 2^31 bytes, to avoid resending segments with the same 
      TCP sequence number, data, and length under the same key. 

How is this intended to work?

It seems to me that a useful system needs to describe a complete set
of mechanisms that allow the establishment of a single static key which
can be used to secure multiple connections. I don't see that this 
document does that.

Previous comments which I believe remain outstanding:
S 1.
   there have been escalating attacks on the algorithm itself [Be05] 
   [Bu06].  TCP MD5 also lacks both key management and algorithm 

These citations should be to the original papers, not the summaries
(not that I mind you citing Steve's and my paper...) 

[New: you've added a cite to Burr's paper, but you should be
citing Wang et al.]

S 1.1.
I don't see a lot of value in pre-specifying two MAC algorithms
as MTI. There's no reason to believe one isn't plenty, as used
in other protocols.

S 2.2.
Figure 2 is kind of hard to read since the length of the kind
field is 16 bits, but kinds are 8 bits, rigth?

S 3.
               >> 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.

S 9.
   TCP-AO does not expose the MAC algorithm used to authenticate a 
   particular connection; that information is kept in the TSAD at the 
   endpoints, and is not indicated in the header. 

This seems to be of extremely marginal security benefit. There
are likely to be <5 algorithms in use. So, searching all of them
increases the effective key size by <3 bits. 

[New: Again, this isn't a security issue]

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

---

From: Joe Touch <[email-masked]>
Date: Sun, 27 Jul 2008 23:38:32 -0700

Hi, Eric (et al.),

We'll have time to discuss these issues in detail later today at the
TCPM meeting. Here is some potential context for that...

Joe

Eric Rescorla wrote:
| $Id: draft-ietf-tcpm-tcp-auth-01-rev.txt,v 1.1 2008/07/28 03:06:22 ekr
Exp $
|
| I've reviewed the latest version of this document and while it
| seems to incorporate some improvements over the -00 version,
| I still have a number of concerns:
|
| - The document seems to assume an (unspecified) external key management
| mechanism. That seems less than maximally useful

The split of this work into separate key management and TCP extension
documents was a prerequisite to the design team's output. The WG chairs
and/or ADs can speak to it more directly.

| - There's discussion of a "per-connection nonce" in S 3.2,
| but it's non-normative and does not completely specify how
| the nonce is to be used:
|
|      MACs typically benefit from a per-connection nonce, notably in
|      avoiding the impact of key reuse. The presence of TCP's pair of
|      Initial Sequence Numbers presents a nonce that may be useful in that
|      case. Such a nonce could be computed as the concatenation of the
ISNs
|      (initiator, responder), and the socket pair (addresses, ports):
|
|      o  Nonce = ISN_i, ISN_r, IP_address_i, IP_address_r, port_i, port_r
|
|      The initial SYN would not know ISN_r, so that packet's nonce would
|      use ISN_r = 0. Use of these nonces avoids the need to avoid key
reuse
|      on a per connection basis.
|
|      >> ISN and socket pair nonces MUST be used to generate unique per-
|      session keys.
|
|    I don't see in the draft where it actually describes how this is
|    intended to work.

The nonce would be used by the external session key management
mechanism. This part of the document may move to that other specification.

| - The discussion of key rollover seems incomplete
|
|       >> TCP-AO implementations SHOULD change keys for a connection at
|       least every 2^31 bytes, to avoid resending segments with the same
|       TCP sequence number, data, and length under the same key.
|
| How is this intended to work?

The key management mechanism should react to sequence numbers rolling
over the ISN (perhaps masking out the high bit to roll over twice as often).

| It seems to me that a useful system needs to describe a complete set
| of mechanisms that allow the establishment of a single static key which
| can be used to secure multiple connections. I don't see that this
| document does that.

This document does not specify a key management mechanism; that
mechanism would use a single static key to generate per-session keys.

| Previous comments which I believe remain outstanding:
| S 1.
|    there have been escalating attacks on the algorithm itself [Be05]
|    [Bu06].  TCP MD5 also lacks both key management and algorithm
|
| These citations should be to the original papers, not the summaries
| (not that I mind you citing Steve's and my paper...)
|
| [New: you've added a cite to Burr's paper, but you should be
| citing Wang et al.]

Thanks - that will be updated.

| S 1.1.
| I don't see a lot of value in pre-specifying two MAC algorithms
| as MTI. There's no reason to believe one isn't plenty, as used
| in other protocols.

The need for two required algorithms mirrors the intent of RFC4305's
"SHOULD+", which requires one, but suggests that two algs may be
required in the future. The design team suggested that requiring two
algorithms now would be prudent, notably so that if one were compromised
(either entirely, or effectively weakened due to computational
exploits), the other would be pre-deployed. The two could also trade
strength for performance, depending on which algorithms are recommended
by SAAG.

| S 2.2.
| Figure 2 is kind of hard to read since the length of the kind
| field is 16 bits, but kinds are 8 bits, rigth?

The length of the field is wide due to the text; that will be fixed to
be proportional to the bit width (8 bits, as you note).

| S 3.
|                >> 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.

We discussed the utility of asymmetry in Philadelphia last March. The
point is to require implementations to allow the user to request
connections configured this way; we can add that connections MUST
default to using a real MAC in both directions by default. Does that
address your concern?

| S 9.
|    TCP-AO does not expose the MAC algorithm used to authenticate a
|    particular connection; that information is kept in the TSAD at the
|    endpoints, and is not indicated in the header.
|
| This seems to be of extremely marginal security benefit. There
| are likely to be <5 algorithms in use. So, searching all of them
| increases the effective key size by <3 bits.
|
| [New: Again, this isn't a security issue]

The text should be updated to note that the primary and sufficient
reason for omitting it is space conservation and the fact that there is
no utility in including it. The number of algorithms doesn't merely
augment the key space, though - it an algorithm is known weak(er),
indicating it in the header is a signal in the clear that the packet
stream is more vulnerable.

Joe

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Jul 2008 06:05:32 -0700

At Sun, 27 Jul 2008 23:38:32 -0700,
Joe Touch wrote:
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Hi, Eric (et al.),
> 

I'm not in Dublin. I plan to make some attempt to follow via audio
and Jabber but I don't know if I'll actually be able to make that
work, both for technical and logistical reasons (i.e., I'm at a
conference at the same time and I don't know how well the network
will work or if I'll have to do something else).

> and/or ADs can speak to it more directly.

That may be so, but it seems to me that it's unwise regardless.  As I
indicated in PHL, this protocol as it stands isn't really useful in
the absence of a key management protocol.  Since no such protocol
appears to be on the horizon... With that in mind, I've elided the
detailed comments below relative to that.

> strength for performance, depending on which algorithms are recommended

Yes, as I've now said several times, this strikes me as massive
overkill. If SHA-1 is ever weakened to the point where HMAC-SHA1
is implicated, we'll have problems far, far, more serious than
the occasional attack on TCP AO.

> default to using a real MAC in both directions by default. Does that

Well, as I recall, you asserted it the value of it and I disagreed.
As I recall, the example you offered was the one-way authentication in
TLS, which is really not that apropos, since it only applies to the
key management protocol, not to the data, which is authenticated in
both directions.

So, no, this does not address my concern. I think the world would
be far simpler if you simply required both sides to generate MACs.
(and certainly I can't imagine why you would *require* implementations
to allow neither side to do so). 

Perhaps you could restate your rationale for this?

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Jul 2008 06:12:53 -0700

I did want to make one more note.

> over the ISN (perhaps masking out the high bit to roll over twice as often).

Regardless of whether there is a KMP, it strikes me as unwise to punt this
job to it. 

The TCP authentication protocol should be able to provide security for
packets even in the face of sequence number rollover, out to the
limits of security of the MAC algorithm (which far exceed 2^31 bytes
in both cases). There are (at least) two potential approaches:

1. Use a (synthetic) extended sequence number.
2. Change the key used to compute the MAC inside the protoco.

But I don't think it's a good idea to punt this to the KMP, since
you don't really need to change the key for any cryptographic reason.

-Ekr

---

From: Joe Touch <[email-masked]>
Date: Mon, 28 Jul 2008 07:25:08 -0700

Hi, Eric,

Eric Rescorla wrote:
| At Sun, 27 Jul 2008 23:38:32 -0700,
| Joe Touch wrote:
|> -----BEGIN PGP SIGNED MESSAGE-----
|> Hash: SHA1
|>
|> Hi, Eric (et al.),
|>
|> We'll have time to discuss these issues in detail later today at the
|> TCPM meeting. Here is some potential context for that...
|
| I'm not in Dublin.

We can continue on the list in that case...

|> Eric Rescorla wrote:
|> | $Id: draft-ietf-tcpm-tcp-auth-01-rev.txt,v 1.1 2008/07/28 03:06:22 ekr
|> Exp $
|> |
|> | I've reviewed the latest version of this document and while it
|> | seems to incorporate some improvements over the -00 version,
|> | I still have a number of concerns:
|> |
|> | - The document seems to assume an (unspecified) external key management
|> | mechanism. That seems less than maximally useful
|>
|> The split of this work into separate key management and TCP extension
|> documents was a prerequisite to the design team's output. The WG chairs
|> and/or ADs can speak to it more directly.
|
| That may be so, but it seems to me that it's unwise regardless.  As I
| indicated in PHL, this protocol as it stands isn't really useful in
| the absence of a key management protocol.  Since no such protocol
| appears to be on the horizon... With that in mind, I've elided the
| detailed comments below relative to that.

My understanding is that this document will not move forward without a
companion keying document. Let's assume that and press on...

|> | S 1.1.
|> | I don't see a lot of value in pre-specifying two MAC algorithms
|> | as MTI. There's no reason to believe one isn't plenty, as used
|> | in other protocols.
|>
|> The need for two required algorithms mirrors the intent of RFC4305's
|> "SHOULD+", which requires one, but suggests that two algs may be
|> required in the future. The design team suggested that requiring two
|> algorithms now would be prudent, notably so that if one were compromised
|> (either entirely, or effectively weakened due to computational
|> exploits), the other would be pre-deployed. The two could also trade
|> strength for performance, depending on which algorithms are recommended
|> by SAAG.
|
| Yes, as I've now said several times, this strikes me as massive
| overkill. If SHA-1 is ever weakened to the point where HMAC-SHA1
| is implicated, we'll have problems far, far, more serious than
| the occasional attack on TCP AO.

It's trivial to resolve this via WG feedback and SAAG input. If one is
sufficient, so be it.

|> | S 2.2.
|> | Figure 2 is kind of hard to read since the length of the kind
|> | field is 16 bits, but kinds are 8 bits, rigth?
|>
|> The length of the field is wide due to the text; that will be fixed to
|> be proportional to the bit width (8 bits, as you note).
|>
|> | S 3.
|> |                >> 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.
|>
|> We discussed the utility of asymmetry in Philadelphia last March. The
|> point is to require implementations to allow the user to request
|> connections configured this way; we can add that connections MUST
|> default to using a real MAC in both directions by default. Does that
|> address your concern?
|
| Well, as I recall, you asserted it the value of it and I disagreed.

I asserted the value of keeping it in for potential future use.

| As I recall, the example you offered was the one-way authentication in
| TLS, which is really not that apropos, since it only applies to the
| key management protocol, not to the data, which is authenticated in
| both directions.

We discussed that in Phila. I recall that we agreed that this wasn't
exactly like TLS. However, I preferred leaving it in for future use.

| Perhaps you could restate your rationale for this?

About 10 minutes into that future ;-), we were discussing (as I recall)
channel binding and connection latching, at which point someone (?)
suggested TCP-AO could start in NULL in one direction, and escalate via
enabling a new KeyID (and thus configuration) via in-band exchange. I
recall your noting that this was a good reason for asymmetry.

We could update the doc to include that rationale...

Joe

---

From: Joe Touch <[email-masked]>
Date: Mon, 28 Jul 2008 07:28:13 -0700

Hi, Eric,

Eric Rescorla wrote:
| I did want to make one more note.
|
| At Sun, 27 Jul 2008 23:38:32 -0700,
| Joe Touch wrote:
|> | - The discussion of key rollover seems incomplete
|> |
|> |       >> TCP-AO implementations SHOULD change keys for a connection at
|> |       least every 2^31 bytes, to avoid resending segments with the same
|> |       TCP sequence number, data, and length under the same key.
|> |
|> | How is this intended to work?
|>
|> The key management mechanism should react to sequence numbers rolling
|> over the ISN (perhaps masking out the high bit to roll over twice as
often).
|
| Regardless of whether there is a KMP, it strikes me as unwise to punt this
| job to it.

There is a KMP; it is required (and we can't move forward to submit this
as final until there is).

| The TCP authentication protocol should be able to provide security for
| packets even in the face of sequence number rollover, out to the
| limits of security of the MAC algorithm (which far exceed 2^31 bytes
| in both cases). There are (at least) two potential approaches:
|
| 1. Use a (synthetic) extended sequence number.

We discussed this, but there are concerns with interactions with TCP. We
don't want to add separate, coordinated state outside the existing TCP
state mechanism.

| 2. Change the key used to compute the MAC inside the protoco.

Can you explain this?

| But I don't think it's a good idea to punt this to the KMP, since
| you don't really need to change the key for any cryptographic reason.

If there's no cryptographic reason, why would we need to change the key
at all? I.e., isn't the need for a unique per-packet nonce a
cryptographic requirement (if not, why do we care?)

Joe

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Jul 2008 07:47:21 -0700

At Mon, 28 Jul 2008 07:28:13 -0700,
> as final until there is).

Well, as I've indicated previously, I don't agree that a KMP is
required or desirable. It's quite straightforward to make this system
work with a single, pairwise, static key, provided you have an
appropriate key diversification mechanism. If you want to call that a
KMP, I suppose you could, but since it doesn't require actually
exchanging any messages, I would not do so.

If your assertion is that a KMP is required to make this protocol
useful, given that (1) there's no draft for such a KMP on the
horizon and (2) the most likely consumers of this draft, the 
routing/ops community, seem to have no interest in doing a KMP, 
then I think this raises serious questions about the viability
of this approach.

> don't want to add separate, coordinated state outside the existing TCP

Uh, ok... It's not like this doesn't need to be tightly coordinated
with TCP in any case.

> | 2. Change the key used to compute the MAC inside the protoco.

Sure. You have a per-connection key. Every time the sequence number
rolls, you run the KDF again to generate a fresh per-connection key.
No KMP required. (This meshes with my previous key diversification
comments).

> cryptographic requirement (if not, why do we care?)

There is no need for a unique per-packet nonce.

-Ekr

---

From: Joe Touch <[email-masked]>
Date: Mon, 28 Jul 2008 08:05:05 -0700

Eric Rescorla wrote:
...
|> | Regardless of whether there is a KMP, it strikes me as unwise to
punt this
|> | job to it.
|>
|> There is a KMP; it is required (and we can't move forward to submit this
|> as final until there is).
|
| Well, as I've indicated previously, I don't agree that a KMP is
| required or desirable. It's quite straightforward to make this system
| work with a single, pairwise, static key, provided you have an
| appropriate key diversification mechanism. If you want to call that a
| KMP, I suppose you could, but since it doesn't require actually
| exchanging any messages, I would not do so.

OK; we're dancing around terms here. TCP-AO uses a _separate_ document
to specify the out-of-band key mechanism. What that includes can be
discussed in that context - e.g., on SAAG.

| If your assertion is that a KMP is required to make this protocol
| useful, given that (1) there's no draft for such a KMP on the
| horizon and (2) the most likely consumers of this draft, the
| routing/ops community, seem to have no interest in doing a KMP,
| then I think this raises serious questions about the viability
| of this approach.

The "KMP" (or whatever we're calling it) should be underway in SAAG; if
it has stalled, then we'll address that issue off-list.

|> | The TCP authentication protocol should be able to provide security for
|> | packets even in the face of sequence number rollover, out to the
|> | limits of security of the MAC algorithm (which far exceed 2^31 bytes
|> | in both cases). There are (at least) two potential approaches:
|> |
|> | 1. Use a (synthetic) extended sequence number.
|>
|> We discussed this, but there are concerns with interactions with TCP. We
|> don't want to add separate, coordinated state outside the existing TCP
|> state mechanism.
|
| Uh, ok... It's not like this doesn't need to be tightly coordinated
| with TCP in any case.
|
|
|> | 2. Change the key used to compute the MAC inside the protoco.
|>
|> Can you explain this?
|
| Sure. You have a per-connection key. Every time the sequence number
| rolls, you run the KDF again to generate a fresh per-connection key.
| No KMP required. (This meshes with my previous key diversification
| comments).

That's burying the key generation protocol inside TCP-AO. My
understanding is that this is the reason for an external mechanism,
whatever it is called, and regardless of whether it explicitly or
implicitly coordinates with the other end (you're referring to implicit
coordination).

|> | But I don't think it's a good idea to punt this to the KMP, since
|> | you don't really need to change the key for any cryptographic reason.
|>
|> If there's no cryptographic reason, why would we need to change the key
|> at all? I.e., isn't the need for a unique per-packet nonce a
|> cryptographic requirement (if not, why do we care?)
|
| There is no need for a unique per-packet nonce.

If so, then why generate fresh keys on rollover?

Joe

---

From: "Adam Langley" <[email-masked]>
Date: Mon, 28 Jul 2008 09:31:46 -0700

> If so, then why generate fresh keys on rollover?

(This is pretty much a reposting of a previous email, but people still
seem to be hazy on this point)

We have a couple of reasons for wanting to define an nonce:

Reason 1: Without a monotonic counter, a MAC is open to replay
attacks. I'm not sure how serious this is. Certainly you can elicit
different behaviour from stacks by replaying, say, an ACK very
quickly. This is undesirable, but it might be acceptable. More
troubling is the possibility of exploiting sequence number rollover to
inject a valid packet from 2^32 bytes in the past into the current
stream. A monotonic nonce would mean that we could reject replays.

Rotating the keys faster than the sequence number rolls over mitigates
the most grievous of these issues.

Reason 2: Modern dot-product and polynomial MAC functions require an
nonce as an input and their
security depends on the nonce never being reused for any other message
with the same key. Consider a connection where all the
application-level data transfer is one way and a packet, seq number n,
is lost by the network. Here, it's very possible that an ACK for n-1
is transmitted, followed by an ACK for n-1 with a SACK option. Now
we've transmitted two different messages with the same nonce. Any
nonce based only the sequence numbers has this problem unless we
disable/don't include SACK. Also, if we are only including 32-bits of
seq, then we trivially repeat every 2^32 bytes.

Now, we can just ignore the MAC functions described in reason 2;
having a per-message counter is probably too much additional work.
Having a "pseudo" extended sequence number is very little work
(really, I've already implemented it) and that mean that we don't have
to rekey faster than the 32-bit sequence rollover. However, the
rekeying isn't all that painful anyway.

AGL

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

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Jul 2008 09:40:13 -0700

At Mon, 28 Jul 2008 08:05:05 -0700,
> discussed in that context - e.g., on SAAG.

Well, I think that's a mistake as well.

(1) It's extremely confusing to have two documents.
(2) There are two issues:

    - What's used to establish an association and keying material
    - How that association and keying material get turned into
      per session keying material.

    In IPsec with IKE, the KMP is run for every new association
    and so these end up specified in a separate document as
    a single entity. However, in this case, because people don't
    want a separat KMP run for each association, these are separate.
    The second needs to be tied to the transport protocol. The
    first is replaceable. The problem here is that you have 
    merged them and treated them both as separate. That's problematic.

(3) SAAG has no capability to work on anything, and isn't doing so.

> That's burying the key generation protocol inside TCP-AO.

Again, key generation != key establishment.

> If so, then why generate fresh keys on rollover?

The protocol must be constructed so that it is not possible to substitute
one packet for another and have it be accepted. This means that (either)
the data fed into the authentication function must be distinct or the
authentication function must have a distinct key. I wouldn't call this
a "nonce" in either case, and I don't know what a "per-packet nonce"
means. We're talking about the connection and packet parameters.

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Jul 2008 09:42:35 -0700

At Mon, 28 Jul 2008 09:31:46 -0700,
> Now, we can just ignore the MAC functions described in reason 2;

Indeed, we should do so. If those algorithms in fact need a MAC they
should describe some procedure for generating and using them 
(and presumably attaching them to the message). AFAIK, neither
HMAC nor CBC-MAC requires such a nonce.

> rekeying isn't all that painful anyway.

It depends what you mean by rekeying. If it involves a new protocol
exchange it is incredibly painful. If you mean just running the kdf
again, I agree that's fine.

-Ekr

---

From: "Adam Langley" <[email-masked]>
Date: Mon, 28 Jul 2008 09:48:11 -0700

> again, I agree that's fine.

It would just be rerunning the KDF every 2**31 bytes. I'd suggest
something along the lines of this:

For keys k1, k2, k3, ... and a manually configured master key K:

H(x) is some hash function (say SHA1)
H2(x) = H(x | "\x00")

k1 = H2(K)
k2 = H2(H(K))
k3 = H2(H(H(k)))
...

AGL

---

From: Joe Touch <[email-masked]>
Date: Mon, 28 Jul 2008 09:51:23 -0700

Adam,

Adam Langley wrote:
| On Mon, Jul 28, 2008 at 8:05 AM, Joe Touch <[email-masked]> wrote:
|> | There is no need for a unique per-packet nonce.
|>
|> If so, then why generate fresh keys on rollover?
|
| (This is pretty much a reposting of a previous email, but people still
| seem to be hazy on this point)

Indeed - note that the statement above is from you indicating that there
is no need for a per packet nonce.

| We have a couple of reasons for wanting to define an nonce:

So this indicates you want one Which is it?

Joe

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Jul 2008 10:00:26 -0700

At Mon, 28 Jul 2008 09:48:11 -0700,
> H(x) is some hash function (say SHA1)

Obviously there are a number of ways to do this. I think I would
prefer to use an ESN, but I agree this would work.

-Ekr

---

From: Joe Touch <[email-masked]>
Date: Mon, 28 Jul 2008 10:47:48 -0700

Hi, Eric,

Eric Rescorla wrote:
...
|> OK; we're dancing around terms here. TCP-AO uses a _separate_ document
|> to specify the out-of-band key mechanism. What that includes can be
|> discussed in that context - e.g., on SAAG.
|
| Well, I think that's a mistake as well.

That's outside the scope of this document; that was handed to the design
team as a requirement of this work. Perhaps the ADs should address the
reasons directly.

| (2) There are two issues:
|
|     - What's used to establish an association and keying material
|     - How that association and keying material get turned into
|       per session keying material.
|
|     In IPsec with IKE, the KMP is run for every new association
|     and so these end up specified in a separate document as
|     a single entity. However, in this case, because people don't
|     want a separat KMP run for each association, these are separate.

I'm not sure this is the case...

|     The second needs to be tied to the transport protocol. The
|     first is replaceable. The problem here is that you have
|     merged them and treated them both as separate. That's problematic.

Are you saying that we generate per-session keys inside TCP-AO? We
attempted to split the TCP-AO/key issue in a particular place; if
there's a better place to split (e.g., burying the ISN stuff in the
TCP-AO side), it might be useful to hear more...

My concern is that the point of the key system is to decouple potential
changes to session keying from the option side. All the crypto-related
info should stay on the keying/MAC side of the house if at all possible,
i.e., external to TCP-AO.

| (3) SAAG has no capability to work on anything, and isn't doing so.

Tim Polk spoke to that issue; he said we'd see something this fall.

|> |> | The TCP authentication protocol should be able to provide
security for
|> |> | packets even in the face of sequence number rollover, out to the
|> |> | limits of security of the MAC algorithm (which far exceed 2^31 bytes
|> |> | in both cases). There are (at least) two potential approaches:
|> |> |
|> |> | 1. Use a (synthetic) extended sequence number.
|> |>
|> |> We discussed this, but there are concerns with interactions with
TCP. We
|> |> don't want to add separate, coordinated state outside the existing TCP
|> |> state mechanism.
|> |
|> | Uh, ok... It's not like this doesn't need to be tightly coordinated
|> | with TCP in any case.
|> |
|> |
|> |> | 2. Change the key used to compute the MAC inside the protoco.
|> |>
|> |> Can you explain this?
|> |
|> | Sure. You have a per-connection key. Every time the sequence number
|> | rolls, you run the KDF again to generate a fresh per-connection key.
|> | No KMP required. (This meshes with my previous key diversification
|> | comments).
|>
|> That's burying the key generation protocol inside TCP-AO.
|
| Again, key generation != key establishment.

Agreed, but there is utility in keeping TCP-AO clean from algorithmic
crypto issues.

|> |> | But I don't think it's a good idea to punt this to the KMP, since
|> |> | you don't really need to change the key for any cryptographic
reason.
|> |>
|> |> If there's no cryptographic reason, why would we need to change
the key
|> |> at all? I.e., isn't the need for a unique per-packet nonce a
|> |> cryptographic requirement (if not, why do we care?)
|> |
|> | There is no need for a unique per-packet nonce.
|>
|> If so, then why generate fresh keys on rollover?
|
| The protocol must be constructed so that it is not possible to substitute
| one packet for another and have it be accepted. This means that (either)
| the data fed into the authentication function must be distinct or the
| authentication function must have a distinct key.

That implies a per-packet nonce, i.e., some fields - either in the
packet or external - that are unique on a per-packet basis.

| I wouldn't call this
| a "nonce" in either case, and I don't know what a "per-packet nonce"
| means. We're talking about the connection and packet parameters.

I think this is a per-packet nonce, at least as I understand it. As I
noted, that can be handled by the rekeying system.

Joe

---

From: Joe Touch <[email-masked]>
Date: Mon, 28 Jul 2008 10:52:09 -0700

Eric Rescorla wrote:
...
|> having a per-message counter is probably too much additional work.
|> Having a "pseudo" extended sequence number is very little work
|> (really, I've already implemented it) and that mean that we don't have
|> to rekey faster than the 32-bit sequence rollover. However, the
|> rekeying isn't all that painful anyway.
|
| It depends what you mean by rekeying. If it involves a new protocol
| exchange it is incredibly painful. If you mean just running the kdf
| again, I agree that's fine.

Both ends' key mgt systems can run the kdf again and this should work
fine. No need for on-the-wire exchanges, but no need to bury this into
TCP-AO IMO either.

Joe

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Jul 2008 11:02:53 -0700

At Mon, 28 Jul 2008 10:52:09 -0700,
> fine. No need for on-the-wire exchanges, but no need to bury this into

Well, it needs to be used with TCP-AO regardless of which 
integrity algorithm is used. Why wouldn't we want to 
"bury" that in TCP-AO?

-Ekr

---

From: "Adam Langley" <[email-masked]>
Date: Mon, 28 Jul 2008 11:06:35 -0700

Some points from the discussion:

Regarding NATs:

Your reasoning, as I understood it, for not including an option to
exclude the pseudoheader and port numbers for NAT traversal was that
the host needs these items to lookup the correct key anyway.

There are several situation where this is not the case. (I'll point
out that I see TCP-AO as being useful outside the domain of securing
BGP sessions between backbone routers)

1) A host installs a key on a listening socket with a wildcard
address. Thus, one can only connect to the socket if you know the key.
The key probably rotates based on time. This is currently, usually
done based on "port knocking" - which has always struck me as a messy
solution. The resulting, ESTABLISHED connection knows the port numbers
and IP addresses without having to establish it before hand.

2) An unauthenticated connection is established and the userland code
wishes to upgrade to TCP-AO. Again, since the connection is
established the keyset to use are implicit. I didn't know that the
NONE mac was designed for upgrading like this. In my Linux patches
there's a TCP_AUTH_LATCH option which means "accept unsigned packets
until the first signed packet, then require signatures".

In both of these cases, excluding port numbers and/or pesudoheaders is
needed given the deployment of NAT boxes which change these headers.

Keyids:

I agree that keeping the cryptography in the MAC is a good thing.
There is an implementation issue about the number of keys that a
kernel may have to store (80ish bytes per key * 256 keys * number of
configured hosts), but that's not a spec problem.

---

From: Joe Touch <[email-masked]>
Date: Mon, 28 Jul 2008 11:06:41 -0700

Eric Rescorla wrote:
| At Mon, 28 Jul 2008 10:52:09 -0700,
| Joe Touch wrote:
|> -----BEGIN PGP SIGNED MESSAGE-----
|> Hash: SHA1
|>
|>
|>
|> Eric Rescorla wrote:
|> ...
|> |> having a per-message counter is probably too much additional work.
|> |> Having a "pseudo" extended sequence number is very little work
|> |> (really, I've already implemented it) and that mean that we don't have
|> |> to rekey faster than the 32-bit sequence rollover. However, the
|> |> rekeying isn't all that painful anyway.
|> |
|> | It depends what you mean by rekeying. If it involves a new protocol
|> | exchange it is incredibly painful. If you mean just running the kdf
|> | again, I agree that's fine.
|>
|> Both ends' key mgt systems can run the kdf again and this should work
|> fine. No need for on-the-wire exchanges, but no need to bury this into
|> TCP-AO IMO either.
|
| Well, it needs to be used with TCP-AO regardless of which
| integrity algorithm is used. Why wouldn't we want to
| "bury" that in TCP-AO?

The point of the split of TCP-AO and the key system was to leave the
latter in the hands of SAAG. Since the key system MUST be used with
TCP-AO, it's all part of the solution anyway.

Joe

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Jul 2008 11:09:07 -0700

At Mon, 28 Jul 2008 10:47:48 -0700,
> team as a requirement of this work. Perhaps the ADs should address the

Well, to the extent to which this was an instruction from the
AD, I think this should be reconsidered.

> Are you saying that we generate per-session keys inside TCP-AO?

Per-connection keys, yes.

> Agreed, but there is utility in keeping TCP-AO clean from algorithmic

Perhaps, but there's also utility in having a single, complete,
spec.

> packet or external - that are unique on a per-packet basis.

Well, perhaps we're just differing in terminology, but I don't call
per-packet data fed into the authentication function a nonce. 
I think of the nonce as a discrete value, not just the data.
But in this case we're just talking about MACing the packet.

I just checked and neither AH nor TLS uses the term nonce here.

-Ekr

---

From: "Anantha Ramaiah (ananth)" <[email-masked]>
Date: Tue, 29 Jul 2008 05:46:17 -0700

Folks,
   The extended feeling which I get after watching some of the
conversation is that we seem to be in a cherry picking mode of what to
include/exclude in the digest (MAC) computation. (psuedo header, TCP
options etc.,)

So, if we are going down that route, then I would argue it may be
worthwhile to debate "how much" to include in general, i.e, is it
worthwhile to include selective portions OR part of the data portion of
the TCP data in the MAC computation instead of he entire data.?
Rationale and reasoning follows :-

- performance sensitive applications (in cases there are no hardware
assists for computing the crypto)
- the very reason of NAT (which you mnetion), yes, I am talking about
NAT ALG's which can muck around the data portion of the payload.

My point is that it boils down to how much flexibility one wants to
provide with the TCP AO. 

-Anantha

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On 
> Behalf Of Adam Langley
> Sent: Monday, July 28, 2008 11:07 AM
> To: Joe Touch
> Cc: [email-masked]
> Subject: Re: [tcpm] Review of draft-ietf-tcpm-tcp-auth-opt-01
> 
> Your reasoning, as I understood it, for not including an 
> option to exclude the pseudoheader and port numbers for NAT 
> traversal was that the host needs these items to lookup the 
> correct key anyway.
> 
> There are several situation where this is not the case. (I'll 
> point out that I see TCP-AO as being useful outside the 
> domain of securing BGP sessions between backbone routers)
> 
> 1) A host installs a key on a listening socket with a 
> wildcard address. Thus, one can only connect to the socket if 
> you know the key.
> The key probably rotates based on time. This is currently, 
> usually done based on "port knocking" - which has always 
> struck me as a messy solution. The resulting, ESTABLISHED 
> connection knows the port numbers and IP addresses without 
> having to establish it before hand.
> 
> 2) An unauthenticated connection is established and the 
> userland code wishes to upgrade to TCP-AO. Again, since the 
> connection is established the keyset to use are implicit. I 
> didn't know that the NONE mac was designed for upgrading like 
> this. In my Linux patches there's a TCP_AUTH_LATCH option 
> which means "accept unsigned packets until the first signed 
> packet, then require signatures".
> 
> In both of these cases, excluding port numbers and/or 
> pesudoheaders is needed given the deployment of NAT boxes 
> which change these headers.
> 
> 
> 
> Keyids:
> 
> There is an implementation issue about the number of keys 
> that a kernel may have to store (80ish bytes per key * 256 
> keys * number of configured hosts), but that's not a spec problem.
> 
> 
> --

---

From: Joe Touch <[email-masked]>
Date: Tue, 29 Jul 2008 06:40:48 -0700

Anantha Ramaiah (ananth) wrote:
| Folks,
|    The extended feeling which I get after watching some of the
| conversation is that we seem to be in a cherry picking mode of what to
| include/exclude in the digest (MAC) computation. (psuedo header, TCP
| options etc.,)
|
| So, if we are going down that route, then I would argue it may be
| worthwhile to debate "how much" to include in general, i.e, is it
| worthwhile to include selective portions OR part of the data portion of
| the TCP data in the MAC computation instead of he entire data.?

Absolutely; that can be implemented inside the MAC algorithm, opaquely
to TCP-AO, though. I.e., I can create a MAC that hashes only the odd
blocks, only the first half of the blocks, etc.

Whether or not there are options to that MAC or not that need to be
coordinated end-to-end is up to the key management system; e.g.,
parameters like "just the firs 10 bytes" can be encoded - again opaquely
to TCP-AO - in the key used on a connection.

Joe

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 29 Jul 2008 06:52:59 -0700

At Tue, 29 Jul 2008 06:40:48 -0700,
> to TCP-AO - in the key used on a connection.

Well, it's true that one *could* do this, but I think it's a really
bad idea. MACs should provide a uniform interface and set of semantics.
If you want to have partial coverage, this should be handled at the
TCP-AO level.

I appreciate that you're trying to isolate the crypto from the TCP-AO
service, but I don't think you can isolate it to this extent.

-Ekr

---

From: "Anantha Ramaiah (ananth)" <[email-masked]>
Date: Tue, 29 Jul 2008 07:05:42 -0700

> Behalf Of Eric Rescorla
> Sent: Tuesday, July 29, 2008 6:53 AM
> To: Joe Touch
> Cc: Adam Langley; [email-masked]; Anantha Ramaiah (ananth)
> > | conversation is that we seem to be in a cherry picking 
> mode of what 
> > | to include/exclude in the digest (MAC) computation. 
> (psuedo header, 
> > | TCP options etc.,)
> > |
> > | worthwhile to include selective portions OR part of the 
> data portion 
> > | of the TCP data in the MAC computation instead of he entire data.?
> > 
> > parameters like "just the firs 10 bytes" can be encoded - again 
> > opaquely to TCP-AO - in the key used on a connection.
> 
> Well, it's true that one *could* do this, but I think it's a 
> really bad idea. MACs should provide a uniform interface and 
> set of semantics.
> If you want to have partial coverage, this should be handled 
> at the TCP-AO level.

I agree and that was what I was thinking when I was proposing this.

> 
> I appreciate that you're trying to isolate the crypto from 
> the TCP-AO service, but I don't think you can isolate it to 
> this extent.

Agreed. It needs to come from TCP-AO level even it means changing the
format of the TCP-AO option to accomadate this. As an end user of this
option I wan't to know how much was "digested" explicitly conveyed as
opposed to implicit schemes. Having this in TCP-AO allows a  per packet
granularity and that is good to have, IMO, if we are going down this
route.

-Anantha

---

From: Joe Touch <[email-masked]>
Date: Tue, 29 Jul 2008 07:10:19 -0700

Hi, Eric,

Eric Rescorla wrote:
| At Tue, 29 Jul 2008 06:40:48 -0700,
| Joe Touch wrote:
|> -----BEGIN PGP SIGNED MESSAGE-----
|> Hash: SHA1
...
|> | So, if we are going down that route, then I would argue it may be
|> | worthwhile to debate "how much" to include in general, i.e, is it
|> | worthwhile to include selective portions OR part of the data portion of
|> | the TCP data in the MAC computation instead of he entire data.?
|>
|> Absolutely; that can be implemented inside the MAC algorithm, opaquely
|> to TCP-AO, though. I.e., I can create a MAC that hashes only the odd
|> blocks, only the first half of the blocks, etc.
...
| Well, it's true that one *could* do this, but I think it's a really
| bad idea. MACs should provide a uniform interface and set of semantics.
| If you want to have partial coverage, this should be handled at the
| TCP-AO level.

First, I'm not sure this overall function is useful; since apps can't
align data to the TCP segments, IMO the data is "all or none". I don't
see a reason to omit the data entirely from a MAC (excepting performance
for statistical benefit).

Overall, this doesn't seem to fit the spirit of "TCP-AO should be simple".

| I appreciate that you're trying to isolate the crypto from the TCP-AO
| service, but I don't think you can isolate it to this extent.

It would be useful to explain the reason you see a need for coupling
here (provided this is even needed, as noted above).

Joe

---

From: Joe Touch <[email-masked]>
Date: Tue, 29 Jul 2008 07:12:17 -0700

Anantha Ramaiah (ananth) wrote:
...
|> If you want to have partial coverage, this should be handled
|> at the TCP-AO level.
|
| I agree and that was what I was thinking when I was proposing this.
|
|> I appreciate that you're trying to isolate the crypto from
|> the TCP-AO service, but I don't think you can isolate it to
|> this extent.
|
| Agreed. It needs to come from TCP-AO level even it means changing the
| format of the TCP-AO option to accomadate this. As an end user of this
| option I wan't to know how much was "digested" explicitly conveyed as
| opposed to implicit schemes. Having this in TCP-AO allows a  per packet
| granularity and that is good to have, IMO, if we are going down this
| route.

Can you explain how this might correlate to a segment? or why
per-segment info is needed?

More to the point, given there is no corresponding UDP-lite for TCP, why
is this needed for TCP-AO?

Joe

---

From: "Anantha Ramaiah (ananth)" <[email-masked]>
Date: Tue, 29 Jul 2008 07:46:03 -0700

Joe,

<snip>
 
> |> If you want to have partial coverage, this should be 
> handled at the 
> |> TCP-AO level.
> |
> the TCP-AO 
> |> service, but I don't think you can isolate it to this extent.
> |
> | opposed to implicit schemes. Having this in TCP-AO allows a  per 
> | packet granularity and that is good to have, IMO, if we are 
> going down 
> | this route.
> 

Flexibility, applications would want to ( I am not making this up)
"protect" crucial information, atleast what it considers as crucial
information. For performance reasons being one of them. Agreed, TCP
shouldn't care.

> 
> More to the point, given there is no corresponding UDP-lite 
> for TCP, why is this needed for TCP-AO?

After you clarified to me in the hallway conversation, I agree with your
viewpoint.

Anyways, it appears that we are not yet converged on what can be
included in the TCP-AO and the degree of flexibilty one can expect. At
the least it would be expedient to reflect the discussions in the
document since I am sure these things would come up at some point again.

-Anantha

 <snip>

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 29 Jul 2008 08:17:49 -0700

At Tue, 29 Jul 2008 07:10:19 -0700,
> here (provided this is even needed, as noted above).

(1) I don't think it's needed.
(2) The semantics of partial protection are only meaningful at the TCP
    layer. The MAC just operates on chunks of bits.

-Ekr

---

From: "Caitlin Bestler" <[email-masked]>
Date: Tue, 29 Jul 2008 15:10:57 -0400

A few comments on the alignment issue:

1) Compared to the cost of supporting the crypto-engines and their
supporting
   data, dealing with variable alignment is unlikely to be a major
factor in
   determining whether to include hardware support for TCP-Auth or not.
2) The optimizing alignment might be 64-bits anyway. This only
emphasizes the
   point that putting padding in TCP headers based on presumptions of
what is
   efficient is short-sighted.
3) Hardware support for TCP-Auth is in competition with MACsec, IPSEC
and TLS.
   So any thoughts of optimizing for implementation should probably
focus on
   software implementations and/or specialized devices. I would be
surprised
   to see hardware assists for this in general purpose NICs.

---

From: Joe Touch <[email-masked]>
Date: Tue, 29 Jul 2008 15:28:59 -0700

Adam,

Adam Langley wrote:
| Some points from the discussion:
|
| Regarding NATs:
|
| Your reasoning, as I understood it, for not including an option to
| exclude the pseudoheader and port numbers for NAT traversal was that
| the host needs these items to lookup the correct key anyway.
|
| There are several situation where this is not the case. (I'll point
| out that I see TCP-AO as being useful outside the domain of securing
| BGP sessions between backbone routers)
|
| 1) A host installs a key on a listening socket with a wildcard
| address.

We don't support this use. There are no wildcard addresses in installed
keys; only the source port can be wildcarded.

| Thus, one can only connect to the socket if you know the key.
| The key probably rotates based on time. This is currently, usually
| done based on "port knocking" - which has always struck me as a messy
| solution. The resulting, ESTABLISHED connection knows the port numbers
| and IP addresses without having to establish it before hand.
|
| 2) An unauthenticated connection is established and the userland code
| wishes to upgrade to TCP-AO. Again, since the connection is
| established the keyset to use are implicit. I didn't know that the
| NONE mac was designed for upgrading like this. In my Linux patches
| there's a TCP_AUTH_LATCH option which means "accept unsigned packets
| until the first signed packet, then require signatures".

That's changing from NONE to a non-NONE MAC.

| Keyids:
|
| I agree that keeping the cryptography in the MAC is a good thing.
| There is an implementation issue about the number of keys that a
| kernel may have to store (80ish bytes per key * 256 keys * number of
| configured hosts), but that's not a spec problem.

Agreed. I'll try to capture that.

Joe

---

From: Joe Touch <[email-masked]>
Date: Tue, 29 Jul 2008 15:29:48 -0700

Hi, Eric,

Eric Rescorla wrote:
...(concerns about having a separate key mgt doc)

These concerns can be taken to the ADs, but at this point they may be
moot. We might consider merging the resulting docs, but it's not clear
why that would be useful.

|> | The protocol must be constructed so that it is not possible to
substitute
|> | one packet for another and have it be accepted. This means that
(either)
|> | the data fed into the authentication function must be distinct or the
|> | authentication function must have a distinct key.
|>
|> That implies a per-packet nonce, i.e., some fields - either in the
|> packet or external - that are unique on a per-packet basis.
|
| Well, perhaps we're just differing in terminology, but I don't call
| per-packet data fed into the authentication function a nonce.
| I think of the nonce as a discrete value, not just the data.
| But in this case we're just talking about MACing the packet.
|
| I just checked and neither AH nor TLS uses the term nonce here.

IPsec uses sequence numbers for multiple reasons, so they're not called
just nonces. I'm not sure if the same is true for TLS. If we're at least
talking about the same thing (which I think we are now), then we can
find a better word to describe it...

Joe

---

From: Lars Eggert <[email-masked]>
Date: Wed, 30 Jul 2008 14:11:04 +0100

...
> (3) SAAG has no capability to work on anything, and isn't doing so.

My recollection of the history here is that the split into an option  
part done in TCPM and a keying part done somewhere in the SEC area was  
deliberate, and came out of long discussions between TSV, SEC and RTG  
folks.

One motivation was that it seemed unlikely that TCPM needed to be  
involved in the details of the keying effort, past the stage of making  
sure that the necessary hooks were in place. Another was the hope that  
the two efforts could more or less run in parallel. The SEC keying  
effort has been slow to get off the ground.

Unless there are critical reasons to revisit this decision, I'd like  
to avoid it. Anything that delays publication of AO isn't helpful at  
this point.

Lars

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 30 Jul 2008 14:32:53 -0700

At Wed, 30 Jul 2008 14:11:04 +0100,
> deliberate, and came out of long discussions between TSV, SEC and RTG  

But again, it depends what you mean by "a keying part".

Here's the general situation that applies with any communication security
protocol: 

- Alice and Bob have long term keys K_a and K_b respectively.
- Each individual connetion must have connection keys C_ab and
  C_ba for transmission between Alice and Bob and Bob and Alice
  respectively.

We need some way to arrange that we start with K_a, K_b and we end up
with C_ab, C_ba.

For comparison, IPsec solves this problem by having two flavors of key
managment:

- Null (manual) key management in which K_a, K_b are symmetric keys
  (actually probably one key) with a static mapping to C_ab, C_ba,
  e.g.. C_ab = K_a, C_ba=K_b
- An automatic key management protocol (IKE) which is run every time
  an association needs to be set up and which bootstraps K_a, K_b
  into C_ab, C_ba

TCP-MD5 offers a reduced version of the Null model with a single
key. draft-bonica and TCP-AO-00 (I'll get to -01 in a minute) 
in principle support both models, however, as there has been
no progress whatsoever on actually doing an automatic key management
protocol for this application, that leaves us with the Null model.
Again, there's a static key (or perhaps keys) that is used 
directly as a per-connection key for all connections.

The problem with this scheme, as everyone is no doubt tired of hearing
me say, is that it is susceptible to a variety of cut-and-paste
attacks, both between connections (with the same host/port quartet)
and within connections (due to seqno rollover). 

Now, one could have a number of possible attitudes about this:

(A) It's no big deal.
(B) We'll live with this for manual keying but we'll deal with it
    when we finally do automatic keying.
(C) We should try to fix it.

Given the progress of AKM and the general lack of interest in it from
the relevant community, I claim that (B) is more or less the same as
(C), at least for the medium term. Now, I personally waver between (A) 
and (C), but to the extent to which we don't value bits on the wire
compatibility, as I observed before, it's possible to remove these
problems with TCP-AO without any explicit key management protocol.
The solution is to have a set of "key diversification" rules that
arrange that even when two packets have the same set of TCP parameters
on the wire they are not substitutable. Namely:

- Use the ISNs to arrange that different connections have different
  keys.
- Use either an extended sequence number or internal key rollover
  to avoid cut-and-paste within connections.

It should be clear that this sort of technique requires a fairly
tight binding between the key diversification/MAC code and the
TCP stack, because:

- The key computation code needs to know the ISNs for the connection.
- If you're using key rollover, then the key computation code needs
  to know when the seqno rolls over.

Now, obviously, you *can* think of this as a particularly dumb form 
of external key management. I.e., you tell it when you're establishing
a new connection and it gives you the key (actually you need *two*
interfaces here, because the first packet has to use a 0 ISN for the
peer), and then (if using key rollover) you tell it that the ISN
rolled over and you would like a separate key. But I think this is
unwise for several reasons:

- It requires instantiating a new abstraction layer and defining 
  interfaces which are necessarily fairly wide for something which
  is in principle conceptually quite simple and tightly bound to
  AO.
- These abstractions aren't obviously the abstractions you want
  for a real (explicit) external key management protocol.
- You want the rollover functionality even with an external 
  key management protocol.

To expand on the final point, there is no cryptographic reason
why you would need to change keys every 2^31 bytes. The *sole*
reason is that the TCP seqno is too short. I don't really understand
the claimed reasons why an extended sequence number is considered
bad, but it doesn't really make sense to call out to the key
management system to correct a problem which is TCP-AO, not 
in the key management, and is common to *every* key management
system. Far better to simply define how this works with AO
for every key management system and MAC algorithm. 

I promised I would get to TCP-AO-01, and though it's taken me
a long time, here we are. IMHO, TCP-AO-01 reflects the sort of
confused interface you end up with when you try to make this
unnecessary separation:

(1) It suggests how to compute a "nonce" based on the ISNs, but (a)
    doesn't require this computation algorithm and (b) doesn't specify
    how one would actually use the nonce with a MAC. The text reads
    "MACs typically benefit from a per-connection nonce, notably in
    avoiding the impact of key reuse." Except neither of the most
    commonly proposed MACs, HMAC or AES-CMAC, uses a nonce, so it's totally
    unclear how to use this functionality.

(2) It suggests key rollover at 2^31 bytes but doesn't describe how to
    do it.

To be clear, if you're using manual key management with key diversification
(i.e., without an explicit KMP), then these aren't matters that can
be negotiated. Both sides need to simply be configured with how the
keys are computed (and diversified) and whether to do key rollover
or not. Moreover, again, these issues are largely orthogonal to the
choice of MAC.

> sure that the necessary hooks were in place.

Given the very tight coupling between TCP and the issues I'm
discussing above, I don't really see how TCPM can avoid being
involved in these issues.

> to avoid it. Anything that delays publication of AO isn't helpful at  

Well, I'm not suggesting that TCP-AO be specified with a full external
KMP. I'm suggesting that it be specified with the above key diversification
techniques rather than the current set of vague/confusing hints and a
hope that some other document will eventually be specified to fill in
the gaps.

-Ekr

---

From: Joe Touch <[email-masked]>
Date: Wed, 30 Jul 2008 15:22:38 -0700

Given Eric's points on this topic, as a way forward, there are a few
alternatives (comments requested)

1. assume the key management system (KMS) will rollover the keys every
2^31 bytes

	Eric noted this is weak, since we cannot rely on the KMS
	to act on this without other info. Let's presume this
	is unacceptable to the WG and move on...

2. include an extended sequence number (ESN) inside TCP-AO
	ESN starts at 0
	increment ESN when the TCP sequence number rolls over*
	passed ESN to the encryption algorithm as part of the MAC'd data

3. have TCP-AO ask the KMS to add a new key for the connection when the
sequence number rolls over (actually just before, e.g., 2^31 rolls over)

- ------------------------------------

#2 is internal to TCP-AO, i.e., it requires no 'callback' to the KMS
There appears to be a synchronization issue here - exactly when is the
ESN incremented? Suppose endpoints A and B; there are two ESNs - ESN_ab
and ESN_ba:
	A increments ESN_ab when A receives an ack from B w/seqno > 2^31
	B increments ESN_ab when B sends an ack to A w/seqno > 2^31
	B increments ESN_ba when B receives an ack from A w/seqno > 2^31
	A increments ESN_ba when A sends an ack to B w/seqno > 2^31
i.e., the ESN is incremented when the reverse channel succeeds; we can't
use the forward channel, since one side would change the ESN in ways the
other would never notice (it wouldn't decode it)

Given that algorithm, every ESN increment would trash data in transit
from A-B. Is there an algorithm that does not do this?

- -------------------------------------

#3 allows packets to be reordered without loss during key rollover, and
is not susceptible to the burst-losses of #2

Note that #2 should not 'insert a key into the TSAD' - that interface
should be under the exclusive control of the KMS - at which point asking
the KMS to keep that info (or bury it in the TSAD where the KMS can
refer to it) seems sufficient.

Comments?

---

From: "Adam Langley" <[email-masked]>
Date: Wed, 30 Jul 2008 16:10:19 -0700

>        is unacceptable to the WG and move on...

I don't really like this solution, but I don't think it's too bad.
Here's what my test impl's currently do:

Each direction has a TX key and two valid RX keys configured. From the
point of view of a sending application, which keeps track of the
number of bytes sent:
  If I'm just about to cross a 2**31 bytes boundary, install the next TX key.

This means that retransmissions of some bytes with seq numbers less
than the boundary get the new key, but that's not a huge problem.

On the receiving side (for a given half-connection):
  From the current number of bytes received (n), ensure that keys for
n - 2**30 and n + 2**30 are installed as valid RX keys.

This ends up meaning that RX keys are rotated ever 2**31 bytes with a
2**30 byte phase.

This is fine so long as the window is < 2**31 bytes (which is defined
by the window scaling spec at the moment)

> from A-B. Is there an algorithm that does not do this?

This seems an odd ESN to me:

The ESN is just a 64-bit sequence number. The SEQ field in the TCP
header is just the lower 32-bits of this counter. Thus, for the
half-connection from A to B, A knows the ESN exactly for every packet.
For a packet recved by B, it guesses the ESN based on the closest
value to it's last understanding. An example for B:

At the beginning of the connection, B knows the ESN for the A->B half
connection exactly: top 32-bits are 0, bottom 32-bits from the
handshake.
For each packet recved it gets the low 32-bits of the ESN, now assume
that that the ESN is the closest of the 2**32 possible ESN's to the
previous value of the ECN.
Update the previous value with this new guess.

This is very easy code.

Any packets which are reordered > 2**32 sequence bytes will be
misclassified and dropped, but 2**32 sequence bytes is a long way.

AGL

---

From: Joe Touch <[email-masked]>
Date: Wed, 30 Jul 2008 16:17:50 -0700

Adam Langley wrote:
...
| The ESN is just a 64-bit sequence number. The SEQ field in the TCP
| header is just the lower 32-bits of this counter. Thus, for the
| half-connection from A to B, A knows the ESN exactly for every packet.
| For a packet recved by B, it guesses the ESN based on the closest
| value to it's last understanding. An example for B:
|
| At the beginning of the connection, B knows the ESN for the A->B half
| connection exactly: top 32-bits are 0, bottom 32-bits from the
| handshake.
| For each packet recved it gets the low 32-bits of the ESN, now assume
| that that the ESN is the closest of the 2**32 possible ESN's to the
| previous value of the ECN.

Can you explain the algorithm for "closest"?

| Update the previous value with this new guess.
|
| This is very easy code.
|
| Any packets which are reordered > 2**32 sequence bytes will be
| misclassified and dropped, but 2**32 sequence bytes is a long way.

<individual hat on>

If you update the ESN on the first packet whose Seqno causes you to
determine a rollover, won't any packets that are reordered around it be
dropped? i.e.:

	packets with higher seqnos that arrive earlier cause
	the ESN to be updated earlier; all subsequent packets
	with the pre-increment ESN would be droppped

<individual hat off>

---

From: "Adam Langley" <[email-masked]>
Date: Wed, 30 Jul 2008 16:36:36 -0700

> Can you explain the algorithm for "closest"?

Sure,

let the last 'known' value for the ESN be a uint64_t called last_esn
and the current SEQ be a uint32_t called current.

uint64_t last_top32bits = last_esn >> 32;
uint64_t possibility_1 = (last_top32bits - 1) << 32 | current;
uint64_t possibility_2 = last_top32bits << 32 | current;
uint64_t possibility_3 = (last_top32bits + 1) << 32 | current;

uint64_t delta_1 = distance(possibility_1, last_esn);
uint64_t delta_2 = distance(possibility_2, last_esn);
uint64_t delta_3 = distance(possibility_3, last_esn);

uint64_t new_esn = min(delta_1, delta_2, delta_3);

That's written to try and be clear, rather than actual code that I would write.

The idea is that, when we get a seq number, we know that the sending
side had a definite 64-bit ESN in mind when they sent it. We know the
bottom 32-bits of this, so there are 2**32 possible ESNs (the set of
64-bit numbers with those 32 bits in the lower half). We pick the one
that is closest to the last known value.

If our last known value was 0, and we get 1, we assume that the ESN is one.

If the last ESN was 2**32 - 1, and we get 1, we assume that the ESN is
2**32 + 1.

If the last ESN was 2**32 + 1, and we get 2**32 - 5 (packet
reordering), we assume that the ESN is 2**32 - 5, because it's closer
than assuming that nearly 2**32 bytes went by, unnoticed.

I hope that's clear. I'll write real code if I still being inarticulate.

AGL

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 30 Jul 2008 17:16:09 -0700

At Wed, 30 Jul 2008 15:22:38 -0700,

> sequence number rolls over (actually just before, e.g., 2^31 rolls over)

I'm sorry, but I don't understand the issue. The ESN dosn't have to
move monotonically forward, any more than the packet sequence numbers
do. You assign bytes sequence numbers in a 64-bit rather than 32-bit
space and only transmit the low-order 32 bits in the packet.

By way of illustration, let's work in 16-bit space with an 8-bit
sequence number in the packet. 

1. A transmits bytes 0x00f0 - 0x0101  (packet sn 0xf0)  [lost]
2. A transmits bytes 0x0101 - 0x0111  (packet sn 0x01)
3. A retransmits bytes 0x00f0 - 0x0101 (packet sn 0xf0)

> refer to it) seems sufficient.

Well, again I think this whole notion of the TSAD is an abstraction
which is confusing rather than clarifying. Let's try walking through
the situation we actually have to deal with right now.

1. The user configures a single static key that applies to 
   all connections between some set of host/port quartets
2. When a connection is instantiated, that single static key
   has to somehow get diversified into a per-connection key
   that gets attached to that connection.
3. If the user configures a new key, that needs to get noticed
   and a new set of diversified per-connection keys needs to
   be attached.

Thinking of this as a database with various portions of the system
having read/write access seems to me only to confuse the issue.

I suggest we discuss what bits on the wire we expect to have
and then we can discuss what model is best to describe it.

1. The user establishes a key, which we'll call key 9 with value K_9
   and sets it for all connections between 10.0.0.1:* (remote) and
   10.0.10.1:555 (local).

2. Host 10.0.0.1:911 sends a SYN to 10.0.10.1:555 with ISN X.
   This packet is protected with a key computed as:

   k_i = PRF(K_9, 10.0.0.1, 911, 10.0.10.1, 555, X, 0).
   This packet has key-id 9.

3. Host 10.0.10.1:555 sends a SYN/ACK to 10.0.0.1:911
   with ISN Y.

   This packet is protected with a key computed as:

   k_j = PRF(K_9, 10.0.10.1, 555, 10.0.0.1, 911, Y, X).
   This packet has key-id 9.

4. Host 10.0.0.1:911 sends an ACK to 10.0.10.1:555 with ISN X.
   This packet is protected with a key computed as:

   k_k = PRF(K_9, 10.0.0.1, 911, 10.0.10.1, 555, X, Y).
   This packet has key-id 9.

Future packets from 10.0.0.1:911 -> 10.0.10.1:555 are protected
with k_k. Packets in the reverse direction are protected with
k_j.

...

5. Host 10.0.0.1:911 sends an packet to 10.0.10.1:555 with a
   sequence number of 0xfffffff0 and length 32. 
   This packet is protected with key k_k and bears key-id 9.

6. Host 10.0.0.1:911 sends a packet to 10.0.10.1:555 with 
   a sequence number of 0x00000010 (the successor to packet
   5). 

   This packet is protected with a key computed as:

   k_l = PRF(k_k, 10.0.0.1, 911, 10.0.10.1, 555, X, Y).
   This packet has key-id 9.

7. The packet sent in 5 is lost and so must be retransmitted.
   It is protected with key k_k.

So, two salient points:
1. When the sequence number is in the region of 0 (more precisely
   while there are unacked segments on both sides of the region),
   then the sides must maintain two keys and arrange to use
   the appropriate one.
2. The same key-id is used in the packet regardless of the which
   key is being used to protect the traffic. It refers to the
   static key from which the traffic keys were diversified.

We could tell a similar story about ESN handling, except you would
use the same traffic keys, but move the high order word up and down
appropriately.

Do you disagree that this is the right thing to have in the packets?

-Ekr

---

From: Joe Touch <[email-masked]>
Date: Thu, 31 Jul 2008 01:20:13 -0700

Regarding the ESN,

<individual hat on>
My goal was to allow TCP-AO code to be isolated to handling packets just
before exit/entrance to IP. That suggests that all TCP-AO state should
be kept to the TSAD, and not extend the core TCP code unless absolutely
necessary.

Let's assume we compute the ESN

	compute the ESN for each packet as Adam described,
	using the 'nearby' algorithm

The question becomes when to actually increment the ESN?

Eric Rescorla wrote:
| I'm sorry, but I don't understand the issue. The ESN dosn't have to
| move monotonically forward, any more than the packet sequence numbers
| do. You assign bytes sequence numbers in a 64-bit rather than 32-bit
| space and only transmit the low-order 32 bits in the packet.

This would require modifying the core of TCP to use 64-bit sequence
numbers throughout.
<individual hat off>

Does the WG want to keep mods out of the core of TCP, or can we assume a
64-bit sequence number space?

- ------

A separate question is whether ESN rollover should use the keyID
mechanism or not. This is related to Eric's points:

| So, two salient points:
| 1. When the sequence number is in the region of 0 (more precisely
|    while there are unacked segments on both sides of the region),
|    then the sides must maintain two keys and arrange to use
|    the appropriate one.

Eric - can you explain "arrange to use the appropriate one"?

| 2. The same key-id is used in the packet regardless of the which
|    key is being used to protect the traffic. It refers to the
|    static key from which the traffic keys were diversified.

Eric - can you explain where the multiple keys per keyID are determined?
i.e., are they recomputed per-packet or kept somewhere?

<individual hat on>
FWIW, I agree with Eric's example on the wire; the issue is the state
required at the endpoints required to make it happen.
<individual hat off>

Comments?

---

From: "Adam Langley" <[email-masked]>
Date: Thu, 31 Jul 2008 10:10:22 -0700

> be kept to the TSAD, and not extend the core TCP code unless absolutely

Speaking for the Linux stack, the current MD5 code filters at the
entry to the TCP layer since it needs to be near the options parsing
code etc. At that point, we have found a socket and thus have a locked
tcp_sock structure. So adding the ESN would involve adding a couple of
u32's to the tcp_sock structure (they would store the upper 32-bits of
the RX and TX ESNs).

> mechanism or not. This is related to Eric's points:

Personally, my feeling is that it shouldn't.

> Eric - can you explain "arrange to use the appropriate one"?

I believe Eric is discussing the case where the keys change because of
a rollover. Since packets may be reordered, a host past to remember
both the keys for the previous period and the keys for the current
period in case a reordered packet comes in. It's unclear, to me, which
key retransmitted packets would use.

> i.e., are they recomputed per-packet or kept somewhere?

It appears that they are computed when a connection becomes
ESTABLISHED and rotated once every rollover from then.

> required at the endpoints required to make it happen.

I would prefer, for simplicities sake, that the MAC simply include an
ESN rather than roll the keys over, but not strongly.

AGL