Subject: Re: [IPsec] Ticket #74: Extend IKE_SA_INIT instead of new exchange type

From: Paul Hoffman <[email-masked]>
Date: Mon, 16 Feb 2009 16:35:57 -0800

At 12:48 PM -0800 1/25/09, Paul Hoffman wrote:
>Yes, definitely. At this point, we have heard from two groups of authors; hearing from the wider implementers community would be valuable.

We still have not heard from many.

During the interim meeting, a good question was raised: are we making this decision based on implementation desires vs. protocol cleanliness vs. deployment ability. We don't have enough input at this point to pick between those.

So, let me get this thread going again. If you have an opinion about the core issue of how session resumption is done (extend the IKE_SA_INIT or create a new exchange type), please state it again and say what draws you to this conclusion. This is *not* a vote: it is a request to get the discussion going with some hopefully better metrics.

--Paul Hoffman, Director
--VPN Consortium

---

From: Yoav Nir <[email-masked]>
Date: Tue, 17 Feb 2009 12:03:32 +0200

Hi all.

Section 2.8.1 of the draft discusses what to do when Child SAs are rekeyed simultaneously by both peers. Issue #22 asks to clarify the same thing for simultaneous rekeying of IKE SAs.

We've written a proposed additional section, that should be labeled 2.8.2. Since this specifies new behavior that was not specified before, we want your comments before putting this into the draft.

Thanks

Yoav

2.8.2.  Simultaneous IKE SA rekeying

   If the two ends have the same key lifetime policies for IKE SAs, it
   is possible that both will initiate a rekeying at the same time.
   This is unacceptable for IKE SAs, because the IKE SAs own the child
   SAs, and deleting the IKE SA leeds to deletion of all child SAs.  To
   reduce the probability of this happening, the timing of rekeying
   requests SHOULD be jittered (delayed by a random amount of time after
   the need for rekeying is noticed).

   To avoid the case of two IKE SAs created by simultaneous
   CREATE_CHILD_SA exchanges, the IKE SA with the lowest of the
   initiator nonces is silently discarded, and the dependent child SAs
   are transferred only to the IKE SA with the higher of the two
   initiator nonces.  Here "higher" and "lower" refer to octet-by-octet,
   lexicographical comparison of the nonces as large integers.

   The rules are as follows:
   1.  If a rekey request is received before this host has sent a rekey
       request of its own, this host MUST NOT send a rekey request.
       Instead, it MUST reply to the rekey request it has received.
   2.  If a rekey request is received after this host has sent a rekey
       request, then this host MUST compare the two initiator nonce
       values.  If the received nonce is higher than its own, it MUST
       reply to the received request, and SHOULD stop retransmissions of
       its own request.  If the received nonce is lower, it MUST ignore
       the received request.
   3.  If a rekey request is received after this host has sent a rekey
       request, and the peer has already replied, the new received
       request MUST be ignored.

   Following these rules should prevent any case of multiple successful
   rekeys of an IKE SA.  The only case where the 2nd rule would be
   needed is if both requests were sent before either of them was
   processed.  The implementation whose rekey request was answered
   SHOULD delete the old IKE SA soon after.  The other implementation
   SHOULD wait at least one minute before deleting the IKE SA unless its
   peer requests the deletion earlier.

   The following is an explanation of the impact this has on
   implementations.  Assume that hosts A and B have an existing IKE SA,
   and both start rekeying it at the same time:

      Host A                            Host B
      -----------------------------------------------------------------
      send req1: SK{SA, Ni1, [KEi]}
                                  -->
                                   <--  send req2: SK{SA, Ni2, [KEi]}
      recv req2 <--

   At this point, host A knows there is a simultaneous rekeying going
   on.  Assume that Ni2<Ni1.  A knows that req1 is the one to answer, so
   it ignores req2.

                                   -->  recv req1

   Now host B also knows that simultaneous rekeying is going on.  It has
   also figured out that req1 is the one to respond to, so it does so.

                                  <--  send resp1: SK {SA, Nr,[KEr]}
      recv resp1 <--

   Now let's look at the other case, namely where Ni1<Ni2.

      Host A                            Host B
      -----------------------------------------------------------------
      send req1: SK{SA, Ni1, [KEi]}
                                  -->
                                   <--  send req2: SK{SA, Ni2, [KEi]}
      recv req2 <--

   Host A knows that req1 is the one to ignore, because req2 has a
   higher nonce.  It replies to req2, and will not re-transmit req1.

      send resp2: SK {SA, Nr,[KEr]}
                                   -->  recv req1

   Now host B is in exactly the same position as host A was in the first
   example.  It compares nonces, and ignores req1.

                                   -->  recv resp2

   Host B now knows that the rekey is complete.

   To demonstrate the third rule, let's assume again that Ni1<Ni2, but
   that the sequence of messages is as follows:

      Host A                            Host B
      -----------------------------------------------------------------
      send req1: SK{SA, Ni1, [KEi]}
                                  -->
                                   <--  send req2: SK{SA, Ni2, [KEi]}
      recv req2 <--
                                   -->  recv resp2

   Now host B knows nothing about req1, and assumes that its rekey
   request was the only one.  Host A, however, is aware of the
   simultaneous rekey, and has decided that only req2 is to proceed.

                                   -->  recv req1

   Host B now knows about req1, but since it has already received a
   response, it ignores req1.  There is no need to compare nonces.

