Subject: [IPsec] HA protocol replay protection

From: Yaron Sheffer <[email-masked]>
Date: Thu, 11 Nov 2010 17:16:31 +0200

Hi,

it seems to me we have created an overly complicated solution for replay 
protection of the Msg ID = 0 messages. Specifically, I think both the 
failover counter and the nonce can be eliminated.

Since the messages are protected under the IKE SA, we just need to 
ensure that in a correct run of the protocol, there is never any need to 
repeat previous messages. This can be done by including *both* Msg ID 
counters in each message, and specifying a few rules to make sure 
counters never go backwards.

Cluster member to client:
- The counter I plan to use next (based on a traffic/rekey rate 
estimate, must be higher than the last message that was actually sent, 
otherwise it might be rejected)
- The counter I think you will use next (the last known value, as 
received from the failed cluster member)

Client to cluster:
- The counter I really plan to use next (must be equal to or higher than 
the received value)
- The counter you said you will use next

And each side must accept incoming messages only if both values are 
equal to or larger than the corresponding one previously received from 
the same peer, and one of them is strictly larger than the previous value.

Am I missing anything?

Thanks,
     Yaron

---

From: Raj Singh <[email-masked]>
Date: Thu, 18 Nov 2010 22:24:31 +0530

Hi Yaron,

Thanks for the comments, Ticket#205 create to track this.

On Thu, Nov 11, 2010 at 8:46 PM, Yaron Sheffer <[email-masked]>wrote:

> Since the messages are protected under the IKE SA, we just need to ensure
> that in a correct run of the protocol, there is never any need to repeat
> previous messages. This can be done by including *both* Msg ID counters in
> each message, and specifying a few rules to make sure counters never go
> backwards.
>
> - The counter I plan to use next (based on a traffic/rekey rate estimate,
> must be higher than the last message that was actually sent, otherwise it
> might be rejected)
>

It will be better to jump this counter by IKEv2 Message Send Window size
rather than measuring or guessing traffic here.

> - The counter I think you will use next (the last known value, as received
> from the failed cluster member)
>
> Client to cluster:
> And each side must accept incoming messages only if both values are equal
> to or larger than the corresponding one previously received from the same
> peer, and one of them is strictly larger than the previous value.
>
> Am I missing anything?
>
> Thanks,
>    Yaron
> _______________________________________________
> IPsec mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/ipsec
>

---

From: Pekka Riikonen <[email-masked]>
Date: Fri, 19 Nov 2010 06:32:19 +0100 (CET)

On Thu, 18 Nov 2010, Raj Singh wrote:

: > Cluster member to client:
: > - The counter I plan to use next (based on a traffic/rekey rate estimate,
: > must be higher than the last message that was actually sent, otherwise it
: > might be rejected)
: >
: 
: It will be better to jump this counter by IKEv2 Message Send Window size
: rather than measuring or guessing traffic here.
: 
I think this isn't enough.  The failover may have happened after node sent 
the packet but before the message id has been synced to another node (or 
sync was dropped, or whatever).  Skipping window size (for example 1) may 
not be enough here.  The remote peer is already processing the request 
with the message id and now we would be re-using the same message id.

I also don't like that we'd have to guess the message id.

: > - The counter I think you will use next (the last known value, as received
: > from the failed cluster member)
: >
: > Client to cluster:
: > - The counter I really plan to use next (must be equal to or higher than
: > the received value)
: > - The counter you said you will use next
: >
I think it's important that the peer that actually knows my message id 
tells it to me.

IMO, this can work only we're allowed to freely select the next message ID 
I'm going to use.  Ie. skip as much as I want to skip, same way as we can 
skip ESP sequence numbers.

	Pekka

---

From: Yaron Sheffer <[email-masked]>
Date: Fri, 19 Nov 2010 08:50:43 +0200

Yes, in order to avoid replay issues, each side should be able to skip 
forward as much as it wants to.

Thanks,
	Yaron

On 11/19/2010 07:32 AM, Pekka Riikonen wrote:
> :>  Cluster member to client:
> :>  - The counter I plan to use next (based on a traffic/rekey rate estimate,
> :>  must be higher than the last message that was actually sent, otherwise it
> :>  might be rejected)
> :>
> :
> :>  - The counter I think you will use next (the last known value, as received
> :>  from the failed cluster member)
> :>
> :>  Client to cluster:
> :>  - The counter I really plan to use next (must be equal to or higher than
> :>  the received value)
> :>  - The counter you said you will use next
> :>

---

From: Tero Kivinen <[email-masked]>
Date: Fri, 19 Nov 2010 13:38:00 +0200

