RFC 5723

Internet Key Exchange Protocol Version 2 (IKEv2) Session Resumption

πŸ“… published January 2010, from ietf

Internet Key Exchange Protocol Version 2 (IKEv2) Session Resumption πŸŽ€

Okay bestie, this is RFC 5723 πŸ’… The title is Internet Key Exchange Protocol Version 2 (IKEv2) Session Resumption. It was written by Y. Sheffer of Check Point and H. Tschofenig of Nokia Siemens Networks, and it's dated January 2010. It's a Standards Track document with ISSN 2070-1721. The title block doesn't list anything it obsoletes or updates, so no drama there 🫢

Abstract ✨

IKEv2 has some real computational and communication overhead, mostly from how many round trips it needs and the crypto operations it involves. In remote access setups, EAP handles authentication, and that adds several more round trips, which means more latency 😭

Re-establishing security associations (SAs) after a failure recovery is seriously time consuming, especially when an IPsec peer like a VPN gateway has to rebuild a huge number of SAs with different endpoints. A high number of concurrent sessions can cause extra problems for that IPsec peer during SA re-establishment πŸ’€

So to avoid rerunning the whole key exchange from scratch, it would be super useful to have an efficient way to resume an IKE/IPsec session 🧚 This document proposes an IKEv2 extension that lets a client re-establish an IKE SA with a gateway in a highly efficient way, by using a previously established IKE SA.

A client can reconnect to a gateway it got disconnected from. The approach packs partial IKE state into an opaque ticket. That ticket can live on the client or in a centralized store, and it's later made available to the IKEv2 responder for re-authentication. The term "ticket" refers to the opaque data created by the IKEv2 responder. This document doesn't specify the ticket format, but examples are included 🎟️

Status of This Memo ✨

This is an Internet Standards Track document.

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). More info on Internet Standards is in Section 2 of RFC 5741.

Info about the current status of this document, any errata, and how to give feedback on it can be found at http://www.rfc-editor.org/info/rfc5723.

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info), as in effect on the date this document was published. Please review those documents carefully, because they describe your rights and restrictions regarding this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Simplified BSD License.

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of that material outside the IETF Standards Process. Without an adequate license from the person(s) controlling the copyright in those materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English πŸ“œ


Table of Contents πŸ—‚οΈ

1. Introduction ....................................................4
2. Terminology .....................................................5
3. Usage Scenario ..................................................5
4. Protocol Sequences ..............................................7
   4.1. Requesting a Ticket ........................................7
   4.2. Receiving a Ticket .........................................8
   4.3. Presenting a Ticket ........................................9
        4.3.1. Prologue ............................................9
        4.3.2. IKE_SESSION_RESUME Exchange ........................10
        4.3.3. IKE_AUTH Exchange ..................................11
        4.3.4. Epilogue ...........................................12
5. IKE and IPsec State after Resumption ...........................12
   5.1. Generating Cryptographic Material for the Resumed IKE SA ..15
6. Ticket Handling ................................................16
   6.1. Ticket Content ............................................16
   6.2. Ticket Identity and Lifecycle .............................16
7. IKE Notifications ..............................................17
   7.1. TICKET_LT_OPAQUE Notify Payload ...........................17
   7.2. TICKET_OPAQUE Notify Payload ..............................18
8. IANA Considerations ............................................18
9. Security Considerations ........................................19
   9.1. Stolen Tickets ............................................19
   9.2. Forged Tickets ............................................19
   9.3. Denial-of-Service Attacks .................................20
   9.4. Detecting the Need for Resumption .........................20
   9.5. Key Management for "Tickets by Value" .....................20
   9.6. Ticket Lifetime ...........................................21
   9.7. Tickets and Identity ......................................21
   9.8. Ticket Revocation .........................................21
   9.9. Ticket by Value Format ....................................21
   9.10. Identity Privacy, Anonymity, and Unlinkability ...........22
10. Acknowledgements ..............................................22
11. References ....................................................23
   11.1. Normative References .....................................23
   11.2. Informative References ...................................23
Appendix A.  Ticket Format ........................................25
  A.1.  Example "Ticket by Value" Format ..........................25
  A.2.  Example "Ticket by Reference" Format ......................25

1. Introduction πŸ¦‹

IKEv2 has a certain amount of computational and communication overhead, mainly in the number of round trips it needs and the cryptographic operations it involves. In remote access cases in particular, EAP is used for authentication, and that makes latency worse 😀

Re-establishing security associations (SAs) after a failure recovery is time-consuming, especially when an IPsec peer like a VPN gateway needs to re-establish a large number of SAs with various endpoints. A high number of concurrent sessions can cause extra problems for an IPsec responder. Usability also takes a hit when re-establishing an IKE SA means the user has to interact in order to re-authenticate πŸ™ˆ

In lots of failure cases, an efficient way to resume an interrupted IKE/IPsec session would be really useful. This document proposes an IKEv2 extension that lets a client re-establish an IKE SA with a gateway in a highly efficient manner, using a previously established IKE SA ✨