Email secured by Check Point

---

From: David Wierbowski <[email-masked]>
Date: Tue, 17 Feb 2009 09:58:24 -0500

I do not believe the algorithm below is consistent with what was said in
section 5.11.4 of RFC 4718.  Section 5.11.4 of RFC 4718 said:

5.11.4.  Simultaneous IKE_SA Rekeying

   Probably the most complex case occurs when both peers try to rekey
   the IKE_SA at the same time.  Basically, the text in Section 2.8
   applies to this case as well; however, it is important to ensure that
   the CHILD_SAs are inherited by the right IKE_SA.

   The case where both endpoints notice the simultaneous rekeying works
   the same way as with CHILD_SAs.  After the CREATE_CHILD_SA exchanges,
   three IKE_SAs exist between A and B; the one containing the lowest
   nonce inherits the CHILD_SAs.

"After the CREATE_CHILD_SA exchanges" implies the exchanges are expected to
complete before the simultaneous rekey is resolved.  The algorithm below
resolves the simultaneous rekey during the CREATE_CHILD_SA exchange and
only allows one rekey to complete.  My concern is that the algorithm below
will be incompatible with anybody that implemented to RFC 4718.

A slight  tangent to this is that the possibility of a simultaneous
reauthentication exists, however, RFC 4306, RFC 4718, and the current bis
draft does not address that scenario.  Given that the a reauthentication is
done by creating a new IKE_SA from scratch I'm not even sure if it is
possible to detect a simultaneous reauthentication of an IKE_SA, but it
would be nice if we could.

             Yoav Nir                                                      
             <ynir@checkpoint.                                             
             com>                                                       To 
             Sent by:                  "[email-masked]" <[email-masked]>   
             ipsec-bounces@iet                                          cc 
             f.org                                                         
                                                                   Subject 
                                       [IPsec] Issue #22: simultaneous IKE 
             02/17/2009 05:03          SA rekeys                           
             AM                                                            

Hi all.

Section 2.8.1 of the draft discusses what to do when Child SAs are rekeyed
simultaneously by both peers. Issue #22 asks to clarify the same thing for
simultaneous rekeying of IKE SAs.

We've written a proposed additional section, that should be labeled 2.8.2.
Since this specifies new behavior that was not specified before, we want
your comments before putting this into the draft.

Thanks

Yoav

      Host A                            Host B

                                   -->  recv req1

      Host A                            Host B

                                   -->  recv resp2

      Host A                            Host B

                                   -->  recv req1

Email secured by Check Point
_______________________________________________
IPsec mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/ipsec

---

From: Tero Kivinen <[email-masked]>
Date: Wed, 18 Feb 2009 15:25:37 +0200

Paul Hoffman writes:
> >Yes, definitely. At this point, we have heard from two groups of
> authors; hearing from the wider implementers community would be
> valuable. 
> 
> During the interim meeting, a good question was raised: are we
> making this decision based on implementation desires vs. protocol
> cleanliness vs. deployment ability. We don't have enough input at
> this point to pick between those. 
> 
> So, let me get this thread going again. If you have an opinion about
> the core issue of how session resumption is done (extend the
> IKE_SA_INIT or create a new exchange type), please state it again
> and say what draws you to this conclusion. This is *not* a vote: it
> is a request to get the discussion going with some hopefully better
> metrics. 