> the same peer, and one of them is strictly larger than the previous value.

Why not just take max of both counters. I.e. cluster member sends
following counters:

	- host_a_out_id = Message ID I plan to use next (i.e. last
	  message id + 1) 
	- host_a_in_id = Largest Message ID I have received from you 

Then the client has host_b_out_id (Message ID client plans to use next
(i.e. last message id + 1), and host_b_in_id (Largest message ID he
has seen from the cluster members) and will send:

	- max(host_a_out_id, host_b_in_id)
	- max(host_a_in_id, host_b_out_id)

In normal case host_a_out_id and host_b_in_id are same, but if failed
host a cluster member has sent message which never reached the client
before crash, but did reach failover cluster member in sync message
the host_a_out_id might be larger than host_b_in_id, and if failed
cluster member has done exchange with client which didn't reach the
failover cluster member then host_b_in_id might be bigger than
host_a_out_id.

The host_a_in_id should always be smaller than or equal to
host_b_out_id as host B do have authorative knowledge about the
message ID (host A might have missed some messages). If there is
failover situation in both ends (i.e both ends fail simultaneously)
then the host_b_out_id might be smaller than host_a_in_id, and sending
max value of those two will solve even that case.

Now the real question is what are we going to do with the exchanges
which are still in progress when the sync message is received, and how
do we recover when we notice that we do have missed IKE messages,
meaning we have created, rekeyed or deleted some Child SA in those
messages we lost because of failover. 
-- 
[email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Fri, 19 Nov 2010 13:51:28 +0200

> I also don't like that we'd have to guess the message id.

Missed that guess part in the original message. I do not think there
is any way to guess how many messages there was, as in normal case it
will be either 0 or 1 (there are not that many Child SA creations /
rekeys / deletions, and sane implementations do not do periodical
liveness checks).

On the other hand if we take max of the value what sender and receiver
things the mssage ID for that direction should be that will give us
value which can be used from that point on, so no need to guess. 

> skip ESP sequence numbers.

During the failover you will be skipping over the message IDs the
other end has seen, but which you do not know you have sent if we are
using the max of message ID method. 
-- 
[email-masked]

---

From: Yaron Sheffer <[email-masked]>
Date: Fri, 19 Nov 2010 13:51:24 +0200

Hi Tero,

one attractive way to deal with the hard problems is to ignore them :-)

After resynching the IKE SA, the client looks at its active Child SAs. 
If any SA is recent (say, less than 1 minute old), it initiates CCSA for 
that SA.

We could add protocol elements to query the peer regarding active SAs, 
but I don't think we want to go that way.

Thanks,
	Yaron

---

From: Yaron Sheffer <[email-masked]>
Date: Fri, 19 Nov 2010 13:59:53 +0200

Let's take the extreme case where the cluster and the peer synchronize 
the SA, then there is no IKE traffic, and then they synchronize the SA 
again. If we don't do anything special, the second pair of synch 
messages will be identical to the first, i.e. will look like a replay. 
So we have to prevent this case. One trivial solution is to mandate one 
liveness test (initiated by the peer) immediately after the synch.

Thanks,
	Yaron

---

From: Pekka Riikonen <[email-masked]>
Date: Sat, 20 Nov 2010 13:09:08 +0100 (CET)

: Why not just take max of both counters. I.e. cluster member sends
: following counters:
: 
: 	- host_a_out_id = Message ID I plan to use next (i.e. last
: 	  message id + 1) 
: 	- host_a_in_id = Largest Message ID I have received from you 
: 
: Then the client has host_b_out_id (Message ID client plans to use next
: (i.e. last message id + 1), and host_b_in_id (Largest message ID he
: has seen from the cluster members) and will send:
: 
: 	- max(host_a_out_id, host_b_in_id)
: 	- max(host_a_in_id, host_b_out_id)
: 
Isn't this what the -02 draft specifies?

...
   o  The active member dies, and a standby member takes over.  The
      standby member sends its own idea of the IKE Message IDs (both
      incoming and outgoing) to the peer in an Informational message
      exchange with Message ID zero.
   o  The peer first authenticates the message and then validates the
      failover count.  The peer compares the received values with the
      values available locally and picks the higher value.  It then
      updates its Message IDs with the higher values and also propose
      the same values in its response.
...

: Now the real question is what are we going to do with the exchanges
: which are still in progress when the sync message is received, and how
: do we recover when we notice that we do have missed IKE messages,
: meaning we have created, rekeyed or deleted some Child SA in those
: messages we lost because of failover. 
:
Draft specifies what to do here as well, at least partly.  Also note that 
you may never notice missed IKE messages because they happened in the 
failed cluster node.  Normal crash recovery takes care of any desync 
problems that may have happened.

...
   o  The peer should not wait for any pending responses while
      responding with the new Message ID values.  For example, if the
      window size is 5 and the peer's window is 3-7, and if the peer has
      sent requests 3, 4, 5, 6, 7 and received responses only for 4, 5,
      6, 7 but not for 3, then it should include the value 8 in its
      EXPECTED_SEND_REQ_MESSAGE_ID payload and should not wait for a
      response to message 3 anymore.
   o  Similarly, the peer should also not wait for pending (incoming)
      requests.  For example if the window size is 5 and the peer's
      window is 3-7 and if the peer has received requests 4, 5, 6, 7 but
      not 3, then it should send the value 8 in the
      EXPECTED_RECV_REQ_MESSAGE_ID payload, and should not expect to
      receive message 3 anymore.
...

Are the Security Considerations in the draft valid anymore at all?  And 
are the nonce and failover count needed?  Yaron wanted to eliminate these, 
and I'm all for it.

	Pekka

---

From: Pekka Riikonen <[email-masked]>
Date: Sat, 20 Nov 2010 13:14:13 +0100 (CET)

: 
: Let's take the extreme case where the cluster and the peer synchronize 
: the SA, then there is no IKE traffic, and then they synchronize the SA 
: again. If we don't do anything special, the second pair of synch 
: messages will be identical to the first, i.e. will look like a replay. 
: So we have to prevent this case. One trivial solution is to mandate one 
: liveness test (initiated by the peer) immediately after the synch.
: 
Note that draft recommends that the sync is done only when the IKE SA is 
actually needed.  If there is not IKE traffic then the sync would have 
never been done in the first place.

...
   Since there can be a large number of sessions at the standby member,
   and sending synchronization exchanges for all of them may result in
   overload, the standby member can choose to initiate the exchange in a
   "lazy" fashion: only when it has to send or receive the request.  In
   general, the standby member is free to initiate this exchange at its
   discretion.
...

I've implemented the lazy sync, it's seems the best way to do it.

	Pekka

---

From: Yaron Sheffer <[email-masked]>
Date: Sun, 21 Nov 2010 00:01:47 +0200

Hi Pekka,

the text you are quoting provides implementation guidance (probably good 
one), but does not "recommend" (in the RFC 2119 sense of the word, i.e. 
equivalent to a normative SHOULD) to do so. We should have stronger text 
if we are to avoid accidental replay.

Thanks,
	Yaron

---

From: Tero Kivinen <[email-masked]>
Date: Mon, 22 Nov 2010 17:03:09 +0200

> Isn't this what the -02 draft specifies?

Not sure, as I have not yet read the -02 draft fully.

>       the same values in its response.

This still has the failover count, which is not needed, as if we
always take the max of message IDs seen by both parties, then we
cannot go backwards, and replays etc do not matter, as we end up in
same state (i.e. if someone replays request, the other end will set
the message IDs to be the largest value seen). We still need nonce, to
know that the reply matches the request, i.e. so someone cannot replay
old reply, altough in most cases the reply would have smaller numbers
than what was in the request, in which case the sender will
immediately know something is wrong. 
-- 
[email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 23 Nov 2010 15:06:49 +0200

> problems that may have happened.

Define "normal crash recover". We did get rid of most of the crash
recovery stuff in the IKEv2 compared to IKEv1. In RFC5996 we have text
saying:

	"If connection state becomes sufficiently messed up, a node
	MAY close the IKE SA, as described above. It can then rebuild
	the SAs it needs on a clean base under a new IKE SA."

In section 1.5 we also have text saying:

   o  If an ESP or AH packet arrives with an unrecognized SPI.  This
      might be due to the receiving node having recently crashed and
      lost state, or because of some other system malfunction or attack.
...
   In the first case, if the receiving node has an active IKE SA to the
   IP address from whence the packet came, it MAY send an INVALID_SPI
   notification of the wayward packet over that IKE SA in an
   INFORMATIONAL exchange.  The Notification Data contains the SPI of
   the invalid packet.  The recipient of this notification cannot tell
   whether the SPI is for AH or ESP, but this is not important because
   the SPIs are supposed to be different for the two.  

But there is no real description what to do when we receive
INVALID_SPI message (most likely the Child SA will be deleted by
sending normal delete notification, but as the other end will not know
anything about the Child SA it will not reply this message and this
will result in half-closed Child SA, where the section 1.4.1 says:

   Half-closed ESP or AH connections are anomalous, and a node with
   auditing capability should probably audit their existence if they
   persist.  Note that this specification does not specify time periods,
   so it is up to individual endpoints to decide how long to wait.  A
   node MAY refuse to accept incoming data on half-closed connections
   but MUST NOT unilaterally close them and reuse the SPIs.

meaning even when host which did not crash sends delete for the Child
SA which is not there anymore the crashed host will not reply and the
Child SA stays in half-closed state.

The RFC 5996 solution to this is to delete the IKE SA and start over.
If we want to do something different here we need define the behavior
here. 

>       response to message 3 anymore.

This opens new attacks, because now receiving sync message with
message ID zero has also other effects than just syncing the max
message ID for future use, it also causes existing exchanges to be
destroyed.

I.e. if host A and B have done sync earlier, meaning attacker has a
copy of IKE SA Message ID sync message having message ID of zero, then
attacker can wait for host B to start few exchanges and then reply the
old sync message. If host A now immediately while processing the
request destroys old existing exchanges then this allows attackers to
delete exchanges at will.

Nonce in the Message ID sync message will not help in this case, but
the failover counter will help, as in that case the host A will reject
the replay because of the reused failover counter. 

What should host A do if it DOES receive replies for those missing
messages? 

>       receive message 3 anymore.

Again what should the peer do if it does get those messages? Ignore
them? Process them? If they are sent before the crash and were delayed
in the network, and arrived after the sync message, they were most
likely from the previous incarnation of the other end, thus most
likely they need to be ignored.

> are the nonce and failover count needed?  Yaron wanted to eliminate these, 

I think we still need both. The failover counter protects against the
attack I explained in this email (i.e. attacker replaying request),
and nonce protects against the attacks where attacker tries to replay
response message. 
-- 
[email-masked]

---

From: Pekka Riikonen <[email-masked]>
Date: Tue, 23 Nov 2010 15:41:06 +0100 (CET)

: Define "normal crash recover". We did get rid of most of the crash
: recovery stuff in the IKEv2 compared to IKEv1. In RFC5996 we have text
: saying:
: 
I was talking about INVALID_SPI notify.

: But there is no real description what to do when we receive
: INVALID_SPI message (most likely the Child SA will be deleted by
: sending normal delete notification, but as the other end will not know
: anything about the Child SA it will not reply this message and this
: will result in half-closed Child SA, where the section 1.4.1 says:
: 
I don't think sending delete notification after receiving INVALID_SPI 
(over IKE SA) is appropriate.  The other end has already told you it 
doesn't have the SA.  It should be just deleted without notification.  
Isn't this the typical thing to do?

: What should host A do if it DOES receive replies for those missing
: messages? 
: 
It can't do anything because it doesn't have any state for those 
responses.  They existed in the crashed node.  And, they are behind
the new window anyway so they are dropped.

: >    o  Similarly, the peer should also not wait for pending (incoming)
: >       requests.  For example if the window size is 5 and the peer's
: >       window is 3-7 and if the peer has received requests 4, 5, 6, 7 but
: >       not 3, then it should send the value 8 in the
:
: Again what should the peer do if it does get those messages? Ignore
: them? Process them? If they are sent before the crash and were delayed
: in the network, and arrived after the sync message, they were most
: likely from the previous incarnation of the other end, thus most
: likely they need to be ignored.
: 
Again, they are behind the new window and will be dropped.

As long as both ends follow the protocol both ends should have deleted the 
states for any pending requests and responses and moved the window, and 
any stray packets from the network should now fall behind the window and 
are simply dropped.

	Pekka

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 23 Nov 2010 17:14:45 +0200

> Isn't this the typical thing to do?

The other end is telling that he does not have incoming SPI given that
number. The peer is sending message saying he wants to delete the pair
of that SPI meaning is incoming SPI of the same Child SA pair. It is
not exactly same thing.

It could perhaps be interperted that as other end send INVALID_SPI for
his inbound SPI, then that SA is not there, so peer should not wait
for the corresponding delete with that SPI to his request to delete
his own inbound SA.

RFC5996 still says that "A node MAY refuse to accept incoming data on
half-closed connections but MUST NOT unilaterally close them and
reuse the SPIs." which quite clearly say that node who still has SA
up, cannot silently remove his inbound SPI and reuse the SPI, but must
send delete for it before reusing it.

I think correct way to handle INVALID_SPI is that consider it as same
as the other end would have sent delete for that his inbound SPI
listed in the notification, and then send corresponding delete for
your inbound SPI, which the other end will ignore as specified in the
2.25.1:

	... If a peer receives a request to close a Child SA
   that does not exist, it SHOULD reply without a Delete payload.

But anyways, as I have requested before I think we need to add text
for different cases and how to recover them. I.e. how to handle
following situations (Host B1 is the one who has lost state, Host B2
is the new instance missing some state):

1) Host A has sent CREATE_CHILD_SA and got reply to that from B1, but
   B2 does not know anything about it and host A tries to send traffic
   to that SA. 
2) Host A has sent CREATE_CHILD_SA and got reply to that from B1, but
   B2 does not know anything about it and host A tries to rekey that
   SA. 
3) Host A has sent CREATE_CHILD_SA and got reply to that from B1, but
   B2 does not know anything about it and host A tries to delete that
   SA. 
4) Host A has sent CREATE_CHILD_SA and but has not received anything
   from host B before getting sync message ID notification from B2.
5) Host A has sent Delete payload in INFORMATIONAL exchange to B1 and
   has received reply from B1, but now B2 continues sending data to
   the SA which has already been deleted.
