Hi Tero, On your first point, I think this argument assumes the IKE SA rekey happens before the KEYMAT in the child SA is generated. If those happen in the other order -- generating the KEYMAT for the child SA first, then rekeying the original IKE SA afterwards (without tearing down the child SA) -- then I believe the two derivations use the same SK_d.
Perhaps a simpler example is with use of PPKs, where the same static PPK is used in both prf and prf+. The broader point is that use of customisation strings would mean that we wouldn't need to check whether there's any way to induce the prf/prf+ inputs to align. Instead, we'd be guaranteed domain separation for both now and for any future extensions/modifications to the protocol. Re encodings, the current text in the draft is the following: > When KMAC is used as a PRF outside the prf+ construction, the customization > string C is set to the ASCII character string "ikev2 prf", without null > termination. We could say how many characters are in the string if necessary, though I think it's fairly unambiguous currently. Best, Ben -----Original Message----- From: Tero Kivinen <[email protected]> Sent: 21 July 2026 16:34 To: Ben S3 <[email protected]> Cc: [email protected] Subject: [IPsec] Customisation strings with variable-length PRFs? Ben S3 writes: > For instance, consider the following derivations of SKEYSEED > (following a rekey), and of KEYMAT (generated in a CREATE_CHILD_SA): > > SKEYSEED = prf(SK_d (old), g^ir (new) | Ni | Nr) > > KEYMAT = prf+(SK_d, g^ir (new) | Ni | Nr) > > When using KMAC, prf and prf+ are identical, hence if asking for the > same amount of key material, given the same inputs these would produce > the same outputs. Not true. The SK_d is different. The SKEYSEED is used by using old SK_d used before rekey. The SK_d used for the KEYMAT is the new SK_d generated from the SKEYSEED. I.e. the full context is: Initial exchange (marked as _1): SKEYSEED_1 = prf(Ni_1 | Nr_1, g^ir_1) {SK_d_1 | SK_ai_1 | SK_ar_1 | SK_ei_1 | SK_er_1 | SK_pi_1 | SK_pr_1} = prf+ (SKEYSEED_1, Ni_1 | Nr_1 | SPIi_1 | SPIr_1) KEYMAT_1 = prf+(SK_d_1, Ni_1 | Nr_1) Then after rekey the new set of keys is generated (marked as _2): SKEYSEED_2 = prf(SK_d_1, g^ir_2 | Ni_2 | Nr_2) {SK_d_2 | SK_ai_2 | SK_ar_2 | SK_ei_2 | SK_er_2 | SK_pi_2 | SK_pr_2} = prf+ (SKEYSEED_2, Ni_2 | Nr_2 | SPIi_2 | SPIr_2) KEYMAT_2 = prf+(SK_d_2, g^ir_2 | Ni_2 | Nr_2) So the SKEYSEED_2 and KEYMAT_2 have different key, one is using SK_d_1 and another is using SK_d_2. So even if the data is same it should not matter as the keys are completely different. > A way to remove any doubt would be to use customisation strings. > KMAC supports use of a customisation string, which binds the output to > the context in which it was generated, so there'd be no danger of > generating the same value in two different contexts (this property > would likely be easy to prove using a tool like Tamarin, though I have > not done so). However, future standardised XOFs might not support > customisation strings, and adding support for them in legacy IPsec > implementations might be an undesirable amount of work. Are those actual strings, or are they just octet string? We have had some issues with strings, i.e., whether they have newline or nul at the end, and are those added or not... Thats why the IKEv2 RFC7296 has text like: ---------------------------------------------------------------------- For the responder: AUTH = prf( prf(Shared Secret, "Key Pad for IKEv2"), <ResponderSignedOctets>) where the string "Key Pad for IKEv2" is 17 ASCII characters without null termination. ---------------------------------------------------------------------- If they are just octet string, we could just use one octet strings like 0x01, 0x02, 0x03, 0x04, i.e., one octet used as customisation string, when it is one octet string then it is clear there is no newlines, or nul at the end... -- [email protected] _______________________________________________ IPsec mailing list -- [email protected] To unsubscribe send an email to [email protected]
