Subject: [IPsec] Review of the draft-ietf-ipsecme-tcp-encaps-04

From: Tero Kivinen <[email-masked]>
Date: Wed, 11 Jan 2017 17:04:02 +0200

This draft should be quite ready for the WGLC, so I will start that
shortly, but here are comments from my chair review of the draft.

Consider these comments just like any WGLC comments.

--

In section 6, there is text saying:

   In order to close an IKE session, either the initiator or responder
   SHOULD gracefully tear down IKE SAs with DELETE payloads.  Once all
   SAs have been deleted, the initiator of the original connection MUST
   close the TCP connection.

I do not understand the reasoning behind the MUST, or actually also
whether it is that it MUST be initiator of the original connection
closing, it or that connection MUST be closed after all SAs are
deleted.

If it is supposed to say that once all SAs are deleted the connection
MUST be deleted, then it does not really matter who will close it, as
once all SAs are gone, there cannot be any new IKE exchanges on the
TCP connection.

If it is trying to say that only original initiator can close the
connection, just in case it wants to reuse it for new IKE INIT
message, then the text needs to change to say that.

I.e., what is this MUST trying to say?

--

   The streams of data sent over any TCP connection used for this
   protocol MUST begin with the stream prefix value followed by a
   complete message, which is either an encapsulated IKE or ESP message.
...

I think this should be rephrased in a way that when initiator creates
new TCP connection, it MUST send the stream prefix value first,
followed by a IKE or ESP message.

The responder might receive them in pieces, because of the TCP, so
responder should not consider it an error to only receive stream
prefix and parts of the first message. If it sees partial message it
should wait for the rest of the message to come or untile timeout
occurs. Note, the responder do need timeout in this case, as we do
want to clean up the state if we have partial messages in the TCP
stream, even when the TCP connection itself is not broken.

--

   If the connection is being used to resume a previous IKE session, the
   responder can recognize the session using either the IKE SPI from an
   encapsulated IKE message or the ESP SPI from an encapsulated ESP
   message.

There should be note here and later explaining that this IKE or ESP
message must pass authentication checks, and MUST be fresh. I.e.,
replaying old IKE or ESP message over tcp stream must not move traffic
to new TCP connection. This text here tells which IKE it belongs, but
later three is text saying:

					It should choose the TCP
   connection on which it last received a valid and decryptable IKE or
   ESP message.

so that should also include note, that messages must be fresh. Note,
that definition of fresh is not obvious. For the ESP it is not enough
that it is unseen message in the replay window, as the replay window
might be quite large, and acquiring ESP message not seen by the other
end is quite possible. I think it is best to require that the ESP
message must be with higher sequence number ever seen before... This
should be happening anyways, as there will not be reordering happening
inside the TCP connection, so this will not cause issues for normal
cases.

Same for the IKE SA, i.e. the message-id must be larger than anything
seen before, not just something that is in the window.

Also why this text has only lowercase "should", not uppercase MUST? 

--

       If either initiator or responder receives a stream that
   cannot be parsed correctly, it MUST close the TCP connection.

I think this needs more text. I.e., if it receives random garbage,
then it must close the TCP connection. But if it receives
authenticated IKEv2 message, which passes IKE SA message
authentication, but which is cannot be parsed correctly (i.e., result
in the INVALID_SYNTAX error), then it will return INVALID_SYNTAX
error, tear down the IKE SA (as specified in the RFC7296) and close
the TCP connection.

--

   Multiple IKE SAs SHOULD NOT share a single TCP connection.

I think this needs to be MUST NOT. I mean if we assume that the first
IKE or ESP message coming from the newly formed TCP connection tells
which IKE SA this TCP connection belongs, we cannot really use one TCP
connection for multiple IKE SAs.

Of course we should allow IKE SA rekeying over the same TCP
connection, but I think that is only exception to the multiple IKE SAs
using same TCP connection, and in that case the one end will delete
the old rekeyed IKE SA soon.

So I would change that to MUST, and add note about rekeying case.

--

In section 7 we should also mention that the fact whether there is NAT
or not in the path can affect the TCP and UPD packet checksum fixup
for transport mode traffic (RFC7296 section 2.23.1).

--

In section 8, there is text:

   When an IKE session is transitioned between networks using MOBIKE
   [RFC4555], the initiator of the transition may switch between using

MOBIKE is not property of the networks, it is property of the
implementations. I.e., change this to say "When an IKE session is
created between implementations using MOBIKE, ..."

--

In section 9:

   fragmentation.  Even if fragmentation is negotiated, an
   implementation MAY choose to not fragment when going over a TCP
   connection.