6) Host A has sent Delete payload in INFORMATIONAL exchange to B1 but
   has not received anything from host B before getting sync message
   ID nortification from B2.
7) Host B1 has sent CREATE_CHILD_SA and got reply to that from A, but
   B2 does not know anything about it and host A tries to send traffic
   to that SA. 
8) Host B1 has sent CREATE_CHILD_SA and got reply to that from A, but
   B2 does not know anything about it and host A tries to rekey that
   SA. 
9) Host B1 has sent CREATE_CHILD_SA and got reply to that from A, but
   B2 does not know anything about it and host A tries to delete that
   SA. 
10) Host B1 has sent Delete payload in INFORMATIONAL exchange to A and
    has received reply from A, but now B2 continues sending data to
    the SA which has already been deleted.
11) Similar cases for IKE SA rekeying and deletion. 

I would expect we can create generic rules for handling most of those
cases, but I think it is important to analyze all cases (like RFC4718
and RFC5996 did, i.e. RFC4718 did analyze lots of cases, and RFC5996
includes generic rules which covers the cases analyzed in the
RFC4718). Creating those generic rules is impossible unless we really
go through what happens in each situation. 

> the new window anyway so they are dropped.

Yes, but what should it do next? If that was delete notification,
should it retry (most likely yes)? If this was IKE SA rekey
notification, then it is not supposed to send anything else than
delete for IKE SA after CREATE_CHILD_SA exchang rekeying IKE SA etc.

