These are notes on EESP IKEv2 and other EESP related information. To keep it all in one place for quick access. Each section is on its own.
IKEv2 key derivation specified in RFC7296 as prf+, is likely KDF in Feedback Mode
specified in NIST800-108. A prior step to the actual KDF, prf+,
is a Randomness Extractor step, which is prf in RFC7296. The
RFC5869 This is a paper from the same auther HKDF-paper and talk from by Krawczyk
KDF-Lecture
IKEv2 prf+ the iterative method in Section 2.13 RFC7296
In the following, | indicates concatenation. prf+ is defined as: prf+ (K,S) = T1 | T2 | T3 | T4 | …
where: T1 = prf (K, S | 0x01)
T2 = prf (K, T1 | S | 0x02)
T3 = prf (K, T2 | S | 0x03)
T4 = prf (K, T3 | S | 0x04)
…
Section 2.14 of RFC7296 which defined HMAC expansion of SKEYSEED
SKEYSEED = prf(Ni | Nr, g^ir)
IKEv2 key derivation has two setps. Above is the first step and next key expansion using prf+.
{SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr} = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
(indicating that the quantities SK_d, SK_ai, SK_ar, SK_ei, SK_er, SK_pi, and SK_pr are taken in order from the generated bits of the prf+). g^ir is the shared secret from the ephemeral Diffie-Hellman exchange. g^ir is represented as a string of octets in big endian order padded with zeros if necessary to make it the length of the modulus. Ni and Nr are the nonces, stripped of any headers.
KEYMAT = prf+(SK_d, Ni | Nr)
Where Ni and Nr are the nonces from the IKE_SA_INIT exchange if this request is the first Child SA created or the fresh Ni and Nr from the CREATE_CHILD_SA exchange if this is a subsequent creation.
For CREATE_CHILD_SA exchanges including an optional Diffie-Hellman exchange, the keying material is defined as:
KEYMAT = prf+(SK_d, g^ir (new) | Ni | Nr)
where g^ir (new) is the shared secret from the ephemeral Diffie- Hellman exchange of this CREATE_CHILD_SA exchange (represented as an octet string in big endian order padded with zeros in the high-order bits if necessary to make it the length of the modulus).
What EESP IKEv2 proposing as Heirarchial key derivation
NIST800-108 defines Key Hierarchy
In Section 5.4 of Key Management for Multicast RFC2627 a Logical Key Hierarchy (LKH). I din’t follow that completly. It is refered in G-IKEv2.
Fast KDF using AEAD, initial fcous on AES, primitives that can claim 256 strength.
Here is a longer problem statement. The last part is out of my curiosity!
Key Derivation Function (KDF) for Per-Packet Keys: Define a PSP-like KDF that can derive keys per packet at a rate of 200 million or more derivations per second? This should support PSP-like, NIC master key, or IKEv2 SK_d as input.
Sub-SA KDF for IKEv2 We need a KDF that fits the IKEv2 Child SA (using prf and prf+) model and can provide 256-bit strength, ideally on a per-packet basis. We’re also open to slower KDF options depending on the encryption algorithm.
Additional Questions: PSP chose AES-CMAC-256 as their KDF, but IETF doesn’t define or mention it in RFC 8247. Can we add AES-CMAC-256 to RFC 8247?
Out of my curiosity: Are there any KDFs using AEAD that can claim 256-bit strength? I noticed even new ASCON limits itself to ASCON-128 when used as KDF/XOF/MAC.
Current IKEv2 IANA registry,IKEv2-prf, specifies very few hardware friendly Pseudorandom Function Transforms. And IETF recmendations RFC8247 has only PRF_AES128_XCBC.
Hardware friendly prf and prf+ are limited to maximum strength of 128 bits! While the SHA2 does not have this limit. This comes from the limit of input and output block of AES underlying structure. Input is 128 bit and output are 128bits, even when using a 256 bit key. Hence the overall strength when using AES as prf would reduce to 128bit.
In practice many cloud providers appears to be using more hardware friendly PRF, such as AES-CMAC-128 by PSP and very likely AES-CTR by Amazon AWS. Any public citations of AWS PRF? I deduced AES-CTR from their comment to NIST-800-108-comments.
Section 2.14 of RFC7296 “If the negotiated PRF is AES-XCBC-PRF-128 RFC4434 or AES-CMAC-PRF-128 RFC4615, only the first 64 bits of Ni and the first 64 bits of Nr are used in calculating SKEYSEED, but all the bits are used for input to the prf+ function.” When using AES-XCBC-PRF-128 AES-CMAC-PRF-128 the SKEYSEED will be 128bits long. It seems for that reason AES-CMAC-PRF-256 is not standardized?
TLS 1.3, Appendix B of RFC8446 lst HASH. It need a minimum 256 bit output, currently supports SHA256 and SHA384, a.k.a. HASH, HKDF. e.g. TLS_AES_128_GCM_SHA256 TLS_AES_256_GCM_SHA384.
Secure RTP KDF in RFC6188 seems to be similar to our Sub SA.
Sub SA KEYMAT = crypto(Sk_d, Sub SA Salt | Sub SA ID);
e.g with AES-GCM: Sub SA KEYMAT = AES-CTR(Sk_d, Sub SA Salt | Sub SA ID);
Where th Sub SA Salt is derived along with Sk_d to generate extra secret bytes? Sub SA salt together with Sub SA ID would be 128 bits.
I-D.mattsson-cfrg-aes-gcm-sst seems to be deriving per packet keys for GCM. This is an interesting work in cfrg and it is also proposed to NIST. I think their work will keep the IKEv2 prf and prf+ as it is just another layer of HKDF using the AEAD interface specified to RFC5116, which widely reffered API. So any existing implementation that support RFC5116 would be compaitable with GCM SST proposal. I only had qunck glance, so I am not 100% sure yet!
TLS 1.3RFC8446 use hkdf and their reference Krawczyk, H., “Cryptographic Extraction and Key Derivation: The HKDF Scheme”, Proceedings of CRYPTO 2010, August 2010, https://eprint.iacr.org/2010/264.
IETF CFRG is working requirements of AEAD I-D.irtf-cfrg-aead-properties They decided not discuss AEAD as PRF? This is sad news not to specifiy use of same hardware primitive as a PRF for high performance IPsec implimenation.
CFRG discusions point out ChaCha20oly1305 RFC7539 is not a PRF! This points to a reson when using AEAD the underlying crypto operation is used for XOF. Even when the tag 256 bit AES output is 128bits. While there is also a suggestion ChaCha20 is better that AES?
Discussion of I-D.irtf-cfrg-aead-properties https://mailarchive.ietf.org/arch/search/?q=draft-irtf-cfrg-aead-properties%20PRF
Their argument is when using a 128bit primitive as PRF it’s estimated Birthday Attack strength is 128bits. Could this be fixed by using two rounds like PSP did and concatinate it for prf, may be but this need be part of IKEv2. To propose as part of section 2.14
Another possibly related work in cfrg, but for hardware wallets, I.D-dijkhuis-cfrg-hdkeys
IPsecME discussion arguing AES based PRFs would have max 128bit entropy. https://mailarchive.ietf.org/arch/msg/ipsec/Tz4xsjmEHH57jvdMS9pqSFnGbwc/
NIST is coming up with a modern AEAD. The winner is ASCON in 2024. The inventors envsions that AEAD as a PRF. However, only ASCON 128. I found it odd this one only support 128 bit tags. Then we are back to the same argument as this is not good enough for IKEv2 PRF. May be because NIST called it light weight crypto:) We need one for 400Gbps too. A hardware NIC looks like an IoT.
Assume we use some KDF-AES-256 with AES blocksize of 128 bits. Let K_in be the 256 bits input key of KDF-AES-256, n be some 128 bits plaintext and K_out the 128 bits derived session key such that
KDF-AES-256(K_in, n) = K_out.
Because the key space is 256 bits and plaintext/cipertext space is just 128 bits, the function KDF-AES-256 can’t be bijective. This means that there must be multiple keys K_in_i such that
KDF-AES-256(K_in_i, n) = K_out.
This means that you don’t need to find K_in to break the session key K_out. It is sufficiant to find one of the ‘identical’keys K_in_i.
Given keyspace of 256 bits and plaintext/cipertext of 128 bits, we have 2^256/2^128 = 2^128 ‘different’ keys.
So to find K_out, we just need to try 2^128 different keys, even though the keyspace is size is 2^256.
This is why 256 bit keys have the same security level as 128 bit keys in this particular case.
Unfortunately I had to figure that out myself, none of the documents that were written with that knowledge mentioned the problem.
— Actually, this is not quite right:
Given keyspace of 256 bits and plaintext/cipertext of 128 bits, we have 2^256/2^128 = 2^128 ‘different’ keys.
It is so that:
Given keyspace of 256 bits and plaintext/cipertext of 128 bits, we have 2^256/2^128 = 2^128 ‘identical’ keys.
But in this case 2^128 ‘identical’ keys is the same as having 2^128 ‘different’ keys. —
I think this can be generalized. If we have two pairs (n_j,K_out_j) such that:
KDF-AES-256(K_in, n_1) = K_out_1 KDF-AES-256(K_in, n_2) = K_out_2
then we are back at a security level of 2^256. I.e. We have 2^256/(2^128*2^128) =1 ‘identical’ keys. This would be the case if we want to generate a 256 bits key with counter mode.
AA : for the cases where a Salt is required there would be a thrid call. That third call would genearte the salt necessary.
—
Why UDP?
- For Roadwarrior: IPv4 home gateway.
- Why Datacenters, without NAT, using UDP? [Tero] This is a failure for a new protocol.
- In the Cloud per flow limitation, without NAT
- Wide spread RSS Support for UDP when using RFC9611
Current IKEv2 and ESP encapsulation in UDP are specified in RFC3947 and [[RFC3948]. ESP can use the same port opened by IKE. If look at Section 4 of RFC3947 “The initiator MUST set both UDP source and destination ports to 4500.” This means IKE at the source CAN only use source port 4500. HOwever, the RFC further allows inter mediate NAT gateways to change the source port from 4500 to X. This causes split among IPsec adminstrators.
IPsec adminstrators open only out going firewall on the peer for 4500-4500. While the incoming firewall is open for X:4500.
A common question is why use UDP when there is no NAT, especially in cloud environments or why vary UDP source ports for when using multiple SA such as RFC9681].
Cloud providers often enforce bandwidth limits per flow between nodes or to external endpoints. A flow is defined by a 5-tuple: protocol, local IP, remote IP, local port, and remote port. ESP (and likely EESP) lacks port numbers, unlike UDP or TCP, so it is identified only by its local and remote IPs. This causes ESP traffic to be treated as one flow, leading to strict bandwidth limits.
These limits can severely impact IPsec throughput between peers, especially when using RFC9611.
A practical solution is to encapsulate ESP in UDP. By varying the UDP source port based on inner flow characteristics, traffic can be spread across multiple flows. This bypasses bandwidth restrictions and improves throughput. Test results supporting this were presented in AWS-IPsec-NetDev.
For further details, see: Azure-Network, AWS-Network, GCP-Network, I-D.bottorff-ipsecme-mtdcuc-ipsec-lb
RFC5840 WESP has the same issue, because they re-use destination port 4500. WESP-in-UP add additoonal 32 bits, SPI 0x2, to disinguish from EESP. It is 32 bits at the top. SPI 0x2 is from the reserved range SPIs (0-255). I think, the RFC 5840 also advise not to use the first nibble, 4 bits, numbers 4 and 6 could be used by IPv4 or IPv6.
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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Src Port (4500) | Dest Port (4500) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Length | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Protocol Identifier (value = 0x00000002) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Next Header | HdrLen | TrailerLen | Flags | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Existing ESP Encapsulation | ~ ~ | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
EESP could use another spi say 3 as an EESP marker. However, this 4 bytes would lead to waste of 4 bytes every EESP packet.
On Linux define EESPINUDP, a type socket encapsulation. It is similar to ESPINUDP. When set this socket will accept IKE packets, ESP or EESP packets. When sharing the same for port EESP and ESP ESP SPI the bit 31 should be zero.
I-D.mostafa-qesp, QESP-Paper is an effort which is somewhat similart to EESP, especially to expose flow properties outside. The same group also worked on EESP-presenation