why allow fragmentation over TCP connection? I think we could say that
fragmentation SHOULD NOT be used when sending messages over TCP
connection? The only reason I can think why someone would use
fragmentation is that they are using mobike and the initiator is using
UDP and tries to send some large message which requires fragmentation
on UDP first, and then when the packets do not get through it tries to
move to use TCP, and in that case it MUST forward the IKE packet just
as it was sent over the UDP to the TCP, so the packet will have
fragmentation headers in it.

So I would say MUST accept packets with fragmentation from TCP if
fragmentation is supported and enabled. SHOULD NOT fragment packets if
sending them to the TCP connection.

--

In the security considerations section we should also mention that
attackers can do quite a lot of same tricks explained in the MOBIKE
[RFC4555] security considerations. Perhaps put pointer to there, and
think that list through and list which of those can be done also when
using TCP connection. The TCP connection has same kind of properties
than MOBIKE, as it will allow changing the source IP and port of the
incoming connection, and SGW will update its mapping to match the
latest connection...

--

In section B.1, the IKE messages should have "Non-ESP Marker" visible
on the figure 4.

--

In section B.3, there should be the one mandatory IKE or ESP packet
after the "IKETCP" stream prefix. Perhaps use ESP here as example...

--

In section B.4 step 6 should note, that this message in step 6, is
actually retransmission of the message sent in step 2, i.e., it is
exactly same IKE message including message-id and the contents.
-- 
[email-masked]

---

From: "Valery Smyslov" <[email-masked]>
Date: Thu, 12 Jan 2017 16:04:24 +0300

Hi once more,

> stream, even when the TCP connection itself is not broken.

And it should be specified that if responder times out waiting
for complete IKE message, it must not only delete IKE SA state,
but also it must close TCP connection, so that initiator get informed
that it must start over from creating new TCP connection
and resending the whole message. Otherwise if the TCP eventually
resumes, the responder will receive partial message which it'll
treat as invalid (I assume that the responder has already read from the socket 
some part of the message, like length prefix) and the TCP connection
will be closed anyway.

> message must be with higher sequence number ever seen before... 

This will be always true with TCP.

> This should be happening anyways, as there will not be reordering happening

Isn't it easier to add a requirement that the received message must not be a replay?
For example:

					It should choose the TCP
   	connection on which it last received a valid and decryptable IKE or
   	ESP message that is not recognized as a replay of some early message.

I agree with your comment here, however I can see a reason for MAY - 
some implementations may have a single configuration knob, that
triggers between "always fragment" and "never fragment".
These implementations may choose to always fragment
(if the knob is on) regardless of the used transport just for simplicity.

Regards,
Valery.

---

From: Tero Kivinen <[email-masked]>
Date: Thu, 12 Jan 2017 15:37:35 +0200

Valery Smyslov writes:
> Isn't it easier to add a requirement that the received message must
> not be a replay? For example:
> 
> 					It should choose the TCP

No.

Not replay == ESP packet we have not seen before that is still in
window != ESP packet which has largest sequence number.

I.e., attacker sends RST to the tcp connection, initiator recreates
TCP session, and initiator sends one ESP packet to the TCP connection
having sequence number of 0x1000. Attacker messes up with the TCP
connection so that responder never sees the ESP 0x1000 packet, and TCP
connection is reset. For example sends RST before the actual packet
reaches the responder, but after the attacker has seen the contents of
the packet in TCP stream.

Initiator then recreates tcp session with responder and sends some ESP
traffic with sequence numbers of 0x1001-0x1005. Attacker kills that
TCP connection, creates completely new TCP session and replays the old
ESP message with sequence number of 0x1000 (which was not seen by the
server before). Responder will accept this as valid non replayed ESP
packet, and will move all traffic to this new TCP connection.

The attack is not very efficient, and there are most likely easier
ways to do similar attacks, but there might be some other tricks
people might invent if we leave this thing open. Thats why I think it
is better to close it by saying that it is not enough to have valid
ESP packet which is not replay, but it must be valid ESP packet which
have sequence number that is higher than anything seen before.

One way of implementing that is to configure ESP replay window size to
be 1... 

> (if the knob is on) regardless of the used transport just for simplicity.

So we are allowing this kind of stupid things because there might be
some implementation that will implement this new protocol and which
does not want to fix their own broken implementation about
fragmentation?

I assume they do not really care about the fragment sizes, and will
fragment everything to 100 byte fragments, just because of simplicity?