Those cases needs to be analyzed and checked out what is the correct
handling for them. This is timeconsuming task (I remember that Pasi
complained that when he analyzed the collision cases in the RFC4718 it
took some time) and I do not have time to do that, so I would expect
the draft to cover those cases.

> any stray packets from the network should now fall behind the window and 

Even if we are agreeing what should be done for those messages, we
need text in the document explaining those cases and how to handle
them.
-- 
[email-masked]

---

From: Yaron Sheffer <[email-masked]>
Date: Tue, 23 Nov 2010 17:14:58 +0200

Hi Tero,

to reiterate: if you ensure that the Message ID value is always strictly 
larger than in previous messages (i.e. if the failover member sends 
old_value+delta for a large enough delta, and if the peer is willing to 
accepts arbitrary jumps in the value) then both sides can protect 
against replay without requiring either the nonce or the failover 
counter. But this means that the Message ID value is *set* to a new 
value on both sides, rather than *synchronized* (to a previous value).

Thanks,
	Yaron

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 23 Nov 2010 17:19:49 +0200

> value on both sides, rather than *synchronized* (to a previous value).

Except there is no way to know the value of delta. And if you do not
know value of delta, then you open yourself to replay attacks if your
delta was too small.

Having some arbitrary delta, which is impossible to pick properly,
isn't really solving the problem, it just makes the attacks bit harder
for the attacker, but it does not remove those attacks.
-- 
[email-masked]

