Skip to content

Latest commit

 

History

History
530 lines (412 loc) · 18.6 KB

File metadata and controls

530 lines (412 loc) · 18.6 KB

Notes on IKEv2 Key Derivation Function

Introduction

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.

KDF methods

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.

KDF generic problem statement

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.

Hardware friendly prf

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.

KDF References

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.

Steffen’s findings.

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.

UDP Encap

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

UDP Encap Source port

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.

Use cases for UDP Encapsulation without NAT

UDP Encapsulation in Cloud Provider

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

WESP UDP Encap

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.

UDP port sharing on Linux

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.

Old references

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

Normative References

RFC2627

RFC3947

RFC3948

RFC5840

RFC7296

RFC8247

RFC4615

RFC5869

NIST800-108

Informative References

RFC4434

RFC9611

RFC8446

RFC7539

RFC9681

RFC5116

RFC6188

I-D.ietf-ipsecme-g-ikev2

I-D.irtf-cfrg-aead-properties

I-D.mattsson-cfrg-aes-gcm-sst

I-D.bottorff-ipsecme-mtdcuc-ipsec-lb

I-D.mostafa-qesp

Azure-Network

GCP-Network

AWS-Network

AWS-IPsec-NetDev

PRGS20

NIST-800-108-comments

IKEv2-prf

PSP

ASCON

GCM-SST-Paper

GCM-SST

NIST800-185

Keccak-vs-AES

NetDev-2024-psp-video

NetDev-2024-psp-talk

KDF-Lecture

HKDF-paper

Keccak-Lecture

EESP-presenation

QESP-Paper