Again SHOULD will not prevent that, and MUST accept will allow them
to work... Hmm.. and the responder SHOULD respond with fragments too
if I read RFC7383 right...

On the other hand sending fragments to the TCP connection is already
against SHOULD NOT in the RFC7383 which says that "IKE fragmentation
SHOULD NOT be used in cases where IP-layer fragmentation of both the
request and response messages is unlikely."...

So I think SHOULD NOT fragment is correct here, as it is directly
derived from the RFC7383...
-- 
[email-masked]

---

From: "Valery Smyslov" <[email-masked]>
Date: Thu, 12 Jan 2017 17:32:02 +0300

> packet, and will move all traffic to this new TCP connection.

What then? What benefits attacker gains and how it will exploit
the fact it hijacks TCP connection? The responder will eventually
recreate new TCP connection and everything will continue to work.

The reason I opposed your interpretation of "fresh" is that
if you replace ESP with IKE in the example above and if you
require the responder to ignore smaller MESSAGE_IDs if 
the higher are received, then the responder will ignore
IKE message with ID=0x1000 in your example, because
this message will be received after the responder receives 0x1001-0x1005.
Since the initiator will never receive reply for ID=0x1000 
it will eventually kill IKE SA. This is much more dangerous
attack than the attack you described above.

> have sequence number that is higher than anything seen before.

For IKE it'll make things worse.

> One way of implementing that is to configure ESP replay window size to

That's probably OK, since TCP will provide in-order delivery.
However, that will further complicate implementations, because
you'll need to be able to dynamically manipulate ESP window
size in case the transport changes.

And IKE doesn't allow window to shrink, so we'll stick to 
size = 1. Not a good idea.

---

From: Tero Kivinen <[email-masked]>
Date: Thu, 12 Jan 2017 16:57:03 +0200

> recreate new TCP connection and everything will continue to work.