---

From: Yaron Sheffer <[email-masked]>
Date: Tue, 23 Nov 2010 17:28:24 +0200

It is the receiver's responsibility to protect against replays. So the 
down side is, if your delta is too low, the message you send will be 
dropped and you will have to re-establish the SA. You do not open 
yourself to a replay.

IOW, it's a matter of implementation: you need to ensure that the peers 
are synchronized well enough so that you can use a small delta (e.g. 1-2).

Thanks,
	Yaron

---

From: Pekka Riikonen <[email-masked]>
Date: Wed, 24 Nov 2010 10:36:41 +0100 (CET)

On Tue, 23 Nov 2010, Tero Kivinen wrote:
: I think correct way to handle INVALID_SPI is that consider it as same
: as the other end would have sent delete for that his inbound SPI
: listed in the notification, and then send corresponding delete for
: your inbound SPI, which the other end will ignore as specified in the
: 2.25.1:
: 
I'm not sure I agree.  I think it's reasonable to assume that if you 
receive INVALID_SPI notification instead of delete notification is that 
the remote end has crashed or there is something else terribly wrong with 
it and that it most likely doesn't have any state for the SA pair.  In 
which case sending a delete notification would be redundant.  And even if 
you are wrong and the other end has the outbound SA, you will now start 
receiving packets with unknown SPI and will eventually reply with 
INVALID_SPI.  Hence, the situation resolves itself.  The text you quote 
are from the section dealing with delete notifications.  But since the RFC 
doesn't specify what to do with INVALID_SPI I think this is a _reasonable_ 
assumption, especially since this is what is says about it:

   INFORMATIONAL exchange.

