<?xml version="1.0" encoding="UTF-8"?>

<rfc category="std" submissionType="IETF" ipr="trust200902" docName="draft-smyslov-ipsecme-ikev2-cookie-revised-05">

<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>

<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="no"?>
<?rfc iprnotified="no" ?>
<?rfc strict="yes" ?>

    <front>
        <title abbrev="Revised Cookie Processing in IKEv2">Revised Cookie Processing in the IKEv2 Protocol</title>
        <author initials='V.' surname="Smyslov" fullname='Valery Smyslov'>
            <organization>ELVIS-PLUS</organization>
            <address>
                <postal>
                    <street>PO Box 81</street>
                    <city>Moscow (Zelenograd)</city>
                    <code>124460</code>
                    <country>RU</country>
                </postal>
                <phone>+7 495 276 0211</phone>
                <email>svan@elvis.ru</email>
            </address>
        </author>
        <date/>

        <!--
        <keyword></keyword>
        -->

        <abstract>
          <t> This document defines a revised processing of cookies in the Internet Key Exchange protocol Version 2 (IKEv2).
          It is intended to solve a problem in IKEv2 when due to packets loss and reordering
          peers may erroneously fail to authenticate each other when cookies are used in the initial IKEv2 exchange.
          </t>
        </abstract>
    </front>

    <middle>
        <section title="Introduction">
          <t> The Internet Key Exchange protocol Version 2 (IKEv2) described in <xref target="RFC7296" />
          includes mechanism to defend against DoS attacks. The mechanism is based on cookie which
          a responder can request an initiator to return in a subsequent request. This allows
          the responder to avoid creating state until it is sure that the initiator's IP address is not spoofed. 
          The cookie mechanism is optional and it is up to the responder whether to use it or not.
          </t>

          <t> When the cookie mechanism is used in networks with high probability of packets loss and/or reordering, 
          it is possible that peers end up with different views on whether cookies were used or not or
          which content the used cookie had. Since cookie, if used, is a part of an IKEv2 message that is 
          included into calculation of authentication data by both peers, the different views 
          leads to the situation when peers erroneously fail to authenticate each other.
          </t>

          <t> This specification revises processing of cookies in IKEv2 in such a way that peers
          supporting it exclude cookies from the data to be authenticated. This allows them to 
          complete authentication even in the situation described above.
          </t>
        </section>

        <section anchor="mustshouldmay" title="Terminology and Notation">
            <t> The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", 
            "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted 
            as described in BCP 14 <xref target="RFC2119" /> <xref target="RFC8174" /> when, and only when, 
            they appear in all capitals, as shown here.
            </t>
        </section>

        <section anchor="cookie" title="Using Cookies in IKEv2">
          <t> Section 2.6 of <xref target="RFC7296" /> specifies that when a responder 
          detects a large number of half-open IKE SAs, it SHOULD reply to an IKE_SA_INIT request 
          with a response containing the COOKIE notification and If an IKE_SA_INIT response
          includes the COOKIE notification, the initiator MUST then retry the IKE_SA_INIT request, 
          including the received COOKIE notification as the very first payload in it and
          retaining all other payloads intact. This process is illustrated in <xref target="fig-cookie" />.

            <figure anchor="fig-cookie" align="center">
              <artwork align="left"><![CDATA[
 Initiator                             Responder
-----------                           -----------
send req1:
HDR, SAi1, KEi, Ni        -->         recv req1, send resp1:
                          <--         HDR, N(COOKIE,c)
recv resp1, send req2:
HDR, N(COOKIE,c),
     SAi1, KEi, Ni        -->         recv req2, send resp2:
                          <--         HDR, SAr1, KEr, Nr
recv resp2
            ]]></artwork>
            </figure>

          Note, that the responder creates no state when it sends message resp1.
          This is achieved due to the way cookies are generated. A good way to generate 
          a cookie is described in Section 2.6 of <xref target="RFC7296" />:

            <figure align="center">
              <artwork align="left"><![CDATA[
Cookie = <VersionIDofSecret> | Hash(Ni | IPi | SPIi | <secret>)
            ]]></artwork>
            </figure>

          where &lt;secret&gt; is a randomly generated secret known only to the
          responder which is periodically changed. <xref target="RFC7296" />
          advises the responder to change the value of &lt;secret&gt; frequently, especially
          if under attack.
          </t>

          <t> Later in the IKE_AUTH exchange the IKE_SA_INIT messages are authenticated
          by including their content intact into the data that is signed (or MAC'ed) 
          using peers' credentials (see Section 2.15 of <xref target="RFC7296" /> for details).
          </t>
        </section>

        <section anchor="problem" title="Problem Description">
          <t> To successfully complete authentication it is important that both peers
          use the same content of the IKE_SA_INIT messages when calculating authentication data.
          However, when cookies are employed, the IKE_SA_INIT request is sent at least twice 
          with different content. Section 2.15. of <xref target="RFC7296" /> states that if the
          first message of the IKE_SA_INIT exchange is sent multiple times with different content 
          (e.g. with a cookie), it is the latest version of the message that is used for authentication.
          However, in situations when network packets can be lost and/or reordered, peers
          may end up with different views on what is "the latest version of the message".
          Two examples of such situations are shown below.
          </t>

          <t> Consider a situation when at the time the initiator starts creating IKE SA by sending req1 message
          the responder thinks it's under attack and responds with a resp2 message containing cookie request.
          However, this message is delayed in the network.

            <figure align="center">
              <artwork align="left"><![CDATA[
Initiator                             Responder
-----------                           -----------
send req1:
HDR, SAi1, KEi, Ni        -->         recv req1, send resp1:
 (delayed)                <--         HDR, N(COOKIE,c)
            ]]></artwork>
            </figure>

          Since the initiator hasn't received any response, it retransmits the initial request message 
          req1 after some time. During this time the situation on the responder has changed and it 
          doesn't think it's under attack anymore, so it responds with resp2 message and considers 
          the IKE_SA_INIT exchange completed. This message is also delayed in the network.

            <figure align="center">
              <artwork align="left"><![CDATA[
Initiator                             Responder
-----------                           -----------
re-send req1:
HDR, SAi1, KEi, Ni        -->         recv req1, send resp2:
 (delayed)                <--         HDR, SAr1, KEr, Nr
            ]]></artwork>
            </figure>

          After some time the initiator eventually receives the first initiator's response resp1,
          which contains cookie request. It is the first response the initiator receives
          from the responder, so it re-sends the request adding the received cookie into it (req2). However,
          this message is lost and never reaches the responder. Shortly after sending req2
          the initiator receives resp2 message.

            <figure align="center">
              <artwork align="left"><![CDATA[
Initiator                             Responder
-----------                           -----------
recv resp1, send req2:
HDR, N(COOKIE,c),
     SAi1, KEi, Ni        -->          (lost)
recv resp2
            ]]></artwork>
            </figure>

          At this point both peers have completed the IKE_SA_INIT exchange and the KE_AUTH exchange is ready to start. 
          However, the peers have different opinions on what the latest IKE_SA_INIT request message was - 
          the initiator thinks it was req2, while the responder thinks it was req1. As a result - 
          the authentication in the IKE_AUTH exchange will fail.
          </t>

          <t> Let's consider another possible sequence, that leads to the same result.
          As with the previous example the initiator starts creating IKE SA by sending req1 message.
          The responder thinks it's under attack and responds with a resp1 message containing cookie request with cookie c1.
          However, this message is delayed in the network.

            <figure align="center">
              <artwork align="left"><![CDATA[
Initiator                             Responder
-----------                           -----------
send req1:
HDR, SAi1, KEi, Ni        -->         recv req1, send resp1:
 (delayed)                <--         HDR, N(COOKIE, c1)
            ]]></artwork>
            </figure>

          As with the first example, the initiator hasn't received any response and retransmits its initial request message 
          req1 after some time. It happens that within this time the value of &lt;secret&gt; has changed
          (note, that <xref target="RFC7296" /> advises to do it frequently, especially when under attack).
          Since the responder cannot verify cookie c1 and it still thinks it is under attack, it
          acts as if req1 contains no cookie and sends back resp2 message also containing cookie request, with a new cookie c2
          (that was calculated using the same input data and the new value of &lt;secret&gt;).

            <figure align="center">
              <artwork align="left"><![CDATA[
Initiator                             Responder
-----------                           -----------
re-send req1: 
HDR, SAi1, KEi, Ni        -->         recv req1, send resp2:
                          <--         HDR, N(COOKIE, c2)
            ]]></artwork>
            </figure>

          This message is not delayed, it reaches the initiator and the initiator sends
          a new request req2 containing cookie c2. The responder receives this message
          and successfully verifies the cookie using its current value of &lt;secret&gt;.
          Since the cookie verification is successfull, the responder sends back 
          resp3 message and considers the IKE_SA_INIT exchange completed. 
          However, resp3 message is delayed.

            <figure align="center">
              <artwork align="left"><![CDATA[
Initiator                             Responder
-----------                           -----------
recv resp2, send req2:
HDR, N(COOKIE, c2),
     SAi1, KEi, Ni        -->         recv req2, send resp3:
 (delayed)                <--         HDR, SAr1, KEr, Nr
            ]]></artwork>
            </figure>

          After some time the initiator eventually receives resp1 message, which was delayed.
          This message contains another value of cookie - c1. Since this message was received
          later than resp2 message, the initiator thinks the value c1 is fresher than c2
          and sends a new request message req3 now with c1 cookie. This message is lost 
          in the network and never reaches the responder. Shortly after sending req3
          the initiator receives resp3 message.

            <figure align="center">
              <artwork align="left"><![CDATA[
Initiator                             Responder
-----------                           -----------
recv resp1, send req3:
HDR, N(COOKIE, c1),
     SAi1, KEi, Ni        -->          (lost)
recv resp3
            ]]></artwork>
            </figure>
    
          As with the first example, at this point both peers have completed the IKE_SA_INIT exchange and are ready for the KE_AUTH exchange. 
          However, the peers again have different opinions on what the latest IKE_SA_INIT request message was - 
          the initiator thinks it was req3, while the responder thinks it was req2. As a result - 
          the authentication in the IKE_AUTH exchange will fail as with the previous example.
          </t>

          <t> The root of this problem is that the initial request can be re-sent several times with different content
          depending on the responder's current state, which can change over time. Note, that this situation is generally
          not possible with the INVALID_KE_PAYLOAD notification, even that in this case the request is also sent several times. 
          This is because the responder will always either require changing Key Exchange method or not, so it is not possible 
          that eventually peers end up with different opinions on what Key Exchange method was negotiated in the IKE_SA_INIT exchange.
          </t>
        </section>

        <section anchor="protocol" title="Revised Cookie Processing">
          <t> This specification proposes to solve the problem by excluding cookie content from data to be authenticated.
          The rationale for this is that cookie must be verified by the responder independently at the time it is received 
          in the IKE_SA_INIT request, so there is no need to authenticate it.
          </t>

          <section anchor="protocol-negotiation" title="Negotiation of Revised Cookie Processing">
            <t> For the purpose of using revised cookie processing a new Status Type notify REVISED_COOKIE is defined.
            Its Notify Message Type is &lt;TBA by IANA&gt;, Protocol ID and SPI Size are both set to 0.
            The responder includes an empty REVISED_COOKIE notification whenever it sends a response containing COOKIE notification.
            If the initiator doesn't support this extension it will ignore this notification and continues as described in <xref target="RFC7296" />.
            In case the initiator supports revised cookie processing it will re-send its initial request including
            the received cookie, but placing the cookie data into the REVISED_COOKIE notification instead of COOKIE notification.

              <figure anchor="fig-revised-cookie" align="center">
                <artwork align="left"><![CDATA[
Initiator                             Responder
-----------                           -----------
send req1:
HDR, SAi1, KEi, Ni        -->         recv req1, send resp1:
                                      HDR, N(COOKIE,c), 
                          <--              N(REVISED_COOKIE)
recv resp1, send req2:
HDR, N(REVISED_COOKIE,c),
     SAi1, KEi, Ni        -->         recv req2, send resp2:
                          <--         HDR, SAr1, KEr, Nr
recv resp2
              ]]></artwork>
              </figure>

            </t>
          </section>

          <section anchor="protocol-cookie-process" title="Processing of REVISED_COOKIE Notification">
            <t> If the responder has sent the REVISED_COOKIE notification in the message requesting cookie it should be prepared to receive 
            the re-sent IKE_SA_INIT request with the REVISED_COOKIE notification containing the cookie and with no COOKIE notification.
            Processing of the REVISED_COOKIE notification by the responder MUST be identical to the processing of 
            COOKIE notification which is described in Sections 2.6 and 2.7 of <xref target="RFC7296" />.
            </t>
          </section>

          <section anchor="protocol-auth" title="Changes in AUTH Payload Calculation">
            <t> In the subsequent IKE_AUTH exchange peers authenticate each other by signing (or MAC'ing)
            blobs of data. These blobs are defined in Section 2.15 of <xref target="RFC7296" />.
            In particular, initiator's blob is defined as follows:

              <figure anchor="fig-auth" align="center">
                <artwork align="left"><![CDATA[
InitiatorSignedOctets = RealMessage1 | NonceRData | MACedIDForI
GenIKEHDR = [ four octets 0 if using port 4500 ] | RealIKEHDR
RealIKEHDR =  SPIi | SPIr |  . . . | Length
RealMessage1 = RealIKEHDR | RestOfMessage1
NonceRPayload = PayloadHeader | NonceRData
InitiatorIDPayload = PayloadHeader | RestOfInitIDPayload
RestOfInitIDPayload = IDType | RESERVED | InitIDData
MACedIDForI = prf(SK_pi, RestOfInitIDPayload)
                 ]]></artwork>
              </figure>

            In <xref target="fig-auth" /> RealMessage1 is the latest version of the IKE_SA_INIT request message.
            </t>

            <t> If the very first payload in RealMessage1 is the REVISED_COOKIE notify, then InitiatorSignedOctets
            are computed as shown in <xref target="fig-revised-auth" />. In particular:
            <list style="numbers">
              <t>The content of the REVISED_COOKIE notify payload is eliminated from the message;</t>
              <t>The Next Payload field in the IKE Header is set to the value of the Next Payload field in the header of eliminated payload;</t>
              <t>The length of the eliminated payload (indicated in the Length field in its header) is subtracted from the Length field in the IKE Header.</t>
            </list>

    <figure anchor="fig-revised-auth" align="center">
      <artwork align="left"><![CDATA[
InitiatorSignedOctets = PseudoMessage1 | NonceRData | MACedIDForI
RealMessage1 = RealIKEHDR | NotifyREVISED_COOKIE | RestOfMessage1
NotifyREVISED_COOKIE = NextPld | 0 | PldLength | RestOfNotifyCOOKIE
GenIKEHDR = [ four octets 0 if using port 4500 ] | RealIKEHDR
RealIKEHDR = SPIi | SPIr |  HdrNextPld | . . . | MsgLength
PseudoKEHDR =  SPIi | SPIr |  NewHdrNextPld | . . . | NewMsgLength
NewHdrNextPld = NextPld
NewMsgLength = MsgLength - PldLength
PseudoMessage1 = PseudoIKEHDR | RestOfMessage1
NonceRPayload = PayloadHeader | NonceRData
InitiatorIDPayload = PayloadHeader | RestOfInitIDPayload
RestOfInitIDPayload = IDType | RESERVED | InitIDData
MACedIDForI = prf(SK_pi, RestOfInitIDPayload)
       ]]></artwork>
    </figure>

            In brief, if RealMessage1 doesn't contain the REVISED_COOKIE notification then it is used in the authentication as is (<xref target="fig-auth" />).
            Otherwise a new pseudo message PseudoMessage1 is used which is constructed from RealMessage1 as if it doesn't contain the REVISED_COOKIE notification
            (<xref target="fig-revised-auth" />).
            </t>

            <t> This modification excludes Notify payload containing cookie from the input to the AUTH payload calculation,
            thus solving the problem described in <xref target="problem" />.
            </t>

          </section>
        </section>

        <section anchor="security" title="Security Considerations">
          <t> This extension modifies the way IKE initiator is authenticated to the IKE responder. In particular, 
          the cookie, created by the responder and returned by the initiator in the IKE_SA_INIT request is excluded from the 
          data to be authenticated. IKEv2 specification requires that cookie (if present in the request) be verified by the responder 
          at the early stage of the IKE_SA_INIT request message processing. If this verification fails, then the responder 
          must act as if no cookie were present (see Section 2.6 of <xref target="RFC7296" />), which in most 
          cases results in requesting a new cookie. An adversary that is able to modify cookie content (or remove it from the request)
          will get no new advantages if this extension is used: either the responder requests a new cookie,
          or it doesn't care about the cookie at the moment and the IKE_SA_INIT exchange succeeded with invalid cookie.
          In the later case if revised cookie processing is used the subsequent IKE_AUTH exchange will also succeed and IKE SA will be created,
          which is different from the current situation, when authentication will fail in the IKE_AUTH if cookie is changed by the attacker.
          </t>

          <t> Excluding cookie from the data to be authenticated doesn't degrade 
          security properties of IKEv2, because the content of the cookie is generated by the responder 
          and must be verified by the responder well before the authentication takes place.
          The initiator doesn't participate in generation of cookie, it only returns it back as a blob.
          </t>

          <t> Compared to the current processing of cookie the difference caused by the revised processing in a situation when 
          an attacker changes cookie in the IKE_SA_INIT request is that IKE SA will still be created 
          (provided no other obstacles exists), but only if the responder at the moment doesn't care about validity of the received cookie
          (it means that it is not under attack).
          </t>
        </section>

       <section anchor="iana" title="IANA Considerations">
            <t>This document defines a new Notify Message Types in the "Notify Message Types - Status Types" registry:</t>
            <figure align="center">
                <artwork align="left"><![CDATA[
  <TBA>       REVISED_COOKIE
                ]]></artwork>
            </figure>
        </section>

        <section title="Acknowledgements"> 
          <t> Author is grateful to Tero Kivinen and Wei Pan for sharing their thoughts about this problem and potential ways to solve it.
          </t>
        </section>
    </middle>

    <back>
        <references title='Normative References'>
            <?rfc include="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"?>
            <?rfc include="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"?>
            <?rfc include="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7296.xml"?>
        </references>

<!--        <section anchor="alternatives" title="Alternative Designs">
          <t>
          </t>
        </section> -->

    </back>
</rfc>