As I said this is not serious, but it is vulnerability, which is easy
to fix. There might be tricks you can do (for example forward
multigigabyte video stream from server to some unsuspecting client,
while the original recipient is just wondering where is my video,
until after few minutes it times out and tries to recreate the TCP
session, or sends new packet through the TCP session.

> attack than the attack you described above.

IKE will not have this issue, as every single IKE frame will require
response, thus if the original initiator did not get IKE response to
his request when the attacker killed the connection, then it will
retransmit when it recreates the TCP session. This only really affects
ESP, not IKE.

Also in IKE the window size is quite often also 1.

And, I am not saying they should ignore the messages, I say they
should not consider the messages as fresh, meaning they should not
turn old traffic to that new TCP session until they see fresh message.

> For IKE it'll make things worse.

And I was talking about ESP. Not IKE. For IKE there is no problem
there as there is always response, thus blackholes are detected. For
ESP there can be problems. 

> size = 1. Not a good idea.

Again, I do not think this is needed for IKE, I think it is needed for
ESP. With ESP it is possible for the attacker to redirect the packets
from the server to wrong address for long time, by just sending few
packets, and the situation might be fixed only after the original
initiator wonders where his packets are and starts to do corrective
actions. 

(and IKE window can shrink, as rekey resets the window size to 1).
-- 
[email-masked]

---

From: "Valery Smyslov" <[email-masked]>
Date: Thu, 12 Jan 2017 18:25:50 +0300

> to fix. 

I don't think your fix really helps in this scenario.

If attacker intercepts TCP session carrying ESP packet with sequence 
0x1000 and manages to get the packet and drop the TCP session before 
responder gets it, then it can create a new TCP session
sending this packet. The responder will switch to the attacker's
TCP session even with your proposal (until the initiator
creates new TCP session and sends some ESP packets with higher SN).

---

From: Tommy Pauly <[email-masked]>
Date: Thu, 12 Jan 2017 10:13:53 -0800

Hi Tero,

Thanks for the comments! Responses inline.

Best,
Tommy

> On Jan 11, 2017, at 7:04 AM, Tero Kivinen <[email-masked]> wrote:
> 

This MUST should probably be downgraded to a SHOULD, and add explanation about the reuse case. The point of this text was to make sure that initiators don’t needlessly leave TCP connections open to responders, and take up resources on the responder. A better text would be:

"In order to close an IKE session, either the initiator or responder
  SHOULD gracefully tear down IKE SAs with DELETE payloads.  Once all
  SAs have been deleted, the initiator of the original connection SHOULD
  close the TCP connection if it does not intend to use the connection for
  another IKE session to the responder. If the connection is left idle,
  and the responder needs to clean up resources, the responder MAY
  close the TCP connection."

Good point, I will clarify the text to make it clearer that the prefix value must be sent first on any new connection, and that the responder has to deal with parsing partial messages.

I will add text to specify that the IKE and ESP messages must be valid (pass authentication and decryption), and have higher IDs than previous messages.
> Also why this text has only lowercase "should", not uppercase MUST? 

I may want to upgrade it to a SHOULD. If we are in a state in which there are, for a time, two TCP connections up, the only reliable way to return a message from the responder to the initiator is to use the most recently-used TCP connection. However, if a responder implementation did send a response packet on the less-recently used connection, it *might* get back to the initiator. This would probably require some special knowledge about how the implementations were using connections, but if that use case comes up in the future, I don’t think sending a packet on the other connection would necessarily make the implementation out-of-spec. However, if consensus is that this should be a MUST rather than a SHOULD, I’m fine with that!

Good point. I’ll try to word this generically—i.e., any parsing of the IKE and ESP frames should cause the connection to be closed, and any errors within IKE that cause the IKE session to be torn down should do the same.

Sure, that sounds fine. I could imagine that if two IKE SAs were on the same connection, another message 

Will add.
> created between implementations using MOBIKE, …"

Yes, that’s not clear. I meant “When an IKE session that has negotiated MOBIKE is transitioning between networks, the initiator…"

We can switch it to a SHOULD NOT for sending fragments, and a MUST for accepting fragments. Depending on how implementations are built, the IKE logic may not be co-located with the module handling UDP or TCP, and so I expect some implementations to still use fragmentation in the naive case.

> latest connection…
Will add the reference and section discussing the implications of changing the source IP and port mappings.

Will add.
> after the "IKETCP" stream prefix. Perhaps use ESP here as example…

Will add.

Good point, that will make the diagram clearer.

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

---

From: "Hu, Jun (Nokia - US)" <[email-masked]>
Date: Thu, 12 Jan 2017 19:13:30 +0000

I think this is similar case as NAT-T , where system need to update address:port if NAT mapping is changed ( described in last point of 2.23 of RFC7296 ); 
RFC 7296 says: "dynamic address update should only
      be done in response to a new packet; otherwise, an attacker can
      revert the addresses with old replayed packets.  Because of this,
      dynamic updates can only be done safely if replay protection is
      enabled."

I think we could use same requirement (pass anti-replay) here since this is same issue and tcp encap is not make thing worse; 

> -----Original Message-----
> From: IPsec [mailto:[email-masked]] On Behalf Of Valery Smyslov
> Sent: Thursday, January 12, 2017 7:26 AM
> To: 'Tero Kivinen' <[email-masked]>
> Cc: [email-masked]
> Subject: Re: [IPsec] Review of the draft-ietf-ipsecme-tcp-encaps-04
> 
> > > > Initiator then recreates tcp session with responder and sends some
> > > > ESP traffic with sequence numbers of 0x1001-0x1005. Attacker kills
> > > > that TCP connection, creates completely new TCP session and
> > > > replays the old ESP message with sequence number of 0x1000 (which
> > > > was not seen by the server before). Responder will accept this as
> > > > valid non replayed ESP packet, and will move all traffic to this new TCP
> connection.
> > >
> > > What then? What benefits attacker gains and how it will exploit the
> > > fact it hijacks TCP connection? The responder will eventually
> responder gets it, then it can create a new TCP session sending this packet.
> The responder will switch to the attacker's TCP session even with your
> proposal (until the initiator creates new TCP session and sends some ESP
> packets with higher SN).
> 
>

---

From: Tero Kivinen <[email-masked]>
Date: Fri, 13 Jan 2017 11:39:44 +0200

> creates new TCP session and sends some ESP packets with higher SN).

But he cannot take the ESP packet stolen half an hour ago, which still
happens to be in 128 packet ESP replay window. Also he cannot steal 20
packets from the window, and play them one by one, every time original
responder tries to get his TCP session back.

We had this same problem with NAT traversal with UDP packets, i.e.
attacker stealing some packets can always redirect the traffic to
wrong peer, once per each stolen packet. In NAT traversal we cannot do
anything, as there can be out of order packets. With MOBIKE this was
fixed by using UPDATE_SA_ADDRESS notification to update the addresses.