It especially mentions crashed node with sending INVALID_SPI.  I know, it 
doesn't say what to do (and it's MAY), but I think it's best to handle 
INVALID_SPI and delete notification differently.  It's unfortunate this 
was left ambiguous.

: > It can't do anything because it doesn't have any state for those 
: > responses.  They existed in the crashed node.  And, they are behind
: > the new window anyway so they are dropped.
: 
: Yes, but what should it do next? If that was delete notification,
: should it retry (most likely yes)? If this was IKE SA rekey
: notification, then it is not supposed to send anything else than
: delete for IKE SA after CREATE_CHILD_SA exchang rekeying IKE SA etc.
: 
The first thing here is that we don't know what kind of exchanges they 
were.  In a typical cluster implementation all nodes would have the full 
state, that is they have all IKE SAs and IPSEC SAs, and all nodes know 
when they expire and when rekeys need to be started.

The node should know for example that IKE SA expired during the failover 
transition and perhaps it's best to delete it instead of trying to do 
anything else with it (and send N(INITIAL_CONTACT) with possible new 
negotiation).  I'm not sure.  If the IKE SA rekey happened the sync 
protocol will fail and the IKE SA would be deleted.  The node doesn't have 
the new IKE SA either and that SA will probably get deleted too.  
Unfortunately, this all takes time to resolve.

The IPSEC SA desync problem (new SA, rekeyed, deleted) would resolve 
itself if we have consistent way of handling the INVALID_SPI.

Okay, here's my take on this:

: 1) Host A has sent CREATE_CHILD_SA and got reply to that from B1, but
:    B2 does not know anything about it and host A tries to send traffic
:    to that SA.
:
INVALID_SPI fixes (assuming we agree its handling).  Delete notification 
fixes too but will result into half-closed SA for the A's inbound SA.  The 
host A will never receive any traffic to that SA.

: 2) Host A has sent CREATE_CHILD_SA and got reply to that from B1, but
:    B2 does not know anything about it and host A tries to rekey that
:    SA.
:
So this would be case where the SA never had any traffic and is merely 
rekeyed.  This is specified in RFC 5996 section 2.25.1:

  If a peer receives a
   request to rekey a Child SA that does not exist, it SHOULD reply with
   CHILD_SA_NOT_FOUND.

I guess it should delete it.

: 3) Host A has sent CREATE_CHILD_SA and got reply to that from B1, but
:    B2 does not know anything about it and host A tries to delete that
:    SA.
:
Same section as above:

   If a peer receives a request to close a Child SA
   that does not exist, it SHOULD reply without a Delete payload.

The B2 will never send any traffic to the SA because it doesn't have it.

: 4) Host A has sent CREATE_CHILD_SA and but has not received anything
:    from host B before getting sync message ID notification from B2.
:
Covered by the draft.  It deletes the pending request.  It can retry 
later.

: 5) Host A has sent Delete payload in INFORMATIONAL exchange to B1 and 
:    has received reply from B1, but now B2 continues sending data to
:    the SA which has already been deleted.
:
INVALID_SPI fixes (assuming we agree its handling).  Delete notification 
fixes too but will result into half-closed SA for the B2's inbound SA.  
The host B2 will never receive any traffic to that SA.

: 6) Host A has sent Delete payload in INFORMATIONAL exchange to B1 but
:    has not received anything from host B before getting sync message  
:    ID nortification from B2.
:
Covered by the draft.  It deletes the pending request.  It can retry 
later.

: 7) Host B1 has sent CREATE_CHILD_SA and got reply to that from A, but
:    B2 does not know anything about it and host A tries to send traffic
:    to that SA.
:
Same as 1.