I suggest keeping it as separate new exchange type.

That should be cleaner from protocol point of view (keep separate
options separate, do not create master jumbo super hyper exchange
doing everything).

That should also be easier to implement as it can be added as modular
addition to the existing implementation, without breaking existing
functionality. 

The resulting code should be simplier than modifying already complex
code.

One of the things that do require modification of the existing code is
this exchange will change the very basic current practice of the
IKEv2, where the packet is either completely unencryptede or it is
completely encrypted. With this new exchange some payloads are in
clear and some are encrypted. This most likely will cause changes to
the packet parsing and encoding routines. This is not affected by the
fact whether we use separate exchange or change IKE_SA_INIT.

Note, that this text in the ticket is wrong: "More efficient protocol
of the responder *does not* implement this extension".

If the initiator has ticket then it KNOWS that responder do support
this extension (as otherwise responder would not have sent him
ticket). Using IKE_SA_INIT offers a bit more efficient protocol in
case the ticket initiator is using has already expired, and initiator
needs to fall back to full exchange.

If any IKE_SA_INIT packet containing any encrypted payloads is sent to
implementation which do not support this extensions, all those packets
will be silently ignored. This does not offer initiator an option to
try to use ticket with parties it does not know whether they support
this extension or not.

So for my point of view:

Using separate exchange is simplier, easier and cleaner way to do it.

Modifying IKE_SA_INIT optimizies very rare event when the ticket has
already been expired by the responder when initiator tries to use, and
saves one round trip times for those cases. The implementations will
be more complex, and will most likely contain more errors.

