RFC 4718

IKEv2 Clarifications and Implementation Guidelines

๐Ÿ“… published October 2006, from ietf

RFC 4718: IKEv2 Clarifications and Implementation Guidelines โœจ

Okay bestie, here's the title block tea ๐ŸŽ€. This is RFC 4718, called IKEv2 Clarifications and Implementation Guidelines. It was written by P. Eronen (Nokia) and P. Hoffman (VPN Consortium). It's Category: Informational, and it's dated October 2006. The header doesn't list any Obsoletes or Updates entries ๐Ÿ™ˆ.

Part 1 of 11 ๐Ÿ’– more parts are coming!


Status of This Memo ๐Ÿ“œ

Vibe check: this is an informational memo for the Internet community ๐Ÿงš. It does not specify an Internet standard of any kind, and it's free to distribute with no limits ๐ŸŒธ.

Copyright (C) The Internet Society (2006).

Abstract ๐Ÿฆ‹

Okay so this doc clarifies a bunch of the IKEv2 spec ๐Ÿ’…. It isn't introducing any changes to the protocol ๐Ÿ™…โ€โ™€๏ธ. Instead it gives descriptions that are way less prone to ambiguous interpretations โœจ. The whole point is to help people build implementations that actually interoperate ๐Ÿซถ.

Table of Contents ๐Ÿ“š

   1. Introduction ....................................................4
   2. Creating the IKE_SA .............................................4
      2.1. SPI Values in IKE_SA_INIT Exchange .........................4
      2.2. Message IDs for IKE_SA_INIT Messages .......................5
      2.3. Retransmissions of IKE_SA_INIT Requests ....................5
      2.4. Interaction of COOKIE and INVALID_KE_PAYLOAD ...............6
      2.5. Invalid Cookies ............................................8
   3. Authentication ..................................................9
      3.1. Data Included in AUTH Payload Calculation ..................9
      3.2. Hash Function for RSA Signatures ...........................9
      3.3. Encoding Method for RSA Signatures ........................10
      3.4. Identification Type for EAP ...............................11
      3.5. Identity for Policy Lookups When Using EAP ................11
      3.6. Certificate Encoding Types ................................12
      3.7. Shared Key Authentication and Fixed PRF Key Size ..........12
      3.8. EAP Authentication and Fixed PRF Key Size .................13
      3.9. Matching ID Payloads to Certificate Contents ..............13
      3.10. Message IDs for IKE_AUTH Messages ........................14
   4. Creating CHILD_SAs .............................................14
      4.1. Creating SAs with the CREATE_CHILD_SA Exchange ............14
      4.2. Creating an IKE_SA without a CHILD_SA .....................16
      4.3. Diffie-Hellman for First CHILD_SA .........................16
      4.4. Extended Sequence Numbers (ESN) Transform .................17
      4.5. Negotiation of ESP_TFC_PADDING_NOT_SUPPORTED ..............17
      4.6. Negotiation of NON_FIRST_FRAGMENTS_ALSO ...................18
      4.7. Semantics of Complex Traffic Selector Payloads ............18
      4.8. ICMP Type/Code in Traffic Selector Payloads ...............19
      4.9. Mobility Header in Traffic Selector Payloads ..............20
      4.10. Narrowing the Traffic Selectors ..........................20
      4.11. SINGLE_PAIR_REQUIRED .....................................21
      4.12. Traffic Selectors Violating Own Policy ...................21
      4.13. Traffic Selector Authorization ...........................22
   5. Rekeying and Deleting SAs ......................................23
      5.1. Rekeying SAs with the CREATE_CHILD_SA Exchange ............23
      5.2. Rekeying the IKE_SA vs. Reauthentication ..................24
      5.3. SPIs When Rekeying the IKE_SA .............................25
      5.4. SPI When Rekeying a CHILD_SA ..............................25
      5.5. Changing PRFs When Rekeying the IKE_SA ....................26
      5.6. Deleting vs. Closing SAs ..................................26
      5.7. Deleting a CHILD_SA Pair ..................................26
      5.8. Deleting an IKE_SA ........................................27
      5.9. Who is the original initiator of IKE_SA ...................27
      5.10. Comparing Nonces .........................................27
      5.11. Exchange Collisions ......................................28
      5.12. Diffie-Hellman and Rekeying the IKE_SA ...................36

   6. Configuration Payloads .........................................37
      6.1. Assigning IP Addresses ....................................37
      6.2. Requesting any INTERNAL_IP4/IP6_ADDRESS ...................38
      6.3. INTERNAL_IP4_SUBNET/INTERNAL_IP6_SUBNET ...................38
      6.4. INTERNAL_IP4_NETMASK ......................................41
      6.5. Configuration Payloads for IPv6 ...........................42
      6.6. INTERNAL_IP6_NBNS .........................................43
      6.7. INTERNAL_ADDRESS_EXPIRY ...................................43
      6.8. Address Assignment Failures ...............................44
   7. Miscellaneous Issues ...........................................45
      7.1. Matching ID_IPV4_ADDR and ID_IPV6_ADDR ....................45
      7.2. Relationship of IKEv2 to RFC 4301 .........................45
      7.3. Reducing the Window Size ..................................46
      7.4. Minimum Size of Nonces ....................................46
      7.5. Initial Zero Octets on Port 4500 ..........................46
      7.6. Destination Port for NAT Traversal ........................47
      7.7. SPI Values for Messages outside an IKE_SA .................47
      7.8. Protocol ID/SPI Fields in Notify Payloads .................48
      7.9. Which message should contain INITIAL_CONTACT ..............48
      7.10. Alignment of Payloads ....................................48
      7.11. Key Length Transform Attribute ...........................48
      7.12. IPsec IANA Considerations ................................49
      7.13. Combining ESP and AH .....................................50
   8. Implementation Mistakes ........................................50
   9. Security Considerations ........................................51
   10. Acknowledgments ...............................................51
   11. References ....................................................51
      11.1. Normative References .....................................51
      11.2. Informative References ...................................52
   Appendix A. Exchanges and Payloads ................................54
      A.1. IKE_SA_INIT Exchange ......................................54
      A.2. IKE_AUTH Exchange without EAP .............................54
      A.3. IKE_AUTH Exchange with EAP ................................55
      A.4. CREATE_CHILD_SA Exchange for Creating/Rekeying
           CHILD_SAs .................................................56
      A.5. CREATE_CHILD_SA Exchange for Rekeying the IKE_SA ..........56
      A.6. INFORMATIONAL Exchange ....................................56

1. Introduction ๐ŸŒˆ

Okay, so this doc clarifies lots of parts of the IKEv2 spec that can be confusing if you're not deep in the spec and its history ๐Ÿง . The clarifications come from the discussion on the IPsec WG mailing list, from interop testing experience, and from implementation issues that got flagged to the editors ๐Ÿ’Œ.

IKEv2/IPsec has a bunch of uses, like IPsec-based remote access (sometimes called the "road warrior" case), site-to-site virtual private networks (VPNs), and host-to-host protection of application traffic ๐Ÿš—. This doc tries to cover all of them, but remote access gets the most spotlight, ngl ๐Ÿ‘‘.

This document doesn't put any requirements on anyone ๐Ÿ™…โ€โ™€๏ธ. It also doesn't use [RFC2119] keywords like "MUST" and "SHOULD", except when quoting the original IKEv2 documents. The actual requirements live in the IKEv2 specification [IKEv2] and the IKEv2 cryptographic algorithms document [IKEv2ALG] ๐Ÿ“–.

When this doc mentions a numbered section (like "Section 2.15"), it means that section in [IKEv2] ๐Ÿ”ข. Mailing list messages and threads refer to the IPsec WG mailing list at ipsec@ietf.org, and the archives are at <http://www.ietf.org/mail-archive/web/ipsec/index.html> ๐Ÿ“ฌ.


2. Creating the IKE_SA ๐ŸŽ€

2.1. SPI Values in IKE_SA_INIT Exchange ๐Ÿ’ซ

Normal IKE messages include the initiator's and responder's Security Parameter Indexes (SPIs) in the IKE header, and both of them are non-zero ๐Ÿ”‘. But there are some corner cases where the IKEv2 spec isn't totally consistent about which values to use ๐Ÿ™ˆ.

First up: Section 3.1 says that the Responder's SPI "...MUST NOT be zero in any other message" (than the first message of the IKE_SA_INIT exchange). Yet the figure in Section 2.6 shows the second IKE_SA_INIT message as HDR(A,0), N(COOKIE), which totally contradicts the text in 3.1 ๐Ÿ˜ญ.

Since the responder's SPI identifies security-related state held by the responder, and in this case no state gets created, sending a zero value seems reasonable ๐ŸŒธ.

Second, cookies aren't the only case where the IKE_SA_INIT exchange doesn't end up creating an IKE_SA. Others include INVALID_KE_PAYLOAD or NO_PROPOSAL_CHOSEN ๐Ÿค”. So what responder SPI should go in the IKE_SA_INIT response here?

Since the IKE_SA_INIT request always has a zero responder SPI, the value doesn't actually get used by the initiator. So we think sending a zero value is correct in this case too ๐Ÿ’….

If the responder sends a non-zero responder SPI, the initiator should not reject the response only for that reason. However, when retrying the IKE_SA_INIT request, the initiator will use a zero responder SPI, as described in Section 3.1: "Responder's SPI [...] This value MUST be zero in the first message of an IKE Initial Exchange (including repeats of that message including a cookie) [...]". We believe the intent was to cover repeats of that message due to other reasons, such as INVALID_KE_PAYLOAD, as well ๐Ÿงš.

(References: "INVALID_KE_PAYLOAD and clarifications document" thread, Sep-Oct 2005.)

2.2. Message IDs for IKE_SA_INIT Messages ๐Ÿฆ‹

The Message ID for IKE_SA_INIT messages is always zero 0๏ธโƒฃ. That includes retries of the message caused by responses like COOKIE and INVALID_KE_PAYLOAD ๐Ÿ”.

Why? Message IDs are part of the IKE_SA state. When the responder replies to an IKE_SA_INIT request with N(COOKIE) or N(INVALID_KE_PAYLOAD), it doesn't allocate any state, so there's no Message ID to keep track of ๐Ÿงธ.