: 8) Host B1 has sent CREATE_CHILD_SA and got reply to that from A, but 
:    B2 does not know anything about it and host A tries to rekey that
:    SA.
:
Same as 2.

: 9) Host B1 has sent CREATE_CHILD_SA and got reply to that from A, but
:    B2 does not know anything about it and host A tries to delete that
:    SA.
:
Same as 3.

: 10) Host B1 has sent Delete payload in INFORMATIONAL exchange to A and
:     has received reply from A, but now B2 continues sending data to
:     the SA which has already been deleted.
:
Same as 5, different sides.

I don't see anything that prevents working connections.

	Pekka

---

From: Tero Kivinen <[email-masked]>
Date: Wed, 24 Nov 2010 13:18:24 +0200

Pekka Riikonen writes:
> it and that it most likely doesn't have any state for the SA pair.

General principle in the IKEv2 is that it is reliable protocol, and
the state should not get out of sync. If you are getting INVALID_SPI
for SA which you think is valid that means that other end is doing
something wrong (for base IKEv2 case).

The assumption in IKEv2 is that if IKE SA is working, then all the
child SAs negotiated with it are also working. If some Child SA can
only be removed by sending delete notification or by deleting whole
IKE SA. There is text in the RFC5996 explaining that in several
places, altough it is splitted around so it might not be that clear:

						  Receipt of a fresh
   cryptographically protected message on an IKE SA or any of its Child
   SAs ensures liveness of the IKE SA and all of its Child SAs.  Note
   that this places requirements on the failure modes of an IKE
   endpoint.  An implementation needs to stop sending over any SA if
   some failure prevents it from receiving on all of the associated SAs.
   If a system creates Child SAs that can fail independently from one
   another without the associated IKE SA being able to send a delete
   message, then the system MUST negotiate such Child SAs using separate
   IKE SAs.
...
					If an IKE endpoint chooses to
   delete Child SAs, it MUST send Delete payloads to the other end
   notifying it of the deletion.

Because there is no normal case where INVALID_SPI would be sent inside
the IKE SA in normal IKEv2 there is no processing rules for it in the
RFC5996. As it seems we do need processing rules for it when used in
high availability IKEv2 then that text needs to be in this document.

> In which case sending a delete notification would be redundant.

Most likely yes, but IKEv2 says you do not delete SAs without sending
delete payloads. If we want to modify IKEv2 we need to state so
explictly, not just assume people do same assumptions on the missing
text in RFC5996.

> And even if you are wrong and the other end has the outbound SA, you
> will now start receiving packets with unknown SPI and will
> eventually reply with INVALID_SPI. Hence, the situation resolves
> itself.

Most likely yes, or the other end assumes that state is messed up, and
deletes the whole IKE SA, and starts over (which is what RFC5996
suggests). 

> The text you quote are from the section dealing with delete
> notifications. But since the RFC doesn't specify what to do with
> INVALID_SPI I think this is a _reasonable_ assumption, especially
> since this is what is says about it:

It is better not to assume people do things same way unless explictly
specified, which is why I think the new high availibility protocol
needs to have text explaining these situations. I do not really care
which way the text is written as long as it is there and tells how to
handle these situations. 

> INVALID_SPI and delete notification differently.  It's unfortunate this 

Note, that the assumption here is that the unrecognized SPI here is
not negotiated over the same IKE SA over which the INVALID_SPI is
sent, thus there is no point of sending delete notifications or
anything similar over the new IKE SA we have with the peer. It is
assumed that the INVALID_SPI for SPI x belonging to the old IKE SA
will most likely trigger liveness check on that old IKE SA, which will
then fail as the other end has rebooted and that will cause old IKE SA
and the Child SAs being deleted.

IKEv2 do assume that if IKE SA is up, then all Child SAs are also up,
unless explictly deleted.

The text above does not even try to cover high availibility cases, as
they were outside the scope of original IKEv2 (and IKEv2bis) work. 

> were.

The one who is throwing away the exchanges he is trying to do, does
know what those are. If the exchanges are already finished then there
is no way to know what they were, and whether they were processed by
the other end or whether they were transferred to the fall back pair. 

> Okay, here's my take on this:

That is good start, but it should be put to the draft to be useful.

> host A will never receive any traffic to that SA.

I agree on that. Adding text for INVALID_SPI handling would most
likely be best. 

> I guess it should delete it.