Here we can make the things better even for ESP packets, as there
should not be reordered packets, thus requiring latest sequence number
to update the address does not cause issues.
-- 
[email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Fri, 13 Jan 2017 13:43:07 +0200

Tommy Pauly writes:
> This MUST should probably be downgraded to a SHOULD, and add
> explanation about the reuse case. The point of this text was to make
> sure that initiators don’t needlessly leave TCP connections open to
> responders, and take up resources on the responder. A better text
> would be: 
> 

Much better text, this I can understand and agree...

> I will add text to specify that the IKE and ESP messages must be
> valid (pass authentication and decryption), and have higher IDs than
> previous messages.

Actually Valery did raise good point, that for IKE this might cause
issues.

Now when I am thinking about this, I think that for IKE packets the
response to the IKE request should go to the same TCP session where
the request came in. This would be aligned with the RFC7296 which says
you reverse ip-addresses and ports for incoming IKE request, and reply
to that address.

I.e., if you get request 5 in using tcp connection 1, you send your
response to connection 1, if you another request 6 coming in using
connection 2, you send your response to connection 2. If you then see
retransmission of the same request 6 from connection 1, you resend
your response to connection 1. I.e., it might be that connection 2 is
not working properly, for example return packets do not get through.

This kind of things can happen if for example NAT or firewall in the
middle is blocking inbound traffic for some ports or something.

For new requests the IKE should use the same TCP session than what is
being used for ESP, i.e., the most fresh one.

The most fresh should then be defined as the one which has received
ESP sequence number which is not out of order (note, that there might
be multipe ESP SAs in the same TCP connection, so largest sequence
number is not right way to express this), or which has received new
IKE request (note, not IKE respose, or retrasmitted request) last.
-- 
[email-masked]

---

From: "Valery Smyslov" <[email-masked]>
Date: Fri, 20 Jan 2017 10:18:05 +0300

Hi Tero,

> responder tries to get his TCP session back.

So what? If an attacker is so powerful that it can steal ESP packets,
block delivering them to the responder and replay these packets 
later, it doesn't really matter whether it is latest ESP packet
(with the highest SN) or some previous packet. The attacker 
can easily manipulate values in IP and TCP headers of stolen packets, 
so that the responder will try to send packet back to probably 
non-existing address/port. 

> to update the address does not cause issues.

Sure, but it won't help against this kind of attack.

Regards,
Valery.

---

From: "Valery Smyslov" <[email-masked]>
Date: Fri, 20 Jan 2017 10:47:40 +0300

HI Tero,

> you reverse ip-addresses and ports for incoming IKE request, and reply

That makes sense.

> IKE request (note, not IKE respose, or retrasmitted request) last.

It doesn't really help to prevent attack, but unnecessary complicates implementations.
I'd rather suggest to choose the TCP connection over which the latest
valid ESP or IKE packet (that is not a retransmission) is received. 

In most cases this is equivalent to the rules you suggests
(since TCP prevents reordering the latest packet will have
the highest SN/MID). In case of powerful attacker on the path,
who can steal, drop, modify and replay packets, the rules
you suggest won't help anyway.

Regards,
Valery.

---

From: Tommy Pauly <[email-masked]>
Date: Fri, 20 Jan 2017 08:02:36 -0800

> On Jan 19, 2017, at 11:47 PM, Valery Smyslov <[email-masked]> wrote:
> 
> HI Tero,
> 

Right, so how about we say that a packet that causes the responder to choose which TCP connection to use must be:
- A valid IKE or ESP message that can be successfully decrypted and authenticated
- Not a retransmission
- Not outside of the ESP replay window
- In order for the sequence of message IDs for that SA

Does that work to sufficiently be conservative about which packets to trust, while not adding undue complication?

Thanks,
Tommy

---

From: "Valery Smyslov" <[email-masked]>
Date: Mon, 23 Jan 2017 15:07:28 +0300

Hi Tommy,

> Right, so how about we say that a packet that causes the responder to choose which TCP connection
to
> use must be:

Technically this requirement  is wrong, since every ESP packet
with SN greater than the highest seen so far will be outside
ESP replay window (and will update this window if the packet
is decrypted and verified successfully).

> Does that work to sufficiently be conservative about which packets to trust, while not adding
undue
> complication?

I think that it is enough if this is a valid (one that passed a replay check,
then successfully decrypted and authenticated)  ESP packet or IKE message that 
is most recently received.

This rule would avoid all complexities concerned with determining the highest 
SN for many ESP connections over single TCP. In normal cases (no attack)
the most recently received ESP packet will always have the highest SN if
TCP encapsulation is employed. In case of attack that Tero described the attacker
must be on the path and there is no defense against she anyway,
so no need to complicate the responder.

It is also a good thing to advise, that for TCP encapsulation
ESP replay window size should be set to 0 (since TCP doesn't allow
reordered packets). 

Regards,
Valery.