(References: "Question about N(COOKIE) and N(INVALID_KE_PAYLOAD) combination" thread, Oct 2004. Tero Kivinen's mail "Comments of draft-eronen-ipsec-ikev2-clarifications-02.txt", 2005-04-05.)

2.3. Retransmissions of IKE_SA_INIT Requests ๐Ÿ”

okay so when a responder gets an IKE_SA_INIT request, it has to figure out whether the packet is a retransmission for an existing "half-open" IKE_SA (in which case it sends the same response again) or a brand new request (in which case it creates a new IKE_SA and sends a fresh response). ๐Ÿ’…

The spec doesn't go into detail about how that call gets made. ngl, it is NOT enough to just use the initiator's SPI and/or IP address ๐Ÿ™… because two different peers behind a single NAT could pick the same initiator SPI. The chance of that is not necessarily small, since IKEv2 does not require SPIs to be chosen randomly ๐Ÿ’€. So instead, the responder should do the IKE_SA lookup using the whole packet or its hash (or at the minimum, the Ni payload, which is always chosen randomly) โœจ.

For all other packets than IKE_SA_INIT requests, finding the right IKE_SA is done based on the recipient's SPI. Whether that's the initiator SPI or the responder SPI depends on the value of the Initiator bit in the IKE header ๐Ÿงš.

There are two common reasons the initiator might have to retry the IKE_SA_INIT exchange: the responder requests a cookie, or it wants a different Diffie-Hellman group than the one included in the KEi payload. Both of these are pretty simple on their own, but it's not totally obvious what happens when they show up at the same time, meaning the IKE_SA_INIT exchange gets retried several times ๐ŸŒ€.

The big question is this: if the initiator gets a cookie from the responder, should it include the cookie in only the next retry of the IKE_SA_INIT request, or in all the retries after that too? ๐Ÿค” Section 3.10.1 says:

"This notification MUST be included in an IKE_SA_INIT request retry if a COOKIE notification was included in the initial response."

That could be read as meaning that once a cookie comes back in the initial response, it goes in every retry. But Section 2.6 says:

"Initiators who receive such responses MUST retry the IKE_SA_INIT with a Notify payload of type COOKIE containing the responder supplied cookie data as the first payload and all other payloads unchanged."

Including the same cookie in later retries only makes sense if the "all other payloads unchanged" restriction applies to the first retry but not to the ones after it ๐Ÿง.

Honestly, both readings can coexist peacefully ๐Ÿซถ. If the initiator only includes the cookie in the next retry, one extra roundtrip may be needed in some cases:

   Initiator                   Responder
  -----------                 -----------
   HDR(A,0), SAi1, KEi, Ni -->
                           <-- HDR(A,0), N(COOKIE)
   HDR(A,0), N(COOKIE), SAi1, KEi, Ni  -->
                           <-- HDR(A,0), N(INVALID_KE_PAYLOAD)
   HDR(A,0), SAi1, KEi', Ni -->
                           <-- HDR(A,0), N(COOKIE')
   HDR(A,0), N(COOKIE'), SAi1, KEi',Ni -->
                           <-- HDR(A,B), SAr1, KEr, Nr

An extra roundtrip is also needed if the initiator includes the cookie in all retries but the responder doesn't support that. For instance, if the responder includes the SAi1 and KEi payloads in the cookie calculation, it will reject the request by sending a new cookie (see also Section 2.5 of this document for more text about invalid cookies) ๐Ÿ™ˆ:

   Initiator                   Responder
  -----------                 -----------
   HDR(A,0), SAi1, KEi, Ni -->
                           <-- HDR(A,0), N(COOKIE)
   HDR(A,0), N(COOKIE), SAi1, KEi, Ni  -->
                           <-- HDR(A,0), N(INVALID_KE_PAYLOAD)
   HDR(A,0), N(COOKIE), SAi1, KEi', Ni -->
                           <-- HDR(A,0), N(COOKIE')
   HDR(A,0), N(COOKIE'), SAi1, KEi',Ni -->
                           <-- HDR(A,B), SAr1, KEr, Nr

If both peers support including the cookie in all retries, a slightly shorter exchange can happen โšก:

   Initiator                   Responder
  -----------                 -----------
   HDR(A,0), SAi1, KEi, Ni -->
                           <-- HDR(A,0), N(COOKIE)
   HDR(A,0), N(COOKIE), SAi1, KEi, Ni  -->
                           <-- HDR(A,0), N(INVALID_KE_PAYLOAD)
   HDR(A,0), N(COOKIE), SAi1, KEi', Ni -->
                           <-- HDR(A,B), SAr1, KEr, Nr

This document recommends that implementations should support this shorter exchange, but it must not be assumed the other peer also supports it ๐Ÿซ .

In theory, even this exchange has one unnecessary roundtrip, since the cookie and the Diffie-Hellman group could be checked at the same time ๐Ÿคฏ:

   Initiator                   Responder
  -----------                 -----------
   HDR(A,0), SAi1, KEi, Ni -->
                           <-- HDR(A,0), N(COOKIE),
                                         N(INVALID_KE_PAYLOAD)
   HDR(A,0), N(COOKIE), SAi1, KEi',Ni -->
                           <-- HDR(A,B), SAr1, KEr, Nr

However, this case is clearly not allowed by the text in Section 2.6, since "all other payloads" clearly includes the KEi payload as well ๐Ÿšซ.

(References: "INVALID_KE_PAYLOAD and clarifications document" thread, Sep-Oct 2005.)

2.5. Invalid Cookies ๐Ÿช

There's been some confusion about what should be done when an IKE_SA_INIT request containing an invalid cookie is received. Here "invalid" means its contents don't match the value the responder expected ๐Ÿ™ƒ.

The correct action is to ignore the cookie and process the message as if no cookie had been included. Usually that means sending a response that contains a new cookie. This is shown in Section 2.6 when it says "The responder in that case MAY reject the message by sending another response with a new cookie [...]" ๐Ÿ‘‘.

Other options, like ignoring the whole request (or even all requests from this IP address for some time), create strange failure modes even when there are no malicious attackers, and they don't give any extra protection against DoS attacks ๐Ÿ’€.

(References: "Invalid Cookie" thread, Sep-Oct 2005.)

3. Authentication ๐Ÿ”

3.1. Data Included in AUTH Payload Calculation ๐Ÿงฎ

Section 2.15 describes how the AUTH payloads are calculated. This calculation involves the values prf(SK_pi,IDi') and prf(SK_pr,IDr'). The text describes the method in words but doesn't give clear definitions of what is signed or MACed (i.e., protected with a message authentication code) ๐Ÿ˜ญ.

The initiator's signed octets can be described as:

    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 | RestOfIDPayload
    RestOfInitIDPayload = IDType | RESERVED | InitIDData
    MACedIDForI = prf(SK_pi, RestOfInitIDPayload)

The responder's signed octets can be described as:

    ResponderSignedOctets = RealMessage2 | NonceIData | MACedIDForR
    GenIKEHDR = [ four octets 0 if using port 4500 ] | RealIKEHDR
    RealIKEHDR =  SPIi | SPIr |  . . . | Length
    RealMessage2 = RealIKEHDR | RestOfMessage2
    NonceIPayload = PayloadHeader | NonceIData
    ResponderIDPayload = PayloadHeader | RestOfIDPayload
    RestOfRespIDPayload = IDType | RESERVED | InitIDData
    MACedIDForR = prf(SK_pr, RestOfRespIDPayload)

3.2. Hash Function for RSA Signatures ๐ŸŒถ๏ธ

Section 3.8 says that an RSA digital signature is "Computed as specified in section 2.15 using an RSA private key over a PKCS#1 padded hash."

Unlike IKEv1, IKEv2 doesn't negotiate a hash function for the IKE_SA. The algorithm for signatures is picked by the signing party, who generally may not know beforehand which algorithms the verifying party supports ๐Ÿคทโ€โ™€๏ธ. On top of that, [IKEv2ALG] doesn't say which algorithms implementations are required or recommended to support. This clearly has the potential to cause interoperability problems, since authentication will fail if the signing party selects an algorithm the verifying party doesn't support, or one that isn't acceptable under the verifying party's policy ๐Ÿฅฒ.

This document recommends that all implementations support SHA-1 and use SHA-1 as the default hash function when generating signatures, unless there are good reasons (such as explicit manual configuration) to believe the peer supports something else ๐Ÿฆ‹.

Note that hash function collision attacks are not important for the AUTH payloads, since they aren't intended for third-party verification, and the data includes fresh nonces. See [HashUse] for more discussion about hash function attacks and IPsec ๐Ÿง .

Another reasonable choice would be to use the hash function that the CA used when signing the peer certificate. However, that doesn't guarantee the IKEv2 peer will be able to validate the AUTH payload, because the same code might not be used to validate certificate signatures and IKEv2 message signatures, and those two routines may support different sets of hash algorithms. The peer could be configured with a fingerprint of the certificate, or certificate validation could be done by an external entity using [SCVP]. Furthermore, not all CERT payload types include a signature, and the certificate could be signed with some algorithm other than RSA ๐Ÿ™„.

Note that unlike IKEv1, IKEv2 uses the PKCS#1 v1.5 [PKCS1v20] signature encoding method (see the next section for details), which includes the algorithm identifier for the hash algorithm. So when the verifying party receives the AUTH payload, it can at least figure out which hash function was used ๐Ÿ’….

(References: Magnus Alstrom's mail "RE:", 2005-01-03. Pasi Eronen's reply, 2005-01-04. Tero Kivinen's reply, 2005-01-04. "First draft of IKEv2.1" thread, Dec 2005/Jan 2006.)

3.3. Encoding Method for RSA Signatures โœ๏ธ

Section 3.8 says that the RSA digital signature is "Computed as specified in section 2.15 using an RSA private key over a PKCS#1 padded hash."

The PKCS#1 specification [PKCS1v21] defines two different encoding methods (ways of "padding the hash") for signatures. However, the Internet-Draft approved by the IESG referred to the older PKCS#1 v2.0 [PKCS1v20]. That version has only one encoding method for signatures (EMSA-PKCS1-v1_5), so there's no ambiguity ๐ŸŽ€.

Note that this encoding method is different from the one used in IKEv1. If future revisions of IKEv2 add support for other encoding methods (such as EMSA-PSS), they will be given new Auth Method numbers ๐ŸŒˆ.

(References: Pasi Eronen's mail "RE:", 2005-01-04.)

3.4. Identification Type for EAP ๐ŸŽ€

okay so Section 3.5 lists a bunch of identification payload types, like ID_FQDN, ID_RFC822_ADDR, and ID_KEY_ID ๐Ÿ’…. EAP [EAP] doesn't force any particular identifier type, but EAP is often used with Network Access Identifiers (NAIs) from [NAI] ๐Ÿซถ. NAIs look kinda like email addresses (think "joe@example.com"), but the syntax isn't exactly the same as email address syntax in [RFC822]. So the big question is: which identification type should you use? ๐Ÿค”

This document recommends using the ID_RFC822_ADDR identification type for NAIs that include the realm component. So responder implementations should not try to verify that the contents match the exact syntax given in [RFC822] or [RFC2822] ๐Ÿ™ˆ. Instead, they should accept any reasonable looking NAI โœจ.

For NAIs that don't include the realm component, this document recommends using the ID_KEY_ID identification type ๐Ÿ”‘.

(References: "need your help on this IKEv2/i18n/EAP issue" and "IKEv2 identifier issue with EAP" threads, Aug 2004.)


3.5. Identity for Policy Lookups When Using EAP ๐Ÿ”

When the initiator authentication uses EAP, it's possible that the contents of the IDi payload are only used for AAA routing and for picking which EAP method to use ๐Ÿงญ. That value might be different from the identity authenticated by the EAP method (see [EAP], Sections 5.1 and 7.3).

It is important that policy lookups and access control decisions use the actual authenticated identity ๐Ÿ‘‘. Often the EAP server is a separate AAA server that talks to the IKEv2 responder using, e.g., RADIUS [RADEAP]. In that case, the authenticated identity has to be sent from the AAA server to the IKEv2 responder ๐Ÿ“จ.

(References: Pasi Eronen's mail "RE: Reauthentication in IKEv2", 2004-10-28. "Policy lookups" thread, Oct/Nov 2004. RFC 3748, Section 7.3.)


3.6. Certificate Encoding Types ๐Ÿ”

Section 3.6 defines a total of twelve different certificate encoding types, and it says "Specific syntax is for some of the certificate type codes above is not defined in this document." ๐Ÿ˜ญ The text doesn't point to any other documents that describe the exact contents and use of those values.

Without that info, you literally can't build interoperable implementations ๐Ÿ’€. So this document recommends that the following certificate encoding values should not be used before new specifications that specify their use are available:

        PKCS #7 wrapped X.509 certificate    1
        PGP Certificate                      2
        DNS Signed Key                       3
        Kerberos Token                       6
        SPKI Certificate                     9

This document recommends that most implementations should use only those values that are "MUST"/"SHOULD" requirements in [IKEv2]; i.e., "X.509 Certificate - Signature" (4), "Raw RSA Key" (11), "Hash and URL of X.509 certificate" (12), and "Hash and URL of X.509 bundle" (13) ๐ŸŒธ.

Furthermore, Section 3.7 says that the "Certificate Encoding" field for the Certificate Request payload uses the same values as the Certificate payload. However, the contents of the "Certification Authority" field are only defined for X.509 certificates (presumably covering at least types 4, 10, 12, and 13). This document recommends that other values should not be used before new specifications that specify their use are available ๐Ÿ™ƒ.

The "Raw RSA Key" type needs one more clarification. Section 3.6 says it contains "a PKCS #1 encoded RSA key". What this means is a DER-encoded RSAPublicKey structure from PKCS#1 [PKCS1v21] ๐Ÿงฉ.


3.7. Shared Key Authentication and Fixed PRF Key Size ๐Ÿ—๏ธ

Section 2.15 says that "If the negotiated prf takes a fixed-size key, the shared secret MUST be of that fixed size". This statement is correct: the shared secret must be of the correct size. If it isn't, it can't be used. There's no padding, truncation, or other processing involved to force it to the correct size ๐Ÿšซ.

This requirement means it's difficult to use these pseudo-random functions (PRFs) with shared key authentication. The authors think this part of the specification was very poorly thought out, and using PRFs with a fixed key size is likely to result in interoperability problems ๐Ÿ˜ค. Thus, we recommend that such PRFs should not be used with shared key authentication. PRF_AES128_XCBC [RFC3664] originally used fixed key sizes; that RFC has been updated to handle variable key sizes in [RFC4434] โœจ.

Note that Section 2.13 also contains text related to PRFs with fixed key size: "When the key for the prf function has fixed length, the data provided as a key is truncated or padded with zeros as necessary unless exceptional processing is explained following the formula". However, this text applies only to the prf+ construction, so it does not contradict the text in Section 2.15 ๐Ÿค“.

(References: Paul Hoffman's mail "Re: ikev2-07: last nits", 2003-05-02. Hugo Krawczyk's reply, 2003-05-12. Thread "Question about PRFs with fixed size key", Jan 2005.)

bestie reminder: a PRF with a fixed key size needs a shared secret of exactly that size, or it's a no-go ๐Ÿšซ

3.8. EAP Authentication and Fixed PRF Key Size ๐ŸŽŸ๏ธ

As described in the previous section, PRFs with a fixed key size require a shared secret of exactly that size. This restriction applies to EAP authentication too ๐Ÿ’œ. For instance, a PRF that requires a 128-bit key cannot be used with EAP, since [EAP] specifies that the MSK is at least 512 bits long.

(References: Thread "Question about PRFs with fixed size key", Jan 2005.)


3.9. Matching ID Payloads to Certificate Contents ๐Ÿชช

In IKEv1, there was some confusion about whether or not the identities in certificates used to authenticate IKE were required to match the contents of the ID payloads ๐Ÿคทโ€โ™€๏ธ. The PKI4IPsec Working Group produced the document [PKI4IPsec], which covers this topic in much more detail. However, Section 3.5 of [IKEv2] explicitly says that the ID payload "does not necessarily have to match anything in the CERT payload" ๐Ÿ’….


3.10. Message IDs for IKE_AUTH Messages ๐Ÿ”ข

According to Section 2.2, "The IKE_SA initial setup messages will always be numbered 0 and 1." That's true when the IKE_AUTH exchange does not use EAP. When EAP is used, each pair of messages has its message numbers incremented. The first pair of AUTH messages will have an ID of 1, the second will be 2, and so on ๐Ÿฆ‹.

(References: "Question about MsgID in AUTH exchange" thread, April 2005.)


4. Creating CHILD_SAs โœจ

4.1. Creating SAs with the CREATE_CHILD_SA Exchange ๐ŸŒˆ

Section 1.3's organization doesn't lead to a clear understanding of what is needed in which environment ๐Ÿ™ˆ. The section can be reorganized with subsections for each use of the CREATE_CHILD_SA exchange (creating child SAs, rekeying IKE SAs, and rekeying child SAs.)

The new Section 1.3, with subsections and the above changes, might look like the following.

NEW-1.3 The CREATE_CHILD_SA Exchange

The CREATE_CHILD_SA Exchange is used to create new CHILD_SAs and to rekey both IKE_SAs and CHILD_SAs. This exchange consists of a single request/response pair, and some of its function was referred to as a phase 2 exchange in IKEv1. It MAY be initiated by either end of the IKE_SA after the initial exchanges are completed ๐Ÿซง.

All messages following the initial exchange are cryptographically protected using the cryptographic algorithms and keys negotiated in the first two messages of the IKE exchange. These subsequent messages use the syntax of the Encrypted Payload described in section 3.14. All subsequent messages include an Encrypted Payload, even if they are referred to in the text as "empty" ๐Ÿ”’.

The CREATE_CHILD_SA is used for rekeying IKE_SAs and CHILD_SAs. This section describes the first part of rekeying, the creation of new SAs. Section 2.8 covers the mechanics of rekeying, including moving traffic from old to new SAs and the deletion of the old SAs. The two sections must be read together to understand the entire process of rekeying ๐Ÿ”.

Either endpoint may initiate a CREATE_CHILD_SA exchange, so in this section the term initiator refers to the endpoint initiating this exchange. An implementation MAY refuse all CREATE_CHILD_SA requests within an IKE_SA ๐Ÿ™…โ€โ™€๏ธ.

The CREATE_CHILD_SA request MAY optionally contain a KE payload for an additional Diffie-Hellman exchange, to enable stronger guarantees of forward secrecy for the CHILD_SA or IKE_SA ๐Ÿ’–. The keying material for the SA is a function of SK_d established during the establishment of the IKE_SA, the nonces exchanged during the CREATE_CHILD_SA exchange, and the Diffie-Hellman value (if KE payloads are included in the CREATE_CHILD_SA exchange). The details are described in sections 2.17 and 2.18.

If a CREATE_CHILD_SA exchange includes a KEi payload, at least one of the SA offers MUST include the Diffie-Hellman group of the KEi. The Diffie-Hellman group of the KEi MUST be an element of the group the initiator expects the responder to accept (additional Diffie-Hellman groups can be proposed). If the responder rejects the Diffie-Hellman group of the KEi payload, the responder MUST reject the request and indicate its preferred Diffie-Hellman group in the INVALID_KE_PAYLOAD Notification payload. In the case of such a rejection, the CREATE_CHILD_SA exchange fails, and the initiator SHOULD retry the exchange with a Diffie-Hellman proposal and KEi in the group that the responder gave in the INVALID_KE_PAYLOAD ๐ŸŽฏ.

NEW-1.3.1 Creating New CHILD_SAs with the CREATE_CHILD_SA Exchange

A CHILD_SA may be created by sending a CREATE_CHILD_SA request. The CREATE_CHILD_SA request for creating a new CHILD_SA is:

            Initiator                                 Responder
           -----------                               -----------
            HDR, SK {[N+], SA, Ni, [KEi],
                       TSi, TSr}        -->

The initiator sends SA offer(s) in the SA payload, a nonce in the Ni payload, optionally a Diffie-Hellman value in the KEi payload, and the proposed traffic selectors for the proposed CHILD_SA in the TSi and TSr payloads. The request can also contain Notify payloads that specify additional details for the CHILD_SA. These include IPCOMP_SUPPORTED, USE_TRANSPORT_MODE, ESP_TFC_PADDING_NOT_SUPPORTED, and NON_FIRST_FRAGMENTS_ALSO ๐Ÿ“ฆ.

The CREATE_CHILD_SA response for creating a new CHILD_SA is:

                                       <--    HDR, SK {[N+], SA, Nr,
                                                    [KEr], TSi, TSr}

The responder replies with the accepted offer in an SA payload, and a Diffie-Hellman value in the KEr payload if KEi was included in the request and the selected cryptographic suite includes that group. As with the request, optional Notification payloads can specify additional details for the CHILD_SA ๐ŸŒŸ.

The traffic selectors for traffic to be sent on that SA are specified in the TS payloads in the response, which may be a subset of what the initiator of the CHILD_SA proposed ๐Ÿงš.

The text about rekeying SAs can be found in Section 5.1 of this document ๐Ÿ’œ.

4.2. Creating an IKE_SA without a CHILD_SA โœจ

okay so CHILD_SAs can get made in two ways: they can ride along on the IKE_AUTH exchange, or they can get their own separate CREATE_CHILD_SA exchange ๐ŸŽ€ the spec isn't super clear about what happens if making the CHILD_SA during IKE_AUTH faills for some reason ๐Ÿ˜ญ

our recommendation? the IKE_SA still gets created as usual ๐Ÿ’– this matches how CREATE_CHILD_SA already works, where a failed CHILD_SA doesn't close the IKE_SA. so it's consistent, bestie ๐Ÿซถ

these IKE_AUTH responses don't stop an IKE_SA from getting set up, at least:

  • NO_PROPOSAL_CHOSEN
  • TS_UNACCEPTABLE
  • SINGLE_PAIR_REQUIRED
  • INTERNAL_ADDRESS_FAILURE
  • FAILED_CP_REQUIRED

(References: "Questions about internal address" thread, April 2005.)


4.3. Diffie-Hellman for First CHILD_SA ๐Ÿฆ‹

Section 1.2 shows that IKE_AUTH messages don't have KEi/KEr or Ni/Nr payloads, and that's a big deal ๐Ÿ‘‘ it means the SA payload in an IKE_AUTH exchange can't have Transform Type 4 (Diffie-Hellman Group) set to anything except NONE. implementations should probably just leave that transform out entirely in this case ๐Ÿ’…

4.4. Extended Sequence Numbers (ESN) Transform ๐Ÿ”ฅ

the ESN transform description in Section 3.3 has proved kinda hard to understand, and I get it ๐Ÿ™ˆ here's what the ESN transform actually means:

  • a proposal with one ESN transform set to 0 means "do not use extended sequence numbers".
  • a proposal with one ESN transform set to 1 means "use extended sequence numbers".
  • a proposal with two ESN transforms, 0 and 1, means "I support both normal and extended sequence numbers, you choose". (Obviously this case is only allowed in requests; the response will contain only one ESN transform.)

usually the exchange initiator puts either the first or the third option in its SA payload ๐Ÿ’œ the second one is rarely useful for the initiator, since it says normal sequence numbers aren't acceptable at all. so if the responder doesn't support ESNs, the exchange fails with NO_PROPOSAL_CHOSEN ๐Ÿ˜ญ

ngl, including the ESN transform is mandatory when creating ESP/AH SAs. (It was optional in earlier drafts of the IKEv2 specification.)

(References: "Technical change needed to IKEv2 before publication", "STRAW POLL: Dealing with the ESN negotiation interop issue in IKEv2" and "Results of straw poll regarding: IKEv2 interoperability issue" threads, March-April 2005.)


4.5. Negotiation of ESP_TFC_PADDING_NOT_SUPPORTED ๐ŸŒธ

the ESP_TFC_PADDING_NOT_SUPPORTED notification is described in Section 3.10.1, which says: "This notification asserts that the sending endpoint will NOT accept packets that contain Flow Confidentiality (TFC) padding".

but the text never says which messages this notification should show up in, or whether it applies to one CHILD_SA or to all of the peer's CHILD_SAs ๐Ÿค”

our take is that the scope is a single CHILD_SA. so this notification goes in any message that has an SA payload negotiating a CHILD_SA โœจ if neither endpoint accepts TFC padding, the notification shows up in both the request proposing the SA and the response accepting it. if it's only in one of those messages, TFC padding can still be sent in one direction ๐Ÿฆ‹

4.6. Negotiation of NON_FIRST_FRAGMENTS_ALSO ๐Ÿงš

the NON_FIRST_FRAGMENTS_ALSO notification is described in Section 3.10.1 super briefly, as "Used for fragmentation control. See [RFC4301] for explanation."

so we go to [RFC4301], which says: "Implementations that will transmit non-initial fragments on a tunnel mode SA that makes use of non-trivial port (or ICMP type/code or MH type) selectors MUST notify a peer via the IKE NOTIFY NON_FIRST_FRAGMENTS_ALSO payload. The peer MUST reject this proposal if it will not accept non-initial fragments in this context. If an implementation does not successfully negotiate transmission of non-initial fragments for such an SA, it MUST NOT send such fragments over the SA."

but honestly it's not clear how the negotiation actually works ๐Ÿ˜ต our interpretation is that it works the same way as IPCOMP_SUPPORTED and USE_TRANSPORT_MODE: sending non-first fragments is only enabled if NON_FIRST_FRAGMENTS_ALSO is included in both the request proposing an SA and the response accepting it. in other words, when the peer "rejects this proposal", it just leaves NON_FIRST_FRAGMENTS_ALSO out of the response, and it does NOT reject the whole CHILD_SA creation ๐Ÿ’…

4.7. Semantics of Complex Traffic Selector Payloads ๐Ÿ‘‘

as Section 3.13 describes, the TSi/TSr payloads can hold one or more individual traffic selectors โœจ

there's no rule that TSi and TSr have to contain the same number of individual traffic selectors ๐ŸŒˆ so here's how they get read: a packet matches a given TSi/TSr if it matches at least one of the individual selectors in TSi, AND at least one of the individual selectors in TSr.

for example, these traffic selectors:

     TSi = ((17, 100, 192.0.1.66-192.0.1.66),
            (17, 200, 192.0.1.66-192.0.1.66))
     TSr = ((17, 300, 0.0.0.0-255.255.255.255),
            (17, 400, 0.0.0.0-255.255.255.255))

would match UDP packets from 192.0.1.66 going anywhere, with any of the four port combinations (100,300), (100,400), (200,300), and (200, 400) ๐Ÿ˜

which means some policies might need several CHILD_SA pairs ๐Ÿ“ for instance, a policy that matches only the source/destination port combinations (100,300) and (200,400), but not the other two, can't be negotiated as a single CHILD_SA pair using IKEv2. main character policy problems, fr ๐Ÿ’€

(References: "IKEv2 Traffic Selectors?" thread, Feb 2005.)


4.8. ICMP Type/Code in Traffic Selector Payloads ๐Ÿฆ‹

the traffic selector types 7 and 8 can also point at ICMP type and code fields. Section 3.13.1 says: "For the ICMP protocol, the two one-octet fields Type and Code are treated as a single 16-bit integer (with Type in the most significant eight bits and Code in the least significant eight bits) port number for the purposes of filtering based on this field."

ICMP packets don't have separate source and destination port fields, so it's a little confusing what the four TS payloads (two in the request, two in the response, each with start and end port fields) are supposed to hold ๐Ÿ™ˆ the answer is in [RFC4301] Section 4.4.1.3.

here's a concrete example ๐Ÿ’– say a host at 192.0.1.234 wants a transport mode SA for sending "Destination Unreachable" packets (ICMPv4 type 3) to 192.0.2.155, but doesn't want to receive them over this SA pair. the CREATE_CHILD_SA exchange would look like this:

   Initiator                   Responder
  -----------                 -----------
   HDR, SK { N(USE_TRANSPORT_MODE), SA, Ni,
             TSi(1, 0x0300-0x03FF, 192.0.1.234-192.0.1.234),
             TSr(1, 65535-0, 192.0.2.155-192.0.2.155) } -->

      <-- HDR, SK { N(USE_TRANSPORT_MODE), SA, Nr,
                    TSi(1, 0x0300-0x03FF, 192.0.1.234-192.0.1.234),
                    TSr(1, 65535-0, 192.0.2.155-192.0.2.155) }

since IKEv2 always creates IPsec SAs in pairs, two SAs get created here too, even though the second one never carries any data traffic ๐Ÿซถ

if you want an SA pair that can be used for both sending AND receiving "Destination Unreachable", you put the same value in all the ports:

   Initiator                   Responder
  -----------                 -----------
   HDR, SK { N(USE_TRANSPORT_MODE), SA, Ni,
             TSi(1, 0x0300-0x03FF, 192.0.1.234-192.0.1.234),
             TSr(1, 0x0300-0x03FF, 192.0.2.155-192.0.2.155) } -->

      <-- HDR, SK { N(USE_TRANSPORT_MODE), SA, Nr,
                    TSi(1, 0x0300-0x03FF, 192.0.1.234-192.0.1.234),
                    TSr(1, 0x0300-0x03FF, 192.0.2.155-192.0.2.155) }

(References: "ICMP and MH TSs for IKEv2" thread, Sep 2005.)


4.9. Mobility Header in Traffic Selector Payloads ๐Ÿงš

traffic selectors can use IP Protocol ID 135 to match the IPv6 mobility header [MIPv6] ๐ŸŒธ the IKEv2 spec doesn't say how to represent the "MH Type" field in traffic selectors though.

people expected a separate document would define it later on. [RFC4301] says: "For IKE, the IPv6 mobility header message type (MH type) is placed in the most significant eight bits of the 16 bit local "port" selector". the direction semantics of the TSi/TSr port fields match ICMP, and they're covered in the previous section ๐Ÿ’œ

(References: Tero Kivinen's mail "Issue #86: Add IPv6 mobility header message type as selector", 2003-10-14. "ICMP and MH TSs for IKEv2" thread, Sep 2005.)


4.10. Narrowing the Traffic Selectors ๐ŸŒˆ

Section 2.9 explains how traffic selectors get negotiated when creating a CHILD_SA. here's a more concise summary of the narrowing process ๐ŸŽ€

  • if the responder's policy doesn't allow any part of the traffic covered by TSi/TSr, it responds with TS_UNACCEPTABLE.
  • if the responder's policy allows the whole set of traffic covered by TSi/TSr, no narrowing is needed, and the responder can just return the same TSi/TSr values.
  • otherwise narrowing is needed. if the responder's policy allows all traffic covered by TSi[1]/TSr[1] (the first traffic selectors in TSi/TSr) but not all of TSi/TSr, the responder narrows to an acceptable subset of TSi/TSr that still includes TSi[1]/TSr[1].
  • if the responder's policy doesn't allow all traffic covered by TSi[1]/TSr[1] but does allow some parts of TSi/TSr, it narrows to an acceptable subset of TSi/TSr.

in the last two cases, there can be several subsets that are acceptable (even though their union isn't). in that situation, the responder arbitrarily picks one of them and includes an ADDITIONAL_TS_POSSIBLE notification in the response ๐Ÿ’…

4.11. SINGLE_PAIR_REQUIRED ๐Ÿ’€

the SINGLE_PAIR_REQUIRED notify payload is described in Sections 2.9 and 3.10.1, and those descriptions aren't fully consistent with each other ๐Ÿ™ˆ

we're not trying to describe this payload in this document either ๐Ÿซถ the reason is that most implementations are expected to not have policies that require separate SAs for each address pair.

so if only some part (or parts) of the TSi/TSr the initiator proposed is acceptable to the responder, most responders should just narrow TSi/TSr down to an acceptable subset (as described in the last two paragraphs of Section 2.9), instead of using SINGLE_PAIR_REQUIRED โœจ

4.12. Traffic Selectors Violating Own Policy โš ๏ธ

Okay so Section 2.9 is the full deep dive on traffic selector negotiation ๐Ÿงš. One part that needs a little extra spotlight: when you create a new SA, the initiator should not propose traffic selectors that violate its own policy ๐Ÿ™…โ€โ™€๏ธ. Skip this and valid traffic can get dropped, and that is not the vibe ๐Ÿ’€.

Let's look at an example, because it makes this way clearer. Host A has a policy where traffic to 192.0.1.66 goes through host B and is encrypted with Advanced Encryption Standard (AES) ๐Ÿ”. Traffic to every other host in 192.0.1.0/24 also goes through B, but it's encrypted with Triple Data Encryption Standard (3DES) ๐ŸŽ€. Host B accepts any mix of AES and 3DES, so it's flexible ๐Ÿซถ.

Now say host A proposes an SA that uses 3DES and includes a TSr of (192.0.1.0-192.0.1.0.255). Host B accepts it ๐Ÿ˜Œ. The problem is that B can also use this SA to send traffic from 192.0.1.66, and A will drop those packets because A requires AES for that traffic ๐Ÿ˜ญ. Even if A makes a brand new SA just for 192.0.1.66 that uses AES, B can keep using the first SA for that traffic anyway. The fix is that when A made the proposal, it should have followed its own policy and included a TSr of ((192.0.1.0-192.0.1.65),(192.0.1.67-192.0.1.255)) instead โœจ.

Here's the general version. If (1) the initiator makes a proposal "for traffic X (TSi/TSr), do SA", and (2) for some subset X' of X, the initiator does not actually accept traffic X' with SA, and (3) the initiator would be willing to accept traffic X' with some SA' (!=SA), then valid traffic can be unnecessarily dropped, since the responder can apply either SA or SA' to traffic X' ๐Ÿฅบ.

(References: "Question about "narrowing" ..." thread, Feb 2005. "IKEv2 needs a "policy usage mode"..." thread, Feb 2005. "IKEv2 Traffic Selectors?" thread, Feb 2005. "IKEv2 traffic selector negotiation examples", 2004-08-08.)


4.13. Traffic Selector Authorization ๐Ÿ”‘

IKEv2 leans on the Peer Authorization Database (PAD) to decide what kinds of IPsec SAs a peer is allowed to create ๐Ÿ‘‘. You can read all about this in [RFC4301] Section 4.4.3. When a peer asks to create an IPsec SA with some traffic selectors, the PAD must contain "Child SA Authorization Data" that links the identity IKEv2 authenticated with the addresses that peer is permitted to use in those traffic selectors ๐Ÿ—๏ธ.

For example, the PAD might be set up so that the authenticated identity "sgw23.example.com" can create IPsec SAs for 192.0.2.0/24. That means this security gateway is a valid "representative" for those addresses ๐ŸŒธ. Host-to-host IPsec needs similar entries too. For instance, "fooserver4.example.com" could be linked with 192.0.1.66/32, meaning this identity is a valid "owner" or "representative" of that address ๐Ÿฆ‹.

As [RFC4301] puts it, "It is necessary to impose these constraints on creation of child SAs to prevent an authenticated peer from spoofing IDs associated with other, legitimate peers." ๐Ÿ™…โ€โ™€๏ธ So in the example above, a correct PAD configuration stops sgw23 from creating IPsec SAs with address 192.0.1.66, and it stops fooserver4 from creating IPsec SAs with addresses from 192.0.2.0/24 ๐Ÿ’….

Here's a super important detail. Just sending IKEv2 packets from some particular address does not give you permission to create IPsec SAs with that address in the traffic selectors ๐Ÿšซ. For example, even if sgw23 could spoof its IP address as 192.0.1.66, it still couldn't create IPsec SAs that match fooserver4's traffic ๐Ÿ™ˆ.

The IKEv2 specification doesn't say exactly how IP address assignment through configuration payloads interacts with the PAD ๐Ÿคทโ€โ™€๏ธ. Our take is that when a security gateway assigns an address using configuration payloads, it also creates a temporary PAD entry that links the authenticated peer identity with the newly allocated inner address ๐Ÿงš.

Configuring the PAD correctly can be tricky in some environments, and that's been recognized ๐Ÿ˜ฉ. For example, if IPsec runs between a pair of hosts whose addresses are allocated dynamically with Dynamic Host Configuration Protocol (DHCP), it's extremely difficult to make sure the PAD lists the correct "owner" for each IP address. You'd need a mechanism that securely passes address assignments from the DHCP server and links them to identities authenticated with IKEv2 ๐Ÿ”—.

Because of this limitation, some vendors have been known to set up their PADs so an authenticated peer can create IPsec SAs with traffic selectors containing the same address that was used for the IKEv2 packets ๐Ÿซ . In environments where IP spoofing is possible (i.e., almost everywhere), this basically lets any peer create IPsec SAs with any traffic selectors ๐Ÿšจ. This is not an appropriate or secure configuration in most circumstances. For an extensive discussion of this issue, and of the limitations of host-to-host IPsec in general, see [Aura05] ๐Ÿ“š.


5. Rekeying and Deleting SAs โœจ

5.1. Rekeying SAs with the CREATE_CHILD_SA Exchange ๐Ÿ”„

Picking up from Section 4.1 of this document ๐Ÿ’–.

NEW-1.3.2 Rekeying IKE_SAs with the CREATE_CHILD_SA Exchange

The CREATE_CHILD_SA request for rekeying an IKE_SA looks like this:

    Initiator                                 Responder
   -----------                               -----------
    HDR, SK {SA, Ni, [KEi]} -->

The initiator sends SA offer(s) in the SA payload, a nonce in the Ni payload, and optionally a Diffie-Hellman value in the KEi payload ๐ŸŽ.

The CREATE_CHILD_SA response for rekeying an IKE_SA looks like this:

                                   <--    HDR, SK {SA, Nr, [KEr]}

The responder replies (using the same Message ID to respond) with the accepted offer in an SA payload, a nonce in the Nr payload, and, optionally, a Diffie-Hellman value in the KEr payload ๐Ÿ’œ.

The new IKE_SA has its message counters set to 0, no matter what they were in the earlier IKE_SA ๐Ÿซง. The window size starts at 1 for any new IKE_SA. The new initiator and responder SPIs are supplied in the SPI fields of the SA payloads ๐Ÿฆ‹.

NEW-1.3.3 Rekeying CHILD_SAs with the CREATE_CHILD_SA Exchange

The CREATE_CHILD_SA request for rekeying a CHILD_SA looks like this:

    Initiator                                 Responder
   -----------                               -----------
    HDR, SK {N(REKEY_SA), [N+], SA,
        Ni, [KEi], TSi, TSr}  -->

The leading Notify payload of type REKEY_SA identifies the CHILD_SA being rekeyed, and it contains the SPI that the initiator expects in the headers of inbound packets ๐ŸŽฏ. The initiator also sends SA offer(s) in the SA payload, a nonce in the Ni payload, optionally a Diffie-Hellman value in the KEi payload, and the proposed traffic selectors in the TSi and TSr payloads ๐Ÿง. The request can also contain Notify payloads that give additional details for the CHILD_SA โœจ.

The CREATE_CHILD_SA response for rekeying a CHILD_SA looks like this:

                                   <--    HDR, SK {[N+], SA, Nr,
                                                [KEr], TSi, TSr}

The responder replies with the accepted offer in an SA payload, and with a Diffie-Hellman value in the KEr payload if KEi was included in the request and the selected cryptographic suite includes that group ๐ŸŒˆ.

The traffic selectors for traffic to be sent on that SA are specified in the TS payloads in the response. They may be a subset of what the initiator of the CHILD_SA proposed ๐Ÿซถ.

5.2. Rekeying the IKE_SA vs. Reauthentication ๐Ÿค”

Rekeying the IKE_SA and reauthentication are different concepts in IKEv2 ๐Ÿ’…. Rekeying the IKE_SA sets up new keys for the IKE_SA and resets the Message ID counters, but it does not authenticate the parties again (no AUTH or EAP payloads are involved) ๐Ÿ™…โ€โ™€๏ธ.

Rekeying the IKE_SA can matter a lot in some environments, but reauthentication (checking that the parties still have access to the long-term credentials) is often even more important ๐Ÿ”.

IKEv2 doesn't have any special support for reauthentication. Instead, reauthentication is done by creating a new IKE_SA from scratch (using IKE_SA_INIT/IKE_AUTH exchanges, without any REKEY_SA notify payloads), creating new CHILD_SAs within the new IKE_SA (without REKEY_SA notify payloads), and finally deleting the old IKE_SA, which deletes the old CHILD_SAs as well ๐Ÿงน.

That means reauthentication also sets up new keys for the IKE_SA and CHILD_SAs ๐Ÿ—๏ธ. So while rekeying can happen more often than reauthentication, the situation where "authentication lifetime" is shorter than "key lifetime" doesn't really make sense ๐Ÿ™ƒ.

Creation of a new IKE_SA can be started by either party (the initiator or the responder of the original IKE_SA). In practice, though, the use of EAP authentication and/or configuration payloads means that reauthentication has to be started by the same party that started the original IKE_SA ๐Ÿ‘‘. The IKEv2 base specification does not let the responder request reauthentication in this case. However, this functionality is added in [ReAuth] โœจ.

(References: "Reauthentication in IKEv2" thread, Oct/Nov 2004.)

5.3. SPIs When Rekeying the IKE_SA ๐Ÿชช

Section 2.18 says that "New initiator and responder SPIs are supplied in the SPI fields". This refers to the SPI fields in the Proposal structures inside the Security Association (SA) payloads ๐Ÿ“ฆ, not the SPI fields in the IKE header ๐Ÿ™…โ€โ™€๏ธ.

(References: Tom Stiemerling's mail "Rekey IKE SA", 2005-01-24. Geoffrey Huang's reply, 2005-01-24.)

5.4. SPI When Rekeying a CHILD_SA ๐ŸŽฏ

Section 3.10.1 says that in REKEY_SA notifications, "The SPI field identifies the SA being rekeyed." ๐Ÿ’œ

Since CHILD_SAs always exist in pairs, there are two different SPIs ๐Ÿ‘ฏโ€โ™€๏ธ. The SPI placed in the REKEY_SA notification is the SPI the exchange initiator would expect in inbound ESP or AH packets, just like in Delete payloads ๐Ÿซถ.

5.5. Changing PRFs When Rekeying the IKE_SA ๐Ÿ”

When rekeying the IKE_SA, Section 2.18 says that "SKEYSEED for the new IKE_SA is computed using SK_d from the existing IKE_SA as follows:

   SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr)

"

If the old and new IKE_SA picked different PRFs, it's not totally clear which one should be used ๐Ÿคทโ€โ™€๏ธ.

Since the rekeying exchange belongs to the old IKE_SA, the old IKE_SA's PRF is the one that gets used ๐Ÿ’–. This also follows the principle that the same key (the old SK_d) should not be used with multiple cryptographic algorithms ๐Ÿ”.

Note that this may work poorly if the new IKE_SA's PRF has a fixed key size, since the PRF output may not be the correct size ๐Ÿ˜ฌ. This backs up our earlier opinion in the document that using PRFs with a fixed key size is a bad idea ๐Ÿ™…โ€โ™€๏ธ.

(References: "Changing PRFs when rekeying the IKE_SA" thread, June 2005.)

5.6. Deleting vs. Closing SAs ๐Ÿ—‘๏ธ

The IKEv2 specification talks about "closing" and "deleting" SAs, but it isn't always clear what exactly is meant ๐Ÿ™ƒ. Still, other parts of the specification make it clear that when local state related to a CHILD_SA is removed, the SA must also be actively deleted with a Delete payload ๐Ÿงน.

In particular, Section 2.4 says that "If an IKE endpoint chooses to delete CHILD_SAs, it MUST send Delete payloads to the other end notifying it of the deletion". Section 1.4 also explains that "ESP and AH SAs always exist in pairs, with one SA in each direction. When an SA is closed, both members of the pair MUST be closed." ๐Ÿซถ

5.7. Deleting a CHILD_SA Pair ๐Ÿฆ‹

okay so Section 1.4 explains how to delete SA pairs using the Informational exchange, and it says: "To delete an SA, an INFORMATIONAL exchange with one or more delete payloads is sent listing the SPIs (as they would be expected in the headers of inbound packets) of the SAs to be deleted. The recipient MUST close the designated SAs."

the "one or more delete payloads" bit has caused some confusion ๐Ÿ™ˆ bestie, you never send delete payloads for the two sides of an SA in a single message. if you have a bunch of SAs to delete at once (like the nested example in that paragraph), you include delete payloads for the inbound half of each SA in your Informational exchange โœจ

5.8. Deleting an IKE_SA ๐Ÿ’œ

IKE_SAs don't come in pairs, so it's not totally clear what the response should contain when the request deleted the IKE_SA ๐Ÿค”

since there's no info that needs to go back to the other side (except that the request was received), an empty Informational response seems like the most logical choice ๐Ÿ’…

(References: "Question about delete IKE SA" thread, May 2005.)

5.9. Who is the original initiator of IKE_SA ๐ŸŒธ

in the IKEv2 document, "initiator" refers to the party who initiated the exchange being described, and "original initiator" refers to the party who initiated the whole IKE_SA. but it's kinda confusing because the IKE_SA can be rekeyed by either party ๐Ÿ˜ญ

so to clear this up, we propose that "original initiator" always refers to the party who initiated the exchange that resulted in the current IKE_SA. in other words, if the "original responder" starts rekeying the IKE_SA, that party becomes the "original initiator" of the new IKE_SA. main character glow-up ๐Ÿ‘‘

(References: Paul Hoffman's mail "Original initiator in IKEv2", 2005-04-21.)

5.10. Comparing Nonces ๐ŸŽ€

Section 2.8 about rekeying says that "If redundant SAs are created though such a collision, the SA created with the lowest of the four nonces used in the two exchanges SHOULD be closed by the endpoint that created it."

here, "lowest" means an octet-by-octet (lexicographical) comparison, NOT comparing the nonces as big integers ๐Ÿ™…โ€โ™€๏ธ you start by comparing the first octet; if they're equal, move to the next one, and so on. if you hit the end of one nonce, that nonce is the lower one โœจ

(References: "IKEv2 rekeying question" thread, July 2005.)

5.11. Exchange Collisions ๐Ÿ’ฅ

since IKEv2 exchanges can be started by both peers, it's possible that two exchanges affecting the same SA partly overlap. this can leave the SA state temporarily out of sync, so a peer can get a request it can't process in the normal way. some of these corner cases are covered in the spec, and some aren't ๐Ÿ˜ฌ

and yes, using a window size greater than one makes things infinitely more complex, especially if requests get processed out of order. in this section we're focusing on the problems that can pop up even with window size 1 ๐Ÿซถ

(References: "IKEv2: invalid SPI in DELETE payload" thread, Dec 2005/ Jan 2006. "Problem with exchanges collisions" thread, Dec 2005.)

5.11.1. Simultaneous CHILD_SA Close ๐Ÿ‘ฏ

the simplest case is when both peers decide to close the same CHILD_SA pair at the same time:

   Host A                      Host B
  --------                    --------
   send req1: D(SPIa) -->
                           <-- send req2: D(SPIb)
                           --> recv req1
                           <-- send resp1: ()
   recv resp1
   recv req2
   send resp2: () -->
                           --> recv resp2

this is described in Section 1.4, and it's handled by leaving the Delete payloads out of the response messages ๐Ÿ’–

5.11.2. Simultaneous IKE_SA Close ๐Ÿฅ€

both peers can also decide to close the IKE_SA at the same time. the end result is obvious, but in some cases the final exchanges might not fully complete ๐Ÿ˜ตโ€๐Ÿ’ซ

   Host A                      Host B
  --------                    --------
   send req1: D() -->
                           <-- send req2: D()
                           --> recv req1

at this point, host B should reply as usual (with empty Informational response), close the IKE_SA, and stop retransmitting req2. the reason is that once host A gets resp1, it might not be able to reply anymore. the situation is symmetric, so host A should behave the same way ๐Ÿชž

   Host A                      Host B
  --------                    --------
                           <-- send resp1: ()
   send resp2: ()

even if neither resp1 nor resp2 ever arrives, the end result is still correct: the IKE_SA is gone ๐Ÿซ  same goes if host A never receives req2.

5.11.3. Simultaneous CHILD_SA Rekeying ๐Ÿ”

another case the spec covers is simultaneous rekeying. Section 2.8 says:

"If the two ends have the same lifetime policies, it is possible that both will initiate a rekeying at the same time (which will result in redundant 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).

This form of rekeying may temporarily result in multiple similar SAs between the same pairs of nodes. When there are two SAs eligible to receive packets, a node MUST accept incoming packets through either SA. If redundant SAs are created though such a collision, the SA created with the lowest of the four nonces used in the two exchanges SHOULD be closed by the endpoint that created it."

however, the spec doesn't explain much about what this means for implementations, and that needs a better explanation ๐Ÿ™„ let's say hosts A and B have an existing IPsec SA pair with SPIs (SPIa1,SPIb1), and both start rekeying it at the same time:

   Host A                      Host B
  --------                    --------
   send req1: N(REKEY_SA,SPIa1),
      SA(..,SPIa2,..),Ni1,..  -->
                           <-- send req2: N(REKEY_SA,SPIb1),
                                  SA(..,SPIb2,..),Ni2,..
   recv req2 <--

at this point, A knows there's a simultaneous rekeying going on. but it can't know yet which exchange will have the lowest nonce, so it just notes the situation and responds as usual ๐Ÿง

   send resp2: SA(..,SPIa3,..),Nr1,.. -->
                           --> recv req1

now B knows about the simultaneous rekeying too. just like host A, it has to respond as usual ๐Ÿ’โ€โ™€๏ธ

                           <-- send resp1: SA(..,SPIb3,..),Nr2,..
   recv resp1 <--
                           --> recv resp2

now there are three CHILD_SA pairs between A and B (the old one and two new ones) ๐Ÿ˜ณ A and B can compare the nonces. say the lowest nonce was Nr1 in message resp2. then B (the sender of req2) deletes the redundant new SA, and A (the node that initiated the surviving rekeyed SA) deletes the old one โœ‚๏ธ

   send req3: D(SPIa1) -->
                           <-- send req4: D(SPIb2)
                           --> recv req3
                           <-- send resp4: D(SPIb1)
   recv req4 <--
   send resp4: D(SPIa3) -->

and the rekeying is finished ๐ŸŽ‰

but there's a second possible sequence if some packets get lost and retransmissions kick in. the rekeying starts as usual, but A's first packet (req1) gets lost ๐Ÿฅฒ

   Host A                      Host B
  --------                    --------
   send req1: N(REKEY_SA,SPIa1),
      SA(..,SPIa2,..),Ni1,..  -->  (lost)
                           <-- send req2: N(REKEY_SA,SPIb1),
                                  SA(..,SPIb2,..),Ni2,..
   recv req2 <--
   send resp2: SA(..,SPIa3,..),Nr1,.. -->
                           --> recv resp2
                           <-- send req3: D(SPIb1)
   recv req3 <--
   send resp3: D(SPIa1) -->
                           --> recv resp3

from B's point of view, the rekeying is done. since it hasn't received A's req1, it doesn't even know there was simultaneous rekeying. but A keeps retransmitting that message, and eventually it reaches B ๐Ÿ“ฌ

   resend req1 -->
                            --> recv req1

so what should B do now? to B, it looks like A is trying to rekey an SA that no longer exists. so failing the request with something non-fatal like NO_PROPOSAL_CHOSEN seems like a reasonable approach ๐Ÿคทโ€โ™€๏ธ

                            <-- send resp1: N(NO_PROPOSAL_CHOSEN)
   recv resp1 <--

when A gets this error, it already knows there was simultaneous rekeying, so it can ignore the error message ๐Ÿ’…

5.11.4. Simultaneous IKE_SA Rekeying ๐ŸŒ€

this is probably the most complicated case: both peers try to rekey the IKE_SA at the same time. basically, the text in Section 2.8 applies here too, but it's super important to make sure the CHILD_SAs get inherited by the right IKE_SA ๐Ÿ‘‘

if both endpoints notice the simultaneous rekeying, it works the same way as with CHILD_SAs. after the CREATE_CHILD_SA exchanges, three IKE_SAs exist between A and B. the one with the lowest nonce inherits the CHILD_SAs โœจ

but there's a twist in the other case, where one rekeying finishes first:

   Host A                      Host B
  --------                    --------
   send req1:
      SA(..,SPIa1,..),Ni1,.. -->
                           <-- send req2: SA(..,SPIb1,..),Ni2,..
                           --> recv req1
                           <-- send resp1: SA(..,SPIb2,..),Nr2,..
   recv resp1 <--
   send req3: D() -->
                           --> recv req3

now host B sees a request to close the IKE_SA. there's not much to do besides replying as usual. but host B should stop retransmitting req2, since once host A gets resp3, it'll delete all the state tied to the old IKE_SA and won't be able to reply to it anymore ๐Ÿ˜ญ

                           <-- send resp3: ()

5.11.5. Closing and Rekeying a CHILD_SA ๐Ÿ™ƒ

a case similar to simultaneous rekeying can happen if one peer decides to close an SA while the other tries to rekey it:

   Host A                      Host B
  --------                    --------
   send req1: D(SPIa) -->
                           <-- send req2: N(REKEY_SA,SPIb),SA,..
                           --> recv req1

at this point, host B notices that host A is trying to close an SA that host B is currently rekeying. replying as usual is probably the best move ๐Ÿฆ‹

                           <-- send resp1: D(SPIb)

depending on the order req2 and resp1 arrive in, host A sees either a request to rekey an SA it's currently closing, or a request to rekey an SA that doesn't exist. either way, NO_PROPOSAL_CHOSEN is probably fine ๐ŸŒธ

   recv req2
   recv resp1
   send resp2: N(NO_PROPOSAL_CHOSEN) -->
                           --> recv resp2

5.11.6. Closing a New CHILD_SA โœจ

Okay, this one is so relatable ๐Ÿ’… Host A creates a CHILD_SA pair, and then, like, soon after, host B changes its mind and wants to delete it (maybe its policy changed ๐Ÿ™ˆ):

   Host A                      Host B
  --------                    --------
   send req1: [N(REKEY_SA,SPIa1)],
      SA(..,SPIa2,..),.. -->
                           --> recv req1
                    (lost) <-- send resp1: SA(..,SPIb2,..),..

                           <-- send req2: D(SPIb2)
   recv req2

At this point, host A hasn't gotten resp1 yet (it's still retransmitting req1), so it doesn't recognize SPIb in req2. So what should host A do? ๐Ÿค”

One option is to reply with an empty Informational response. But ngl, that same reply would also go out if host A had already received resp1 and then sent a brand new request to delete the SA that was just created. Then the peers are no longer in sync about which SAs exist between them ๐Ÿ˜ญ Still, host B would eventually notice that the other half of the CHILD_SA pair never got deleted. Section 1.4 covers this case and says that "a node SHOULD regard half-closed connections as anomalous and audit their existence should they persist", and then continues that "if connection state becomes sufficiently messed up, a node MAY close the IKE_SA".

Another idea that's been floated is replying with an INVALID_SPI notification that contains SPIb. That would explicitly tell host B the SA wasn't deleted, so host B could try again later. Iconic, but this usage isn't part of the IKEv2 specification, and it wouldn't match the normal use of INVALID_SPI, where the data field holds the SPI the recipient would put in outbound packets. Not it ๐Ÿ™…โ€โ™€๏ธ

Yet another option would be to ignore req2 for now and wait until we've received resp1. But this one hasn't been fully analyzed yet. In general, ignoring valid requests is always a bit dangerous, because both endpoints could do it, and then you're stuck in a deadlock ๐Ÿ’€

This document recommends the first alternative. ๐ŸŽ€


5.11.7. Rekeying a New CHILD_SA ๐Ÿฆ‹

Another plot twist: a CHILD_SA gets rekeyed right after it was created:

   Host A                      Host B
  --------                    --------
   send req1: [N(REKEY_SA,SPIa1)],
      SA(..,SPIa2,..),..  -->
                    (lost) <-- send resp1: SA(..,SPIb2,..),..

                           <-- send req2: N(REKEY_SA,SPIb2),
                                  SA(..,SPIb3,..),..
   recv req2 <--

To host A, this looks like a request to rekey an SA that doesn't exist. Just like in the simultaneous rekeying case, replying with NO_PROPOSAL_CHOSEN is probably reasonable:

   send resp2: N(NO_PROPOSAL_CHOSEN) -->
   recv resp1

5.11.8. Collisions with IKE_SA Rekeying ๐ŸŒธ

Now for a messier group chat moment. This happens when one peer starts rekeying the IKE_SA at the same time the other peer starts creating, rekeying, or closing a CHILD_SA. Say host B starts creating a CHILD_SA, and then soon after, host A starts rekeying the IKE_SA:

   Host A                      Host B
  --------                    --------
                           <-- send req1: SA,Ni1,TSi,TSr
   send req2: SA,Ni2,.. -->
                           --> recv req2

So what should host B do here? Replying as usual seems like a totally reasonable choice:

                           <-- send resp2: SA,Ni2,..
   recv resp2 <--
   send req3: D() -->
                           --> recv req3

But here's the problem ๐Ÿ˜ฌ If host B now replies normally with an empty Informational response, host A will delete the state associated with the IKE_SA. That means host B should stop retransmitting req1. However, host B can't know whether host A actually received req1. If host A did get it, host A will move the CHILD_SA to the new IKE_SA as usual, and then the state information will be out of sync.

It seems this situation is tricky to handle correctly. Our proposal is as follows: if a host receives a request to rekey the IKE_SA while it has CHILD_SAs in "half-open" state (currently being created or rekeyed), it should reply with NO_PROPOSAL_CHOSEN. If a host receives a request to create or rekey a CHILD_SA after it has started rekeying the IKE_SA, it should reply with NO_ADDITIONAL_SAS.

The case where CHILD_SAs are being closed is even worse ๐Ÿ˜ญ Our recommendation: if a host receives a request to rekey the IKE_SA while it has CHILD_SAs in "half-closed" state (currently being closed), it should reply with NO_PROPOSAL_CHOSEN. And if a host receives a request to close a CHILD_SA after it has started rekeying the IKE_SA, it should reply with an empty Informational response. This makes sure that at least the other peer will eventually notice the CHILD_SA is still in "half-closed" state, and it will start a new IKE_SA from scratch. โœจ


5.11.9. Closing and Rekeying the IKE_SA ๐Ÿ’œ

The final case in this section happens if one peer decides to close the IKE_SA while the other peer tries to rekey it:

   Host A                      Host B
  --------                    --------
   send req1: SA(..,SPIa1,..),Ni1 -->
                           <-- send req2: D()
                           --> recv req1
   recv req2 <--

At this point, host B should probably reply with NO_PROPOSAL_CHOSEN, and host A should reply as usual, close the IKE_SA, and stop retransmitting req1.

                           <-- send resp1: N(NO_PROPOSAL_CHOSEN)
   send resp2: ()

If host A wants to keep talking to B, it can now start a new IKE_SA. ๐Ÿซถ


5.11.10. Summary ๐Ÿ“

If a host receives a request to rekey:

  • a CHILD_SA pair that the host is currently trying to close: reply with NO_PROPOSAL_CHOSEN.
  • a CHILD_SA pair that the host is currently rekeying: reply as usual, but prepare to close redundant SAs later based on the nonces.
  • a CHILD_SA pair that does not exist: reply with NO_PROPOSAL_CHOSEN.
  • the IKE_SA, and the host is currently rekeying the IKE_SA: reply as usual, but prepare to close redundant SAs and move inherited CHILD_SAs later based on the nonces.
  • the IKE_SA, and the host is currently creating, rekeying, or closing a CHILD_SA: reply with NO_PROPOSAL_CHOSEN.
  • the IKE_SA, and the host is currently trying to close the IKE_SA: reply with NO_PROPOSAL_CHOSEN.

If a host receives a request to close:

  • a CHILD_SA pair that the host is currently trying to close: reply without Delete payloads.
  • a CHILD_SA pair that the host is currently rekeying: reply as usual, with Delete payload.
  • a CHILD_SA pair that does not exist: reply without Delete payloads.
  • the IKE_SA, and the host is currently rekeying the IKE_SA: reply as usual, and forget about our own rekeying request.
  • the IKE_SA, and the host is currently trying to close the IKE_SA: reply as usual, and forget about our own close request.

If a host receives a request to create or rekey a CHILD_SA when it is currently rekeying the IKE_SA: reply with NO_ADDITIONAL_SAS.

If a host receives a request to delete a CHILD_SA when it is currently rekeying the IKE_SA: reply without Delete payloads.


5.12. Diffie-Hellman and Rekeying the IKE_SA ๐Ÿงš

There's been some confusion about whether doing a new Diffie-Hellman exchange is mandatory when the IKE_SA gets rekeyed. ๐Ÿคทโ€โ™€๏ธ

Here's the tea: it seems this case is allowed by the IKEv2 specification. Section 2.18 shows the Diffie-Hellman term (g^ir) in brackets. Section 3.3.3 doesn't contradict this when it says that including the D-H transform is mandatory. Although including the transform is mandatory, it can contain the value "NONE".

However, having the option to skip the Diffie-Hellman exchange when rekeying the IKE_SA doesn't add any useful functionality to the protocol. The main purpose of rekeying the IKE_SA is to make sure that compromising old keying material doesn't reveal anything about the current keys, or vice versa. That requires doing the Diffie-Hellman exchange when rekeying. Honestly, this option would probably have been removed as unnecessary complexity if it had been discussed earlier ๐Ÿ’€

So we recommend that implementations have a hard-coded policy that requires performing a new Diffie-Hellman exchange when rekeying the IKE_SA. In other words, the initiator should not propose the value NONE for the D-H transform, and the responder should not accept such a proposal. This policy also means that a successful exchange rekeying the IKE_SA always includes the KEi/KEr payloads. ๐Ÿ”

(References: "Rekeying IKE_SAs with the CREATE_CHILD_SA exhange" thread, Oct 2005. "Comments of draft-eronen-ipsec-ikev2-clarifications-02.txt" thread, Apr 2005.)


6. Configuration Payloads ๐ŸŽ€

6.1. Assigning IP Addresses ๐ŸŒˆ

Section 2.9 talks about traffic selector negotiation and mentions that "In support of the scenario described in section 1.1.3, an initiator may request that the responder assign an IP address and tell the initiator what it is."

This sentence is correct, but the placement is kinda confusing ๐Ÿ™ˆ IKEv2 does let the initiator request an IP address assignment from the responder, but that happens through configuration payloads, not traffic selector payloads. An address in a TSi payload in a response doesn't mean the responder has assigned that address to the initiator. It only means that if packets matching these traffic selectors are sent by the initiator, IPsec processing can be performed as agreed for this SA. The TSi payload itself doesn't give the initiator permission to configure its TCP/IP stack with the address and use it as its source address. Not the vibe ๐Ÿ™…โ€โ™€๏ธ

In other words, IKEv2 doesn't have two different mechanisms for assigning addresses. It only has one: configuration payloads. In the scenario described in Section 1.1.3, both configuration and traffic selector payloads are usually included in the same message, and they often contain the same information in the response message (see Section 6.3 of this document for some examples). Even so, their semantics are still different ๐Ÿ’–

6.2. Requesting any INTERNAL_IP4/IP6_ADDRESS ๐ŸŽ€

Okay so when we're describing the INTERNAL_IP4_ADDRESS and INTERNAL_IP6_ADDRESS attributes, Section 3.15.1 says "In a request message, the address specified is a requested address (or zero if no specific address is requested)". ๐Ÿค” The real question is whether "zero" means an address of "0.0.0.0" or a zero-length string. Lowkey a very important question. ๐Ÿ’…

Earlier in that same section it also says "If an attribute in the CFG_REQUEST Configuration Payload is not zero-length, it is taken as a suggestion for that attribute". ๐Ÿซถ And the table of configuration attributes shows that INTERNAL_IP4_ADDRESS is either "0 or 4 octets", and INTERNAL_IP6_ADDRESS is either "0 or 17 octets".

So, if the client doesn't request a specific address, it includes a zero-length INTERNAL_IP4/IP6_ADDRESS attribute, not an attribute holding an all-zeroes address. โœจ That means the example in 2.19 is wrong, because it shows the attribute as "INTERNAL_ADDRESS(0.0.0.0)". ๐Ÿ˜ญ

However, since the value is only a suggestion, implementations are recommended to ignore suggestions they do not accept. In other words, they should treat a zero-length INTERNAL_IP4_ADDRESS, "0.0.0.0", and any other address the implementation doesn't recognize as a reasonable suggestion the same way. ๐Ÿงš


6.3. INTERNAL_IP4_SUBNET/INTERNAL_IP6_SUBNET ๐Ÿฆ‹

Section 3.15.1 describes INTERNAL_IP4_SUBNET as "The protected sub-networks that this edge-device protects. This attribute is made up of two fields: the first is an IP address and the second is a netmask. Multiple sub-networks MAY be requested. The responder MAY respond with zero or more sub-network attributes." INTERNAL_IP6_SUBNET is defined in a similar way. ๐ŸŒธ

This raises two questions. First, since this info is usually already in the TSr payload, what does this attribute actually add? ๐Ÿคจ Second, what does it even mean in CFG_REQUESTs? ๐Ÿ’€

For the first question, there seem to be two sensible interpretations. Clearly TSr (in an IKE_AUTH or CREATE_CHILD_SA response) tells you which subnets are reachable through the SA that was just created. โœจ

The first interpretation is that the INTERNAL_IP4/6_SUBNET attributes show additional subnets that can be reached through this gateway, but need a separate SA. ๐Ÿ“ Under this view, the attributes are mostly useful when they contain addresses that TSr doesn't include.

The second interpretation is that the INTERNAL_IP4/6_SUBNET attributes express the gateway's policy about what traffic should go through it. ๐Ÿ‘‘ The client can then decide whether other traffic (covered by TSr, but not by INTERNAL_IP4/6_SUBNET) goes through the gateway or straight to the destination. Under this view, the attributes are mostly useful when TSr contains addresses that aren't in the INTERNAL_IP4/6_SUBNET attributes.

Here's the tea โ˜•: these two interpretations aren't actually incompatible. They're two sides of the same principle. Traffic to the addresses listed in the INTERNAL_IP4/6_SUBNET attributes should be sent via this gateway. If there are no existing IPsec SAs whose traffic selectors cover the address in question, new SAs have to be created. ๐Ÿ”ฅ

Here are a couple of examples. Say there are two subnets, 192.0.1.0/26 and 192.0.2.0/24, and the client's request contains the following:

CP(CFG_REQUEST) =
  INTERNAL_IP4_ADDRESS()
TSi = (0, 0-65535, 0.0.0.0-255.255.255.255)
TSr = (0, 0-65535, 0.0.0.0-255.255.255.255)

Then a valid response could be this one (where TSr and INTERNAL_IP4_SUBNET contain the same information):

CP(CFG_REPLY) =
  INTERNAL_IP4_ADDRESS(192.0.1.234)
  INTERNAL_IP4_SUBNET(192.0.1.0/255.255.255.192)
  INTERNAL_IP4_SUBNET(192.0.2.0/255.255.255.0)
TSi = (0, 0-65535, 192.0.1.234-192.0.1.234)
TSr = ((0, 0-65535, 192.0.1.0-192.0.1.63),
       (0, 0-65535, 192.0.2.0-192.0.2.255))

In these cases, the INTERNAL_IP4_SUBNET doesn't really carry any useful info. ๐Ÿ™ˆ Another possible reply would be this:

CP(CFG_REPLY) =
  INTERNAL_IP4_ADDRESS(192.0.1.234)
  INTERNAL_IP4_SUBNET(192.0.1.0/255.255.255.192)
  INTERNAL_IP4_SUBNET(192.0.2.0/255.255.255.0)

TSi = (0, 0-65535, 192.0.1.234-192.0.1.234)
TSr = (0, 0-65535, 0.0.0.0-255.255.255.255)

This would mean the client can send all of its traffic through the gateway, but the gateway doesn't mind if the client sends traffic that isn't covered by INTERNAL_IP4_SUBNET straight to the destination, without going through the gateway. ๐Ÿฆ‹

A different situation comes up if the gateway has a policy that requires traffic for the two subnets to be carried in separate SAs. โญ In that case, a response like this tells the client that if it wants access to the second subnet, it needs to create a separate SA:

CP(CFG_REPLY) =
  INTERNAL_IP4_ADDRESS(192.0.1.234)
  INTERNAL_IP4_SUBNET(192.0.1.0/255.255.255.192)
  INTERNAL_IP4_SUBNET(192.0.2.0/255.255.255.0)
TSi = (0, 0-65535, 192.0.1.234-192.0.1.234)
TSr = (0, 0-65535, 192.0.1.0-192.0.1.63)

INTERNAL_IP4_SUBNET can also be useful if the client's TSr only included part of the address space. ๐Ÿงš For instance, if the client requests the following:

CP(CFG_REQUEST) =
  INTERNAL_IP4_ADDRESS()
TSi = (0, 0-65535, 0.0.0.0-255.255.255.255)
TSr = (0, 0-65535, 192.0.2.155-192.0.2.155)

Then the gateway's reply could be this:

CP(CFG_REPLY) =
  INTERNAL_IP4_ADDRESS(192.0.1.234)
  INTERNAL_IP4_SUBNET(192.0.1.0/255.255.255.192)
  INTERNAL_IP4_SUBNET(192.0.2.0/255.255.255.0)
TSi = (0, 0-65535, 192.0.1.234-192.0.1.234)
TSr = (0, 0-65535, 192.0.2.155-192.0.2.155)

It's less clear what these attributes mean in CFG_REQUESTs, and whether lengths other than zero make sense in that situation. (For INTERNAL_IP6_SUBNET, though, zero length isn't allowed at all!) ๐Ÿ˜ญ This document recommends that implementations should not include INTERNAL_IP4_SUBNET or INTERNAL_IP6_SUBNET attributes in CFG_REQUESTs. ๐Ÿซถ

For the IPv4 case, this document recommends using only netmasks made of some number of "1" bits followed by "0" bits. For example, "255.0.255.0" would not be a valid netmask for INTERNAL_IP4_SUBNET. ๐Ÿ”ฅ

It's also worth noting that the contents of the INTERNAL_IP4/6_SUBNET attributes don't imply link boundaries. ๐ŸŒˆ For instance, a gateway providing access to a large company intranet that uses addresses from 10.0.0.0/8 can send a single INTERNAL_IP4_SUBNET attribute (10.0.0.0/255.0.0.0), even if the intranet has hundreds of routers and separate links. ๐Ÿ’œ

(References: Tero Kivinen's mail "Intent of couple of attributes in Configuration Payload in IKEv2?", 2004-11-19. Srinivasa Rao Addepalli's mail "INTERNAL_IP4_SUBNET and INTERNAL_IP6_SUBNET in IKEv2", 2004-09-10. Yoav Nir's mail "Re: New I-D: IKEv2 Clarifications and Implementation Guidelines", 2005-02-07. "Clarifications open issue: INTERNAL_IP4_SUBNET/NETMASK" thread, April 2005.)


6.4. INTERNAL_IP4_NETMASK ๐Ÿ“

Section 3.15.1 defines the INTERNAL_IP4_NETMASK attribute and says that "The internal network's netmask. Only one netmask is allowed in the request and reply messages (e.g., 255.255.255.0) and it MUST be used only with an INTERNAL_IP4_ADDRESS attribute". ๐ŸŒธ

But honestly, it's not clear what this attribute actually means. The concept of "netmask" isn't very well defined for point-to-point links. On multi-access links it means "you can reach hosts inside this netmask directly using layer 2, instead of sending packets via a router", but that doesn't translate neatly to point-to-point. ๐Ÿคทโ€โ™€๏ธ Even if the operating system's TCP/IP stack needs a netmask configured, for point-to-point links it could just be set to 255.255.255.255. So, why is this info sent in IKEv2? ๐Ÿ™ˆ

One possible interpretation is that the host is given a whole block of IP addresses instead of a single address. ๐Ÿง  This is also what Framed-IP-Netmask does in [RADIUS], what the IPCP "subnet mask" extension does in PPP [IPCPSubnet], and what the prefix length in the IPv6 Framed-IPv6-Prefix attribute does in [RADIUS6]. However, nothing in the specification supports this interpretation, and discussions on the IPsec WG mailing list confirmed it wasn't intended. Section 3.15.1 also says that multiple addresses are assigned using multiple INTERNAL_IP4/6_ADDRESS attributes. ๐Ÿ’…

Right now, this document's interpretation is this: INTERNAL_IP4_NETMASK in a CFG_REPLY roughly means the same thing as an INTERNAL_IP4_SUBNET with the same info ("send traffic to these addresses through me"), but it also implies a link boundary. โœจ For example, the client could use its own address and the netmask to work out the link's broadcast address. (Whether the gateway actually delivers broadcast packets to other VPN clients and/or other nodes on this link is a different story. ๐Ÿ‘€)

An empty INTERNAL_IP4_NETMASK attribute can be included in a CFG_REQUEST to ask for this info, although the gateway can send it even when it wasn't requested. ๐ŸŽ€ However, it seems that non-empty values for this attribute don't make sense in CFG_REQUESTs.

Good news though! Section 4 clearly says that a minimal implementation doesn't need to include or understand the INTERNAL_IP4_NETMASK attribute. So this document recommends that implementations should not use INTERNAL_IP4_NETMASK, or assume that the other peer supports it. ๐Ÿซถ๐Ÿฆ‹

(References: Charlie Kaufman's mail "RE: Proposed Last Call based revisions to IKEv2", 2004-05-27. Email discussion with Tero Kivinen, Jan 2005. Yoav Nir's mail "Re: New I-D: IKEv2 Clarifications and Implementation Guidelines", 2005-02-07. "Clarifications open issue: INTERNAL_IP4_SUBNET/NETMASK" thread, April 2005.)

6.5. Configuration Payloads for IPv6 ๐Ÿ’–

Okay so IKEv2 also has configuration payloads for IPv6 ๐ŸŽ€ But bestie, they're basically copied from the IPv4 ones and they don't fully vibe with the "normal IPv6 way of doing things" ๐Ÿ’…

A client can get an IPv6 address through the INTERNAL_IP6_ADDRESS configuration payload. A minimal exchange looks like this โœจ

     CP(CFG_REQUEST) =
       INTERNAL_IP6_ADDRESS()
       INTERNAL_IP6_DNS()
     TSi = (0, 0-65535, :: - FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF)
     TSr = (0, 0-65535, :: - FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF)

     CP(CFG_REPLY) =
       INTERNAL_IP6_ADDRESS(2001:DB8:0:1:2:3:4:5/64)
       INTERNAL_IP6_DNS(2001:DB8:99:88:77:66:55:44)
     TSi = (0, 0-65535, 2001:DB8:0:1:2:3:4:5 - 2001:DB8:0:1:2:3:4:5)
     TSr = (0, 0-65535, :: - FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF)

Super important detail ๐Ÿ‘€ IPv6 stateless autoconfiguration, router advertisement messages, and neighbor discovery are not used here. Not even a little ๐Ÿ™ˆ

The client can also send a non-empty INTERNAL_IP6_ADDRESS attribute in the CFG_REQUEST if it wants a specific address or interface identifier ๐Ÿฆ‹ The gateway checks first whether that address is acceptable, and if it is, it hands that exact one back. If it's not acceptable, the gateway tries that interface identifier with some other prefix. And if that also fails, the gateway picks a totally different interface identifier ๐Ÿ˜ญ

The INTERNAL_IP6_ADDRESS attribute also has a prefix length field. When it shows up in a CFG_REPLY, it's the IPv6 version of the INTERNAL_IP4_NETMASK attribute from the IPv4 side (and yes, it used to be called INTERNAL_IP6_NETMASK in earlier IKEv2 drafts ๐ŸŒธ). Check the previous section for the full scoop.

This approach is reasonably simple, but it has some limitations ngl ๐Ÿฅบ IPsec tunnels set up with IKEv2 are not fully-featured "interfaces" in the IPv6 addressing architecture [IPv6Addr] sense. They don't necessarily have link-local addresses, which can make protocols that expect them, like [MLDv2], a bit of a mess ๐Ÿ’€ (Whether they get called "interfaces" in some particular operating system is a totally different drama.)

(References: "VPN remote host configuration IPv6 ?" thread, May 2004. "Clarifications open issue: INTERNAL_IP4_SUBNET/NETMASK" thread, April 2005.)

6.6. INTERNAL_IP6_NBNS ๐Ÿงš

Section 3.15.1 defines the INTERNAL_IP6_NBNS attribute, which is for sending the IPv6 address of NetBIOS name servers.

Here's the tea ๐Ÿซ– NetBIOS isn't defined for IPv6 and probably never will be. So this attribute most likely doesn't make much sense.

(Pointed out by Bernard Aboba in the IP Configuration Security (ICOS) BoF at IETF62.)

6.7. INTERNAL_ADDRESS_EXPIRY โณ

Section 3.15.1 defines the INTERNAL_ADDRESS_EXPIRY attribute as "Specifies the number of seconds that the host can use the internal IP address. The host MUST renew the IP address before this expiry time. Only one of these attributes MAY be present in the reply."

Expiry times and explicit renewals are mostly useful in environments like DHCP, where the server can't reliably know when the client has ghosted ๐Ÿ‘ป In IKEv2, though, the gateway does know. It can just free the address when the IKE_SA gets deleted ๐ŸŽ‰

Also, Section 4 says that supporting renewals is not mandatory. Since this feature is usually not needed, we recommend that gateways should not send the INTERNAL_ADDRESS_EXPIRY attribute ๐Ÿ’… (And since this attribute doesn't really make sense in CFG_REQUESTs, clients should not send it either.)

Note that according to Section 4, clients are required to understand INTERNAL_ADDRESS_EXPIRY if they receive it. A minimum implementation would use the value to limit the lifetime of the IKE_SA โœจ

(References: Tero Kivinen's mail "Comments of draft-eronen-ipsec-ikev2-clarifications-02.txt", 2005-04-05. "Questions about internal address" thread, April 2005.)

6.8. Address Assignment Failures ๐Ÿ™ƒ

If the responder runs into an error while trying to assign an IP address to the initiator, it replies with an INTERNAL_ADDRESS_FAILURE notification, as described in Section 3.10.1. But there are some more complicated error cases too ๐Ÿ˜ฉ

First up, if the responder doesn't support configuration payloads at all, it can just ignore all of them. This kind of implementation never sends INTERNAL_ADDRESS_FAILURE notifications. If the initiator needs an IP address assigned, it will treat a response without CFG_REPLY as an error.

Second, the responder might support configuration payloads but only for one type of address (IPv4 or IPv6). Section 4 says that "A minimal IPv4 responder implementation will ignore the contents of the CP payload except to determine that it includes an INTERNAL_IP4_ADDRESS attribute". So if the initiator includes both INTERNAL_IP4_ADDRESS and INTERNAL_IP6_ADDRESS in the CFG_REQUEST, an IPv4-only responder can simply ignore the IPv6 part and handle the IPv4 request as usual ๐ŸŒˆ

Third, the initiator might request several addresses of a type the responder does support. What should happen if some, but not all, of those requests fail? It seems an optimistic approach would be the best here. If the responder can assign at least one address, it replies with those. It only sends INTERNAL_ADDRESS_FAILURE if no addresses can be assigned at all ๐Ÿซถ

(References: "ikev2 and internal_ivpn_address" thread, June 2005.)

7. Miscellaneous Issues ๐Ÿง

7.1. Matching ID_IPV4_ADDR and ID_IPV6_ADDR ๐Ÿ”

When you use the ID_IPV4_ADDR/ID_IPV6_ADDR identity types in IDi/IDr payloads, IKEv2 doesn't require that address to match anything in the TSi/TSr payloads. For example, in a site-to-site VPN between two security gateways, the gateways could authenticate each other as ID_IPV4_ADDR(192.0.1.1) and ID_IPV4_ADDR(192.0.2.1). Then they could create a CHILD_SA protecting traffic between 192.0.1.55/32 (a host behind the first security gateway) and 192.0.2.240/28 (a network behind the second security gateway). The authenticated identities (IDi/IDr) get linked to the authorized traffic selectors (TSi/TSr) through "Child SA Authorization Data" in the Peer Authorization Database (PAD) ๐Ÿฆ‹

Also, IKEv2 doesn't require the addresses in ID_IPV4_ADDR/ID_IPV6_ADDR to match the address in the IP header of the IKE packets. However, other specifications might add their own requirements here. For example, [PKI4IPsec] requires that implementation must be capable of comparing the addresses in the ID_IPV4_ADDR/ID_IPV6_ADDR with the addresses in the IP header of the IKE packets, and this comparison must be enabled by default ๐Ÿ›ก๏ธ

(References: "Identities types IP address,FQDN/user FQDN and DN and its usage in preshared key authentication" thread, Jan 2005. "Matching ID_IPV4_ADDR and ID_IPV6_ADDR" thread, May 2006.)

7.2. Relationship of IKEv2 to RFC 4301 ๐Ÿค”

The IKEv2 specification refers to [RFC4301], but it never clearly spells out the exact relationship. Bestie, that's a lot of vibes and no definition ๐Ÿ˜ญ

Still, some requirements in the spec make it clear that IKEv2 requires [RFC4301]. In other words, an implementation doing IPsec processing strictly according to [RFC2401] can't be compliant with the IKEv2 specification ๐Ÿšซ

One example is in Section 2.24: "Specifically, tunnel encapsulators and decapsulators for all tunnel-mode SAs created by IKEv2 [...] MUST implement the tunnel encapsulation and decapsulation processing specified in [RFC4301] to prevent discarding of ECN congestion indications."

Honestly, though, the changes needed for existing [RFC2401] implementations aren't very big, especially since supporting many of the new features (like Extended Sequence Numbers) is optional ๐ŸŒธ

7.3. Reducing the Window Size ๐ŸชŸ

In IKEv2, the window size is treated as a (possibly configurable) property of a particular implementation. It's not related to congestion control, unlike the window size in TCP, for instance ๐Ÿ’œ

It's not defined what the responder should do when it gets a SET_WINDOW_SIZE notification with a smaller value than what's currently in effect. So right now there's no way to shrink the window size of an existing IKE_SA. However, when you rekey an IKE_SA, the new IKE_SA starts with window size 1 until it's explicitly increased by sending a new SET_WINDOW_SIZE notification ๐Ÿ”ฅ

(References: Tero Kivinen's mail "Comments of draft-eronen-ipsec-ikev2-clarifications-02.txt", 2005-04-05.)

7.4. Minimum Size of Nonces ๐ŸŽฒ

Section 2.10 says that "Nonces used in IKEv2 MUST be randomly chosen, MUST be at least 128 bits in size, and MUST be at least half the key size of the negotiated prf."

But here's the catch ๐Ÿ™ˆ The initiator picks its nonce before the outcome of the negotiation is known. So the nonce has to be long enough for all the PRFs being proposed.

7.5. Initial Zero Octets on Port 4500 ๐ŸŒŠ

It's not clear whether a peer sending an IKE_SA_INIT request on port 4500 should include the initial four zero octets ๐Ÿคทโ€โ™€๏ธ Section 2.23 explains how to upgrade to tunneling over port 4500 after message 2, but it doesn't say what to do if message 1 goes out on port 4500.

    IKE MUST listen on port 4500 as well as port 500.

    [...]

    The IKE initiator MUST check these payloads if present and if
    they do not match the addresses in the outer packet MUST tunnel
    all future IKE and ESP packets associated with this IKE_SA over
    UDP port 4500.

    To tunnel IKE packets over UDP port 4500, the IKE header has four
    octets of zero prepended and the result immediately follows the
    UDP header. [...]

The very beginning of Section 2 says "... though IKE messages may also be received on UDP port 4500 with a slightly different format (see section 2.23)."

That "slightly different format" only gets described when talking about what to do after switching to port 4500 ๐Ÿ˜ฉ However, [RFC3948] clearly shows the format has the initial zeros even for initiators on port 4500. And without those initial zeros, the processing engine can't tell whether a packet is an IKE packet or an ESP packet.

So all packets sent on port 4500 need the four-zero prefix. Otherwise, the receiver won't know how to handle them ๐Ÿ’€

7.6. Destination Port for NAT Traversal ๐Ÿ›ฐ๏ธ

Section 2.23 says that "an IPsec endpoint that discovers a NAT between it and its correspondent MUST send all subsequent traffic to and from port 4500".

This sentence is kinda misleading ngl. The peer "outside" the NAT uses source port 4500 for the traffic it sends. But the destination port is, of course, taken from packets sent by the peer behind the NAT. That port number is usually dynamically allocated by the NAT ๐Ÿฆ‹

7.7. SPI Values for Messages outside an IKE_SA โœจ

Okay so the IKEv2 spec is kinda unclear about which SPI values go in the IKE header for the small handful of notifications that are allowed to be sent outside an IKE_SA ๐Ÿค” Quick heads up: these notifications are explicitly NOT Informational exchanges. Section 1.5 makes it clear they're one-way messages that must not be responded to. ๐Ÿ™…โ€โ™€๏ธ

There are only two cases where one of these one-way notifications can be sent: INVALID_IKE_SPI and INVALID_SPI. ๐Ÿฆ‹

For INVALID_IKE_SPI, the message is a response message, and Section 2.21 says that "If a response is sent, the response MUST be sent to the IP address and port from whence it came with the same IKE SPIs and the Message ID copied." So that one's pretty straightforward, bestie. ๐Ÿ’–

INVALID_SPI is the messy one ๐Ÿ˜ญ There are no IKE SPI values that would actually mean anything to the recipient, and the message is now an INFORMATIONAL request. A strict reading would make the sender invent garbage values for the SPI fields. We don't think that was the intention, though, so using zero values is acceptable. ๐Ÿงš

(References: "INVALID_IKE_SPI" thread, June 2005.)

7.8. Protocol ID/SPI Fields in Notify Payloads ๐ŸŽ€

Section 3.10 says that the Protocol ID field in Notify payloads "For notifications that do not relate to an existing SA, this field MUST be sent as zero and MUST be ignored on receipt". Iconic rule, but the spec doesn't clearly say which notifications relate to existing SAs and which don't ๐Ÿ™ˆ

Since the whole point of the Protocol ID field is to say what type of SPI you're carrying, our take is that it should be non-zero only when the SPI field is non-empty. Makes sense, right? ๐Ÿ’…

There are currently only two notifications where this is the case: INVALID_SELECTORS and REKEY_SA. ๐Ÿ”ฅ

7.9. Which message should contain INITIAL_CONTACT ๐Ÿ‘‘

The INITIAL_CONTACT notification description in Section 3.10.1 says that "This notification asserts that this IKE_SA is the only IKE_SA currently active between the authenticated identities". Lovely, but neither Section 2.4 nor 3.10.1 says which message this payload is supposed to live in ๐Ÿ˜ค

The general agreement is that INITIAL_CONTACT is best communicated in the first IKE_AUTH request, not as a separate exchange afterwards. Main character energy: first message, no side quests. ๐ŸŒธ

(References: "Clarifying the use of INITIAL_CONTACT in IKEv2" thread, April 2005. "Initial Contact messages" thread, December 2004. "IKEv2 and Initial Contact" thread, September 2004 and April 2005.)

7.10. Alignment of Payloads ๐ŸŒˆ

Lowkey, a lot of IKEv2 payloads have fields marked as "RESERVED". That's mostly because IKEv1 had them, and partly because they make the pictures easier to draw ๐Ÿ™ƒ Also, payloads in IKEv2 are not, in general, aligned to 4-octet boundaries. Fun fact: payloads weren't aligned to 4-octet boundaries in IKEv1 either, so this isn't new drama โœจ

(References: "IKEv2: potential 4-byte alignment problem" thread, June 2004.)

7.11. Key Length Transform Attribute ๐Ÿ’œ

Section 3.3.5 says that "The only algorithms defined in this document that accept attributes are the AES based encryption, integrity, and pseudo-random functions, which require a single attribute specifying key width." Bestie, this one is incorrect ๐Ÿ˜ญ The AES-based integrity and pseudo-random functions defined in [IKEv2] always use a 128-bit key. In fact, there are currently no integrity or PRF algorithms that use the key length attribute, and we recommend that they should not be defined in the future either. ๐Ÿ™…โ€โ™€๏ธ

Encryption algorithms are a little more complicated since there are three different types:

  • The key length attribute is never used with algorithms that use a fixed length key, such as DES and IDEA. ๐Ÿ”‘
  • The key length attribute is always included for the currently defined AES-based algorithms (Cipher Block Chaining (CBC), Counter (CTR) Mode, Counter with CBC-MAC (CCM), and Galois/Counter Mode (GCM)). Omitting the key length attribute is not allowed; if the proposal does not contain it, the proposal has to be rejected. ๐Ÿšซ
  • For other algorithms, the key length attribute can be included but is not mandatory. These algorithms include, e.g., RC5, CAST, and BLOWFISH. If the key length attribute is not included, the default value specified in [RFC2451] is used. ๐Ÿฆ‹

7.12. IPsec IANA Considerations ๐Ÿ“

There are currently three different IANA registry files that contain important numbers for IPsec: ikev2-registry, isakmp-registry, and ipsec-registry. Implementers should note that IKEv2 may use numbers different from those of IKEv1 for a particular algorithm. Watch out, it's a numbers trap ๐Ÿชค

For instance, an encryption algorithm can have up to three different numbers: the IKEv2 "Transform Type 1" identifier in ikev2-registry, the IKEv1 phase 1 "Encryption Algorithm" identifier in ipsec-registry, and the IKEv1 phase 2 "IPSEC ESP Transform Identifier" in isakmp-registry. Some algorithms do have the same number in all three registries, but the registries are not identical, so don't get too comfy ๐Ÿ˜Œ

Integrity algorithms are similar. An integrity algorithm can have at least the IKEv2 "Transform Type 3" identifier in ikev2-registry, the IKEv1 phase 2 "IPSEC AH Transform Identifier" in isakmp-registry, and the IKEv1 phase 2 ESP "Authentication Algorithm Security Association Attribute" identifier in isakmp-registry. And there's also the IKEv1 phase 1 "Hash Algorithm" list in ipsec-registry. Iykyk, it's a lot ๐Ÿ’€

This issue needs special care when you're writing a specification for how a new algorithm is used with IPsec. โœจ

7.13. Combining ESP and AH ๐Ÿ’…

The IKEv2 specification has some misleading text about how ESP and AH can be combined. Not it ๐Ÿ™…โ€โ™€๏ธ

IKEv2 is based on [RFC4301], which does not include "SA bundles" that were part of [RFC2401]. A single packet can go through IPsec processing multiple times, but each pass uses a separate SA, and the passes are coordinated by the forwarding tables. In IKEv2, each of these SAs has to be created using a separate CREATE_CHILD_SA exchange. So the text in Section 2.7 about a single proposal containing both ESP and AH is incorrect. ๐Ÿ˜ค

Also, the combination of ESP and AH (between the same endpoints) had already become largely obsolete in 1998, when RFC 2406 was published. Our recommendation is that IKEv2 implementations should not support this combination, and implementers should not assume the combination can be made to work in an interoperable manner. Let it go, bestie ๐Ÿซถ

(References: "Rekeying SA bundles" thread, Oct 2005.)

8. Implementation Mistakes ๐Ÿ™ˆ

Some implementers at the early IKEv2 bakeoffs didn't do everything correctly. This may seem obvious, but it's probably useful to list a few things that were clear in the document and that some implementers still didn't do. All of these caused interoperability problems, so yikes ๐Ÿ˜ฌ

  • Some implementations continued to send traffic on a CHILD_SA after it was rekeyed, even after receiving a DELETE payload. ๐Ÿ’€
  • After rekeying an IKE_SA, some implementations did not reset their message counters to zero. One set the counter to 2, another did not reset the counter at all. ๐Ÿ”ข
  • Some implementations could only handle a single pair of traffic selectors, or would only process the first pair in the proposal. ๐Ÿšง
  • Some implementations responded to a delete request by sending an empty INFORMATIONAL response and then initiated their own INFORMATIONAL exchange with the pair of SAs to delete. Double the messages, no thanks ๐Ÿ™ƒ
  • Although this did not happen at the bakeoff, the discussion there made it clear that some people had not implemented message window sizes correctly. Some implementations might have sent messages that did not fit into the responder's message windows, and some implementations may not have torn down an SA if they never received a message that they should have. ๐Ÿ˜ญ

9. Security Considerations ๐Ÿ”

This document does not introduce any new security considerations to IKEv2. Honestly, though, clarifying complex areas of the specification can reduce the likelihood of implementation problems that may have security implications, so this doc is basically a security glow-up ๐Ÿ›ก๏ธโœจ

10. Acknowledgments ๐Ÿซถ

This document is mainly based on conversations on the IPsec WG mailing list. The authors would especially like to thank Bernard Aboba, Jari Arkko, Vijay Devarapalli, William Dixon, Francis Dupont, Alfred Hoenes, Mika Joutsenvirta, Charlie Kaufman, Stephen Kent, Tero Kivinen, Yoav Nir, Michael Richardson, and Joel Snyder for their contributions. Iconic squad ๐Ÿ‘‘

In addition, the authors would like to thank all the participants of the first public IKEv2 bakeoff, held in Santa Clara in February 2005, for their questions and proposed clarifications. ๐Ÿ’œ

11. References ๐Ÿ“š

11.1. Normative References

  • [IKEv2] Kaufman, C., Ed., "Internet Key Exchange (IKEv2) Protocol", RFC 4306, December 2005.
  • [IKEv2ALG] Schiller, J., "Cryptographic Algorithms for Use in the Internet Key Exchange Version 2 (IKEv2)", RFC 4307, December 2005.
  • [PKCS1v20] Kaliski, B. and J. Staddon, "PKCS #1: RSA Cryptography Specifications Version 2.0", RFC 2437, October 1998.
  • [PKCS1v21] Jonsson, J. and B. Kaliski, "Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1", RFC 3447, February 2003.
  • [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for the Internet Protocol", RFC 2401, November 1998.
  • [RFC4301] Kent, S. and K. Seo, "Security Architecture for the Internet Protocol", RFC 4301, December 2005.

11.2. Informative References โœจ

Okay bestie, these are the extra-credit reads that back up the spec. ๐Ÿ“š

  • [Aura05] Aura, T., Roe, M., and A. Mohammed, "Experiences with Host-to-Host IPsec", 13th International Workshop on Security Protocols, Cambridge, UK, April 2005.
  • [EAP] Aboba, B., Blunk, L., Vollbrecht, J., Carlson, J., and H. Levkowetz, "Extensible Authentication Protocol (EAP)", RFC 3748, June 2004.
  • [HashUse] Hoffman, P., "Use of Hash Algorithms in IKE and IPsec", Work in Progress, July 2006.
  • [IPCPSubnet] Cisco Systems, Inc., "IPCP Subnet Mask Support Enhancements", http://www.cisco.com/univercd/cc/td/doc/product/software/ios121/121newft/121limit/121dc/121dc3/ipcp_msk.htm, January 2003.
  • [IPv6Addr] Hinden, R. and S. Deering, "IP Version 6 Addressing Architecture", RFC 4291, February 2006.
  • [MIPv6] Johnson, D., Perkins, C., and J. Arkko, "Mobility Support in IPv6", RFC 3775, June 2004.
  • [MLDv2] Vida, R. and L. Costa, "Multicast Listener Discovery Version 2 (MLDv2) for IPv6", RFC 3810, June 2004.
  • [NAI] Aboba, B., Beadles, M., Arkko, J., and P. Eronen, "The Network Access Identifier", RFC 4282, December 2005.
  • [PKI4IPsec] Korver, B., "Internet PKI Profile of IKEv1/ISAKMP, IKEv2, and PKIX", Work in Progress, April 2006.
  • [RADEAP] Aboba, B. and P. Calhoun, "RADIUS (Remote Authentication Dial In User Service) Support For Extensible Authentication Protocol (EAP)", RFC 3579, September 2003.
  • [RADIUS] Rigney, C., Willens, S., Rubens, A., and W. Simpson, "Remote Authentication Dial In User Service (RADIUS)", RFC 2865, June 2000.
  • [RADIUS6] Aboba, B., Zorn, G., and D. Mitton, "RADIUS and IPv6", RFC 3162, August 2001.
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", RFC 2119, March 1997.
  • [RFC2451] Pereira, R. and R. Adams, "The ESP CBC-Mode Cipher Algorithms", RFC 2451, November 1998.
  • [RFC2822] Resnick, P., "Internet Message Format", RFC 2822, April 2001.
  • [RFC3664] Hoffman, P., "The AES-XCBC-PRF-128 Algorithm for the Internet Key Exchange Protocol (IKE)", RFC 3664, January 2004.
  • [RFC3948] Huttunen, A., Swander, B., Volpe, V., DiBurro, L., and M. Stenberg, "UDP Encapsulation of IPsec ESP Packets", RFC 3948, January 2005.
  • [RFC4434] Hoffman, P., "The AES-XCBC-PRF-128 Algorithm for the Internet Key Exchange Protocol (IKE)", RFC 4434, February 2006.
  • [RFC822] Crocker, D., "Standard for the format of ARPA Internet text messages", RFC 822, August 1982.
  • [ReAuth] Nir, Y., "Repeated Authentication in Internet Key Exchange (IKEv2) Protocol", RFC 4478, April 2006.
  • [SCVP] Freeman, T., Housley, R., Malpani, A., Cooper, D., and T. Polk, "Simple Certificate Validation Protocol (SCVP)", Work in Progress, June 2006.

Appendix A. Exchanges and Payloads ๐Ÿงš

This appendix is a quick cheat sheet of the IKEv2 exchanges and which payloads can show up in which message. It's purely informative, so if it ever disagrees with the main body of this document or the IKEv2 specification, the other text wins. ๐Ÿ’…

Vendor-ID (V) payloads may be included in any place in any message. The sequences below show what we think are the most logical spots for them. ๐ŸŒธ

The specification doesn't say which messages can contain N(SET_WINDOW_SIZE). It possibly can go in any message, but it isn't shown in the diagrams below yet. ๐Ÿคทโ€โ™€๏ธ

A.1. IKE_SA_INIT Exchange

request             --> [N(COOKIE)],
                        SA, KE, Ni,
                        [N(NAT_DETECTION_SOURCE_IP)+,
                         N(NAT_DETECTION_DESTINATION_IP)],
                        [V+]

normal response     <-- SA, KE, Nr,
(no cookie)             [N(NAT_DETECTION_SOURCE_IP),
                         N(NAT_DETECTION_DESTINATION_IP)],
                        [[N(HTTP_CERT_LOOKUP_SUPPORTED)], CERTREQ+],
                        [V+]

A.2. IKE_AUTH Exchange without EAP

request             --> IDi, [CERT+],
                        [N(INITIAL_CONTACT)],
                        [[N(HTTP_CERT_LOOKUP_SUPPORTED)], CERTREQ+],
                        [IDr],
                        AUTH,
                        [CP(CFG_REQUEST)],
                        [N(IPCOMP_SUPPORTED)+],
                        [N(USE_TRANSPORT_MODE)],
                        [N(ESP_TFC_PADDING_NOT_SUPPORTED)],
                        [N(NON_FIRST_FRAGMENTS_ALSO)],
                        SA, TSi, TSr,
                        [V+]

response            <-- IDr, [CERT+],
                        AUTH,
                        [CP(CFG_REPLY)],
                        [N(IPCOMP_SUPPORTED)],
                        [N(USE_TRANSPORT_MODE)],
                        [N(ESP_TFC_PADDING_NOT_SUPPORTED)],
                        [N(NON_FIRST_FRAGMENTS_ALSO)],
                        SA, TSi, TSr,
                        [N(ADDITIONAL_TS_POSSIBLE)],
                        [V+]

A.3. IKE_AUTH Exchange with EAP

first request       --> IDi,
                        [N(INITIAL_CONTACT)],
                        [[N(HTTP_CERT_LOOKUP_SUPPORTED)], CERTREQ+],
                        [IDr],
                        [CP(CFG_REQUEST)],
                        [N(IPCOMP_SUPPORTED)+],
                        [N(USE_TRANSPORT_MODE)],
                        [N(ESP_TFC_PADDING_NOT_SUPPORTED)],
                        [N(NON_FIRST_FRAGMENTS_ALSO)],
                        SA, TSi, TSr,
                        [V+]

first response      <-- IDr, [CERT+], AUTH,
                        EAP,
                        [V+]

                  / --> EAP
repeat 1..N times |
                  \ <-- EAP

last request        --> AUTH

last response       <-- AUTH,
                        [CP(CFG_REPLY)],
                        [N(IPCOMP_SUPPORTED)],
                        [N(USE_TRANSPORT_MODE)],
                        [N(ESP_TFC_PADDING_NOT_SUPPORTED)],
                        [N(NON_FIRST_FRAGMENTS_ALSO)],
                        SA, TSi, TSr,
                        [N(ADDITIONAL_TS_POSSIBLE)],
                        [V+]

A.4. CREATE_CHILD_SA Exchange for Creating/Rekeying CHILD_SAs

request             --> [N(REKEY_SA)],
                        [N(IPCOMP_SUPPORTED)+],
                        [N(USE_TRANSPORT_MODE)],
                        [N(ESP_TFC_PADDING_NOT_SUPPORTED)],
                        [N(NON_FIRST_FRAGMENTS_ALSO)],
                        SA, Ni, [KEi], TSi, TSr

response            <-- [N(IPCOMP_SUPPORTED)],
                        [N(USE_TRANSPORT_MODE)],
                        [N(ESP_TFC_PADDING_NOT_SUPPORTED)],
                        [N(NON_FIRST_FRAGMENTS_ALSO)],
                        SA, Nr, [KEr], TSi, TSr,
                        [N(ADDITIONAL_TS_POSSIBLE)]

A.5. CREATE_CHILD_SA Exchange for Rekeying the IKE_SA

request             --> SA, Ni, [KEi]

response            <-- SA, Nr, [KEr]

A.6. INFORMATIONAL Exchange

request             --> [N+],
                        [D+],
                        [CP(CFG_REQUEST)]

response            <-- [N+],
                        [D+],
                        [CP(CFG_REPLY)]

Authors' Addresses ๐ŸŽ€

   Pasi Eronen
   Nokia Research Center
   P.O. Box 407
   FIN-00045 Nokia Group
   Finland

   EMail: pasi.eronen@nokia.com


   Paul Hoffman
   VPN Consortium
   127 Segre Place
   Santa Cruz, CA 95060
   USA

   EMail: paul.hoffman@vpnc.org

The Internet Society owns the copyright for this document, dated 2006. ๐Ÿ“

It's subject to the rights, licenses and restrictions in BCP 78. Apart from what BCP 78 says, the authors keep all their rights. ๐Ÿ”’

The document and the info in it come "AS IS", with no warranties from the contributor, the organization they represent or sponsor (if any), the Internet Society, or the Internet Engineering Task Force. Here's the exact wording, because it's legal and it matters:

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property ๐ŸŒˆ

The IETF doesn't take a side on whether any IPR (intellectual property rights) claimed over the tech in this document are valid or in scope, or whether anyone can get a license for them. It also doesn't claim to have checked for any such rights. ๐Ÿง

If you want the rules for rights in RFC documents, check out BCP 78 and BCP 79. ๐Ÿ“–

IPR disclosures sent to the IETF Secretariat, plus any promised licenses, and any results from trying to get a general license or permission for implementers or users, can all be found in the IETF's online IPR repository at http://www.ietf.org/ipr. ๐Ÿ”

The IETF also invites anyone to flag copyrights, patents, patent applications, or other proprietary rights that might cover tech needed to implement this standard. Send that info to the IETF at ietf-ipr@ietf.org. ๐Ÿ’Œ


Acknowledgement ๐Ÿซถ

Funding for the RFC Editor function comes from the IETF Administrative Support Activity (IASA). Thank you, IASA! ๐Ÿ‘‘โœจ

๐Ÿ“ฆ where this page comes from