Yes, I think this is actually covered by the 2.25 and 2.25.1. 2.25
says it even better and says you delete the Child SA:

   A CHILD_SA_NOT_FOUND notification SHOULD be sent when a peer receives
   a request to rekey a Child SA that does not exist.  The SA that the
   initiator attempted to rekey is indicated by the SPI field in the
   Notify payload, which is copied from the SPI field in the REKEY_SA
   notification.  A peer that receives a CHILD_SA_NOT_FOUND notification
   SHOULD silently delete the Child SA (if it still exists) and send a
   request to create a new Child SA from scratch (if the Child SA does
   not yet exist).

> The B2 will never send any traffic to the SA because it doesn't have it.

But this will leave A with half-closed SAs. The text in 2.25.1 assumes
that the other pair of the SA was deleted because of the exchange
collisions, so it does not need to care about the half-closed SAs as
there will not be such in that situation. 

> I don't see anything that prevents working connections.

But in some cases there is leftover half-closed SAs which by IKEv2 the
other end cannot delete without deleting the whole IKE SA. We might
need some way to resolve those.
-- 
[email-masked]

---

From: Yoav Nir <[email-masked]>
Date: Wed, 24 Nov 2010 13:24:49 +0200

As a general principle, yes. But the HA extension already assumes that due to the failover, there is some discrepancy. The easy way out would be to write a protocol extension that just detects this discrepancy and kills the IKE SA. But that would mean a lot of IKE SA setups following a fail-over.

So in the context of the HA extension, we are willing to live with some unsynchronized state, and try to let it take care of itself.  So the question is, if the peer already does not have the IPsec SA, does it add any information for us to send it a DELETE?

Yoav

---

From: Tero Kivinen <[email-masked]>
Date: Wed, 24 Nov 2010 13:57:13 +0200

Yoav Nir writes:
> As a general principle, yes. But the HA extension already assumes
> that due to the failover, there is some discrepancy. The easy way
> out would be to write a protocol extension that just detects this
> discrepancy and kills the IKE SA. But that would mean a lot of IKE
> SA setups following a fail-over. 

I do not think we need such protocol. 

> So in the context of the HA extension, we are willing to live with
> some unsynchronized state, and try to let it take care of itself.

I agree on first step, but I would rather like to see some text
explaining how they are taken care of. I do not think we can assume
the "problem takes care of itself". 

> So the question is, if the peer already does not have the IPsec SA,
> does it add any information for us to send it a DELETE? 

In IKEv2 context it is mandatory, but in high availability IKEv2
context we can specify whatever we want, but we need to specify what
we want. 
-- 
[email-masked]

---

From: Dacheng Zhang <[email-masked]>
Date: Thu, 25 Nov 2010 18:00:25 +0800

>> for the attacker, but it does not remove those attacks.
[Dacheng Zhang] 
Maybe a client can find the largest counter value in the associated child
SAs and use it as the delta value. Although this approach is not
sophisticated, it can prevent the client selects a delta value which is not
big enough. ^_^

--Dacheng

---

From: Yaron Sheffer <[email-masked]>
Date: Thu, 25 Nov 2010 12:56:45 +0200

Hi Dacheng,

I must be missing something: this discussion was about IKE SA counters 
(Message ID). I don't see how they can be inferred from Child SA replay 
counters. The traffic rates are too different.

Thanks,
	Yaron

---

From: Pekka Riikonen <[email-masked]>
Date: Mon, 29 Nov 2010 07:36:18 +0100 (CET)

: > The text you quote are from the section dealing with delete
: > notifications. But since the RFC doesn't specify what to do with
: > INVALID_SPI I think this is a _reasonable_ assumption, especially
: > since this is what is says about it:
: 
: It is better not to assume people do things same way unless explictly
: specified, which is why I think the new high availibility protocol
: needs to have text explaining these situations. I do not really care
: which way the text is written as long as it is there and tells how to
: handle these situations. 
: 
I agree, we want the text to the draft.

: > :    B2 does not know anything about it and host A tries to send traffic
: > :    to that SA.
: > :
: > INVALID_SPI fixes (assuming we agree its handling).  Delete notification 
: > fixes too but will result into half-closed SA for the A's inbound SA.  The 
: > host A will never receive any traffic to that SA.
: 
: I agree on that. Adding text for INVALID_SPI handling would most
: likely be best. 
: 
Good, I agree on that too, INVALID_SPI is best way to go.

: > I don't see anything that prevents working connections.
: 
: But in some cases there is leftover half-closed SAs which by IKEv2 the
: other end cannot delete without deleting the whole IKE SA. We might
: need some way to resolve those.
:
Yeah, one or two cases may lead to this.  I guess it wouldn't be so 
terrible to do what RFC says and just delete the IKE SA in these cases.

	Pekka