The client (IKEv2 initiator) stores the state about the previous IKE SA locally. The gateway (IKEv2 responder) has two options for keeping the IKEv2 state about the previous IKE SA:

  • In the "ticket by reference" approach, the gateway stores the state locally and gives the client a protected, opaque reference (for example, an index into the gateway's table). The gateway can later use that reference to find the state. The client includes this opaque reference when it resumes the session πŸ”–
  • In the "ticket by value" approach, the gateway stores its state in a ticket (a data structure) that is encrypted and integrity-protected by a key known only to the gateway. The ticket is passed to the client, who treats it as an opaque string, and it's sent back to the gateway when the session is resumed. The gateway can then decrypt the ticket and recover the state πŸ”

The client behaves identically in both cases, and generally doesn't know which approach the gateway is using. Since the ticket (or reference) is only interpreted by the same party that created it, this document doesn't specify the exact format. That said, Appendix A has examples for both "ticket by reference" and "ticket by value" formats 🧩

This approach is similar to the one taken by Transport Layer Security (TLS) session resumption [RFC5077], with the adaptations IKEv2 needs, for example to handle its two-phase protocol structure. The authors borrowed heavily from that specification πŸ™Œ

The proposed solution should also meet these goals:

  • Using only symmetric cryptography to minimize CPU consumption 🧠
  • Providing cryptographic agility πŸ”„
  • Having no negative impact on IKEv2 security features πŸ›‘οΈ

These are the non-goals of this solution:

  • Failover from one gateway to another. This use case may be added in a future specification.
  • Providing load balancing among gateways.
  • Specifying how a client detects the need for resumption.

2. Terminology πŸ“š

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

This document uses terminology defined in [RFC4301] and [RFC4306]. It also uses the following term:

Ticket: An IKEv2 ticket is a data structure that contains all the necessary information that allows an IKEv2 responder to re-establish an IKEv2 security association.

In this document, the term "ticket" refers to an opaque data structure that may either contain IKEv2 state, as described above, or a reference pointing to such state πŸŽ€

3. Usage Scenario ✨

Okay bestie, this spec imagines two usage scenarios for efficient IKEv2 and IPsec SA session re-establishment πŸ’–

The first one is lowkey like the use case in Section 1.1.3 of the IKEv2 specification [RFC4306]. IPsec tunnel mode sets up a secure channel between a remote access client and a gateway, and the traffic can flow between the client and whatever is beyond the gateway 🌐. We'll get into this more below.

The second use case is all about using transport (or tunnel) mode to keep the communication between two endpoints (like two servers) secure πŸ”. These two endpoints have a client-server relationship when it comes to a protocol that runs on top of the protections the IPsec SA provides. Main character energy πŸ‘‘

(a)

  +-+-+-+-+-+                          +-+-+-+-+-+
  |         |      IKEv2/IKEv2-EAP     |         |     Protected
  | Remote  |<------------------------>|         |     Subnet
  | Access  |                          | Access  |<--- and/or
  | Client  |<------------------------>| Gateway |     Internet
  |         |      IPsec tunnel        |         |
  +-+-+-+-+-+                          +-+-+-+-+-+

(b)

  +-+-+-+-+-+                          +-+-+-+-+-+
  |         |    IKE_SESSION_RESUME    |         |
  | Remote  |<------------------------>|         |
  | Access  |                          | Access  |
  | Client  |<------------------------>| Gateway |
  |         |      IPsec tunnel        |         |
  +-+-+-+-+-+                          +-+-+-+-+-+

       Figure 1: Resuming a Session with a Remote Access Gateway

In the first use case, an end host (an entity with a host implementation of IPsec [RFC4301]) sets up a tunnel mode IPsec SA with a gateway in a remote network using IKEv2. The end host here is sometimes called a remote access client πŸ’». Later on, when a client needs to re-establish the IKEv2 session, it can either go for a full IKEv2 exchange or use the IKE_SESSION_RESUME exchange (shown in Figure 1) πŸ¦‹.

For either use case, there are a bunch of situations where this mechanism could come in clutch. Here are some of them (this list isn't exhaustive, and any given deployment might not care about all of them πŸ™ˆ):

  • If a client temporarily loses network connectivity (and the IKE SA times out through the liveness test facility, a.k.a. "dead peer detection"), this mechanism could re-establish the SA with less overhead (network, CPU, authentication infrastructure) and without needing user interaction for authentication 🧚.
  • If the connectivity problems hit a lot of clients (like a big remote access VPN gateway), everyone might reconnect at almost the same time once the connection comes back. This mechanism could help cut down the load spike for cryptographic operations and authentication infrastructure 😭.
  • Losing connectivity can also be predictable and planned, like putting a laptop on "stand-by" before traveling 🧳. This mechanism could re-establish the SA once the laptop is switched back on (again, with less overhead and without user interaction for authentication). Honestly though, that kind of user-level "resumption" may often be disallowed by policy πŸ™…β€β™€οΈ. Also, this document requires the client to destroy the ticket when the user explicitly "logs out" (Section 6.2) πŸšͺ.

4. Protocol Sequences πŸŽ€

This section is where the protocol details live, and it's the normative part of the doc, so it's serious business πŸ’…. This document defines two protocol exchanges: requesting a ticket (see Section 4.1) and presenting a ticket (see Section 4.3).

4.1. Requesting a Ticket 🎟️

A client MAY request a ticket in the following exchanges:

  • In an IKE_AUTH exchange, as shown in the example message exchange in Figure 2 below ✨.
  • In a CREATE_CHILD_SA exchange, when an IKE SA is rekeyed (and only when this exchange is initiated by the client) πŸ”.
  • In an Informational exchange at any time. For example, if the gateway previously replied with an N(TICKET_ACK) instead of giving a ticket, when the ticket lifetime is about to expire, or following a gateway-initiated IKE rekey. All such Informational exchanges MUST be initiated by the client 🫢.
  • While resuming an IKE session, meaning in the IKE_AUTH exchange that follows an IKE_SESSION_RESUME exchange (see Section 4.3.3) 🌸.

Normally, a client requests a ticket in the third message of an IKEv2 exchange (the first IKE_AUTH). Figure 2 shows the message exchange for this typical case πŸ“.

   Initiator                Responder
  -----------              -----------
  HDR, SAi1, KEi, Ni  -->

                      <--    HDR, SAr1, KEr, Nr [, CERTREQ]

  HDR, SK {IDi, [CERT,] [CERTREQ,] [IDr,]
  AUTH, SAi2, TSi, TSr, N(TICKET_REQUEST)}     -->

      Figure 2: Example Message Exchange for Requesting a Ticket

The notification payloads are described in Section 7. The above is just an example, since IKEv2 allows a number of variants on these messages. For more details on IKEv2, check out [RFC4306] and [IKEV2-BIS] πŸ“š.

When an IKEv2 responder gets a request for a ticket using the N(TICKET_REQUEST) payload, it MUST perform one of the following operations, provided it supports the extension defined in this document:

  • It creates a ticket and returns it with the N(TICKET_LT_OPAQUE) payload in a subsequent message towards the IKEv2 initiator. This is shown in Figure 3 🎁.
  • It returns an N(TICKET_NACK) payload if it refuses to grant a ticket for some reason πŸ™….
  • It returns an N(TICKET_ACK) if it can't grant a ticket right away, for example due to packet size limitations. In this case, the client MAY request a ticket later using an Informational exchange, at any time during the lifetime of the IKE SA ⏳.

No matter which choice the responder makes, the behavior of the responder with respect to the IKE exchange doesn't change, and the proper IKE response (for example, an IKE_AUTH response or an error notification) MUST be sent πŸ’Œ.

4.2. Receiving a Ticket πŸ’

The IKEv2 initiator receives the ticket and may accept it, as long as the IKEv2 exchange was successful. The ticket can be used later with an IKEv2 responder that supports this extension. Figure 3 shows how the initiator receives the ticket πŸŽ€.

   Initiator                Responder
  -----------              -----------
         <--    HDR, SK {IDr, [CERT,] AUTH, SAr2, TSi,
                     TSr, N(TICKET_LT_OPAQUE) }

                    Figure 3: Receiving a Ticket

When a multi-round-trip IKE_AUTH exchange is used, the N(TICKET_REQUEST) payload MUST be included in the first IKE_AUTH request, and N(TICKET_LT_OPAQUE) (or TICKET_NACK/TICKET_ACK) MUST only be returned in the final IKE_AUTH response πŸ”.

When the client accepts the ticket, it stores it in local storage for later use, along with the IKE SA the ticket refers to πŸ—‚οΈ. The ticket itself is opaque to the client, so the local storage MUST also include all items marked as "from the ticket" in the table of Section 5. No skipping that part, bestie πŸ™ˆ.

4.3. Presenting a Ticket πŸ¦„

When the client wants to recover from an interrupted session, it presents the ticket to resume the session πŸ”„. This section walks through the resumption process, which has some preparations, an IKE_SESSION_RESUME exchange, an IKE_AUTH exchange, and finalization.

4.3.1. Prologue πŸŒ…

It's up to the client's local policy to decide when communication with the IKEv2 responder counts as interrupted and when the session resumption procedure should kick off πŸ•°οΈ.

A client MAY start a regular (non-ticket-based) IKEv2 exchange even if it has a valid, unexpired ticket. A client MUST NOT present a ticket when it knows the ticket's lifetime has expired β›”.

Tickets are meant for one-time use, so a client MUST NOT reuse a ticket 🚫. A reused ticket SHOULD be rejected by a gateway. Also, a ticket only counts as used once an IKE SA has been established successfully with it βœ….

4.3.2. IKE_SESSION_RESUME Exchange 🌈

This document specifies a new IKEv2 exchange type called IKE_SESSION_RESUME, whose value is 38 πŸ”’. This exchange works like the IKE_SA_INIT exchange, and it MUST be followed by an IKE_AUTH exchange. The client SHOULD NOT use this exchange type unless it knows the gateway supports it (which is trivially true in the context of this document, since the client always resumes into the same gateway that generated the ticket) πŸ€·β€β™€οΈ.

   Initiator                Responder
  -----------              -----------
  HDR, [N(COOKIE),] Ni, N(TICKET_OPAQUE) [,N+]   -->

         Figure 4: IKEv2 Initiator Wishes to Resume an IKE SA

The exchange type in HDR is set to 'IKE_SESSION_RESUME'. The initiator sets the SPIi (Security Parameter Index, Initiator) value in the HDR to a new, unique value, and the SPIr value is set to 0 🧩.

When the IKEv2 responder receives a ticket using the N(TICKET_OPAQUE) payload, it MUST perform one of the following steps, provided it supports the extension defined in this document:

  • If it's willing to accept the ticket, it responds as shown in Figure 5 πŸ₯°.
  • It responds with an unprotected N(TICKET_NACK) notification if it rejects the ticket for any reason. In that case, the initiator should re-initiate a regular IKE exchange. One such case is when the responder receives a ticket for an IKE SA that was previously terminated on the responder itself, which may mean the state is inconsistent between the IKEv2 initiator and the responder 🫠. However, a responder is not required to maintain state for terminated sessions.
   Initiator                Responder
  -----------              -----------
                  <--  HDR, Nr [,N+]

             Figure 5: IKEv2 Responder Accepts the Ticket

Again, the exchange type in HDR is set to 'IKE_SESSION_RESUME'. The responder copies the SPIi value from the request, and the SPIr value is set to a new, unique value πŸͺ„.

Where not specified otherwise, the IKE_SESSION_RESUME exchange behaves exactly like the IKE_SA_INIT exchange. Specifically:

  • The client MAY resume the IKE exchange from any IP address and port, regardless of its original address. The gateway MAY reject the resumed exchange if its policy depends on the client's address (although this rarely makes sense) 🌍.
  • The first message MAY be rejected in denial-of-service (DoS) situations, with the initiator told to send a cookie πŸͺ.
  • Notifications normally associated with IKE_SA_INIT can be sent, in particular NAT detection payloads πŸ”.
  • The client's NAT traversal status SHOULD be determined anew in IKE_SESSION_RESUME. If NAT is detected, the initiator switches to UDP encapsulation on port 4500, as per [RFC4306], Section 2.23. NAT status is explicitly not part of the session resumption state 🚫.
  • The SPI values and Message ID fields behave similarly to IKE_SA_INIT πŸ”.

Even though the IKE SA isn't fully valid until the IKE_AUTH exchange completes, the peers must create much of the SA state (Section 5) right now πŸ—οΈ. Specifically, the shared key values are required to protect the IKE_AUTH payloads. Their generation is described in Section 5.1 πŸ”‘.

4.3.3. IKE_AUTH Exchange ✨

okay so once the IKE_SESSION_RESUME exchange is done, the client MUST kick off an IKE_AUTH exchange πŸ’… it's basically the same as the one in [RFC4306], so this section is just the tea on what's different and what's required 🫢

the AUTH payload gets worked out kind of like IKEv2 pre-shared secret auth πŸ”

AUTH = prf(SK_px, <message octets>)

both sides use their own SK_px value: SK_pi for the initiator and SK_pr for the responder πŸ¦‹ and both come from the brand new IKE SA (Section 5.1) ✨

the exact stuff that gets signed is defined in Section 2.15 of [RFC4306] πŸ“œ

now the IDs, this part is kinda the main character moment πŸ‘‘ the IDi value sent in IKE_AUTH MUST be identical to the one in the ticket. a CERT payload MUST NOT be included here, so you can't negotiate a new IDr, because it wouldn't get authenticated πŸ™ˆ so the IDr value sent in this exchange (by the gateway, and optionally by the client) MUST also be identical to the one in the ticket. no changing names mid-call, bestie πŸ’€

when a session gets resumed, the client will usually ask for a fresh ticket right away 🎟️ that way if something breaks again, it can resume one more time 🌸 the N(TICKET_REQUEST) and N(TICKET_LT_OPAQUE) notifications get included in the IKE_AUTH exchange that comes after IKE_SESSION_RESUME. they act pretty much like a ticket request in a regular IKE exchange, see Section 4.1 πŸ’– and whatever ticket comes back (if any) lines up with the IKE SA made under the rules in Section 5 ✨

4.3.4. Epilogue πŸŽ€

after IKE_AUTH wraps up, both parties create a new IKE SA (see Section 5) and a Child SA gets derived, per Section 2.17 of [RFC4306] 🧚

now here's the drama 😭 when the responder gets a ticket for an IKE SA that's still active, and it accepts the ticket (aka IKE_AUTH finished successfully), the old SA SHOULD be silently deleted without sending a DELETE informational exchange πŸ«₯ and yep, all the dependent IPsec Child SAs get deleted too πŸ’œ

5. IKE and IPsec State after Resumption 🌈

during resumption, both peers make IKE and IPsec state for the resumed IKE SA ✨ the SA isn't fully done until IKE_AUTH succeeds, but a lot of its stuff gets made way earlier, especially the crypto material (Section 5.1) πŸ”

when a ticket shows up, the gateway has to grab the ticket state 🎫 if the client sent a "ticket by reference", the gateway has to resolve that reference to get the state πŸ” if the client sent a "ticket by value", the gateway can just parse the ticket and read the state straight from it πŸ“– either way, the gateway has to process that ticket state to restore the old IKE SA's state, and the client pulls the same state from its own local store πŸ“

this table shows the IKE and IPsec state of both peers after session resumption, and how that connects to what they had before the IKE SA got interrupted πŸ¦‹ when the table says a state item comes "from the ticket", that means:

  • the client grabs this item from its local store πŸ’œ
  • for "ticket by value", the gateway encodes this info in the ticket 🎟️
  • for "ticket by reference", the gateway fetches this info from the ticket store πŸ—„οΈ
+--------------------------------+----------------------------------+
| State Item                     | After Resumption                 |
+--------------------------------+----------------------------------+
| IDi                            | From the ticket (but must also   |
|                                | be exchanged in IKE_AUTH).  See  |
|                                | also Note 1.                     |
|                                |                                  |
| IDr                            | From the ticket (but must also   |
|                                | be exchanged in IKE_AUTH).       |
|                                |                                  |
| Authentication method (PKI,    | From the ticket.                 |
| pre-shared secret, EAP,        |                                  |
| PKI-less EAP [EAP-AUTH] etc.)  |                                  |
|                                |                                  |
| Certificates (when applicable) | From the ticket, see Note 2.     |
|                                |                                  |
| Local IP address/port, peer IP | Selected by the client, see Note |
| address/port                   | 3.                               |
|                                |                                  |
| NAT detection status           | From new exchange.               |
|                                |                                  |
| SPIs                           | From new exchange, see Note 4.   |
|                                |                                  |
| Which peer is the "original    | Determined by the initiator of   |
| initiator"?                    | IKE_SESSION_RESUME.              |
|                                |                                  |
| IKE SA sequence numbers        | Reset to 0 in                    |
| (Message ID)                   | IKE_SESSION_RESUME, and          |
|                                | subsequently incremented         |
|                                | normally.                        |
|                                |                                  |
| IKE SA algorithms (SAr)        | From the ticket.                 |
|                                |                                  |
| IKE SA keys (SK_*)             | The old SK_d is obtained from    |
|                                | the ticket and all keys are      |
|                                | refreshed, see Section 5.1.      |
|                                |                                  |
| IKE SA window size             | Reset to 1.                      |
|                                |                                  |
| Child SAs (ESP/AH)             | Created in new exchange, see     |
|                                | Note 6.                          |
|                                |                                  |
| Internal IP address            | Not resumed, but see Note 5.     |
|                                |                                  |
| Other Configuration Payload    | Not resumed.                     |
| information                    |                                  |
|                                |                                  |
| Peer Vendor IDs                | Not resumed, resent in new       |
|                                | exchange if required.            |
|                                |                                  |
| Peer supports MOBIKE [RFC4555] | From new exchange.               |
|                                |                                  |
| MOBIKE additional addresses    | Not resumed, should be resent by |
|                                | client if necessary.             |
|                                |                                  |
| Time until re-authentication   | From new exchange (but ticket    |
| [RFC4478]                      | lifetime is bounded by this      |
|                                | duration).                       |
|                                |                                  |
| Peer supports redirects        | From new exchange.               |
| [RFC5685]                      |                                  |
+--------------------------------+----------------------------------+

Note 1: the authenticated peer identity used for policy lookups might not match the IDi payload πŸ€” that can happen with certain EAP methods, see Section 3.5 of [RFC4718]. if those identities really are different, then the authenticated client identity MUST be included in the ticket. heads up that the client might not have access to this value πŸ™ˆ

Note 2: certificates don't need to be stored if the peer never uses them for anything once the IKE SA is up πŸ’… but if they're needed (for example, if they're exposed to applications via IPsec APIs), they MUST be stored in the ticket πŸ”₯

Note 3: if the certificate has an iPAddress SubjectAltName, and the implementation needs it to match the peer's source IP address, that same check has to happen on session resumption too, and the required info gets saved locally or in the ticket πŸ“

Note 4: SPI values of the old SA MAY be stored in the ticket, to help the gateway find the matching old IKE state 🧭 but those values MUST NOT be used for the resumed SA 🚫

Note 5: the client can ask for the address it was using before, and if it's possible, the gateway SHOULD honor that request 🏠

Note 6: since info about Child SAs and configuration payloads isn't resumed, IKEv2 features tied to Child SA negotiation (like IPCOMP_SUPPORTED, ESP_TFC_PADDING_NOT_SUPPORTED, ROHC-over-IPsec [ROHCoIPsec], and configuration) usually aren't affected by session resumption ✨

IKEv2 features that only touch the IKE_AUTH exchange are also usually fine 🌷 that includes HTTP_CERT_LOOKUP_SUPPORTED, multiple authentication exchanges [RFC4739], Elliptic Curve Digital Signature Algorithm (ECDSA) authentication [RFC4754], and the Online Certificate Status Protocol (OCSP) [RFC4806]. they usually don't need any state in the IKE SA once the IKE_AUTH exchanges are done, so resumption doesn't change them πŸ’–

new IKEv2 features that aren't covered by Note 6 or by the paragraph right above should specify how they interact with session resumption πŸ“œ

5.1. Generating Cryptographic Material for the Resumed IKE SA πŸ”

the crypto material gets refreshed based on the ticket and the nonce values, Ni and Nr, from the current exchange πŸŽ€ a new SKEYSEED value is derived like this:

SKEYSEED = prf(SK_d_old, "Resumption" | Ni | Nr)

where SK_d_old is taken from the ticket. the literal string gets encoded as 10 ASCII characters, with no NULL terminator 🧁

the keys are derived like this, unchanged from IKEv2 πŸ¦‹

{SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr} =
                            prf+(SKEYSEED, Ni | Nr | SPIi | SPIr)

where SPIi and SPIr are the SPI values created in the new IKE exchange ✨

see [RFC4306] for the notation πŸ“– and "prf" is determined from the SA value in the ticket πŸ’…

6. Ticket Handling 🎟️

6.1. Ticket Content

Okay so, when you hand a "ticket by value" over to the client, the ticket content MUST be integrity protected and encrypted πŸ”βœ¨ no skipping this one, bestie!

A "ticket by reference" doesn't need encryption because it doesn't carry anything sensitive like keying material πŸ¦‹. BUT the storage where that sensitive material lives MUST be protected so only authorized access gets in πŸšͺ🫢. Honestly this ticket gives "stub" energy from [SA-SYNC], or like a Session ID from TLS πŸ’….

Even though it's not strictly required for cryptographic protection, it is RECOMMENDED to integrity-protect the "ticket by reference" 🌸. Skipping it could cause different security vulnerabilities on the gateway side, depending on what the reference looks like 😭. The sketchy stuff includes the gateway getting into URLs it shouldn't (kind of like cross-site scripting) or SQL injection πŸ’€.

When the state is passed by value, the ticket MUST encode all the state information marked "from the ticket" in the table in Section 5 πŸ“‹. In the "ticket by reference" case, that same state MUST be stored in the ticket store πŸ—„οΈ.

A "ticket by value" MUST include a protected expiration time πŸ•°οΈ. It's an absolute time value, and it SHOULD match the value in the TICKET_LT_OPAQUE payload ✨.

A "ticket by value" MUST additionally include a key identity field πŸ”‘. That way the keys for ticket encryption and authentication can be changed, and algorithms can be replaced when needed πŸ”„πŸ§š.


6.2. Ticket Identity and Lifecycle

Each ticket is tied to a single IKE SA πŸŽ€. So when an IKE SA gets deleted by the client or the gateway, the client MUST delete its stored ticket πŸ—‘οΈ. Same energy if the credentials tied to the IKE SA get invalidated (like when a user logs out): the ticket MUST be deleted 🚫. When the IKE SA is rekeyed, the ticket is invalidated and the client SHOULD request a new one πŸ”. If a client doesn't follow these rules, it might present an invalid ticket to the gateway πŸ’€. See Section 9.8 for more on that drama πŸ™ˆ.

The lifetime of the ticket sent by the gateway SHOULD be the minimum of two things: the IKE SA lifetime (per the gateway's local policy) and its re-authentication time, according to [RFC4478] ⏳. Even if the gateway doesn't enforce either of those, a finite lifetime MUST be specified for the ticket β™ΎοΈπŸš«.

The key that protects the ticket MUST have a lifetime that's significantly longer than the lifetime of an IKE SA πŸ”πŸ‘‘.

In normal operation, the client requests a ticket when it establishes the initial IKE SA, and then again every time the SA is rekeyed or re-established because of re-authentication 🌈.


7. IKE Notifications ✨

This document defines a number of notifications. The following Notify Message types have been assigned by IANA πŸ“.

          +-------------------+-------+-----------------+
          | Notification Name | Value | Data            |
          +-------------------+-------+-----------------+
          | TICKET_LT_OPAQUE  | 16409 | See Section 7.1 |
          |                   |       |                 |
          | TICKET_REQUEST    | 16410 | None            |
          |                   |       |                 |
          | TICKET_ACK        | 16411 | None            |
          |                   |       |                 |
          | TICKET_NACK       | 16412 | None            |
          |                   |       |                 |
          | TICKET_OPAQUE     | 16413 | See Section 7.2 |
          +-------------------+-------+-----------------+

For all these notifications, the Protocol ID and the SPI Size fields MUST both be sent as 0 🎯.


7.1. TICKET_LT_OPAQUE Notify Payload

The data for the TICKET_LT_OPAQUE Notify payload is made up of the Notify message header, a Lifetime field, and the ticket itself 🎟️. The four octet Lifetime field holds a relative time value, which is the number of seconds until the ticket expires (an unsigned integer in network byte order) ⏰.

     0                     1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | Next Payload  |C|  Reserved   |      Payload Length           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | Protocol ID   | SPI Size = 0  |    Notify Message Type        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                       Lifetime                                |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    ~                        Ticket                                 ~
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              Figure 6: TICKET_LT_OPAQUE Notify Payload

7.2. TICKET_OPAQUE Notify Payload

The data for the TICKET_OPAQUE Notify payload is made up of the Notify message header and the ticket itself 🎫. Unlike the TICKET_LT_OPAQUE payload, there's no lifetime value in the TICKET_OPAQUE Notify payload πŸ™…β€β™€οΈ.

     0                     1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | Next Payload  |C|  Reserved   |      Payload Length           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | Protocol ID   | SPI Size = 0  |    Notify Message Type        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    ~                        Ticket                                 ~
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

               Figure 7: TICKET_OPAQUE Notify Payload

8. IANA Considerations πŸ“‹

Section 4.3.2 defines a new IKEv2 exchange type, IKE_SESSION_RESUME, and its value has been allocated from the "IKEv2 Exchange Types" registry πŸŽ‰.

Section 7 defines several new IKEv2 notifications, and their Message Type values have been allocated from the "IKEv2 Notify Message Types - Status Types" registry 🏷️.


9. Security Considerations πŸ›‘οΈπŸ’€

This section covers the security issues tied to using a ticket. Buckle up, this part is serious 😀.

9.1. Stolen Tickets

A man in the middle might try to eavesdrop on an exchange to grab a "ticket by value" and use it to set up a session with the IKEv2 responder πŸ‘€. Since every exchange where the client gets a ticket is encrypted, the only way to do this is to listen in while the client uses the ticket to resume a session 🎧. Still, the ticket's contents are encrypted and the attacker doesn't know the secret key, so a stolen ticket can't successfully resume a session πŸ™…β€β™€οΈ. An IKEv2 responder MUST use strong encryption and integrity protection on the ticket so an attacker can't get its contents, for example with a brute force attack πŸ”πŸ’ͺ.

A "ticket by reference" doesn't need to be encrypted. If an adversary can eavesdrop on a resumption attempt, as described in the previous paragraph, the "ticket by reference" can be obtained 😬. Even so, it can't be used by an attacker to successfully resume a session, for the same reasons as a "ticket by value": the attacker wouldn't be able to prove, during IKE_AUTH, that they know the secret part of the IKE state embedded in the ticket 🧠. Moreover, the adversary MUST NOT be able to resolve the ticket via the reference. Access control MUST be enforced so the ticket is only disclosed to authorized entities πŸš§πŸ”’.

Real talk: the reference itself is the thing a snooper can grab, so the access control on the other end is what keeps it locked down πŸ”’.

9.2. Forged Tickets

A malicious user could forge or alter a "ticket by value" to resume a session, extend its lifetime, impersonate another user, or gain extra privileges 😈. This attack doesn't work if the content of the "ticket by value" is protected with a strong integrity protection algorithm πŸ›‘.

With a "ticket by reference," an adversary might try to build a fake one that points at state information stored by the IKEv2 responder 🎭. That attack fails because the adversary doesn't have the keying material associated with the IKEv2 SA πŸ™ƒ. As noted in Section 6.1, it's often useful to integrity-protect the "ticket by reference" too πŸ’œ.

9.3. Denial-of-Service Attacks

An adversary could generate and send a huge number of "tickets by value" to a gateway for verification πŸ“¬. That could burden the gateway's CPU and/or use up its memory with half-open IKE state πŸ₯΅. To keep the chance of this denial of service small, ticket verification should be lightweight (for example, using efficient symmetric key cryptographic algorithms) ⚑.

When an adversary sends a large number of "tickets by reference," it could lead to an amplification attack, because the IKEv2 responder gets forced to resolve each reference to a ticket just to find out that the adversary doesn't have the keying material for the stored state, or that the reference is void πŸ”πŸ˜΅. To minimize this attack, the protocol used to resolve the reference should be as lightweight as possible and should not generate a large number of messages πŸͺΆ.

Also, the regular IKEv2 cookie mechanism can be used to handle state-overflow DoS situations πŸͺ.

9.4. Detecting the Need for Resumption

Figuring out when an old IKE SA is no longer usable and needs to be resumed is out of scope for this document πŸ€·β€β™€οΈ. Still, clients are warned against using a more liberal policy than the one used to detect failed IKE SAs (Section 2.4 of RFC 4306) ⚠️. In particular, untrusted messages MUST NOT be relied upon to make this decision πŸš«πŸ“¨.

9.5. Key Management for "Tickets by Value"

A full description of managing the keys that protect a "ticket by value" is beyond the scope of this document πŸ—οΈ. Here's a list of RECOMMENDED practices:

  • The keys should be generated securely, following the randomness recommendations in [RFC4086] 🎲.
  • The keys and cryptographic protection algorithms should be at least 128 bits in strength πŸ’ͺ.
  • The keys should not be used for any other purpose than generating and verifying tickets πŸ™…β€β™€οΈ.
  • The keys should be changed regularly πŸ”„.
  • The keys should be changed if the ticket format or cryptographic protection algorithms change πŸ†•.

9.6. Ticket Lifetime

An IKEv2 responder controls how long the state information stays valid by attaching a lifetime to a ticket ⏳. The lifetime that gets picked depends on the operational and security requirements of the environment where this IKEv2 extension is deployed 🏒. The responder tells the IKEv2 initiator about the ticket lifetime so the initiator can manage its tickets πŸ—‚οΈ.

9.7. Tickets and Identity

A ticket is associated with a certain identity, and it MUST be managed securely on the client side πŸ”πŸ«Ά. Section 6.2 requires that a ticket be deleted when the credentials tied to the ticket's identity are no longer valid, for example when a user whose credentials were used to create the SA logs out πŸ‘‹.

9.8. Ticket Revocation 🚫

okay so picture this: a sneaky client still holds a ticket for an IKE SA that already got deleted, and it tries to resume the session anyway πŸ’€ that's a no from [Section 6.2]. This only happens with "ticket by value", because a "ticket by reference" has already been deleted from the ticket store 🧹

to block this for "ticket by value", the gateway may keep an Invalid Ticket List (ITL), see [TOKENS] πŸ—’οΈ it can be a super simple blacklist of revoked tickets. or, [TOKENS] suggests Bloom Filters [Bloom70] so the list stays constant space, which is so clever 🧠✨ managing these lists is out of scope for this doc, so that's a later problem 🫢 also, a policy that makes tickets live shorter (like 1 hour) seriously helps with this too πŸ•πŸ’…

9.9. Ticket by Value Format πŸŽ€

the ticket's format isn't defined here, bestie, because interop doesn't need it πŸ™…β€β™€οΈ BUT you have to be really careful when you design one, so the requirements from [Section 6.1] still get met πŸ‘€ the "ticket by value" MUST have its integrity and confidentiality protected with strong cryptographic techniques, or the whole system gets breached πŸ˜­πŸ” this is not a vibe to skip 🚨

9.10. Identity Privacy, Anonymity, and Unlinkability πŸ¦‹

okay this one is giving main character privacy energy 🌸 opaque state info gets passed between the IKEv2 initiator and the IKEv2 responder, so leaking stuff like the identities of the initiator and the responder MUST be avoided πŸ™ˆ

here's the tea: when an IKEv2 initiator presents a ticket in the IKE_SESSION_RESUME exchange, there's no confidentiality for that exchange πŸ‘€ so an on-path adversary could watch several handshakes using the same state info and figure out they all come from the same endpoints. not cute πŸ’€

so this doc says the ticket gets presented to the IKEv2 responder only once 🎟️ under normal conditions (like no active attacker), there should be no multiple use of the same ticket ✨

we aren't aware of any extra security problems with ticket reuse, because the protocol still guarantees freshness of the generated crypto material πŸ’œ still, as noted in [Section 4.3.1], the gateway SHOULD prevent multiple uses of the same ticket πŸ›‘οΈ that's just an extra precaution to make sure clients don't reuse tickets. the gateway isn't expected to hang onto old tickets for long periods, periodt 🫢

10. Acknowledgements 🌈

we want to thank Paul Hoffman, Pasi Eronen, Florian Tegeler, Stephen Kent, Sean Shen, Xiaoming Fu, Stjepan Gros, Dan Harkins, Russ Housely, Yoav Nir, Peny Yang, Sean Turner, and Tero Kivinen for their comments πŸ’– extra huge thanks to Florian Tegeler and Stjepan Gros for their implementation work, and Florian Tegeler again for a formal verification using the Casper tool set πŸ‘‘

we also want to thank the authors of [SA-SYNC] (Yan Xu, Peny Yang, Yuanchen Ma, Hui Deng, and Ke Xu) for their input on the stub concept 🧚

and we want to thank Hui Deng, Tero Kivinen, Peny Yang, Ahmad Muhanna, and Stephen Kent for their feedback on the "ticket by reference" concept πŸ“

Vidya Narayanan and Lakshminath Dondeti coauthored several past versions of this doc, and their contribution was seriously significant 🫢✨

11. References πŸ“š

11.1. Normative References

  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC4306] Kaufman, C., "Internet Key Exchange (IKEv2) Protocol", RFC 4306, December 2005.

11.2. Informative References

  • [Bloom70] Bloom, B., "Space/time trade-offs in hash coding with allowable errors", Comm. ACM 13(7):422-6, July 1970.
  • [EAP-AUTH] Eronen, P., Tschofenig, H., and Y. Sheffer, "An Extension for EAP-Only Authentication in IKEv2", Work in Progress, October 2009.
  • [IKEV2-BIS] Kaufman, C., Hoffman, P., Nir, Y., and P. Eronen, "Internet Key Exchange Protocol: IKEv2", Work in Progress, October 2009.
  • [RFC4086] Eastlake, D., Schiller, J., and S. Crocker, "Randomness Requirements for Security", BCP 106, RFC 4086, June 2005.
  • [RFC4301] Kent, S. and K. Seo, "Security Architecture for the Internet Protocol", RFC 4301, December 2005.
  • [RFC4478] Nir, Y., "Repeated Authentication in Internet Key Exchange (IKEv2) Protocol", RFC 4478, April 2006.
  • [RFC4555] Eronen, P., "IKEv2 Mobility and Multihoming Protocol (MOBIKE)", RFC 4555, June 2006.
  • [RFC4718] Eronen, P. and P. Hoffman, "IKEv2 Clarifications and Implementation Guidelines", RFC 4718, October 2006.
  • [RFC4739] Eronen, P. and J. Korhonen, "Multiple Authentication Exchanges in the Internet Key Exchange (IKEv2) Protocol", RFC 4739, November 2006.
  • [RFC4754] Fu, D. and J. Solinas, "IKE and IKEv2 Authentication Using the Elliptic Curve Digital Signature Algorithm (ECDSA)", RFC 4754, January 2007.
  • [RFC4806] Myers, M. and H. Tschofenig, "Online Certificate Status Protocol (OCSP) Extensions to IKEv2", RFC 4806, February 2007.
  • [RFC5077] Salowey, J., Zhou, H., Eronen, P., and H. Tschofenig, "Transport Layer Security (TLS) Session Resumption without Server-Side State", RFC 5077, January 2008.
  • [RFC5685] Devarapalli, V. and K. Weniger, "Redirect Mechanism for the Internet Key Exchange Protocol Version 2 (IKEv2)", RFC 5685, November 2009.
  • [ROHCoIPsec] Ertekin, E., Christou, C., Jasani, R., Kivinen, T., and C. Bormann, "IKEv2 Extensions to Support Robust Header Compression over IPsec (ROHCoIPsec)", Work in Progress, December 2009.
  • [SA-SYNC] Xu, Y., Yang, P., Ma, Y., Deng, H., and H. Deng, "IKEv2 SA Synchronization for session resumption", Work in Progress, October 2008.
  • [TOKENS] Rescorla, E., "How to Implement Secure (Mostly) Stateless Tokens", Work in Progress, March 2007.

Appendix A. Ticket Format 🎫

this doc doesn't specify a particular ticket format, or even suggested contents for a ticket πŸ’… both are totally up to the implementer 🧚 the formats below are just useful examples, and you're free to use them as-is or change them however you need 🌸

A.1. Example "Ticket by Value" Format πŸŽ€

  struct {
      [authenticated] struct {
          octet format_version;    // 1 for this version of the protocol
          octet reserved[3];       // sent as 0, ignored by receiver.
          octet key_id[8];         // arbitrary byte string
          opaque IV[0..255];       // actual length (possibly 0) depends
                                   // on the encryption algorithm

          [encrypted] struct {
              opaque IDi, IDr;     // the full payloads
              octet SPIi[8], SPIr[8];
              opaque SA;           // the full SAr payload
              octet SK_d[0..255];  // actual length depends on SA value
              enum ... authentication_method;
              int32 expiration;    // an absolute time value, seconds
                                   // since Jan. 1, 1970
          } ikev2_state;
      } protected_part;
      opaque MAC[0..255];          // the length (possibly 0) depends
                                   // on the integrity algorithm
  } ticket;

the key defined by "key_id" decides which encryption and authentication algorithms get used for this ticket πŸ”‘ those algorithms are totally separate from the transforms in the SA payload πŸ™ƒ

the reader should check out [TOKENS], which recommends a similar (but not identical) ticket format and digs into related security considerations in depth πŸ“–βœ¨

A.2. Example "Ticket by Reference" Format πŸ”–

for implementations that would rather pass a reference to IKE state in the ticket instead of the state itself, we suggest this format πŸ¦‹

  struct {
        [authenticated] struct {
            octet format_version;  // 1 for this version of the protocol
            octet reserved[3];     // sent as 0, ignored by receiver.
            octet key_id[8];       // arbitrary byte string

            struct {
                opaque state_ref;  // reference to IKE state
                int32 expiration;  // an absolute time value, seconds
                                   // since Jan. 1, 1970
            } ikev2_state_ref;
        } protected_part;
        opaque MAC[0..255];        // the length depends
                                   // on the integrity algorithm
  } ticket;

Authors' Addresses πŸ’Œ

Yaron Sheffer Check Point Software Technologies Ltd. 5 Hasolelim St. Tel Aviv 67897 Israel

EMail: yaronf@checkpoint.com

Hannes Tschofenig Nokia Siemens Networks Linnoitustie 6 Espoo 02600 Finland

Phone: +358 (50) 4871445 EMail: Hannes.Tschofenig@gmx.net URI: http://www.tschofenig.priv.at

that's the whole RFC, bestie πŸŒˆπŸ’–βœ¨

πŸ“¦ where this page comes from