I do like the unix tools principle, i.e. make small tools (cat, grep,
head, tail etc) that do the work they are designed to and then combine
them for more complex things. Here I would like to have one more new
clean tool (new IKE_SESSION_RESUME exchange) instead of tweaking
existing tool (IKE_SA_INIT) to do yet another thing.
-- 
[email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Wed, 18 Feb 2009 16:11:56 +0200

>    This is unacceptable for IKE SAs, because the IKE SAs own the child
	     ^^^^^^^^^^^^

It is not unacceptable to initiate rekeying at the same time. It can
and will happen. What is unacceptable is that we get two IKE SAs and
parties do not agree on which one is the one that should be used, and
to which one the Child SAs are moved to.

>    CREATE_CHILD_SA exchanges, the IKE SA with the lowest of the

Again we cannot avoid the case where they start CREATE_CHILD_SA
exchange simultaneously. We can only give rules how to solve this.

>    lexicographical comparison of the nonces as large integers.

This is completely unacceptable. Firstly it is not following the rules
already in the RFC4306 which cleary says that both IKE SAs are created
as normally, and then the one follow the rule: "the SA created with
the lowest of the four nonces used in the two exchanges SHOULD be
closed by the endpoint that created it."

With IKE SAs this just requires that both ends need to agree that
child SAs are always moved to the other IKE SA.

We already do implement this rule specified in the RFC4306 for IKE
SAs, we do not care about the simultaneous CHILD_SA/IPsec SA rekeys as
they do not really cause problems (there will be duplicate
CHILD_SAs/IPsec SAs but everything still works).

Anyways we cannot "silently discard" any IKE SA packets, IKE SA basic
principle is to provide request/reply exchages, thus there must be
reply, as otherwise the other end will tear down the IKE SA. 

>        request, and the peer has already replied, the new received

This will be major change to the existing RFC4306 behavior. Especially
is it violates the basic IKEv2 exchange principles. I thing doing this
is really bad idea.

It requires quite big changes to all over the code (i.e. ability to
get messages back from the retransmit and window processing queue),
and so on.

The current code we have already implemented, and which works (I only
use the example where all request packets from responder are lost for
duration of the initiators exchnage as that covers all possible
cases):

    Host A                           Host B
   ------------                  ----------------
   # Start rekey		 # Start rekey
   HDR, SK{SA(SPIa1), Ni1, KEi1} --->

		      X <--- HDR, SK{SA(SPIb2), Ni2, KEi2}
                This is dropped

				# B receives A's requst
				# It knows there is simultaneous
				# rekey, but it will not yet
				# know A's reply nonce, so cannot
				# do anything. It ties both
				# rekeyed SAs together and to old IKE
				# SA, and replies normaly
			<--- HDR, SK{SA(SPIb1), Nr1, KEr1}

   # A receives B's reply, but it
   # still does not know there
   # is simultaneous rekey as
   # it has not seen B's
   # request yet.
   # It processes request
   # normally, creates new IKE SA1
   # and moves Child SAs from old
   # IKE SA to this IKE SA1.
   # It starts timer that will
   # delete old IKE SA after a
   # while (60 seconds or so)
   # It will still tie
   # old IKE SA and new IKE SA1
   # together.

				# B retransmits and A gets the request 
		        <--- HDR, SK{SA(SPIb2), Ni2, KEi2}

   # Now A notices there was
   # Simultaneous rekey
   # It will process the request
   # normally and create new IKE SA2
   # and send reply back
   HDR, SK{SA(SPIa2), Nr2, KEr2} --->

   # A knows there was		# B already knows there was 
   # simultaneous rekey		# simultaneous rekey so it
   # so it starts to handle	# finishes the IKE SA2
   # the case. It has already	# and starts to handle 
   # tied the old IKE SA and	# the case. It also has
   # IKE SA1 togther, and now	# old IKE SA and both 
   # it adds IKE SA2 there, and	# new IKE SAs tied together
   # compares the Nonces (Ni1,	# so it will do the same thing
   # Ni2, Nr1, Nr2) and finds	# as A does, i.e. checks 
   # the lowest one of them.	# which one of new IKE SAs
   # If it was one if his	# survived, and moves
   # then it starts timer	# all child SAs from 
   # to close that SA after	# loosing IKE SA to the
   # timeout. In any case	# surviving one. 
   # it makes sure all		# If it was the one 
   # child SAs of that		# creating the loosing one
   # losing IKE SA is moved	# it will start 
   # to the surviving IKE SA.	# timer to delete it.

   # Lets say IKE SA1 lost, so
   # A will delete it after some
   # timeout (60 seconds or so
   # to make sure other end has
   # received all packets)

   HDR(IKE SA1), SK{D} --->

		       		# B deletes IKE SA 1, which
				# is already empty, and
				# sends reply

			<--- HDR(IKE SA1), SK{}

   # Either end can delete the old IKE SA (normally it is done
   # by the host who started rekey, but as both here started
   # it either end can delete it). Lets assume here that
   # A's timer expires first (most likely as it started it before it
   # even knew B has started rekey), so A will send delete for that SA
   # too.

   HDR(old IKE SA), SK{D} --->

		       		# B deletes old IKE SA, which
				# is already empty, and
				# sends reply

			<--- HDR(old IKE SA), SK{}

This is what we have in our implementation and this is also what is
described in the RFC4306. As RFC4306 only says this very briefly and
bit vague terms (i.e. just refers to SA, not separting Child SAs and
IKE SAs), this requires more text to the bis document, but I do not
think we want to completely change the behavior of the protocol in
this exeptional case.  Especially we do not want to break IKEv2 rules
where (from section 1 Introduction):

  - All IKE communications consist of pairs of messages:
    a request and a response.  

  - IKE message flow always consists of a request followed by a
    response. It is the responsibility of the requester to ensure
    reliability. If the response is not received within a timeout
    interval, the requester needs to retransmit the request (or
    abandon the connection)

For example I do not have any idea what happens to the message IDs of
the old IKE SA in your case, i.e. if request is pulled back, is the
message ID still incremented, and if request is silently ignored is
that message id still marked as used in the window etc. What if we
sent first IKE SA rekey and then another message (i.e using window
size > 1), now if we pupp back that IKE SA rekey request, do we reuse
the empty slot we have in window. If we do not have any other exchange
we want to send do we fill it with some junk exchange. Also for
example mobike do assume that message IDs are used in order, i.e.
message ID n must be sent AFTER message ID n-1, i.e. address update in
message ID n-1 can be safely ignored when address update in message ID
n is seen, as message ID n is newer than message ID n-1, thus refers
to the latest situation. 
-- 
[email-masked]