Commit 0dd1c50fc0 for openssl.org
commit 0dd1c50fc0706866800c4ad6e5cd05771be5d0d8
Author: Helen Zhang <helzhang@cisco.com>
Date: Fri Mar 13 17:25:31 2026 +0000
Add IKEV2KDF implementation
In compliance with RFC7296 and SP800-135
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
MergeDate: Tue Mar 24 17:21:21 2026
(Merged from https://github.com/openssl/openssl/pull/30121)
diff --git a/.github/workflows/run-checker-daily.yml b/.github/workflows/run-checker-daily.yml
index 2e38038b0e..5a50f1627b 100644
--- a/.github/workflows/run-checker-daily.yml
+++ b/.github/workflows/run-checker-daily.yml
@@ -70,6 +70,7 @@ jobs:
no-hmac-drbg-kdf,
no-hw,
no-idea,
+ no-ikev2kdf,
no-kbkdf,
no-krb5kdf,
enable-lms,
diff --git a/.gitignore b/.gitignore
index d2201aaecf..a7d7b19e30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -104,6 +104,7 @@ providers/implementations/encode_decode/encode_key2ms.inc
providers/implementations/kdfs/argon2.inc
providers/implementations/kdfs/hkdf.inc
providers/implementations/kdfs/hmacdrbg_kdf.inc
+providers/implementations/kdfs/ikev2kdf.inc
providers/implementations/kdfs/kbkdf.inc
providers/implementations/kdfs/krb5kdf.inc
providers/implementations/kdfs/pbkdf1.inc
diff --git a/CHANGES.md b/CHANGES.md
index e7dd11abf0..4cd74cea87 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -74,6 +74,10 @@ OpenSSL Releases
*William McCormack*
+ * Added IKEV2 KDF (EVP_KDF-IKEV2KDF) implementation.
+
+ *Helen Zhang*
+
### Changes between 3.6 and 4.0 [xx XXX xxxx]
* Added `-expected-rpks` option to the `openssl s_client`
diff --git a/Configure b/Configure
index 50cb79b874..38b7399de0 100755
--- a/Configure
+++ b/Configure
@@ -464,6 +464,7 @@ my @disablables_algorithms = (
"krb5kdf",
"gost",
"idea",
+ "ikev2kdf",
"md2",
"md4",
"md5",
@@ -661,7 +662,7 @@ my @disable_cascades = (
"des", "dgram", "dh", "dsa",
"ec", "ech",
"filenames", "hmac-drbg-kdf",
- "idea", "kbkdf", "krb5kdf", "ktls", "lms",
+ "idea", "ikev2kdf", "kbkdf", "krb5kdf", "ktls", "lms",
"md4", "ml-dsa", "ml-kem", "multiblock",
"nextprotoneg", "ocsp", "ocb", "poly1305", "psk",
"pvkkdf", "rc2", "rc4", "rmd160",
diff --git a/INSTALL.md b/INSTALL.md
index e83ad1015d..43408b1c98 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1186,7 +1186,7 @@ The `lms` algorithm support is currently limited to verification only as per
no-{aria|bf|blake2|camellia|cast|chacha|cmac|
des|dh|dsa|
- ec|ec2m|ecdh|ecdsa|hmac-drbg-kdf|idea|kbkdf|krb5kdf|
+ ec|ec2m|ecdh|ecdsa|hmac-drbg-kdf|idea|ikev2kdf|kbkdf|krb5kdf|
md4|mdc2|
ml-dsa|ml-kem|
ocb|poly1305|pvkkdf|rc2|rc4|rmd160|scrypt|
diff --git a/build.info b/build.info
index 5e20a7ed7c..fdcccb46da 100644
--- a/build.info
+++ b/build.info
@@ -60,6 +60,7 @@ DEPEND[]=include/openssl/asn1.h \
providers/implementations/kdfs/argon2.inc \
providers/implementations/kdfs/hkdf.inc \
providers/implementations/kdfs/hmacdrbg_kdf.inc \
+ providers/implementations/kdfs/ikev2kdf.inc \
providers/implementations/kdfs/kbkdf.inc \
providers/implementations/kdfs/krb5kdf.inc \
providers/implementations/kdfs/pbkdf1.inc \
@@ -183,6 +184,7 @@ DEPEND[providers/implementations/asymciphers/rsa_enc.inc \
providers/implementations/kdfs/argon2.inc \
providers/implementations/kdfs/hkdf.inc \
providers/implementations/kdfs/hmacdrbg_kdf.inc \
+ providers/implementations/kdfs/ikev2kdf.inc \
providers/implementations/kdfs/kbkdf.inc \
providers/implementations/kdfs/krb5kdf.inc \
providers/implementations/kdfs/pbkdf1.inc \
@@ -290,6 +292,8 @@ GENERATE[providers/implementations/kdfs/hkdf.inc]=\
providers/implementations/kdfs/hkdf.inc.in
GENERATE[providers/implementations/kdfs/hmacdrbg_kdf.inc]=\
providers/implementations/kdfs/hmacdrbg_kdf.inc.in
+GENERATE[providers/implementations/kdfs/ikev2kdf.inc]=\
+ providers/implementations/kdfs/ikev2kdf.inc.in
GENERATE[providers/implementations/kdfs/kbkdf.inc]=\
providers/implementations/kdfs/kbkdf.inc.in
GENERATE[providers/implementations/kdfs/krb5kdf.inc]=\
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 902f432299..ba558f5a9a 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -1089,11 +1089,14 @@ PROV_R_INVALID_MAC:151:invalid mac
PROV_R_INVALID_MEMORY_SIZE:235:invalid memory size
PROV_R_INVALID_MGF1_MD:167:invalid mgf1 md
PROV_R_INVALID_MODE:125:invalid mode
+PROV_R_INVALID_NONCE_LENGTH:264:invalid nonce length
PROV_R_INVALID_OUTPUT_LENGTH:217:invalid output length
PROV_R_INVALID_PADDING_MODE:168:invalid padding mode
+PROV_R_INVALID_PARAMETERS_FOR_DKM:261:invalid parameters for dkm
PROV_R_INVALID_PREHASHED_DIGEST_LENGTH:241:invalid prehashed digest length
PROV_R_INVALID_PUBINFO:198:invalid pubinfo
PROV_R_INVALID_SALT_LENGTH:112:invalid salt length
+PROV_R_INVALID_SECRET_LENGTH:265:invalid secret length
PROV_R_INVALID_SEED_LENGTH:154:invalid seed length
PROV_R_INVALID_SIGNATURE_SIZE:179:invalid signature size
PROV_R_INVALID_STATE:212:invalid state
@@ -1111,10 +1114,12 @@ PROV_R_MISSING_CEK_ALG:144:missing cek alg
PROV_R_MISSING_CIPHER:155:missing cipher
PROV_R_MISSING_CONFIG_DATA:213:missing config data
PROV_R_MISSING_CONSTANT:156:missing constant
+PROV_R_MISSING_DKM:262:missing dkm
PROV_R_MISSING_EID:255:missing eid
PROV_R_MISSING_KEY:128:missing key
PROV_R_MISSING_MAC:150:missing mac
PROV_R_MISSING_MESSAGE_DIGEST:129:missing message digest
+PROV_R_MISSING_NONCE:263:missing nonce
PROV_R_MISSING_OID:209:missing OID
PROV_R_MISSING_PASS:130:missing pass
PROV_R_MISSING_SALT:131:missing salt
diff --git a/doc/build.info b/doc/build.info
index 3501c4dec6..9f87ba71a9 100644
--- a/doc/build.info
+++ b/doc/build.info
@@ -4601,6 +4601,10 @@ DEPEND[html/man7/EVP_KDF-HMAC-DRBG.html]=man7/EVP_KDF-HMAC-DRBG.pod
GENERATE[html/man7/EVP_KDF-HMAC-DRBG.html]=man7/EVP_KDF-HMAC-DRBG.pod
DEPEND[man/man7/EVP_KDF-HMAC-DRBG.7]=man7/EVP_KDF-HMAC-DRBG.pod
GENERATE[man/man7/EVP_KDF-HMAC-DRBG.7]=man7/EVP_KDF-HMAC-DRBG.pod
+DEPEND[html/man7/EVP_KDF-IKEV2KDF.html]=man7/EVP_KDF-IKEV2KDF.pod
+GENERATE[html/man7/EVP_KDF-IKEV2KDF.html]=man7/EVP_KDF-IKEV2KDF.pod
+DEPEND[man/man7/EVP_KDF-IKEV2KDF.7]=man7/EVP_KDF-IKEV2KDF.pod
+GENERATE[man/man7/EVP_KDF-IKEV2KDF.7]=man7/EVP_KDF-IKEV2KDF.pod
DEPEND[html/man7/EVP_KDF-KB.html]=man7/EVP_KDF-KB.pod
GENERATE[html/man7/EVP_KDF-KB.html]=man7/EVP_KDF-KB.pod
DEPEND[man/man7/EVP_KDF-KB.7]=man7/EVP_KDF-KB.pod
@@ -5208,6 +5212,7 @@ html/man7/EVP_CIPHER-SM4.html \
html/man7/EVP_KDF-ARGON2.html \
html/man7/EVP_KDF-HKDF.html \
html/man7/EVP_KDF-HMAC-DRBG.html \
+html/man7/EVP_KDF-IKEV2KDF.html \
html/man7/EVP_KDF-KB.html \
html/man7/EVP_KDF-KRB5KDF.html \
html/man7/EVP_KDF-PBKDF1.html \
@@ -5372,6 +5377,7 @@ man/man7/EVP_CIPHER-SM4.7 \
man/man7/EVP_KDF-ARGON2.7 \
man/man7/EVP_KDF-HKDF.7 \
man/man7/EVP_KDF-HMAC-DRBG.7 \
+man/man7/EVP_KDF-IKEV2KDF.7 \
man/man7/EVP_KDF-KB.7 \
man/man7/EVP_KDF-KRB5KDF.7 \
man/man7/EVP_KDF-PBKDF1.7 \
diff --git a/doc/man1/openssl-kdf.pod.in b/doc/man1/openssl-kdf.pod.in
index 8631cb0e55..61113846c8 100644
--- a/doc/man1/openssl-kdf.pod.in
+++ b/doc/man1/openssl-kdf.pod.in
@@ -140,7 +140,7 @@ This option is identical to the B<-mac> option.
=item I<kdf_name>
Specifies the name of a supported KDF algorithm which will be used.
-The supported algorithms names include TLS1-PRF, HKDF, SSKDF, PBKDF2,
+The supported algorithms names include TLS1-PRF, HKDF, IKEV2KDF, SSKDF, PBKDF2,
SNMPKDF, SRTPKDF, SSHKDF, X942KDF-ASN1, X942KDF-CONCAT, X963KDF and SCRYPT.
=back
@@ -157,6 +157,55 @@ Use HKDF to create a hex-encoded derived key from a secret key, salt and info:
openssl kdf -keylen 10 -kdfopt digest:SHA2-256 -kdfopt key:secret \
-kdfopt salt:salt -kdfopt info:label HKDF
+Use IKEV2KDF to create a hex-encoded SEEDKEY from initiator_nonce,
+ responder_nonce, and shared secret:
+
+ openssl kdf -keylen 32 -kdfopt digest:SHA256 \
+ -kdfopt hexni:3651FEF5C9C35E93 \
+ -kdfopt hexnr:C09A8B90A3F04D59 \
+ -kdfopt hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C \
+ -kdfopt mode:0 IKEV2KDF
+
+Use IKEV2KDF to create a hex-encoded Derived Key Material (DKM) from initiator_nonce,
+ responder_nonce, SPI_initiator, SPI_responder and SEEDKEY(seed):
+
+ openssl kdf -keylen 224 -kdfopt digest:SHA256 \
+ -kdfopt hexni:3651FEF5C9C35E93 \
+ -kdfopt hexnr:C09A8B90A3F04D59 \
+ -kdfopt hexspii:8E5C3AE507221684 \
+ -kdfopt hexspir:B1F201BB155C3ACD \
+ -kdfopt hexseed:EFAA7AB0EAA85A3D0BE2100CD4B6FE00FF5025A9EAFDDB3EF518E9F0D3FE60E6 \
+ -kdfopt mode:1 IKEV2KDF
+
+Use IKEV2KDF to create a hex-encoded DKM(Child_SA) from initiator_nonce,
+ responder_nonce and sk_d(key):
+
+ openssl kdf -keylen 224 -kdfopt digest:SHA256 \
+ -kdfopt hexni:3651FEF5C9C35E93 \
+ -kdfopt hexnr:C09A8B90A3F04D59 \
+ -kdfopt hexkey:462B9DD525D4FD71169174272779E704BAF62C6231779AE9EFE8C58B21916B42 \
+ -kdfopt mode:1 IKEV2KDF
+
+Use IKEV2KDF to create a hex-encoded DKM(Child_DH) from initiator_nonce,
+ responder_nonce, sk_d(key) and new shared secret:
+
+ openssl kdf -keylen 224 -kdfopt digest:SHA256 \
+ -kdfopt hexni:3651FEF5C9C35E93 \
+ -kdfopt hexnr:C09A8B90A3F04D59 \
+ -kdfopt hexkey:462B9DD525D4FD71169174272779E704BAF62C6231779AE9EFE8C58B21916B42 \
+ -kdfopt hexsecret:52F00AB174C25D5B7139AE5FF4E8E9EDDEE5992D2E36ADF8A559FFD90DAB1442E4FBE429D320C0F33552A17D1557FA41EA70E8FB916C4FA27ED52B5F8EBD8461AFA78F1159159A64055AC5F6319E29C28EAE58CBC6847770F32C3FED1D04750484F854790F95E9EC01BC5BC461F24966462E359511329305038E94DEB6DD42C2 \
+ -kdfopt mode:1 IKEV2KDF
+
+Use IKEV2KDF to create a hex-encoded REKEY from initiator_nonce,
+ responder_nonce, sk_d(key) and new shared secret:
+
+ openssl kdf -keylen 32 -kdfopt digest:SHA256 \
+ -kdfopt hexni:3651FEF5C9C35E93 \
+ -kdfopt hexnr:C09A8B90A3F04D59 \
+ -kdfopt hexkey:462B9DD525D4FD71169174272779E704BAF62C6231779AE9EFE8C58B21916B42 \
+ -kdfopt hexsecret:52F00AB174C25D5B7139AE5FF4E8E9EDDEE5992D2E36ADF8A559FFD90DAB1442E4FBE429D320C0F33552A17D1557FA41EA70E8FB916C4FA27ED52B5F8EBD8461AFA78F1159159A64055AC5F6319E29C28EAE58CBC6847770F32C3FED1D04750484F854790F95E9EC01BC5BC461F24966462E359511329305038E94DEB6DD42C2 \
+ -kdfopt mode:2 IKEV2KDF
+
Use SSKDF with KMAC to create a hex-encoded derived key from a secret key, salt and info:
openssl kdf -keylen 64 -kdfopt mac:KMAC-128 -kdfopt maclen:20 \
@@ -177,9 +226,10 @@ Use SSKDF with Hash to create a hex-encoded derived key from a secret key, salt
Use SNMPKDF to create a hex-encoded derived key from an engine ID, hash and password:
- openssl kdf -keylen 20 -kdfopt digest:SHA1 \
+ openssl kdf -keylen 32 -kdfopt digest:SHA256 \
-kdfopt pass:IFUcNbMl \
- -kdfopt hexeid:800002b805123456789abcdef0123456789abcdef0123456789abcdef0123456 SNMPKDF
+ -kdfopt hexeid:800002b805123456789abcdef0123456789abcdef0123456789abcdef0123456
+ SNMPKDF
Use SRTPKDF to create a SRTP authentication derived key from a cipher, mkey, msalt,
kdr, index and label:
diff --git a/doc/man7/EVP_KDF-IKEV2KDF.pod b/doc/man7/EVP_KDF-IKEV2KDF.pod
new file mode 100644
index 0000000000..cac50f44c5
--- /dev/null
+++ b/doc/man7/EVP_KDF-IKEV2KDF.pod
@@ -0,0 +1,349 @@
+=pod
+
+=head1 NAME
+
+EVP_KDF-IKEV2KDF - The IKEV2KDF EVP_KDF implementation
+
+=head1 DESCRIPTION
+
+Support for computing the B<IKEV2KDF> KDF through the B<EVP_KDF> API.
+
+The EVP_KDF-IKEV2KDF algorithm implements the IKEv2 key derivation function.
+It is defined in RFC 7296, sections 2.13, 2.14, 2.17, 2.18 and is used by the
+Internet Key Exchange version 2 (IKEv2) protocol to derive various keys from
+the shared secret established during the Diffie-Hellman (DH) exchange.
+RFC 4753 specifies additional ECDH groups for use with IKEv2.
+The key derivation requires several inputs including the hash function,
+the shared secret (g^ir), nonces from both parties, the Security
+Parameter Index (SPI) values from both parties, and new shared secret (new g^ir).
+SA refers to the Security Association established between the two parties.
+
+=head2 Identity
+
+"IKEV2KDF" is the name for this implementation; it
+can be used with the EVP_KDF_fetch() function.
+
+=head2 Supported parameters
+
+The supported parameters are:
+
+=over 4
+
+=item "properties" (B<OSSL_KDF_PARAM_PROPERTIES>) <UTF8 string>
+
+=item "digest" (B<OSSL_KDF_PARAM_DIGEST>) <UTF8 string>
+
+These parameters work as described in L<EVP_KDF(3)/PARAMETERS>.
+The digest parameter must be set to one of "SHA1", "SHA224", "SHA256", "SHA384",
+or "SHA512" for the IKEV2KDF implementation.
+If a value is already set, the contents are replaced.
+
+=item "secret" (B<OSSL_KDF_PARAM_SECRET>) <octet string>
+
+This parameter sets the shared secret (g^ir) used for generating the SEEDKEY,
+or the new shared secret (new g^ir) used for deriving DKM(Child_DH) or REKEY.
+The shared secret length is in the range of 8 to 1024 bytes as specified in the NIST
+ACVP draft (L<https://pages.nist.gov/ACVP/draft-celi-acvp-kdf-ikev2.html>).
+If a value is already set, the contents are replaced.
+
+=item "ni" (B<OSSL_KDF_PARAM_IKEV2_NI>) <octet string>
+
+This parameter sets the initiator's nonce (Ni) value for the KDF.
+The nonce length is in the range of 8 to 256 bytes as specified in NIST
+ACVP draft (L<https://pages.nist.gov/ACVP/draft-celi-acvp-kdf-ikev2.html>).
+If a value is already set, the contents are replaced.
+
+=item "nr" (B<OSSL_KDF_PARAM_IKEV2_NR>) <octet string>
+
+This parameter sets the responder's nonce (Nr) value for the KDF.
+The nonce length is in the range of 8 to 256 bytes as specified in NIST
+ACVP draft (L<https://pages.nist.gov/ACVP/draft-celi-acvp-kdf-ikev2.html>).
+If a value is already set, the contents are replaced.
+
+=item "spii" (B<OSSL_KDF_PARAM_IKEV2_SPII>) <octet string>
+
+This parameter sets the initiator's Security Parameter Index (SPIi) value
+for the KDF. If a value is already set, the contents are replaced.
+
+=item "spir" (B<OSSL_KDF_PARAM_IKEV2_SPIR>) <octet string>
+
+This parameter sets the responder's Security Parameter Index (SPIr) value
+for the KDF. If a value is already set, the contents are replaced.
+
+=item "seedkey" (B<OSSL_KDF_PARAM_SEEDKEY>) <octet string>
+
+This parameter sets the SEEDKEY used for deriving DKM(Initial SA).
+If a value is already set, the contents are replaced.
+
+=item "key" (B<OSSL_KDF_PARAM_KEY>) <octet string>
+
+This parameter sets the SK_d used for deriving DKM(Child_SA) or REKEY.
+If a value is already set, the contents are replaced.
+
+=item "mode" (B<OSSL_KDF_PARAM_MODE>) <int>
+
+This parameter sets the IKEv2 KDF mode. The IKEV2KDF implementation supports
+three different modes of operation:
+
+=over 8
+
+=item EVP_KDF_IKEV2_MODE_GEN
+
+It generates the SKEYSEED used in deriving key material.
+It is the default mode if the "mode" parameter is not set.
+It takes the shared secret (g^ir) and nonces (Ni and Nr) as input and
+generates the SKEYSEED.
+
+=item EVP_KDF_IKEV2_MODE_DKM
+
+It operates in three stages, based on the input parameter sets.
+
+It first performs initial key derivation: it derives the initial set of keys
+(SK_d, SK_ai, SK_ar, SK_ei, SK_er, SK_pi, SK_pr) using SKEYSEED generated in
+"EVP_KDF_IKEV2_MODE_GEN", the nonces (from both sides), and security parameter
+index (SPI) values (from both sides).
+
+Then, it derives keying material for the Child_SA, using the SK_d as input
+along with new nonces.
+
+Finally, it derives keying material for the Child_DH, using the SK_d as input
+along with new nonces and new shared secret (new g^ir).
+
+=item EVP_KDF_IKEV2_MODE_REKEY
+
+It derives a new SKEYSEED when rekeying the IKE SA, using the existing SK_d as
+input along with new nonces and new shared secret (new g^ir).
+
+=back
+
+=back
+
+=head1 NOTES
+
+A context for IKEV2KDF can be obtained by calling:
+
+ EVP_KDF *kdf = EVP_KDF_fetch(NULL, "IKEV2KDF", NULL);
+ EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
+
+The output length for IKEV2KDF can be specified by the caller based on the
+specific key being derived (e.g., SK_d, SK_ai, SK_ar, SK_ei, SK_er, SK_pi, SK_pr).
+Different keys may require different lengths depending on the cryptographic
+algorithms being used.
+
+=head1 EXAMPLES
+
+=head2 Example of SEEDKEY generation
+
+This example derives a 32-byte SEEDKEY using SHA-256 with the appropriate
+shared secret and nonces:
+
+ EVP_KDF *kdf = NULL;
+ EVP_KDF_CTX *kctx = NULL;
+ unsigned char secret[32] = "0123456789abcdef0123456789abcdef"; /* g^ir */
+ unsigned char ni[8] = "01234567";
+ unsigned char nr[8] = "89abcdef";
+ int mode = EVP_KDF_IKEV2_MODE_GEN;
+ unsigned char out[32];
+ size_t outlen = sizeof(out);
+ OSSL_PARAM params[6], *p = params;
+
+ kdf = EVP_KDF_fetch(NULL, "IKEV2KDF", NULL);
+ kctx = EVP_KDF_CTX_new(kdf);
+ if (!kctx) {
+ /* Error handling */
+ }
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ SN_sha256, strlen(SN_sha256));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET,
+ secret, sizeof(secret));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NI,
+ ni, sizeof(ni));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NR,
+ nr, sizeof(nr));
+ *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
+ *p = OSSL_PARAM_construct_end();
+ if (EVP_KDF_derive(kctx, out, outlen, params) <= 0) {
+ /* Error */
+ ;
+ }
+ EVP_KDF_CTX_free(kctx);
+ EVP_KDF_free(kdf);
+
+=head2 Example of deriving key material DKM(Initial SA)
+
+ EVP_KDF *kdf = NULL;
+ EVP_KDF_CTX *kctx = NULL;
+ unsigned char ni[8] = "01234567";
+ unsigned char nr[8] = "89abcdef";
+ unsigned char spii[8] = "01234567";
+ unsigned char spir[8] = "89abcdef";
+ unsigned char skeyseed[32] = "0123456789abcdef0123456789abcdef";
+ int mode = EVP_KDF_IKEV2_MODE_DKM;
+ unsigned char out[224];
+ OSSL_PARAM params[8], *p = params;
+
+ kdf = EVP_KDF_fetch(NULL, "IKEV2KDF", NULL);
+ kctx = EVP_KDF_CTX_new(kdf);
+ if (!kctx) {
+ /* Error handling */
+ }
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ SN_sha256, strlen(SN_sha256));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
+ skeyseed, sizeof(skeyseed));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NI,
+ ni, sizeof(ni));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NR,
+ nr, sizeof(nr));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_SPII,
+ spii, sizeof(spii));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_SPIR,
+ spir, sizeof(spir));
+ *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
+ *p = OSSL_PARAM_construct_end();
+ if (EVP_KDF_derive(kctx, out, sizeof(out), params) <= 0) {
+ /* Error handling */
+ ;
+ }
+ EVP_KDF_CTX_free(kctx);
+ EVP_KDF_free(kdf);
+
+=head2 Example of generating DKM(Child_SA)
+
+ EVP_KDF *kdf = NULL;
+ EVP_KDF_CTX *kctx = NULL;
+ unsigned char ni[8] = "01234567";
+ unsigned char nr[8] = "89abcdef";
+ unsigned char sk_d[32] = "0123456789abcdef0123456789abcdef";
+ int mode = EVP_KDF_IKEV2_MODE_DKM;
+ unsigned char out[224];
+ OSSL_PARAM params[6], *p = params;
+
+ kdf = EVP_KDF_fetch(NULL, "IKEV2KDF", NULL);
+ kctx = EVP_KDF_CTX_new(kdf);
+ if (!kctx) {
+ /* Error handling */
+ }
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ SN_sha256, strlen(SN_sha256));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ sk_d, sizeof(sk_d));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NI,
+ ni, sizeof(ni));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NR,
+ nr, sizeof(nr));
+ *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
+ *p = OSSL_PARAM_construct_end();
+ if (EVP_KDF_derive(kctx, out, sizeof(out), params) <= 0) {
+ /* Error handling */
+ ;
+ }
+ EVP_KDF_CTX_free(kctx);
+ EVP_KDF_free(kdf);
+
+=head2 Example of generating DKM(Child_DH)
+
+ EVP_KDF *kdf = NULL;
+ EVP_KDF_CTX *kctx = NULL;
+ unsigned char ni[8] = "01234567";
+ unsigned char nr[8] = "89abcdef";
+ unsigned char sk_d[32] = "0123456789abcdef0123456789abcdef";
+ unsigned char new_secret[32] = "0123456789abcdef0123456789abcdef"; /* new g^ir */
+ int mode = EVP_KDF_IKEV2_MODE_DKM;
+ unsigned char out[224];
+ OSSL_PARAM params[7], *p = params;
+
+ kdf = EVP_KDF_fetch(NULL, "IKEV2KDF", NULL);
+ kctx = EVP_KDF_CTX_new(kdf);
+ if (!kctx) {
+ /* Error handling */
+ }
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ SN_sha256, strlen(SN_sha256));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ sk_d, sizeof(sk_d));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET,
+ new_secret, sizeof(new_secret));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NI,
+ ni, sizeof(ni));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NR,
+ nr, sizeof(nr));
+ *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
+ *p = OSSL_PARAM_construct_end();
+ if (EVP_KDF_derive(kctx, out, sizeof(out), params) <= 0) {
+ /* Error */
+ ;
+ }
+ EVP_KDF_CTX_free(kctx);
+ EVP_KDF_free(kdf);
+
+=head2 Example of rekeying the IKE SA
+
+ EVP_KDF *kdf = NULL;
+ EVP_KDF_CTX *kctx = NULL;
+ unsigned char ni[8] = "01234567";
+ unsigned char nr[8] = "89abcdef";
+ unsigned char sk_d[32] = "0123456789abcdef0123456789abcdef";
+ unsigned char new_secret[32] = "0123456789abcdef0123456789abcdef"; /* new g^ir */
+ int mode = EVP_KDF_IKEV2_MODE_REKEY;
+ unsigned char out[32];
+ OSSL_PARAM params[7], *p = params;
+
+ kdf = EVP_KDF_fetch(NULL, "IKEV2KDF", NULL);
+ kctx = EVP_KDF_CTX_new(kdf);
+ if (!kctx) {
+ /* Error handling */
+ }
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ SN_sha256, strlen(SN_sha256));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ sk_d, sizeof(sk_d));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET,
+ new_secret, sizeof(new_secret));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NI,
+ ni, sizeof(ni));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_IKEV2KDF_NR,
+ nr, sizeof(nr));
+ *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
+ *p = OSSL_PARAM_construct_end();
+ if (EVP_KDF_derive(kctx, out, sizeof(out), params) <= 0) {
+ /* Error handling */
+ ;
+ }
+ EVP_KDF_CTX_free(kctx);
+ EVP_KDF_free(kdf);
+
+=head1 CONFORMING TO
+
+RFC 7296 and SP800-135
+
+=head1 SEE ALSO
+
+L<EVP_KDF(3)>,
+L<EVP_KDF_CTX_new(3)>,
+L<EVP_KDF_CTX_dup(3)>,
+L<EVP_KDF_CTX_free(3)>,
+L<EVP_KDF_CTX_set_params(3)>,
+L<EVP_KDF_CTX_get_kdf_size(3)>,
+L<EVP_KDF_derive(3)>,
+L<EVP_KDF(3)/PARAMETERS>
+
+=head1 HISTORY
+
+This functionality was added in OpenSSL 4.1.
+
+=head1 COPYRIGHT
+
+Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man7/OSSL_PROVIDER-FIPS.pod b/doc/man7/OSSL_PROVIDER-FIPS.pod
index 2f93d95176..04e722f1dc 100644
--- a/doc/man7/OSSL_PROVIDER-FIPS.pod
+++ b/doc/man7/OSSL_PROVIDER-FIPS.pod
@@ -115,6 +115,8 @@ It is used internally as a sub algorithm of CSHAKE.
=item HKDF-SHA512, see L<EVP_KDF-HKDF(7)>
+=item IKEV2KDF, see L<EVP_KDF-IKEV2KDF(7)>
+
=item TLS13-KDF, see L<EVP_KDF-TLS13_KDF(7)>
=item SSKDF, see L<EVP_KDF-SS(7)>
@@ -480,6 +482,8 @@ Key agreement tests used with the "KAT_KA" type.
=item "HKDF" (B<OSSL_SELF_TEST_DESC_KDF_HKDF>)
+=item "IKEV2KDF" (B<OSSL_SELF_TEST_DESC_KDF_IKEV2KDF>)
+
=item "TLS13_KDF_EXTRACT" (B<OSSL_SELF_TEST_DESC_KDF_TLS13_EXTRACT>)
=item "TLS13_KDF_EXPAND" (B<OSSL_SELF_TEST_DESC_KDF_TLS13_EXPAND>)
diff --git a/doc/man7/OSSL_PROVIDER-default.pod b/doc/man7/OSSL_PROVIDER-default.pod
index e1bbf5b336..c987e9de96 100644
--- a/doc/man7/OSSL_PROVIDER-default.pod
+++ b/doc/man7/OSSL_PROVIDER-default.pod
@@ -135,6 +135,8 @@ The OpenSSL default provider supports these operations and algorithms:
=item HKDF-SHA512, see L<EVP_KDF-HKDF(7)>
+=item IKEV2KDF, see L<EVP_KDF-IKEV2KDF(7)>
+
=item TLS13-KDF, see L<EVP_KDF-TLS13_KDF(7)>
=item SSKDF, see L<EVP_KDF-SS(7)>
diff --git a/include/internal/fips.h b/include/internal/fips.h
index b48c66e1a6..47d1213007 100644
--- a/include/internal/fips.h
+++ b/include/internal/fips.h
@@ -89,6 +89,13 @@ typedef enum {
ST_ID_KDF_KBKDF_KMAC,
#endif
ST_ID_KDF_HKDF,
+#ifndef OPENSSL_NO_IKEV2KDF
+ ST_ID_KDF_IKEV2KDF_GEN,
+ ST_ID_KDF_IKEV2KDF_DKM1,
+ ST_ID_KDF_IKEV2KDF_DKM2,
+ ST_ID_KDF_IKEV2KDF_DKM3,
+ ST_ID_KDF_IKEV2KDF_REKEY,
+#endif
#ifndef OPENSSL_NO_SNMPKDF
ST_ID_KDF_SNMPKDF,
#endif
diff --git a/include/openssl/core_names.h.in b/include/openssl/core_names.h.in
index d753f7f484..7d8080f59e 100644
--- a/include/openssl/core_names.h.in
+++ b/include/openssl/core_names.h.in
@@ -71,6 +71,7 @@ extern "C" {
#define OSSL_KDF_NAME_HKDF_SHA256 "HKDF-SHA256"
#define OSSL_KDF_NAME_HKDF_SHA384 "HKDF-SHA384"
#define OSSL_KDF_NAME_HKDF_SHA512 "HKDF-SHA512"
+#define OSSL_KDF_NAME_IKEV2KDF "IKEV2KDF"
#define OSSL_KDF_NAME_TLS1_3_KDF "TLS13-KDF"
#define OSSL_KDF_NAME_PBKDF1 "PBKDF1"
#define OSSL_KDF_NAME_PBKDF2 "PBKDF2"
diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h
index f3267eae38..ab79e02e04 100644
--- a/include/openssl/kdf.h
+++ b/include/openssl/kdf.h
@@ -67,6 +67,10 @@ int EVP_KDF_names_do_all(const EVP_KDF *kdf,
#define EVP_KDF_HKDF_MODE_EXTRACT_ONLY 1
#define EVP_KDF_HKDF_MODE_EXPAND_ONLY 2
+#define EVP_KDF_IKEV2_MODE_GEN 0
+#define EVP_KDF_IKEV2_MODE_DKM 1
+#define EVP_KDF_IKEV2_MODE_REKEY 2
+
#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV 65
#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI 66
#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV 67
diff --git a/include/openssl/proverr.h b/include/openssl/proverr.h
index d32984a5b2..79bbc6628e 100644
--- a/include/openssl/proverr.h
+++ b/include/openssl/proverr.h
@@ -80,11 +80,14 @@
#define PROV_R_INVALID_MEMORY_SIZE 235
#define PROV_R_INVALID_MGF1_MD 167
#define PROV_R_INVALID_MODE 125
+#define PROV_R_INVALID_NONCE_LENGTH 264
#define PROV_R_INVALID_OUTPUT_LENGTH 217
#define PROV_R_INVALID_PADDING_MODE 168
+#define PROV_R_INVALID_PARAMETERS_FOR_DKM 261
#define PROV_R_INVALID_PREHASHED_DIGEST_LENGTH 241
#define PROV_R_INVALID_PUBINFO 198
#define PROV_R_INVALID_SALT_LENGTH 112
+#define PROV_R_INVALID_SECRET_LENGTH 265
#define PROV_R_INVALID_SEED_LENGTH 154
#define PROV_R_INVALID_SIGNATURE_SIZE 179
#define PROV_R_INVALID_STATE 212
@@ -102,10 +105,12 @@
#define PROV_R_MISSING_CIPHER 155
#define PROV_R_MISSING_CONFIG_DATA 213
#define PROV_R_MISSING_CONSTANT 156
+#define PROV_R_MISSING_DKM 262
#define PROV_R_MISSING_EID 255
#define PROV_R_MISSING_KEY 128
#define PROV_R_MISSING_MAC 150
#define PROV_R_MISSING_MESSAGE_DIGEST 129
+#define PROV_R_MISSING_NONCE 263
#define PROV_R_MISSING_OID 209
#define PROV_R_MISSING_PASS 130
#define PROV_R_MISSING_SALT 131
diff --git a/include/openssl/self_test.h b/include/openssl/self_test.h
index c7eb50860f..02c8f9ba1d 100644
--- a/include/openssl/self_test.h
+++ b/include/openssl/self_test.h
@@ -80,6 +80,11 @@ extern "C" {
#define OSSL_SELF_TEST_DESC_KA_DH "DH"
#define OSSL_SELF_TEST_DESC_KA_ECDH "ECDH"
#define OSSL_SELF_TEST_DESC_KDF_HKDF "HKDF"
+#define OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_GEN "IKEV2KDF_GEN"
+#define OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_DKM1 "IKEV2KDF_DKM"
+#define OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_DKM2 "IKEV2KDF_DKM(Child_SA)"
+#define OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_DKM3 "IKEV2KDF_DKM(Child_DH)"
+#define OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_REKEY "IKEV2KDF_REKEY"
#define OSSL_SELF_TEST_DESC_KDF_SSKDF "SSKDF"
#define OSSL_SELF_TEST_DESC_KDF_X963KDF "X963KDF"
#define OSSL_SELF_TEST_DESC_KDF_X942KDF "X942KDF"
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index 3392e0e475..7e3e189dd2 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -114,15 +114,21 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
"invalid memory size" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MGF1_MD), "invalid mgf1 md" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE), "invalid mode" },
+ { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_NONCE_LENGTH),
+ "invalid nonce length" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_OUTPUT_LENGTH),
"invalid output length" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PADDING_MODE),
"invalid padding mode" },
+ { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PARAMETERS_FOR_DKM),
+ "invalid parameters for dkm" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH),
"invalid prehashed digest length" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PUBINFO), "invalid pubinfo" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SALT_LENGTH),
"invalid salt length" },
+ { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SECRET_LENGTH),
+ "invalid secret length" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SEED_LENGTH),
"invalid seed length" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SIGNATURE_SIZE),
@@ -149,11 +155,13 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONFIG_DATA),
"missing config data" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONSTANT), "missing constant" },
+ { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_DKM), "missing dkm" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_EID), "missing eid" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_KEY), "missing key" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MAC), "missing mac" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MESSAGE_DIGEST),
"missing message digest" },
+ { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_NONCE), "missing nonce" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_OID), "missing OID" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_PASS), "missing pass" },
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SALT), "missing salt" },
diff --git a/providers/defltprov.c b/providers/defltprov.c
index d19d6ece26..c471cf8e7e 100644
--- a/providers/defltprov.c
+++ b/providers/defltprov.c
@@ -372,6 +372,9 @@ static const OSSL_ALGORITHM deflt_kdfs[] = {
{ PROV_NAMES_TLS1_PRF, "provider=default", ossl_kdf_tls1_prf_functions },
{ PROV_NAMES_PBKDF2, "provider=default", ossl_kdf_pbkdf2_functions },
{ PROV_NAMES_PKCS12KDF, "provider=default", ossl_kdf_pkcs12_functions },
+#ifndef OPENSSL_NO_IKEV2KDF
+ { PROV_NAMES_IKEV2KDF, "provider=default", ossl_kdf_ikev2kdf_functions },
+#endif
#ifndef OPENSSL_NO_SSKDF
{ PROV_NAMES_SSKDF, "provider=default", ossl_kdf_sskdf_functions },
#endif
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index cbd2d10539..e16c913592 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -381,6 +381,9 @@ static const OSSL_ALGORITHM fips_macs_internal[] = {
*/
static const OSSL_ALGORITHM fips_kdfs[] = {
FIPS_KDFS_COMMON(),
+#ifndef OPENSSL_NO_IKEV2KDF
+ { PROV_NAMES_IKEV2KDF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_ikev2kdf_functions },
+#endif
#ifndef OPENSSL_NO_SSKDF
{ PROV_NAMES_SSKDF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_sskdf_functions },
#endif
@@ -408,6 +411,9 @@ static const OSSL_ALGORITHM fips_kdfs[] = {
static const OSSL_ALGORITHM fips_kdfs_internal[] = {
FIPS_KDFS_COMMON(),
+#ifndef OPENSSL_NO_IKEV2KDF
+ { PROV_NAMES_IKEV2KDF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_ikev2kdf_functions },
+#endif
#ifndef OPENSSL_NO_SSKDF
{ PROV_NAMES_SSKDF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_sskdf_functions },
#endif
diff --git a/providers/fips/self_test_data.c b/providers/fips/self_test_data.c
index a0a86b1216..1f403be7dc 100644
--- a/providers/fips/self_test_data.c
+++ b/providers/fips/self_test_data.c
@@ -307,8 +307,224 @@ static const ST_KAT_PARAM hkdf_params[] = {
ST_KAT_PARAM_END()
};
+#ifndef OPENSSL_NO_IKEV2KDF
+static const char ikev2kdf_digest[] = "SHA256";
+
+static const unsigned char ikev2kdf_ni[] = {
+ 0x36, 0x51, 0xfe, 0xf5, 0xc9, 0xc3, 0x5e, 0x93
+};
+
+static const unsigned char ikev2kdf_nr[] = {
+ 0xc0, 0x9a, 0x8b, 0x90, 0xa3, 0xf0, 0x4d, 0x59
+};
+
+static const unsigned char ikev2kdf_spi_init[] = {
+ 0x8e, 0x5c, 0x3a, 0xe5, 0x07, 0x22, 0x16, 0x84
+};
+
+static const unsigned char ikev2kdf_spi_resp[] = {
+ 0xb1, 0xf2, 0x01, 0xbb, 0x15, 0x5c, 0x3a, 0xcd
+};
+
+static const unsigned char ikev2kdf_gir[] = {
+ 0xd0, 0x84, 0xa3, 0x01, 0x66, 0xa5, 0x0f, 0xb7, 0x32, 0x5c, 0x39, 0x60,
+ 0x87, 0x4a, 0x83, 0x94, 0x49, 0xef, 0x97, 0x41, 0xc2, 0xf4, 0xf9, 0x47,
+ 0xd0, 0x20, 0x1d, 0xd8, 0xc1, 0x26, 0x92, 0x73, 0xd7, 0x95, 0x09, 0xf3,
+ 0x7e, 0x3c, 0xa3, 0xeb, 0x4f, 0xa2, 0xfe, 0x2a, 0x28, 0x25, 0x4e, 0x28,
+ 0x9c, 0xd3, 0xf3, 0x4d, 0xad, 0x4e, 0xb4, 0xdf, 0x1a, 0x07, 0x68, 0x5a,
+ 0x4b, 0x8a, 0x94, 0xfa, 0x61, 0xe2, 0x49, 0x1f, 0x75, 0x98, 0xb3, 0xce,
+ 0x65, 0x54, 0x7f, 0xf1, 0x33, 0xb3, 0xf6, 0x3d, 0x1a, 0xc4, 0x17, 0x5e,
+ 0xaa, 0x69, 0x50, 0x33, 0xf3, 0xce, 0xdb, 0x02, 0x6a, 0x68, 0x73, 0xa3,
+ 0x64, 0x55, 0x17, 0x2a, 0x85, 0x40, 0xb8, 0xa5, 0xd2, 0x3a, 0x01, 0x43,
+ 0xbe, 0xd0, 0x39, 0x0e, 0xe4, 0x9b, 0x16, 0x82, 0x69, 0xd7, 0x5f, 0xff,
+ 0xee, 0x9f, 0xb6, 0x2b, 0xe9, 0x65, 0x99, 0x3c
+};
+
+static const unsigned char ikev2kdf_new_gir[] = {
+ 0x52, 0xf0, 0x0a, 0xb1, 0x74, 0xc2, 0x5d, 0x5b, 0x71, 0x39, 0xae, 0x5f,
+ 0xf4, 0xe8, 0xe9, 0xed, 0xde, 0xe5, 0x99, 0x2d, 0x2e, 0x36, 0xad, 0xf8,
+ 0xa5, 0x59, 0xff, 0xd9, 0x0d, 0xab, 0x14, 0x42, 0xe4, 0xfb, 0xe4, 0x29,
+ 0xd3, 0x20, 0xc0, 0xf3, 0x35, 0x52, 0xa1, 0x7d, 0x15, 0x57, 0xfa, 0x41,
+ 0xea, 0x70, 0xe8, 0xfb, 0x91, 0x6c, 0x4f, 0xa2, 0x7e, 0xd5, 0x2b, 0x5f,
+ 0x8e, 0xbd, 0x84, 0x61, 0xaf, 0xa7, 0x8f, 0x11, 0x59, 0x15, 0x9a, 0x64,
+ 0x05, 0x5a, 0xc5, 0xf6, 0x31, 0x9e, 0x29, 0xc2, 0x8e, 0xae, 0x58, 0xcb,
+ 0xc6, 0x84, 0x77, 0x70, 0xf3, 0x2c, 0x3f, 0xed, 0x1d, 0x04, 0x75, 0x04,
+ 0x84, 0xf8, 0x54, 0x79, 0x0f, 0x95, 0xe9, 0xec, 0x01, 0xbc, 0x5b, 0xc4,
+ 0x61, 0xf2, 0x49, 0x66, 0x46, 0x2e, 0x35, 0x95, 0x11, 0x32, 0x93, 0x05,
+ 0x03, 0x8e, 0x94, 0xde, 0xb6, 0xdd, 0x42, 0xc2
+};
+
+static const unsigned char ikev2kdf_expected_seedkey[] = {
+ 0xEF, 0xAA, 0x7A, 0xB0, 0xEA, 0xA8, 0x5A, 0x3D,
+ 0x0B, 0xE2, 0x10, 0x0C, 0xD4, 0xB6, 0xFE, 0x00,
+ 0xFF, 0x50, 0x25, 0xA9, 0xEA, 0xFD, 0xDB, 0x3E,
+ 0xF5, 0x18, 0xE9, 0xF0, 0xD3, 0xFE, 0x60, 0xE6
+};
+
+static const unsigned char ikev2kdf_expected_dkm[] = {
+ 0x46, 0x2B, 0x9D, 0xD5, 0x25, 0xD4, 0xFD, 0x71,
+ 0x16, 0x91, 0x74, 0x27, 0x27, 0x79, 0xE7, 0x04,
+ 0xBA, 0xF6, 0x2C, 0x62, 0x31, 0x77, 0x9A, 0xE9,
+ 0xEF, 0xE8, 0xC5, 0x8B, 0x21, 0x91, 0x6B, 0x42,
+ 0x01, 0x01, 0x64, 0xAF, 0x21, 0x11, 0xEB, 0xD7,
+ 0x62, 0xF6, 0x91, 0x6C, 0xA9, 0xA6, 0xF0, 0xEE,
+ 0x05, 0xC8, 0xB3, 0x20, 0xE4, 0xEE, 0x27, 0x70,
+ 0x55, 0x21, 0xDE, 0x25, 0x89, 0xAD, 0xEA, 0x18,
+ 0x78, 0xF1, 0xA5, 0x51, 0x73, 0x8A, 0xF7, 0xC8,
+ 0x8D, 0xC4, 0xF0, 0xBB, 0x0C, 0x09, 0x6A, 0x3F,
+ 0x7D, 0x1F, 0x1A, 0x67, 0x0F, 0xC7, 0x9F, 0x49,
+ 0xF6, 0x78, 0xD6, 0x0D, 0x66, 0x5B, 0xB3, 0x71,
+ 0x0C, 0x86, 0x57, 0xF0, 0x3B, 0xA9, 0xF6, 0x2B,
+ 0x9A, 0x81, 0x8D, 0x7A, 0x22, 0x89, 0x68, 0xC5,
+ 0x06, 0xE2, 0x37, 0xAE, 0x95, 0x02, 0xAA, 0x6D,
+ 0xB3, 0x95, 0xC6, 0x1E, 0xA6, 0xA3, 0xE7, 0x95,
+ 0x04, 0xF8, 0x6B, 0x73, 0x68, 0xBF, 0xB5, 0x42,
+ 0x3D, 0xF7, 0x9E, 0x48, 0x80, 0x9B, 0xBC, 0xCD,
+ 0x49, 0xFD, 0x82, 0x6D, 0x02, 0x4F, 0x63, 0xD7,
+ 0xC2, 0xA5, 0x56, 0x64, 0x00, 0xA1, 0x2E, 0x73,
+ 0x6A, 0xA0, 0x34, 0x51, 0x04, 0x28, 0xF5, 0xEA,
+ 0x00, 0x8F, 0xE2, 0xFC, 0x16, 0x88, 0x6F, 0xA3,
+ 0x88, 0x27, 0x4E, 0xA6, 0xC2, 0xB4, 0xFC, 0xFC,
+ 0x61, 0x41, 0xBF, 0x04, 0xF8, 0x20, 0x7E, 0xF8,
+ 0xAF, 0xC2, 0x24, 0xEA, 0x10, 0x59, 0xCB, 0x22,
+ 0x0D, 0xC0, 0xB2, 0x3A, 0xC0, 0xE4, 0xCC, 0xDA,
+ 0x49, 0x5A, 0x4E, 0x13, 0x1B, 0x1D, 0x56, 0xE2,
+ 0x23, 0xAB, 0xA5, 0xA4, 0x8E, 0x8E, 0xD1, 0xF5
+};
+
+/* sk_d = the first 32 bytes (SHA256) of ikev2kdf_expected_dkm */
+static const unsigned char ikev2kdf_sk_d[] = {
+ 0x46, 0x2B, 0x9D, 0xD5, 0x25, 0xD4, 0xFD, 0x71,
+ 0x16, 0x91, 0x74, 0x27, 0x27, 0x79, 0xE7, 0x04,
+ 0xBA, 0xF6, 0x2C, 0x62, 0x31, 0x77, 0x9A, 0xE9,
+ 0xEF, 0xE8, 0xC5, 0x8B, 0x21, 0x91, 0x6B, 0x42
+};
+
+static const unsigned char ikev2kdf_expected_dkm_sa[] = {
+ 0x23, 0x64, 0x76, 0x77, 0xE7, 0xD4, 0x03, 0xFA,
+ 0x1E, 0x30, 0x06, 0xF1, 0x98, 0x40, 0xAE, 0xE1,
+ 0x8A, 0xD9, 0xFE, 0xCC, 0x42, 0x15, 0x81, 0x4C,
+ 0x41, 0x31, 0xBD, 0xEB, 0xA9, 0x84, 0x33, 0xD8,
+ 0xB0, 0xE3, 0x1B, 0xFB, 0xBD, 0xDF, 0x82, 0x2A,
+ 0xBC, 0xCE, 0x5E, 0x06, 0x48, 0x6A, 0xA3, 0x88,
+ 0x02, 0x2B, 0x75, 0xE2, 0x7E, 0x1E, 0x68, 0xAA,
+ 0x59, 0x83, 0x02, 0x8B, 0x65, 0x28, 0x2C, 0x73,
+ 0x0C, 0x5D, 0x49, 0xEF, 0x76, 0x06, 0x77, 0x03,
+ 0x76, 0xCF, 0xDE, 0xC4, 0x1F, 0x7C, 0xC4, 0x35,
+ 0xD8, 0x16, 0x02, 0x99, 0x89, 0xBC, 0x35, 0x3D,
+ 0x3B, 0x67, 0xB9, 0xFD, 0x11, 0x68, 0xDD, 0xCB,
+ 0x89, 0x78, 0x85, 0x0D, 0xA9, 0xB7, 0x52, 0xAE,
+ 0xE6, 0xA3, 0x0D, 0x00, 0x86, 0xD2, 0xC4, 0xD7,
+ 0x4E, 0xC0, 0xE0, 0x36, 0x48, 0xA0, 0xDA, 0xD3,
+ 0x34, 0xFA, 0xF5, 0xFE, 0x88, 0x08, 0x4E, 0x67,
+ 0xB0, 0xF3, 0xE8, 0xFE, 0xE8, 0xB5, 0xE1, 0xBD,
+ 0x38, 0x50, 0xDB, 0x54, 0x0F, 0x1F, 0xB8, 0xCF,
+ 0xFE, 0x23, 0xC9, 0xE9, 0x2C, 0xDA, 0x20, 0x93,
+ 0x73, 0xF3, 0x54, 0x88, 0x0C, 0x24, 0x6C, 0x75,
+ 0x3E, 0x2A, 0x0E, 0xCA, 0x9C, 0xB7, 0x3B, 0x99,
+ 0x10, 0xA8, 0x53, 0x1C, 0x40, 0x10, 0xE6, 0x76,
+ 0x8F, 0xA2, 0x9F, 0x90, 0x9E, 0x60, 0xAF, 0x77,
+ 0x7F, 0xED, 0x6E, 0x73, 0x9C, 0x3C, 0xFD, 0xA0,
+ 0x34, 0x67, 0xE9, 0x15, 0xD6, 0xF0, 0x3F, 0xCE,
+ 0x9C, 0x41, 0xF5, 0xF9, 0xD5, 0x78, 0xF8, 0x91,
+ 0x2D, 0x66, 0xA7, 0x54, 0x57, 0xE7, 0x9E, 0xE1,
+ 0xD5, 0xBC, 0xC2, 0xBE, 0x5C, 0x2F, 0x9B, 0xAE
+};
+
+static const unsigned char ikev2kdf_expected_dkm_dh[] = {
+ 0x6A, 0x91, 0x93, 0x87, 0xA5, 0xFA, 0x28, 0x35,
+ 0xFE, 0x8A, 0x82, 0x37, 0xE4, 0xA1, 0x48, 0x45,
+ 0xBD, 0x2B, 0x99, 0x30, 0xDB, 0x87, 0xEF, 0xF7,
+ 0xAD, 0xF2, 0x68, 0xF6, 0x21, 0x86, 0x00, 0x49,
+ 0x02, 0xDB, 0xA9, 0xAA, 0x94, 0x2D, 0x02, 0x59,
+ 0xA0, 0xED, 0xC4, 0x12, 0x0B, 0x93, 0x2A, 0x50,
+ 0x38, 0x65, 0xB5, 0x7B, 0xA8, 0xFB, 0x88, 0x11,
+ 0x7E, 0xF5, 0xDF, 0x7B, 0x26, 0x79, 0x9C, 0xD8,
+ 0xBA, 0x37, 0xAA, 0x54, 0x38, 0x10, 0x8C, 0xB1,
+ 0xA4, 0xFE, 0x11, 0x79, 0x07, 0xC9, 0xD0, 0x59,
+ 0x7B, 0x70, 0x8C, 0x3F, 0x11, 0x15, 0x1F, 0xEF,
+ 0xD6, 0x24, 0xD2, 0x31, 0x72, 0x02, 0xB7, 0xC8,
+ 0x14, 0x30, 0x60, 0x0E, 0x6F, 0xCB, 0xB6, 0xE1,
+ 0xA8, 0xDF, 0x2B, 0x48, 0x61, 0xEF, 0x23, 0x63,
+ 0xD5, 0x3D, 0xE1, 0xBE, 0x69, 0x05, 0x7B, 0x0C,
+ 0xF6, 0x63, 0x4A, 0x7E, 0x7B, 0xFA, 0x97, 0xB3,
+ 0xC2, 0x81, 0x06, 0x23, 0xE2, 0xBD, 0x67, 0x57,
+ 0x73, 0x87, 0x77, 0x17, 0x70, 0x36, 0xE9, 0xC3,
+ 0xA3, 0x97, 0x94, 0x45, 0x69, 0x54, 0xBD, 0x41,
+ 0xFC, 0x44, 0x4A, 0x12, 0x50, 0x7A, 0xB9, 0xCA,
+ 0xC6, 0x9A, 0x05, 0x40, 0xD1, 0x3C, 0x29, 0xDB,
+ 0x85, 0x10, 0xF5, 0x66, 0xA6, 0x91, 0x69, 0x1B,
+ 0xAA, 0x2D, 0x95, 0x69, 0xDA, 0xCC, 0x99, 0x0D,
+ 0x56, 0xA4, 0x54, 0xBB, 0x44, 0x4B, 0xCB, 0xBE,
+ 0x87, 0x51, 0xB0, 0x55, 0x0A, 0x52, 0x78, 0x81,
+ 0x2F, 0xC5, 0xAB, 0x4F, 0x28, 0x99, 0x0D, 0xD6,
+ 0xD6, 0x08, 0x53, 0x8D, 0x7D, 0xDD, 0xE2, 0x4D,
+ 0xC8, 0x1B, 0xDA, 0xAC, 0xA7, 0x75, 0x1F, 0xDE
+};
+
+static const unsigned char ikev2kdf_expected_rekey[] = {
+ 0x90, 0x72, 0x2C, 0x42, 0xBD, 0x84, 0x9E, 0x9B,
+ 0x72, 0xD2, 0x40, 0xFC, 0x25, 0x41, 0x74, 0x27,
+ 0x0F, 0xA8, 0x29, 0x5D, 0xE6, 0xF0, 0x33, 0x8D,
+ 0xAF, 0xC3, 0x03, 0xA9, 0xEC, 0x10, 0x4F, 0x12
+};
+
+static const int ikev2kdf_mode_gen = EVP_KDF_IKEV2_MODE_GEN;
+static const ST_KAT_PARAM ikev2kdf_gen_params[] = {
+ ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, ikev2kdf_digest),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NI, ikev2kdf_ni),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NR, ikev2kdf_nr),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SECRET, ikev2kdf_gir),
+ ST_KAT_PARAM_INT(OSSL_KDF_PARAM_MODE, ikev2kdf_mode_gen),
+ ST_KAT_PARAM_END()
+};
+
+static const int ikev2kdf_mode_dkm = EVP_KDF_IKEV2_MODE_DKM;
+static const ST_KAT_PARAM ikev2kdf_dkm_params_dkm[] = {
+ ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, ikev2kdf_digest),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NI, ikev2kdf_ni),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NR, ikev2kdf_nr),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_SPII, ikev2kdf_spi_init),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_SPIR, ikev2kdf_spi_resp),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SEED, ikev2kdf_expected_seedkey),
+ ST_KAT_PARAM_INT(OSSL_KDF_PARAM_MODE, ikev2kdf_mode_dkm),
+ ST_KAT_PARAM_END()
+};
+
+static const ST_KAT_PARAM ikev2kdf_dkm_params_sa[] = {
+ ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, ikev2kdf_digest),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NI, ikev2kdf_ni),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NR, ikev2kdf_nr),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, ikev2kdf_sk_d),
+ ST_KAT_PARAM_INT(OSSL_KDF_PARAM_MODE, ikev2kdf_mode_dkm),
+ ST_KAT_PARAM_END()
+};
+
+static const ST_KAT_PARAM ikev2kdf_dkm_params_dh[] = {
+ ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, ikev2kdf_digest),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NI, ikev2kdf_ni),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NR, ikev2kdf_nr),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, ikev2kdf_sk_d),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SECRET, ikev2kdf_new_gir),
+ ST_KAT_PARAM_INT(OSSL_KDF_PARAM_MODE, ikev2kdf_mode_dkm),
+ ST_KAT_PARAM_END()
+};
+
+static const int ikev2kdf_mode_rekey = EVP_KDF_IKEV2_MODE_REKEY;
+
+static const ST_KAT_PARAM ikev2kdf_rekey_params[] = {
+ ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, ikev2kdf_digest),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NI, ikev2kdf_ni),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_IKEV2KDF_NR, ikev2kdf_nr),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SECRET, ikev2kdf_new_gir),
+ ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, ikev2kdf_sk_d),
+ ST_KAT_PARAM_INT(OSSL_KDF_PARAM_MODE, ikev2kdf_mode_rekey),
+ ST_KAT_PARAM_END()
+};
+#endif
+
#ifndef OPENSSL_NO_SNMPKDF
-static const char snmpkdf_digest[] = "SHA1";
+static const char snmpkdf_digest[] = "SHA256";
static const unsigned char snmpkdf_eid[] = {
0x80, 0x00, 0x02, 0xb8, 0x05, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde,
0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56,
@@ -319,8 +535,10 @@ static const unsigned char snmpkdf_password[] = {
0x52, 0x65, 0x52, 0x4a
};
static const unsigned char snmpkdf_expected[] = {
- 0x3c, 0xd1, 0x21, 0xcb, 0xf3, 0xe8, 0xbf, 0x9e, 0x6d, 0x80, 0xf5, 0xf0,
- 0x53, 0x83, 0x5b, 0x3c, 0x24, 0x1c, 0xd2, 0x1e
+ 0xE2, 0x3C, 0xCD, 0xA8, 0xCE, 0x93, 0x51, 0x79,
+ 0xA9, 0xF0, 0x38, 0xAA, 0xEA, 0x08, 0xA0, 0xFA,
+ 0x03, 0x11, 0x9D, 0x80, 0xA8, 0xCF, 0x2E, 0x98,
+ 0x9F, 0xAD, 0x33, 0x2C, 0x20, 0x77, 0xE0, 0x52
};
static const ST_KAT_PARAM snmpkdf_params[] = {
ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, snmpkdf_digest),
@@ -3862,6 +4080,63 @@ ST_DEFINITION st_all_tests[ST_ID_MAX] = {
},
.depends_on = hkdf_depends_on,
},
+#ifndef OPENSSL_NO_IKEV2KDF
+ {
+ ST_ID_KDF_IKEV2KDF_GEN,
+ OSSL_KDF_NAME_IKEV2KDF,
+ OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_GEN,
+ SELF_TEST_KAT_KDF,
+ SELF_TEST_STATE_INIT,
+ .expected = ITM_BUF(ikev2kdf_expected_seedkey),
+ .u.kdf = {
+ ikev2kdf_gen_params,
+ },
+ },
+ {
+ ST_ID_KDF_IKEV2KDF_DKM1,
+ OSSL_KDF_NAME_IKEV2KDF,
+ OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_DKM1,
+ SELF_TEST_KAT_KDF,
+ SELF_TEST_STATE_INIT,
+ .expected = ITM_BUF(ikev2kdf_expected_dkm),
+ .u.kdf = {
+ ikev2kdf_dkm_params_dkm,
+ },
+ },
+ {
+ ST_ID_KDF_IKEV2KDF_DKM2,
+ OSSL_KDF_NAME_IKEV2KDF,
+ OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_DKM2,
+ SELF_TEST_KAT_KDF,
+ SELF_TEST_STATE_INIT,
+ .expected = ITM_BUF(ikev2kdf_expected_dkm_sa),
+ .u.kdf = {
+ ikev2kdf_dkm_params_sa,
+ },
+ },
+ {
+ ST_ID_KDF_IKEV2KDF_DKM3,
+ OSSL_KDF_NAME_IKEV2KDF,
+ OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_DKM3,
+ SELF_TEST_KAT_KDF,
+ SELF_TEST_STATE_INIT,
+ .expected = ITM_BUF(ikev2kdf_expected_dkm_dh),
+ .u.kdf = {
+ ikev2kdf_dkm_params_dh,
+ },
+ },
+ {
+ ST_ID_KDF_IKEV2KDF_REKEY,
+ OSSL_KDF_NAME_IKEV2KDF,
+ OSSL_SELF_TEST_DESC_KDF_IKEV2KDF_REKEY,
+ SELF_TEST_KAT_KDF,
+ SELF_TEST_STATE_INIT,
+ .expected = ITM_BUF(ikev2kdf_expected_rekey),
+ .u.kdf = {
+ ikev2kdf_rekey_params,
+ },
+ },
+#endif
#ifndef OPENSSL_NO_SNMPKDF
{
ST_ID_KDF_SNMPKDF,
diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c
index a7c856b01b..17f79b9d0c 100644
--- a/providers/fips/self_test_kats.c
+++ b/providers/fips/self_test_kats.c
@@ -260,7 +260,7 @@ static int self_test_kdf(const ST_DEFINITION *t, OSSL_SELF_TEST *st,
OSSL_LIB_CTX *libctx)
{
int ret = 0;
- unsigned char out[128];
+ unsigned char out[256];
EVP_KDF *kdf = NULL;
EVP_KDF_CTX *ctx = NULL;
OSSL_PARAM *params = NULL;
@@ -294,6 +294,9 @@ err:
EVP_KDF_free(kdf);
EVP_KDF_CTX_free(ctx);
OSSL_PARAM_free(params);
+#ifdef OPENSSL_PEDANTIC_ZEROIZATION
+ OPENSSL_cleanse(out, 256);
+#endif
OSSL_SELF_TEST_onend(st, ret);
return ret;
}
diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h
index a64b30ec2a..76b3d6d3e3 100644
--- a/providers/implementations/include/prov/implementations.h
+++ b/providers/implementations/include/prov/implementations.h
@@ -294,6 +294,7 @@ extern const OSSL_DISPATCH ossl_kdf_hkdf_functions[];
extern const OSSL_DISPATCH ossl_kdf_hkdf_sha256_functions[];
extern const OSSL_DISPATCH ossl_kdf_hkdf_sha384_functions[];
extern const OSSL_DISPATCH ossl_kdf_hkdf_sha512_functions[];
+extern const OSSL_DISPATCH ossl_kdf_ikev2kdf_functions[];
extern const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[];
extern const OSSL_DISPATCH ossl_kdf_snmpkdf_functions[];
extern const OSSL_DISPATCH ossl_kdf_srtpkdf_functions[];
diff --git a/providers/implementations/include/prov/names.h b/providers/implementations/include/prov/names.h
index c900e5063b..a80eb99a08 100644
--- a/providers/implementations/include/prov/names.h
+++ b/providers/implementations/include/prov/names.h
@@ -292,6 +292,7 @@
#define PROV_DESCS_HKDF_SHA384_SIGN "OpenSSL HKDF-SHA384 via EVP_PKEY implementation"
#define PROV_NAMES_HKDF_SHA512 "HKDF-SHA512:id-alg-hkdf-with-sha512:1.2.840.113549.1.9.16.3.30"
#define PROV_DESCS_HKDF_SHA512_SIGN "OpenSSL HKDF-SHA512 via EVP_PKEY implementation"
+#define PROV_NAMES_IKEV2KDF "IKEV2KDF"
#define PROV_NAMES_TLS1_3_KDF "TLS13-KDF"
#define PROV_NAMES_SSKDF "SSKDF"
#define PROV_NAMES_PBKDF1 "PBKDF1"
diff --git a/providers/implementations/kdfs/build.info b/providers/implementations/kdfs/build.info
index fbf6097dc0..1a890cd45d 100644
--- a/providers/implementations/kdfs/build.info
+++ b/providers/implementations/kdfs/build.info
@@ -3,6 +3,7 @@
$TLS1_PRF_GOAL=../../libdefault.a ../../libfips.a
$HKDF_GOAL=../../libdefault.a ../../libfips.a
+$IKEV2_GOAL=../../libdefault.a ../../libfips.a
$KBKDF_GOAL=../../libdefault.a ../../libfips.a
$KRB5KDF_GOAL=../../libdefault.a
$PBKDF1_GOAL=../../liblegacy.a
@@ -22,6 +23,9 @@ SOURCE[$TLS1_PRF_GOAL]=tls1_prf.c
SOURCE[$HKDF_GOAL]=hkdf.c
+IF[{- !$disabled{ikev2kdf} -}]
+ SOURCE[$IKEV2_GOAL]=ikev2kdf.c
+ENDIF
IF[{- !$disabled{kbkdf} -}]
SOURCE[$KBKDF_GOAL]=kbkdf.c
ENDIF
diff --git a/providers/implementations/kdfs/ikev2kdf.c b/providers/implementations/kdfs/ikev2kdf.c
new file mode 100644
index 0000000000..377a70fb18
--- /dev/null
+++ b/providers/implementations/kdfs/ikev2kdf.c
@@ -0,0 +1,750 @@
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+#include <openssl/core_names.h>
+#include <openssl/proverr.h>
+#include "internal/cryptlib.h"
+#include "internal/fips.h"
+#include "prov/provider_ctx.h"
+#include "prov/providercommon.h"
+#include "prov/implementations.h"
+#include "prov/provider_util.h"
+#include "providers/implementations/kdfs/ikev2kdf.inc"
+
+/* The shared secret length: 28 ~ 1024 bytes */
+#define IKEV2KDF_MIN_SECRET_LENGTH 28
+#define IKEV2KDF_MAX_GROUP19_MODLEN 32 /* ECDH p256 */
+#define IKEV2KDF_MAX_GROUP20_MODLEN 48 /* ECDH p384 */
+#define IKEV2KDF_MAX_GROUP21_MODLEN 66 /* ECDH p521 */
+#define IKEV2KDF_MAX_GROUP2_MODLEN 128 /* DH group 2, no longer secure */
+#define IKEV2KDF_MAX_GROUP14_MODLEN 256
+#define IKEV2KDF_MAX_GROUP15_MODLEN 384
+#define IKEV2KDF_MAX_GROUP16_MODLEN 512
+#define IKEV2KDF_MAX_GROUP17_MODLEN 768
+#define IKEV2KDF_MAX_GROUP18_MODLEN 1024
+#define IKEV2KDF_MIN_NONCE_LENGTH 8
+#define IKEV2KDF_MAX_NONCE_LENGTH 256
+#define IKEV2KDF_MAX_DKM_LENGTH 2048
+
+static OSSL_FUNC_kdf_newctx_fn kdf_ikev2kdf_new;
+static OSSL_FUNC_kdf_dupctx_fn kdf_ikev2kdf_dup;
+static OSSL_FUNC_kdf_freectx_fn kdf_ikev2kdf_free;
+static OSSL_FUNC_kdf_reset_fn kdf_ikev2kdf_reset;
+static OSSL_FUNC_kdf_derive_fn kdf_ikev2kdf_derive;
+static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_ikev2kdf_settable_ctx_params;
+static OSSL_FUNC_kdf_set_ctx_params_fn kdf_ikev2kdf_set_ctx_params;
+static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_ikev2kdf_gettable_ctx_params;
+static OSSL_FUNC_kdf_get_ctx_params_fn kdf_ikev2kdf_get_ctx_params;
+
+static int IKEV2_GEN(OSSL_LIB_CTX *libctx, unsigned char *seedkey, const size_t keylen,
+ char *md_name, const unsigned char *ni, const size_t ni_len,
+ const unsigned char *nr, const size_t nr_len,
+ const unsigned char *shared_secret, const size_t shared_secret_len);
+static int IKEV2_REKEY(OSSL_LIB_CTX *libctx, unsigned char *seedkey, const size_t keylen,
+ char *md_name, const unsigned char *ni, const size_t ni_len,
+ const unsigned char *nr, const size_t nr_len,
+ const unsigned char *shared_secret, const size_t shared_secret_len,
+ const unsigned char *sk_d, const size_t skd_len);
+static int IKEV2_DKM(OSSL_LIB_CTX *libctx, unsigned char *dkm, const size_t len_out,
+ const EVP_MD *evp_md, const unsigned char *seedkey, const size_t seedkey_len,
+ const unsigned char *ni, const size_t ni_len,
+ const unsigned char *nr, const size_t nr_len,
+ const unsigned char *spii, const size_t spii_len,
+ const unsigned char *spir, const size_t spir_len,
+ const unsigned char *shared_secret, const size_t shared_secret_len);
+
+typedef struct {
+ OSSL_LIB_CTX *libctx;
+ PROV_DIGEST digest;
+ uint8_t *secret;
+ size_t secret_len;
+ uint8_t *seedkey;
+ size_t seedkey_len;
+ uint8_t *ni;
+ size_t ni_len;
+ uint8_t *nr;
+ size_t nr_len;
+ uint8_t *spii;
+ size_t spii_len;
+ uint8_t *spir;
+ size_t spir_len;
+ uint8_t *sk_d;
+ size_t sk_d_len;
+ int mode;
+} KDF_IKEV2KDF;
+
+static void *kdf_ikev2kdf_new(void *provctx)
+{
+ KDF_IKEV2KDF *ctx;
+
+ if (!ossl_prov_is_running())
+ return NULL;
+
+#ifdef FIPS_MODULE
+ if (!ossl_deferred_self_test(PROV_LIBCTX_OF(provctx),
+ ST_ID_KDF_IKEV2KDF_GEN))
+ return NULL;
+#endif
+
+ if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL)
+ ctx->libctx = PROV_LIBCTX_OF(provctx);
+ return ctx;
+}
+
+static void *kdf_ikev2kdf_dup(void *vctx)
+{
+ KDF_IKEV2KDF *src = (KDF_IKEV2KDF *)vctx;
+ KDF_IKEV2KDF *dest = NULL;
+
+ dest = OPENSSL_zalloc(sizeof(*src));
+ if (dest != NULL) {
+ dest->libctx = src->libctx;
+ if ((src->secret != NULL)
+ && (!ossl_prov_memdup(src->secret, src->secret_len,
+ &dest->secret, &dest->secret_len)))
+ goto err;
+
+ if ((src->seedkey != NULL)
+ && (!ossl_prov_memdup(src->seedkey, src->seedkey_len,
+ &dest->seedkey, &dest->seedkey_len)))
+ goto err;
+
+ if ((src->ni != NULL)
+ && (!ossl_prov_memdup(src->ni, src->ni_len, &dest->ni, &dest->ni_len)))
+ goto err;
+
+ if ((src->nr != NULL)
+ && (!ossl_prov_memdup(src->nr, src->nr_len, &dest->nr, &dest->nr_len)))
+ goto err;
+ if ((src->spii != NULL)
+ && (!ossl_prov_memdup(src->spii, src->spii_len, &dest->spii, &dest->spii_len)))
+ goto err;
+ if ((src->spir != NULL)
+ && (!ossl_prov_memdup(src->spir, src->spir_len, &dest->spir, &dest->spir_len)))
+ goto err;
+
+ if ((src->sk_d != NULL)
+ && (!ossl_prov_memdup(src->sk_d, src->sk_d_len,
+ &dest->sk_d, &dest->sk_d_len)))
+ goto err;
+
+ if (!ossl_prov_digest_copy(&dest->digest, &src->digest))
+ goto err;
+ dest->mode = src->mode;
+ }
+ return dest;
+
+err:
+ kdf_ikev2kdf_free(dest);
+ return NULL;
+}
+static void kdf_ikev2kdf_free(void *vctx)
+{
+ KDF_IKEV2KDF *ctx = (KDF_IKEV2KDF *)vctx;
+
+ if (ctx != NULL) {
+ kdf_ikev2kdf_reset(ctx);
+ OPENSSL_free(ctx);
+ }
+}
+
+static void kdf_ikev2kdf_reset(void *vctx)
+{
+ KDF_IKEV2KDF *ctx = (KDF_IKEV2KDF *)vctx;
+ OSSL_LIB_CTX *libctx = ctx->libctx;
+
+ ossl_prov_digest_reset(&ctx->digest);
+ OPENSSL_clear_free(ctx->secret, ctx->secret_len);
+ OPENSSL_clear_free(ctx->seedkey, ctx->seedkey_len);
+ OPENSSL_clear_free(ctx->sk_d, ctx->sk_d_len);
+ OPENSSL_clear_free(ctx->ni, ctx->ni_len);
+ OPENSSL_clear_free(ctx->nr, ctx->nr_len);
+ OPENSSL_clear_free(ctx->spii, ctx->spii_len);
+ OPENSSL_clear_free(ctx->spir, ctx->spir_len);
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->libctx = libctx;
+}
+
+static int ikev2kdf_set_membuf(unsigned char **dst, size_t *dst_len,
+ const OSSL_PARAM *p)
+{
+ OPENSSL_clear_free(*dst, *dst_len);
+ *dst = NULL;
+ *dst_len = 0;
+ return OSSL_PARAM_get_octet_string(p, (void **)dst, 0, dst_len);
+}
+
+static int ikev2_common_check_ctx_params(KDF_IKEV2KDF *ctx)
+{
+ if (ctx->ni == NULL) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_NONCE);
+ return 0;
+ }
+
+ if (ctx->nr == NULL) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_NONCE);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * RFC 7296: section 2.14
+ * 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.
+ * The secret length is in range of 28 ~ 1024 bytes, and the padding length
+ * is determined by the secret length:
+ * ecdh group 19 32 bytes
+ * ecdh group 20 48 bytes
+ * ecdh group 21 66 bytes
+ * dh group 2 128 bytes (no longer secure, but still supported for interoperability)
+ * dh group 14 256 bytes
+ * dh group 15 384 bytes
+ * dh group 16 512 bytes
+ * dh group 17 768 bytes
+ * dh group 18 1024 bytes
+ * secret is required for GEN, REKEY and DKM(Child_DH).
+ */
+static int ikev2_check_secret_and_pad(KDF_IKEV2KDF *ctx)
+{
+ size_t pad_len = 0;
+ uint8_t *new_secret = NULL;
+
+ if (ctx->secret_len == 0)
+ return 1;
+ if ((ctx->secret_len < IKEV2KDF_MIN_SECRET_LENGTH)
+ || (ctx->secret_len > IKEV2KDF_MAX_GROUP18_MODLEN)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SECRET_LENGTH);
+ return 0;
+ }
+ if ((ctx->secret_len == IKEV2KDF_MAX_GROUP19_MODLEN)
+ || (ctx->secret_len == IKEV2KDF_MAX_GROUP20_MODLEN)
+ || (ctx->secret_len == IKEV2KDF_MAX_GROUP21_MODLEN)
+ || (ctx->secret_len == IKEV2KDF_MAX_GROUP2_MODLEN)
+ || (ctx->secret_len == IKEV2KDF_MAX_GROUP14_MODLEN)
+ || (ctx->secret_len == IKEV2KDF_MAX_GROUP15_MODLEN)
+ || (ctx->secret_len == IKEV2KDF_MAX_GROUP16_MODLEN)
+ || (ctx->secret_len == IKEV2KDF_MAX_GROUP17_MODLEN)
+ || (ctx->secret_len == IKEV2KDF_MAX_GROUP18_MODLEN))
+ /* no padding needed if secret_len is already valid */
+ return 1;
+
+ if (ctx->secret_len < IKEV2KDF_MAX_GROUP19_MODLEN)
+ pad_len = IKEV2KDF_MAX_GROUP19_MODLEN - ctx->secret_len;
+ if ((ctx->secret_len > IKEV2KDF_MAX_GROUP19_MODLEN)
+ && (ctx->secret_len < IKEV2KDF_MAX_GROUP20_MODLEN))
+ pad_len = IKEV2KDF_MAX_GROUP20_MODLEN - ctx->secret_len;
+ if ((ctx->secret_len > IKEV2KDF_MAX_GROUP20_MODLEN)
+ && (ctx->secret_len < IKEV2KDF_MAX_GROUP21_MODLEN))
+ pad_len = IKEV2KDF_MAX_GROUP21_MODLEN - ctx->secret_len;
+ if ((ctx->secret_len > IKEV2KDF_MAX_GROUP21_MODLEN)
+ && (ctx->secret_len < IKEV2KDF_MAX_GROUP2_MODLEN))
+ pad_len = IKEV2KDF_MAX_GROUP2_MODLEN - ctx->secret_len;
+ if ((ctx->secret_len > IKEV2KDF_MAX_GROUP2_MODLEN)
+ && (ctx->secret_len < IKEV2KDF_MAX_GROUP14_MODLEN))
+ pad_len = IKEV2KDF_MAX_GROUP14_MODLEN - ctx->secret_len;
+ if ((ctx->secret_len > IKEV2KDF_MAX_GROUP14_MODLEN)
+ && (ctx->secret_len < IKEV2KDF_MAX_GROUP15_MODLEN))
+ pad_len = IKEV2KDF_MAX_GROUP15_MODLEN - ctx->secret_len;
+ if ((ctx->secret_len > IKEV2KDF_MAX_GROUP15_MODLEN)
+ && (ctx->secret_len < IKEV2KDF_MAX_GROUP16_MODLEN))
+ pad_len = IKEV2KDF_MAX_GROUP16_MODLEN - ctx->secret_len;
+ if ((ctx->secret_len >= IKEV2KDF_MAX_GROUP16_MODLEN)
+ && (ctx->secret_len < IKEV2KDF_MAX_GROUP17_MODLEN))
+ pad_len = IKEV2KDF_MAX_GROUP17_MODLEN - ctx->secret_len;
+ if (ctx->secret_len > IKEV2KDF_MAX_GROUP17_MODLEN)
+ pad_len = IKEV2KDF_MAX_GROUP18_MODLEN - ctx->secret_len;
+
+ new_secret = OPENSSL_zalloc(ctx->secret_len + pad_len);
+ if (new_secret == NULL) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memcpy(new_secret + pad_len, ctx->secret, ctx->secret_len);
+ OPENSSL_clear_free(ctx->secret, ctx->secret_len);
+ ctx->secret = new_secret;
+ ctx->secret_len += pad_len;
+ return 1;
+}
+
+static int kdf_ikev2kdf_derive(void *vctx, unsigned char *key, size_t keylen,
+ const OSSL_PARAM params[])
+{
+ KDF_IKEV2KDF *ctx = (KDF_IKEV2KDF *)vctx;
+ const EVP_MD *md;
+ size_t md_size;
+
+ if (!ossl_prov_is_running() || !kdf_ikev2kdf_set_ctx_params(ctx, params))
+ return 0;
+
+ md = ossl_prov_digest_md(&ctx->digest);
+ if (md == NULL) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+ return 0;
+ }
+ md_size = EVP_MD_size(md);
+ if (md_size <= 0)
+ return 0;
+
+ if (!ikev2_common_check_ctx_params(ctx))
+ return 0;
+
+ switch (ctx->mode) {
+ case EVP_KDF_IKEV2_MODE_GEN:
+ if ((ctx->secret == NULL) || (ctx->secret_len == 0)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
+ return 0;
+ }
+ if (keylen != md_size) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ if (!ikev2_check_secret_and_pad(ctx))
+ return 0;
+ return (IKEV2_GEN(ctx->libctx, key, keylen, (char *)EVP_MD_name(md),
+ ctx->ni, ctx->ni_len, ctx->nr, ctx->nr_len,
+ ctx->secret, ctx->secret_len));
+
+ case EVP_KDF_IKEV2_MODE_DKM:
+ /*
+ * if spi_init != NULL and spi_resp != NULL and shared_secret = NULL
+ * and seedkey != NULL
+ * calculate DKM
+ * else if spi_init == NULL and spi_resp == NULL and shared_secret != NULL
+ * and sk_d != NULL
+ * calculate DKM(Child_DH)
+ * else if spi_init == NULL and spi_resp == NULL and shared_secret == NULL
+ * and sk_d != NULL
+ * calculate DKM(Child_SA)
+ * endif
+ */
+ if ((ctx->spii != NULL) && (ctx->spii_len != 0)
+ && (ctx->spir != NULL) && (ctx->spir_len != 0)
+ && (ctx->secret == NULL) && (ctx->secret_len == 0)) {
+ if ((ctx->seedkey == NULL) || (ctx->seedkey_len == 0)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
+ return 0;
+ }
+ if (ctx->seedkey_len != (size_t)md_size) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ if ((keylen < md_size) || (keylen > IKEV2KDF_MAX_DKM_LENGTH)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ /* calculate DKM */
+ return (IKEV2_DKM(ctx->libctx, key, keylen, md, ctx->seedkey, ctx->seedkey_len,
+ ctx->ni, ctx->ni_len, ctx->nr, ctx->nr_len,
+ ctx->spii, ctx->spii_len, ctx->spir, ctx->spir_len,
+ NULL, 0));
+ } else if ((ctx->spii == NULL) && (ctx->spir == NULL)
+ && (ctx->spii_len == 0) && (ctx->spir_len == 0)) {
+ if ((ctx->sk_d == NULL) || (ctx->sk_d_len == 0)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_DKM);
+ return 0;
+ }
+ if ((keylen < md_size) || (keylen > IKEV2KDF_MAX_DKM_LENGTH)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ /* If Child_DH is intended, require secret_len > 0 */
+ if (ctx->secret != NULL && ctx->secret_len == 0) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
+ return 0;
+ }
+ if (!ikev2_check_secret_and_pad(ctx))
+ return 0;
+ /* calculate DKM(Child_SA) or DKM(Child_DH) */
+ return (IKEV2_DKM(ctx->libctx, key, keylen, md, ctx->sk_d, ctx->sk_d_len,
+ ctx->ni, ctx->ni_len, ctx->nr, ctx->nr_len,
+ NULL, 0, NULL, 0,
+ ctx->secret, ctx->secret_len));
+ } else {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PARAMETERS_FOR_DKM);
+ return 0;
+ }
+ case EVP_KDF_IKEV2_MODE_REKEY:
+ if ((ctx->secret == NULL) || (ctx->secret_len == 0)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
+ return 0;
+ }
+ if ((ctx->sk_d == NULL) || (ctx->sk_d_len == 0)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_DKM);
+ return 0;
+ }
+ if (ctx->sk_d_len != (size_t)md_size) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ if (keylen != md_size) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ if (!ikev2_check_secret_and_pad(ctx))
+ return 0;
+ return (IKEV2_REKEY(ctx->libctx, key, keylen, (char *)EVP_MD_name(md),
+ ctx->ni, ctx->ni_len, ctx->nr, ctx->nr_len,
+ ctx->secret, ctx->secret_len, ctx->sk_d, ctx->sk_d_len));
+ default:
+ /* This error is already checked in set_ctx_params */
+ ;
+ }
+ return 0;
+}
+
+static int kdf_ikev2kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+ struct ikev2_set_ctx_params_st p;
+ KDF_IKEV2KDF *ctx = vctx;
+ const EVP_MD *md;
+
+ if (params == NULL)
+ return 1;
+
+ if (ctx == NULL || !ikev2_set_ctx_params_decoder(params, &p))
+ return 0;
+
+ if (p.digest != NULL) {
+ if (!ossl_prov_digest_load(&ctx->digest, p.digest, p.propq, ctx->libctx))
+ return 0;
+ md = ossl_prov_digest_md(&ctx->digest);
+ if (md == NULL) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+ return 0;
+ }
+
+ if (!EVP_MD_is_a(md, SN_sha1)
+ && !EVP_MD_is_a(md, SN_sha224)
+ && !EVP_MD_is_a(md, SN_sha256)
+ && !EVP_MD_is_a(md, SN_sha384)
+ && !EVP_MD_is_a(md, SN_sha512))
+ return 0;
+ }
+ if (p.ni != NULL) {
+ if (!ikev2kdf_set_membuf(&ctx->ni, &ctx->ni_len, p.ni))
+ return 0;
+ if ((ctx->ni_len < IKEV2KDF_MIN_NONCE_LENGTH)
+ || (ctx->ni_len > IKEV2KDF_MAX_NONCE_LENGTH)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_NONCE_LENGTH);
+ return 0;
+ }
+ }
+ if (p.nr != NULL) {
+ if (!ikev2kdf_set_membuf(&ctx->nr, &ctx->nr_len, p.nr))
+ return 0;
+ if ((ctx->nr_len < IKEV2KDF_MIN_NONCE_LENGTH)
+ || (ctx->nr_len > IKEV2KDF_MAX_NONCE_LENGTH)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_NONCE_LENGTH);
+ return 0;
+ }
+ }
+ if (p.spii != NULL)
+ if (!ikev2kdf_set_membuf(&ctx->spii, &ctx->spii_len, p.spii))
+ return 0;
+ if (p.spir != NULL)
+ if (!ikev2kdf_set_membuf(&ctx->spir, &ctx->spir_len, p.spir))
+ return 0;
+ if (p.secret != NULL)
+ if (!ikev2kdf_set_membuf(&ctx->secret, &ctx->secret_len, p.secret))
+ return 0;
+ if (p.seedkey != NULL)
+ if (!ikev2kdf_set_membuf(&ctx->seedkey, &ctx->seedkey_len, p.seedkey))
+ return 0;
+ if (p.sk_d != NULL)
+ if (!ikev2kdf_set_membuf(&ctx->sk_d, &ctx->sk_d_len, p.sk_d))
+ return 0;
+ if (p.mode != NULL) {
+ if (!OSSL_PARAM_get_int(p.mode, &ctx->mode))
+ return 0;
+ if ((ctx->mode != EVP_KDF_IKEV2_MODE_GEN)
+ && (ctx->mode != EVP_KDF_IKEV2_MODE_DKM)
+ && (ctx->mode != EVP_KDF_IKEV2_MODE_REKEY)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static const OSSL_PARAM *kdf_ikev2kdf_settable_ctx_params(ossl_unused void *ctx,
+ ossl_unused void *p_ctx)
+{
+ return ikev2_set_ctx_params_list;
+}
+
+static int kdf_ikev2kdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+ struct ikev2_get_ctx_params_st p;
+ KDF_IKEV2KDF *ctx = vctx;
+
+ if (ctx == NULL || !ikev2_get_ctx_params_decoder(params, &p))
+ return 0;
+
+ if (p.size != NULL) {
+ size_t sz = 0;
+ const EVP_MD *md = NULL;
+
+ md = ossl_prov_digest_md(&ctx->digest);
+ if (md == NULL) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+ return 0;
+ }
+ sz = EVP_MD_size(md);
+ if (sz <= 0)
+ return 0;
+ if (!OSSL_PARAM_set_size_t(p.size, sz))
+ return 0;
+ }
+ return 1;
+}
+
+static const OSSL_PARAM *kdf_ikev2kdf_gettable_ctx_params(ossl_unused void *ctx,
+ ossl_unused void *p_ctx)
+{
+ return ikev2_get_ctx_params_list;
+}
+
+const OSSL_DISPATCH ossl_kdf_ikev2kdf_functions[] = {
+ { OSSL_FUNC_KDF_NEWCTX, (void (*)(void))kdf_ikev2kdf_new },
+ { OSSL_FUNC_KDF_DUPCTX, (void (*)(void))kdf_ikev2kdf_dup },
+ { OSSL_FUNC_KDF_FREECTX, (void (*)(void))kdf_ikev2kdf_free },
+ { OSSL_FUNC_KDF_RESET, (void (*)(void))kdf_ikev2kdf_reset },
+ { OSSL_FUNC_KDF_DERIVE, (void (*)(void))kdf_ikev2kdf_derive },
+ { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+ (void (*)(void))kdf_ikev2kdf_settable_ctx_params },
+ { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))kdf_ikev2kdf_set_ctx_params },
+ { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+ (void (*)(void))kdf_ikev2kdf_gettable_ctx_params },
+ { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))kdf_ikev2kdf_get_ctx_params },
+ { 0, NULL }
+};
+
+/*
+ * IKEV2_GEN - KDF in compliance with SP800-135 for IKEv2,
+ * generate the seedkey.
+ *
+ * algorithm: HMAC(ni || nr, shared_secret)
+ *
+ * Inputs:
+ * libctx - provider LIB context
+ * seedkey - pointer to output for seedkey
+ * keylen - length of seedkey(in bytes)
+ * md_name - name of the SHA digest
+ * ni - pointer to initiator nonce input
+ * ni_len - initiator nonce length(in bytes)
+ * nr - pointer to responder nonce input
+ * nr_len - nonce length(in bytes)
+ * shared_secret - pointer to secret input
+ * shared_secret_len - secret length(in bytes)
+ * Outputs:
+ * return - 1 pass, 0 fail
+ * seedkey - output seedkey when passing.
+ */
+static int IKEV2_GEN(OSSL_LIB_CTX *libctx, unsigned char *seedkey, const size_t keylen,
+ char *md_name, const unsigned char *ni, const size_t ni_len,
+ const unsigned char *nr, const size_t nr_len,
+ const unsigned char *shared_secret, const size_t shared_secret_len)
+{
+ EVP_MAC_CTX *ctx = NULL;
+ EVP_MAC *mac = NULL;
+ size_t outl = 0;
+ int ret = 0;
+ unsigned char *nonce = NULL;
+ OSSL_PARAM params[] = {
+ OSSL_PARAM_construct_utf8_string("digest", md_name, 0),
+ OSSL_PARAM_construct_end()
+ };
+
+ nonce = OPENSSL_malloc(ni_len + nr_len);
+ if (nonce == NULL)
+ return ret;
+ memcpy(nonce, ni, ni_len);
+ memcpy(nonce + ni_len, nr, nr_len);
+
+ mac = EVP_MAC_fetch(libctx, (char *)"HMAC", NULL);
+ if ((mac == NULL)
+ || ((ctx = EVP_MAC_CTX_new(mac)) == NULL)
+ || (!EVP_MAC_init(ctx, nonce, ni_len + nr_len, params))
+ || (!EVP_MAC_update(ctx, shared_secret, shared_secret_len))
+ || (!EVP_MAC_final(ctx, seedkey, &outl, keylen))
+ || (outl != keylen))
+ goto err;
+
+ ret = 1;
+err:
+ OPENSSL_clear_free(nonce, ni_len + nr_len);
+ EVP_MAC_CTX_free(ctx);
+ EVP_MAC_free(mac);
+ return ret;
+}
+
+/*
+ * IKEV2_REKEY - KDF in compliance with SP800-135 for IKEv2,
+ * re-generate the seedkey.
+ *
+ * algorithm: HMAC(sk_d, Ni || Nr || seedkey || (if dh==1 then shared_secret))
+ *
+ * Inputs:
+ * libctx - provider LIB context
+ * seedkey - pointer to output for seedkey
+ * keylen - length of seedkey(in bytes)
+ * md_name - name of the SHA digest
+ * ni - pointer to initiator nonce input
+ * ni_len - initiator nonce length(in bytes)
+ * nr - pointer to responder nonce input
+ * nr_len - responder nonce length(in bytes)
+ * shared_secret - (new) pointer to secret input
+ * shared_secret_len - (new)secret length(in bytes)
+ * sk_d - pointer to sk_d portion of DKM
+ * skd_len - length of sk_d (in bytes)
+ * Outputs:
+ * return = 1 pass, 0 fail
+ * seedkey - output seedkey when passing.
+ */
+static int IKEV2_REKEY(OSSL_LIB_CTX *libctx, unsigned char *seedkey, const size_t keylen,
+ char *md_name, const unsigned char *ni, const size_t ni_len,
+ const unsigned char *nr, const size_t nr_len,
+ const unsigned char *shared_secret, const size_t shared_secret_len,
+ const unsigned char *sk_d, const size_t sk_d_len)
+{
+ EVP_MAC_CTX *ctx = NULL;
+ EVP_MAC *mac = NULL;
+ size_t outl = 0;
+ int ret = 0;
+ OSSL_PARAM params[] = {
+ OSSL_PARAM_construct_utf8_string("digest", md_name, 0),
+ OSSL_PARAM_construct_end()
+ };
+
+ mac = EVP_MAC_fetch(libctx, "HMAC", NULL);
+ if ((mac == NULL)
+ || ((ctx = EVP_MAC_CTX_new(mac)) == NULL)
+ || (!EVP_MAC_init(ctx, sk_d, sk_d_len, params))
+ || (!EVP_MAC_update(ctx, shared_secret, shared_secret_len))
+ || (!EVP_MAC_update(ctx, ni, ni_len))
+ || (!EVP_MAC_update(ctx, nr, nr_len))
+ || (!EVP_MAC_final(ctx, seedkey, &outl, keylen))
+ || (outl != keylen))
+ goto err;
+
+ ret = 1;
+
+err:
+ EVP_MAC_CTX_free(ctx);
+ EVP_MAC_free(mac);
+ return ret;
+}
+
+/*
+ * IKEV2_DKM - KDF in compliance with SP800-135 for IKEv2,
+ * generate the Derived Keying Material(DKM),
+ * DKM(Child SA) and DKM(Child SA DH).
+ * algorithm:
+ * if spii != NULL and spir != NULL and shared_secret == NULL
+ * and seedkey != NULL
+ * calculate DKM:
+ * HMAC(seedkey, ni || nr || spii || spir)
+ * else if spii == NULL and spir == NULL and shared_secret == NULL
+ * calculate DKM(Child_SA):
+ * HMAC(sk_d, ni || nr)
+ * else if spii == NULL and spir == NULL and shared_secret != NULL
+ * calculate DKM(Child_DH):
+ * HMAC(sk_d, ni || nr || new_shared_secret)
+ * endif
+ *
+ * Inputs:
+ * libctx - provider LIB context
+ * dkm - pointer to output dkm
+ * len_out - output length(in bytes)
+ * evp_md - pointer to SHA digest
+ * seekkey - pointer to seedkey (seekkey for DKM, sk_d for Child_SA/DH)
+ * seedkey_len - length of seedkey(in bytes)
+ * ni - pointer to initiator nonce
+ * ni_len - initiator nonce length(in bytes)
+ * nr - pointer to responder nonce
+ * nr_len - responder nonce length(in bytes)
+ * shared_secret - pointer to secret input
+ * shared_secret_len - secret length(in bytes)
+ * Outputs:
+ * return - 1 pass, 0 fail
+ * dkm - output dkm when passing.
+ */
+static int IKEV2_DKM(OSSL_LIB_CTX *libctx, unsigned char *dkm, const size_t len_out,
+ const EVP_MD *evp_md,
+ const unsigned char *seedkey, const size_t seedkey_len,
+ const unsigned char *ni, const size_t ni_len,
+ const unsigned char *nr, const size_t nr_len,
+ const unsigned char *spii, const size_t spii_len,
+ const unsigned char *spir, const size_t spir_len,
+ const unsigned char *shared_secret, const size_t shared_secret_len)
+{
+ EVP_MAC_CTX *ctx = NULL;
+ EVP_MAC *mac = NULL;
+ size_t outl = 0, hmac_len = 0, ii;
+ unsigned char *hmac = NULL;
+ int ret = 0;
+ int md_size = 0;
+ unsigned char counter = 1;
+ OSSL_PARAM params[] = {
+ OSSL_PARAM_construct_utf8_string("digest", (char *)EVP_MD_name(evp_md), 0),
+ OSSL_PARAM_construct_end()
+ };
+
+ md_size = EVP_MD_size(evp_md);
+ if (md_size <= 0)
+ return 0;
+ /* len_out may not fit the last hmac, round up */
+ hmac_len = ((len_out + md_size - 1) / md_size) * md_size;
+ hmac = OPENSSL_malloc(hmac_len);
+ if (hmac == NULL)
+ return 0;
+
+ mac = EVP_MAC_fetch(libctx, "HMAC", NULL);
+ if ((mac == NULL)
+ || ((ctx = EVP_MAC_CTX_new(mac)) == NULL))
+ goto err;
+
+ /*
+ * len_out <= IKEV2_MAX_DKM_LEN
+ * loop count will fit in 1 byte value
+ */
+ for (ii = 0; ii < len_out; ii += md_size) {
+ if (!EVP_MAC_init(ctx, seedkey, seedkey_len, params))
+ goto err;
+ if (ii != 0)
+ if (!EVP_MAC_update(ctx, &hmac[ii - md_size], md_size))
+ goto err;
+ if (shared_secret != NULL)
+ if (!EVP_MAC_update(ctx, shared_secret, shared_secret_len))
+ goto err;
+ if (!EVP_MAC_update(ctx, ni, ni_len)
+ || !EVP_MAC_update(ctx, nr, nr_len))
+ goto err;
+ if (spii != NULL)
+ if (!EVP_MAC_update(ctx, spii, spii_len)
+ || !EVP_MAC_update(ctx, spir, spir_len))
+ goto err;
+ if (!EVP_MAC_update(ctx, &counter, 1))
+ goto err;
+ if (!EVP_MAC_final(ctx, &hmac[ii], &outl, len_out))
+ goto err;
+ counter++;
+ }
+
+ memcpy(dkm, hmac, len_out);
+ ret = 1;
+err:
+ OPENSSL_clear_free(hmac, hmac_len);
+ EVP_MAC_CTX_free(ctx);
+ EVP_MAC_free(mac);
+ return ret;
+}
diff --git a/providers/implementations/kdfs/ikev2kdf.inc.in b/providers/implementations/kdfs/ikev2kdf.inc.in
new file mode 100644
index 0000000000..9f1dc5782a
--- /dev/null
+++ b/providers/implementations/kdfs/ikev2kdf.inc.in
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the \"License\"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+-}
+
+{- produce_param_decoder('ikev2_set_ctx_params',
+ (['OSSL_KDF_PARAM_PROPERTIES', 'propq', 'utf8_string'],
+ ['OSSL_KDF_PARAM_DIGEST', 'digest', 'utf8_string'],
+ ['OSSL_KDF_PARAM_IKEV2KDF_NI', 'ni', 'octet_string'],
+ ['OSSL_KDF_PARAM_IKEV2KDF_NR', 'nr', 'octet_string'],
+ ['OSSL_KDF_PARAM_IKEV2KDF_SPII', 'spii', 'octet_string'],
+ ['OSSL_KDF_PARAM_IKEV2KDF_SPIR', 'spir', 'octet_string'],
+ ['OSSL_KDF_PARAM_SEED', 'seedkey', 'octet_string'],
+ ['OSSL_KDF_PARAM_KEY', 'sk_d', 'octet_string'],
+ ['OSSL_KDF_PARAM_SECRET', 'secret', 'octet_string'],
+ ['OSSL_KDF_PARAM_MODE', 'mode', 'int32'],
+ )); -}
+
+{- produce_param_decoder('ikev2_get_ctx_params',
+ (['OSSL_KDF_PARAM_SIZE', 'size', 'size_t'],
+ )); -}
diff --git a/providers/implementations/kdfs/snmpkdf.c b/providers/implementations/kdfs/snmpkdf.c
index d01b0e9c96..6b5837e420 100644
--- a/providers/implementations/kdfs/snmpkdf.c
+++ b/providers/implementations/kdfs/snmpkdf.c
@@ -7,9 +7,6 @@
* https://www.openssl.org/source/license.html
*/
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
#include <openssl/evp.h>
#include <openssl/kdf.h>
#include <openssl/sha.h>
@@ -17,8 +14,6 @@
#include <openssl/proverr.h>
#include "internal/cryptlib.h"
#include "internal/fips.h"
-#include "internal/numbers.h"
-#include "crypto/evp.h"
#include "prov/provider_ctx.h"
#include "prov/providercommon.h"
#include "prov/implementations.h"
@@ -174,7 +169,11 @@ static int kdf_snmpkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
return 0;
#ifdef FIPS_MODULE
md = ossl_prov_digest_md(&ctx->digest);
- if (!EVP_MD_is_a(md, SN_sha1))
+ if (!EVP_MD_is_a(md, SN_sha1)
+ && !EVP_MD_is_a(md, SN_sha224)
+ && !EVP_MD_is_a(md, SN_sha256)
+ && !EVP_MD_is_a(md, SN_sha384)
+ && !EVP_MD_is_a(md, SN_sha512))
return 0;
#endif
}
diff --git a/providers/implementations/kdfs/srtpkdf.c b/providers/implementations/kdfs/srtpkdf.c
index 0c8693d5db..4ae77aedee 100644
--- a/providers/implementations/kdfs/srtpkdf.c
+++ b/providers/implementations/kdfs/srtpkdf.c
@@ -7,9 +7,6 @@
* https://www.openssl.org/source/license.html
*/
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
#include <stdbool.h>
#include <openssl/evp.h>
#include <openssl/kdf.h>
@@ -18,8 +15,6 @@
#include <openssl/proverr.h>
#include "internal/cryptlib.h"
#include "internal/fips.h"
-#include "internal/numbers.h"
-#include "crypto/evp.h"
#include "prov/provider_ctx.h"
#include "prov/providercommon.h"
#include "prov/implementations.h"
diff --git a/test/recipes/30-test_evp.t b/test/recipes/30-test_evp.t
index 70b2cecd82..d94c76fe79 100644
--- a/test/recipes/30-test_evp.t
+++ b/test/recipes/30-test_evp.t
@@ -39,6 +39,7 @@ my $no_sskdf = disabled("sskdf");
my $no_x942kdf = disabled("x942kdf");
my $no_x963kdf = disabled("x963kdf");
my $no_determinstic_nonce = disabled("hmac-drbg-kdf");
+my $no_ikev2kdf = disabled("ikev2kdf");
my $no_kbkdf = disabled("kbkdf");
my $no_krb5kdf = disabled("krb5kdf");
my $no_snmpkdf = disabled("snmpkdf");
@@ -75,6 +76,7 @@ my @files = qw(
evppkey_rsa_sigalg.txt
evprand.txt
);
+push @files, qw(evpkdf_ikev2.txt) unless $no_ikev2kdf;
push @files, qw(evpkdf_ssh.txt) unless $no_sshkdf;
push @files, qw(evpkdf_snmp.txt) unless $no_snmpkdf;
push @files, qw(evpkdf_srtp.txt) unless $no_srtpkdf;
diff --git a/test/recipes/30-test_evp_data/evpkdf_ikev2.txt b/test/recipes/30-test_evp_data/evpkdf_ikev2.txt
new file mode 100644
index 0000000000..6d0333ad87
--- /dev/null
+++ b/test/recipes/30-test_evp_data/evpkdf_ikev2.txt
@@ -0,0 +1,340 @@
+#
+# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+# Tests start with one of these keywords
+# digest, ni, nr, secret, new secret, spi_init, spi_resp, mode
+# and continue until a blank line. Lines starting with a pound sign are ignored.
+# https://github.com/usnistgov/ACVP-Server/tree/master/gen-val/json-files/kdf-components-ikev2-1.0
+
+Title = IKEV2KDF tests
+
+# self_test_data.c - GEN
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:0
+Output = EFAA7AB0EAA85A3D0BE2100CD4B6FE00FF5025A9EAFDDB3EF518E9F0D3FE60E6
+
+# test case, GEN missing mode, mode is default as 0
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+#Ctrl.mode = mode:0
+Output = EFAA7AB0EAA85A3D0BE2100CD4B6FE00FF5025A9EAFDDB3EF518E9F0D3FE60E6
+
+# self_test_data.c - DKM
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexspii = hexspii:8E5C3AE507221684
+Ctrl.hexspir = hexspir:B1F201BB155C3ACD
+Ctrl.hexseed = hexseed:EFAA7AB0EAA85A3D0BE2100CD4B6FE00FF5025A9EAFDDB3EF518E9F0D3FE60E6
+Ctrl.mode = mode:1
+Output = 462B9DD525D4FD71169174272779E704BAF62C6231779AE9EFE8C58B21916B42010164AF2111EBD762F6916CA9A6F0EE05C8B320E4EE27705521DE2589ADEA1878F1A551738AF7C88DC4F0BB0C096A3F7D1F1A670FC79F49F678D60D665BB3710C8657F03BA9F62B9A818D7A228968C506E237AE9502AA6DB395C61EA6A3E79504F86B7368BFB5423DF79E48809BBCCD49FD826D024F63D7C2A5566400A12E736AA034510428F5EA008FE2FC16886FA388274EA6C2B4FCFC6141BF04F8207EF8AFC224EA1059CB220DC0B23AC0E4CCDA495A4E131B1D56E223ABA5A48E8ED1F5
+
+# self_test_data.c - DKM(Child_SA)
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexkey = hexkey:462B9DD525D4FD71169174272779E704BAF62C6231779AE9EFE8C58B21916B42
+Ctrl.mode = mode:1
+Output = 23647677E7D403FA1E3006F19840AEE18AD9FECC4215814C4131BDEBA98433D8B0E31BFBBDDF822ABCCE5E06486AA388022B75E27E1E68AA5983028B65282C730C5D49EF7606770376CFDEC41F7CC435D816029989BC353D3B67B9FD1168DDCB8978850DA9B752AEE6A30D0086D2C4D74EC0E03648A0DAD334FAF5FE88084E67B0F3E8FEE8B5E1BD3850DB540F1FB8CFFE23C9E92CDA209373F354880C246C753E2A0ECA9CB73B9910A8531C4010E6768FA29F909E60AF777FED6E739C3CFDA03467E915D6F03FCE9C41F5F9D578F8912D66A75457E79EE1D5BCC2BE5C2F9BAE
+
+# self_test_data.c - DKM(Child_DH)
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexkey = hexkey:462B9DD525D4FD71169174272779E704BAF62C6231779AE9EFE8C58B21916B42
+Ctrl.hexsecret = hexsecret:52F00AB174C25D5B7139AE5FF4E8E9EDDEE5992D2E36ADF8A559FFD90DAB1442E4FBE429D320C0F33552A17D1557FA41EA70E8FB916C4FA27ED52B5F8EBD8461AFA78F1159159A64055AC5F6319E29C28EAE58CBC6847770F32C3FED1D04750484F854790F95E9EC01BC5BC461F24966462E359511329305038E94DEB6DD42C2
+Ctrl.mode = mode:1
+Output = 6A919387A5FA2835FE8A8237E4A14845BD2B9930DB87EFF7ADF268F62186004902DBA9AA942D0259A0EDC4120B932A503865B57BA8FB88117EF5DF7B26799CD8BA37AA5438108CB1A4FE117907C9D0597B708C3F11151FEFD624D2317202B7C81430600E6FCBB6E1A8DF2B4861EF2363D53DE1BE69057B0CF6634A7E7BFA97B3C2810623E2BD6757738777177036E9C3A39794456954BD41FC444A12507AB9CAC69A0540D13C29DB8510F566A691691BAA2D9569DACC990D56A454BB444BCBBE8751B0550A5278812FC5AB4F28990DD6D608538D7DDDE24DC81BDAACA7751FDE
+
+# self_test_data.c - rekey
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexkey = hexkey:462B9DD525D4FD71169174272779E704BAF62C6231779AE9EFE8C58B21916B42
+Ctrl.hexsecret = hexsecret:52F00AB174C25D5B7139AE5FF4E8E9EDDEE5992D2E36ADF8A559FFD90DAB1442E4FBE429D320C0F33552A17D1557FA41EA70E8FB916C4FA27ED52B5F8EBD8461AFA78F1159159A64055AC5F6319E29C28EAE58CBC6847770F32C3FED1D04750484F854790F95E9EC01BC5BC461F24966462E359511329305038E94DEB6DD42C2
+Ctrl.mode = mode:2
+Output = 90722C42BD849E9B72D240FC254174270FA8295DE6F0338DAFC303A9EC104F12
+
+# negative test case, GEN missing digest
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+#Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:0
+Result = KDF_DERIVE_ERROR
+Reason = missing message digest
+
+# negative test case, GEN invalid digest
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA3-256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:0
+Result = KDF_CTRL_ERROR
+
+# negative test case, GEN missing ni
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+#Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:0
+Result = KDF_DERIVE_ERROR
+Reason = missing nonce
+
+# negative test case, GEN ni < 8 bytes
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:0
+Result = KDF_CTRL_ERROR
+Reason = invalid nonce length
+
+# negative test case, GEN missing nr
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+#Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:0
+Result = KDF_DERIVE_ERROR
+Reason = missing nonce
+
+# negative test case, GEN nr < 8 bytes
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:0
+Result = KDF_CTRL_ERROR
+Reason = invalid nonce length
+
+# negative test case, GEN missing secret g^ir
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+#Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:0
+Result = KDF_DERIVE_ERROR
+Reason = missing secret
+
+# negative test case, DKM missing SPIi
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+#Ctrl.hexspii = hexspii:8E5C3AE507221684
+Ctrl.hexspir = hexspir:B1F201BB155C3ACD
+Ctrl.hexseed = hexseed:EFAA7AB0EAA85A3D0BE2100CD4B6FE00FF5025A9EAFDDB3EF518E9F0D3FE60E6
+Ctrl.mode = mode:1
+Result = KDF_DERIVE_ERROR
+Reason = invalid parameters for dkm
+
+# negative test case, DKM missing SPIr
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexspii = hexspii:8E5C3AE507221684
+#Ctrl.hexspir = hexspir:B1F201BB155C3ACD
+Ctrl.hexseed = hexseed:CD2E8050137832245F1DBACC6E4F0A92F94D45D6
+Ctrl.mode = mode:1
+Result = KDF_DERIVE_ERROR
+Reason = invalid parameters for dkm
+
+# negative test case, DKM has spii, spir and secret
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexspii = hexspii:8E5C3AE507221684
+#Ctrl.hexspir = hexspir:B1F201BB155C3ACD
+Ctrl.hexseed = hexseed:CD2E8050137832245F1DBACC6E4F0A92F94D45D6
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:1
+Result = KDF_DERIVE_ERROR
+Reason = invalid parameters for dkm
+
+# negative test case, rekey missing key
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+#Ctrl.hexkey = hexkey:6F1B12CAD3CBE097B35430356D869D54CDDB0198
+Ctrl.hexsecret = hexsecret:52F00AB174C25D5B7139AE5FF4E8E9EDDEE5992D2E36ADF8A559FFD90DAB1442E4FBE429D320C0F33552A17D1557FA41EA70E8FB916C4FA27ED52B5F8EBD8461AFA78F1159159A64055AC5F6319E29C28EAE58CBC6847770F32C3FED1D04750484F854790F95E9EC01BC5BC461F24966462E359511329305038E94DEB6DD42C2
+Ctrl.mode = mode:2
+Result = KDF_DERIVE_ERROR
+Reason = missing dkm
+
+# negative test case, rekey missing secret
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexkey = hexkey:462B9DD525D4FD71169174272779E704BAF62C6231779AE9EFE8C58B21916B42
+#Ctrl.hexsecret = hexsecret:52F00AB174C25D5B7139AE5FF4E8E9EDDEE5992D2E36ADF8A559FFD90DAB1442E4FBE429D320C0F33552A17D1557FA41EA70E8FB916C4FA27ED52B5F8EBD8461AFA78F1159159A64055AC5F6319E29C28EAE58CBC6847770F32C3FED1D04750484F854790F95E9EC01BC5BC461F24966462E359511329305038E94DEB6DD42C2
+Ctrl.mode = mode:2
+Result = KDF_DERIVE_ERROR
+Reason = missing secret
+
+# test case, invalid mode
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexni = hexni:3651FEF5C9C35E93
+Ctrl.hexnr = hexnr:C09A8B90A3F04D59
+Ctrl.hexsecret = hexsecret:D084A30166A50FB7325C3960874A839449EF9741C2F4F947D0201DD8C1269273D79509F37E3CA3EB4FA2FE2A28254E289CD3F34DAD4EB4DF1A07685A4B8A94FA61E2491F7598B3CE65547FF133B3F63D1AC4175EAA695033F3CEDB026A6873A36455172A8540B8A5D23A0143BED0390EE49B168269D75FFFEE9FB62BE965993C
+Ctrl.mode = mode:3
+Result = KDF_CTRL_ERROR
+Reason = invalid mode
+
+# https://raw.githubusercontent.com/usnistgov/ACVP-Server/refs/heads/master/gen-val/json-files/kdf-components-ikev2-1.0/prompt.json
+
+# From libacvp testing sample testcases
+# tgId = 7, tcId = 121, GEN
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.ni = hexni:F096BC348F4C0BE7A0932E065F72DA82F9E312379CBEC86574837E535DEDD0F81E86FE52F9D89336B17BF5DC030E766E71D25B60D724AAEFE8B60C2383BD6395703214D6E04C545443E95B47ADB11C80A60110C083402B335CDF9E4E2CD6200DC3A28D1F8E1D6F8293DEA1025707CE870439F9A3CB2638FE52A3F350CEE833E4EBB34F7C3920B9A0A4DCE7BC3E7DD6502F6D365FBB0BC0131FC74048BD145E7B9BE07F2E58FDF53A98B5AF8C3958C592ECB1642D63CEC46BE1A77A2E5B525554682114040FC201949B992E8076A2BA99F59C9B1368C69CB0E48FF0599290D4C635262EF4F1BB2E87C4CDF4FF7EA9FAD2010CBF30198B7A961606BF3E49C5618F
+Ctrl.nr = hexnr:AA241EAD5C65408AE109D09993DBA807FF23E00883A466F2F408BCED7A8BB37729ABB124DE79A7652CDD450911B4FF1A252D11B8D6EF065B48FD2703CB6D682712E24E92F6CE3511DBB6F78AFFAFEF1B0B875AE2B3C559783EA7F2138B831C236845B800D00AA28010C47D2F6744033A10B286E791D16DCBE31E9C994E45D659E65ECF03EAFFCD916FEBB320913C97DB41415961DC02823849A2009D9C126CC4E50F6CFE1F447C691463EA1309B66DE3BC39ABBB0ABC69525DEF486669E1F45AFFBDD6FE1F5314EDFC631E4655DF289108697F906C6C82BC0D8C52343278CD32A93FF33247764D3CCA18278C7876DEB0247ADE36149D99F3EF1E746D90DE0524
+Ctrl.secret = hexsecret:9E3D6F5B906FAC77CC7C877948F19113FF2AAC2B51DDA3D03803808E09B840E1E73DC8489C31659BDD78218B367DA86DC0EA41408ACADC67860C8DF60A8AF0EE07BEF7F05E51FD416B37F62D4429DCC5FA8A19FAA648A0DF2D279A9A72D0D2D4A666B51342A2F7D9E4E7882AA90A8F20A7FFC6DD5E9755BDD23A92562BE228F462A037D34A84C4C1677791FB067219C07EC57C9BC43474DE3A009707635F5175E38F9DC3CA0DE6249A8B12D37590BE6942F6B67C580C83FF6402E130A85F4C794A078CC4DC5BB73542D5A74734D8E11C313F67B0D99C7D6F53791F824228F942D346AC56ACEFA9A9A79018D57CD67983842459A1A21FC0F65E38B386045EC55B
+Ctrl.mode = mode:0
+Output = CB5B5E3729A6E797A257EE0124A6EA6143E753B7545C1266413119F5C108FE2E
+
+# tgId = 7, tcId = 121, DKM
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.ni = hexni:F096BC348F4C0BE7A0932E065F72DA82F9E312379CBEC86574837E535DEDD0F81E86FE52F9D89336B17BF5DC030E766E71D25B60D724AAEFE8B60C2383BD6395703214D6E04C545443E95B47ADB11C80A60110C083402B335CDF9E4E2CD6200DC3A28D1F8E1D6F8293DEA1025707CE870439F9A3CB2638FE52A3F350CEE833E4EBB34F7C3920B9A0A4DCE7BC3E7DD6502F6D365FBB0BC0131FC74048BD145E7B9BE07F2E58FDF53A98B5AF8C3958C592ECB1642D63CEC46BE1A77A2E5B525554682114040FC201949B992E8076A2BA99F59C9B1368C69CB0E48FF0599290D4C635262EF4F1BB2E87C4CDF4FF7EA9FAD2010CBF30198B7A961606BF3E49C5618F
+Ctrl.nr = hexnr:AA241EAD5C65408AE109D09993DBA807FF23E00883A466F2F408BCED7A8BB37729ABB124DE79A7652CDD450911B4FF1A252D11B8D6EF065B48FD2703CB6D682712E24E92F6CE3511DBB6F78AFFAFEF1B0B875AE2B3C559783EA7F2138B831C236845B800D00AA28010C47D2F6744033A10B286E791D16DCBE31E9C994E45D659E65ECF03EAFFCD916FEBB320913C97DB41415961DC02823849A2009D9C126CC4E50F6CFE1F447C691463EA1309B66DE3BC39ABBB0ABC69525DEF486669E1F45AFFBDD6FE1F5314EDFC631E4655DF289108697F906C6C82BC0D8C52343278CD32A93FF33247764D3CCA18278C7876DEB0247ADE36149D99F3EF1E746D90DE0524
+Ctrl.spii = hexspii:DC90D7D683D1C342
+Ctrl.spir = hexspir:4BADDAC5301B550B
+Ctrl.seed = hexseed:CB5B5E3729A6E797A257EE0124A6EA6143E753B7545C1266413119F5C108FE2E
+Ctrl.mode = mode:1
+Output = CDDD59534E22D7306C94D07D5C14FAD33E58838E02C7A8FA9C421F66FB72E51B553BC4798039DC7DD51967D2DF6759C4196849E790D3874066C14443938FF6B04305B4A6E1297FC561554AF242F404342721A1A92F0AA5FD66EA1835DEC564042326B81DDDE622818BFA1B413BD02817F3AADD4DC43DFD64AC1EC3F072088E972D871E1100A0C23EC40484A45685889973984A17E8E081D0E80C91267D152E6B258C18525124FD2667249E1C645D98F6586E791222C5D4B94AE15F59D147F12821AED76B0F43BF3CB36410E58611C3CE61F08AB39A12639395FC4725AC23C9AD8635B508BCCACC79AB81AD68D531D439E4379A916EA19B63BB021576DDC7E4C14F471E368A6AE46852129931952DBEBC16AC8869C0462EDD98F80445495301F1BD6E1AB76312434C212DE18AA260DBD1EBDB13A3AD91ADA28D4CD533545EB93C0F2766E9034344855304DAD700A1CAC269DD9C36CCF08F01389D627B46D81F9CB43502FEE7584F74441C96EAC7F7D0EEBEB6B13BCD3041A94B3D5B08E3699B97
+
+# tgId = 7, tcId = 121, DKM(Child_SA)
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.ni = hexni:F096BC348F4C0BE7A0932E065F72DA82F9E312379CBEC86574837E535DEDD0F81E86FE52F9D89336B17BF5DC030E766E71D25B60D724AAEFE8B60C2383BD6395703214D6E04C545443E95B47ADB11C80A60110C083402B335CDF9E4E2CD6200DC3A28D1F8E1D6F8293DEA1025707CE870439F9A3CB2638FE52A3F350CEE833E4EBB34F7C3920B9A0A4DCE7BC3E7DD6502F6D365FBB0BC0131FC74048BD145E7B9BE07F2E58FDF53A98B5AF8C3958C592ECB1642D63CEC46BE1A77A2E5B525554682114040FC201949B992E8076A2BA99F59C9B1368C69CB0E48FF0599290D4C635262EF4F1BB2E87C4CDF4FF7EA9FAD2010CBF30198B7A961606BF3E49C5618F
+Ctrl.nr = hexnr:AA241EAD5C65408AE109D09993DBA807FF23E00883A466F2F408BCED7A8BB37729ABB124DE79A7652CDD450911B4FF1A252D11B8D6EF065B48FD2703CB6D682712E24E92F6CE3511DBB6F78AFFAFEF1B0B875AE2B3C559783EA7F2138B831C236845B800D00AA28010C47D2F6744033A10B286E791D16DCBE31E9C994E45D659E65ECF03EAFFCD916FEBB320913C97DB41415961DC02823849A2009D9C126CC4E50F6CFE1F447C691463EA1309B66DE3BC39ABBB0ABC69525DEF486669E1F45AFFBDD6FE1F5314EDFC631E4655DF289108697F906C6C82BC0D8C52343278CD32A93FF33247764D3CCA18278C7876DEB0247ADE36149D99F3EF1E746D90DE0524
+Ctrl.key = hexkey:CDDD59534E22D7306C94D07D5C14FAD33E58838E02C7A8FA9C421F66FB72E51B
+Ctrl.mode = mode:1
+Output = 6E7CC5B65BB20CBDB06825802B98B62357D824F72D7756F9C97FD132788216F6594726217705098DA118A2023849DFF1A502E4BA5D8DFE9FFECEFDEE2BF79A3713C8E7A5C63A1429539AAB4C7C372C5A561BDCC82CCFAEAAFFF9ABDEBB2EA3B901EEC8252811CFA2422AAF2BA24CF1F9DD9AFB54C0F65A11BE7566AE0E6B5170BC205AC9A703E35D7D60D5ECF70A9B9EF4D72D37AB88AF021D38808341FC6EA522E6741550942799C4974333FEB6F9A3E7254EB476DA31DCF717DA189F8B7A075EB1BB06B5DC14714FFAAE1FD15F142CF9E6993E0A5A282124B46AEAAA5FC773EA3BDD3CC43E64ADC689BE3EAA9F977D950425203739C15794D2F3D48086CCF6404F799FB59BDB1F4D9596255CF2EDBD96C787B66CF47EFD7947469363D41750163B2D79D43A829C0D3695234094D3DCF56317948A92338BD22E3D3C27B976373B4FB513B38B696B340A747860DAD4DBDE0FD7D15D53F0A49DEF2A404FC152043FE94B868989F43CD4E90E3A90F95B6246072A55FD70A987A25BBFD93A37C8F7
+
+# tgId = 7, tcId = 121, DKM(Child_DH)
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.ni = hexni:F096BC348F4C0BE7A0932E065F72DA82F9E312379CBEC86574837E535DEDD0F81E86FE52F9D89336B17BF5DC030E766E71D25B60D724AAEFE8B60C2383BD6395703214D6E04C545443E95B47ADB11C80A60110C083402B335CDF9E4E2CD6200DC3A28D1F8E1D6F8293DEA1025707CE870439F9A3CB2638FE52A3F350CEE833E4EBB34F7C3920B9A0A4DCE7BC3E7DD6502F6D365FBB0BC0131FC74048BD145E7B9BE07F2E58FDF53A98B5AF8C3958C592ECB1642D63CEC46BE1A77A2E5B525554682114040FC201949B992E8076A2BA99F59C9B1368C69CB0E48FF0599290D4C635262EF4F1BB2E87C4CDF4FF7EA9FAD2010CBF30198B7A961606BF3E49C5618F
+Ctrl.nr = hexnr:AA241EAD5C65408AE109D09993DBA807FF23E00883A466F2F408BCED7A8BB37729ABB124DE79A7652CDD450911B4FF1A252D11B8D6EF065B48FD2703CB6D682712E24E92F6CE3511DBB6F78AFFAFEF1B0B875AE2B3C559783EA7F2138B831C236845B800D00AA28010C47D2F6744033A10B286E791D16DCBE31E9C994E45D659E65ECF03EAFFCD916FEBB320913C97DB41415961DC02823849A2009D9C126CC4E50F6CFE1F447C691463EA1309B66DE3BC39ABBB0ABC69525DEF486669E1F45AFFBDD6FE1F5314EDFC631E4655DF289108697F906C6C82BC0D8C52343278CD32A93FF33247764D3CCA18278C7876DEB0247ADE36149D99F3EF1E746D90DE0524
+Ctrl.key = hexkey:CDDD59534E22D7306C94D07D5C14FAD33E58838E02C7A8FA9C421F66FB72E51B
+Ctrl.secret = hexsecret:5540B8884168C2D05B43FC37A9BC613D0F66FF3EEF3783D126DCC18EB6BBAE71376572F77F43874BECC9FCB3EC7BE89D1F8D923143FBA7C83838CBC8B3AF9A58F7E9B2915A81CBA198423A96FFBB09F2A4753E5014A65BEAF7CD784BE5208E2660FC6EF66D8C135EDEA6D89EE59E96B083B1E842D6FA5466DF1F1E6EDFA94870E11F35966C8DA38DB7144A680C3A0A163C57F42E916F469692DB83101ACA72290FE4D9EFB4D20877DF79B11C90E6416330393951D25855BA0FEA68750582066931DB4F4E9D3B4F75A9C786E62A5680FB5088932034A3045F33762B0348B23F6560DC7311E291EBC4596DF5D7B789313AEEB12744E86645A4EC31E089FFA8E39E
+Ctrl.mode = mode:1
+Output = 81C3D430D4C808318288287AE8BEF264942D5DEB2DC42B8BE559315640E50ED9BFECA0F62B108FFB4E485BEB859B1704266D5B4450D7DAB7A65697F4CE95310A75E66EA170791911DB8D934D8DA9DBF47976666F61183AD2D98CD6BFC7442763BED87583C106BA42729FD7E2806E766E4A82B746AAF46126AFCC6FD932E5680C1000167E26C5777CAEC49BFF1B40566E017045200A9CFCDD1A5E87ADCC0E2E84CDFCB21C286028971AEE733D897ACF16A95C7D9016339983C3089E24CA41E178D120485657839F53B0220BD477BBB9D90DFDB8E647E3E8C59A74465697AC6D57D6BC67FBAEAB737D6DD7CCC912C37BFE4F11B4854CBEC8F15E6320E89D68133D5B0BC5ADF60DD7B83631B317717574956043CBAD4F1BF1769B3E5F2843D86876CF82E9AE7FBDCCB7E7C68D22F4954A03880AA8C26E0E48A02A3FDC14EF3C7FB91C3B5F745EB8B1C654168FD6D71EC3360A904E2F52DA7B25D02C0E3B31179C3724271F63DA41E5BE3992EF71AC864A6A352EFD05A88A2773AFD48A47DAACAEEE
+
+# tgId = 7, tcId = 121, ReKey
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA256
+Ctrl.ni = hexni:F096BC348F4C0BE7A0932E065F72DA82F9E312379CBEC86574837E535DEDD0F81E86FE52F9D89336B17BF5DC030E766E71D25B60D724AAEFE8B60C2383BD6395703214D6E04C545443E95B47ADB11C80A60110C083402B335CDF9E4E2CD6200DC3A28D1F8E1D6F8293DEA1025707CE870439F9A3CB2638FE52A3F350CEE833E4EBB34F7C3920B9A0A4DCE7BC3E7DD6502F6D365FBB0BC0131FC74048BD145E7B9BE07F2E58FDF53A98B5AF8C3958C592ECB1642D63CEC46BE1A77A2E5B525554682114040FC201949B992E8076A2BA99F59C9B1368C69CB0E48FF0599290D4C635262EF4F1BB2E87C4CDF4FF7EA9FAD2010CBF30198B7A961606BF3E49C5618F
+Ctrl.nr = hexnr:AA241EAD5C65408AE109D09993DBA807FF23E00883A466F2F408BCED7A8BB37729ABB124DE79A7652CDD450911B4FF1A252D11B8D6EF065B48FD2703CB6D682712E24E92F6CE3511DBB6F78AFFAFEF1B0B875AE2B3C559783EA7F2138B831C236845B800D00AA28010C47D2F6744033A10B286E791D16DCBE31E9C994E45D659E65ECF03EAFFCD916FEBB320913C97DB41415961DC02823849A2009D9C126CC4E50F6CFE1F447C691463EA1309B66DE3BC39ABBB0ABC69525DEF486669E1F45AFFBDD6FE1F5314EDFC631E4655DF289108697F906C6C82BC0D8C52343278CD32A93FF33247764D3CCA18278C7876DEB0247ADE36149D99F3EF1E746D90DE0524
+Ctrl.key = hexkey:CDDD59534E22D7306C94D07D5C14FAD33E58838E02C7A8FA9C421F66FB72E51B
+Ctrl.secret = hexsecret:5540B8884168C2D05B43FC37A9BC613D0F66FF3EEF3783D126DCC18EB6BBAE71376572F77F43874BECC9FCB3EC7BE89D1F8D923143FBA7C83838CBC8B3AF9A58F7E9B2915A81CBA198423A96FFBB09F2A4753E5014A65BEAF7CD784BE5208E2660FC6EF66D8C135EDEA6D89EE59E96B083B1E842D6FA5466DF1F1E6EDFA94870E11F35966C8DA38DB7144A680C3A0A163C57F42E916F469692DB83101ACA72290FE4D9EFB4D20877DF79B11C90E6416330393951D25855BA0FEA68750582066931DB4F4E9D3B4F75A9C786E62A5680FB5088932034A3045F33762B0348B23F6560DC7311E291EBC4596DF5D7B789313AEEB12744E86645A4EC31E089FFA8E39E
+Ctrl.mode = mode:2
+Output = AAEBE45EE40BC364248FEBD74A9869B56E5DF1EA23D3619D23D0AFC1681E3F72
+
+# tgId = 13, tcId = 241, GEN
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA512
+Ctrl.ni = hexni:834EA4753E9A06832072FA15E89E799035A1285CE241CAF3B5C724ECE8ECD0D2D1AC46FAB3D9D86BF2EBF4CC8F93E06C5342415E14DFCBC949574E1606F96F143E8AA8C80BCCD376FF3D3BAE0B134A04DD2AE557010E5D7A7552C6864FD8A82D99FFDFDA97BE97389A426D7259411B10DD9EEFAE2709141E654087A2056EB86DAF95EF262328A2CDD90C61152DC2BBFCF4CCF4084557C3892603023A8B7045FC589A35143E10DCD1A73406EA923B21687A12134B6A1007E4AA2E37FFFA4901DFF6F3514E2B350F08175E194D3C6DB75E03FD838D503CEFA9E9604A4E18F330C08142574A992465FEA063875ABAF144F47C50F32A0A83224E3EEA739033AF6B9F
+Ctrl.nr = hexnr:F833709DE457FB58ABE1D26E8DECC8FE889D503954C4812AC0F41271394AF7C148B15A241C2D6D6502C3C57DAE854A97BFB3CCDCEC650153578CCB51BDFE1C715E81F3D78488B1547A3C9E5617D9B78B46D06F56BB56423C88DEACCD82E7A2A11ADD56651091682F0987332EA28A32045A4D39609F364EB5E70468ECB7BBDCAD6B41E04ADD11D97F300E8D0A0C2941F1CB64885F940EE2FA273477E910983E96913F58E37BFD68E3ADCD6E813176E95FEE7985F5526EEDC3245C4746F5864D9E90BF80F6882F6A505ADACD81D106576F7A6C705E37CE551235E012E64EC3BE7B4F3F8889E664CC5ED7BCC4A88022A437439609B3019CDE1948665A548E420D1E
+Ctrl.secret = hexsecret:9566A04BF95F433C6497B3AE8CB0F600043F8438EB2B9E97E912AF1C5ACE9A73A8884BF1FF80A895EB97A6F5494B6CEA5B1C3123C3A9CBE057A0CBA2F52FD40A8DFDF9F99B521D356347E2B70CF637B5B4A44C2ED92770A281E6431CB50BDDCE4FB2EC8100218FA84B0A4A344C4DC79BBC81ADD2FD23BC797EFA1B2AFA6840AD7B2E04D391F33662774A5296A0EF9C9C113E84F5B958FD54857E75378406F29DA1EB23E9E9D9D94177672BFA7742F7F4319F31ED06E1999E17EEAC6B35ADC9A245CAD998E3CE3C422B8AD752F7144332E9AAE44EA837677A8406B7261C04CB4EB9230FBA75E09E16EEDA246D5B1DA5CF14C96F00FC83C555854E7982E52A1D4F
+Ctrl.mode = mode:0
+Output = 3DAA296C25DD8CBDE8E9F5FE85498CB06339FC7AAA93F60987831A0FA79829E244AFE92BD66590D8C7F1BC281BADC619ED2C9762FDB913B052842E50E3989863
+
+# tgId = 13, tcId = 241, DKM
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA512
+Ctrl.ni = hexni:834EA4753E9A06832072FA15E89E799035A1285CE241CAF3B5C724ECE8ECD0D2D1AC46FAB3D9D86BF2EBF4CC8F93E06C5342415E14DFCBC949574E1606F96F143E8AA8C80BCCD376FF3D3BAE0B134A04DD2AE557010E5D7A7552C6864FD8A82D99FFDFDA97BE97389A426D7259411B10DD9EEFAE2709141E654087A2056EB86DAF95EF262328A2CDD90C61152DC2BBFCF4CCF4084557C3892603023A8B7045FC589A35143E10DCD1A73406EA923B21687A12134B6A1007E4AA2E37FFFA4901DFF6F3514E2B350F08175E194D3C6DB75E03FD838D503CEFA9E9604A4E18F330C08142574A992465FEA063875ABAF144F47C50F32A0A83224E3EEA739033AF6B9F
+Ctrl.nr = hexnr:F833709DE457FB58ABE1D26E8DECC8FE889D503954C4812AC0F41271394AF7C148B15A241C2D6D6502C3C57DAE854A97BFB3CCDCEC650153578CCB51BDFE1C715E81F3D78488B1547A3C9E5617D9B78B46D06F56BB56423C88DEACCD82E7A2A11ADD56651091682F0987332EA28A32045A4D39609F364EB5E70468ECB7BBDCAD6B41E04ADD11D97F300E8D0A0C2941F1CB64885F940EE2FA273477E910983E96913F58E37BFD68E3ADCD6E813176E95FEE7985F5526EEDC3245C4746F5864D9E90BF80F6882F6A505ADACD81D106576F7A6C705E37CE551235E012E64EC3BE7B4F3F8889E664CC5ED7BCC4A88022A437439609B3019CDE1948665A548E420D1E
+Ctrl.spii = hexspii:6E5F49D279F4FBBB
+Ctrl.spir = hexspir:FF7AE472AA4DD7AF
+Ctrl.seed = hexseed:3DAA296C25DD8CBDE8E9F5FE85498CB06339FC7AAA93F60987831A0FA79829E244AFE92BD66590D8C7F1BC281BADC619ED2C9762FDB913B052842E50E3989863
+Ctrl.mode = mode:1
+Output = 2BD66826C397A19618E3133ACE96F6168A04EF9AFA53F2F07CECDA9E0F6139C37CC6512551F523006B74D501C5DD1AE502689ECE8A43CE7B3D866C7372176B1D5BC4A0B863F642351FD4822C79F0A8D97B03B09FA1393679149432798BEA545F70C663675E751A68AEEB7B238CA790229C7775E6A074BECDFAAD324AC546EEB5D0A9480B1AA06B6F225CBFAC7447DE3D8D292B0BEB7D9A5B709C02946A10F8799DD4E4B18C6D10CEDA39A82B9DAE01EFEBE6C31735590EF7D44E1C8DBBAD98DAFE620843065E5141D7C57770234128599E3223139656DBB3D0C494FABA482AE9740FAA3D3957EFD9D90FD24144BC9B317C7955722426A6719D0095D068FD0B63469140D1EF9DDEFC43B2BCFFF971A08A7E67E75B8F0DED8C4737175ABF04C32B906FE7D53E8C3B11B3829DB0082B73F44C042C285F079A3BD6C33F91559F31043E23BB0A79B83C93AAF1CFEAF6C5996E717869C2D7F6528C8ACAE6656A8430164886385441484107261DE0D9A9B6B39A24812CCFA24C1F964AEAC69CE6D00541
+
+# tgId = 13, tcId = 241, DKM(Child_SA)
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA512
+Ctrl.ni = hexni:834EA4753E9A06832072FA15E89E799035A1285CE241CAF3B5C724ECE8ECD0D2D1AC46FAB3D9D86BF2EBF4CC8F93E06C5342415E14DFCBC949574E1606F96F143E8AA8C80BCCD376FF3D3BAE0B134A04DD2AE557010E5D7A7552C6864FD8A82D99FFDFDA97BE97389A426D7259411B10DD9EEFAE2709141E654087A2056EB86DAF95EF262328A2CDD90C61152DC2BBFCF4CCF4084557C3892603023A8B7045FC589A35143E10DCD1A73406EA923B21687A12134B6A1007E4AA2E37FFFA4901DFF6F3514E2B350F08175E194D3C6DB75E03FD838D503CEFA9E9604A4E18F330C08142574A992465FEA063875ABAF144F47C50F32A0A83224E3EEA739033AF6B9F
+Ctrl.nr = hexnr:F833709DE457FB58ABE1D26E8DECC8FE889D503954C4812AC0F41271394AF7C148B15A241C2D6D6502C3C57DAE854A97BFB3CCDCEC650153578CCB51BDFE1C715E81F3D78488B1547A3C9E5617D9B78B46D06F56BB56423C88DEACCD82E7A2A11ADD56651091682F0987332EA28A32045A4D39609F364EB5E70468ECB7BBDCAD6B41E04ADD11D97F300E8D0A0C2941F1CB64885F940EE2FA273477E910983E96913F58E37BFD68E3ADCD6E813176E95FEE7985F5526EEDC3245C4746F5864D9E90BF80F6882F6A505ADACD81D106576F7A6C705E37CE551235E012E64EC3BE7B4F3F8889E664CC5ED7BCC4A88022A437439609B3019CDE1948665A548E420D1E
+Ctrl.key = hexkey:2BD66826C397A19618E3133ACE96F6168A04EF9AFA53F2F07CECDA9E0F6139C37CC6512551F523006B74D501C5DD1AE502689ECE8A43CE7B3D866C7372176B1D
+Ctrl.mode = mode:1
+Output = 0B0D01A13515AC0727F7D90456D3D2FD9C1172096CDED4A20BDA43FC796184BAEB3A7F34FFC09C584DD9BEEBC7629A36A5D143DFB1C2931F369E6702769B6A01AA20B7B955C30481D7894DF2AEBAB0DD669C3E1E168BE5F122F8A9D8A589F3C6C48EFC031129481E2DEA1F6FC10E07F3E39A1FCC3D660E289778458E752802501DBDE1EB0EDE3D2227DE7FAE3F265D66986B1AE4CF407EDC3A5168A6179ED8CA2006ACC2D9104749C3E2231482374E5F0CE3DA3C8B8520D37F37092669FBB78EAA4CC818BE8CA31935529E085BCE3830040F679883E3375C274CEF5BF5F36F34D8705B9EC48B4DC2FE9E3A269B41BED2D659767726DC775404610ED1B285067D900D20A38D02192475D2934AE8E4C47B4CF5729A42FEC7AF15C01AEB019069F2C87F2E6429D6CB2755384980DFAB9173C70AEDB30611A05FCD03078F2CAA8CB323452D6E899197992CF3B93343EEBAA1251E1D8F0B3664D0D0310217889510885D319C2BD8CD3A8FD49848D8331F8C248E6C3C7B6E3D4E376F7BC71FF10D66D1
+
+# tgId = 13, tcId = 241, DKM(Child_DH)
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA512
+Ctrl.ni = hexni:834EA4753E9A06832072FA15E89E799035A1285CE241CAF3B5C724ECE8ECD0D2D1AC46FAB3D9D86BF2EBF4CC8F93E06C5342415E14DFCBC949574E1606F96F143E8AA8C80BCCD376FF3D3BAE0B134A04DD2AE557010E5D7A7552C6864FD8A82D99FFDFDA97BE97389A426D7259411B10DD9EEFAE2709141E654087A2056EB86DAF95EF262328A2CDD90C61152DC2BBFCF4CCF4084557C3892603023A8B7045FC589A35143E10DCD1A73406EA923B21687A12134B6A1007E4AA2E37FFFA4901DFF6F3514E2B350F08175E194D3C6DB75E03FD838D503CEFA9E9604A4E18F330C08142574A992465FEA063875ABAF144F47C50F32A0A83224E3EEA739033AF6B9F
+Ctrl.nr = hexnr:F833709DE457FB58ABE1D26E8DECC8FE889D503954C4812AC0F41271394AF7C148B15A241C2D6D6502C3C57DAE854A97BFB3CCDCEC650153578CCB51BDFE1C715E81F3D78488B1547A3C9E5617D9B78B46D06F56BB56423C88DEACCD82E7A2A11ADD56651091682F0987332EA28A32045A4D39609F364EB5E70468ECB7BBDCAD6B41E04ADD11D97F300E8D0A0C2941F1CB64885F940EE2FA273477E910983E96913F58E37BFD68E3ADCD6E813176E95FEE7985F5526EEDC3245C4746F5864D9E90BF80F6882F6A505ADACD81D106576F7A6C705E37CE551235E012E64EC3BE7B4F3F8889E664CC5ED7BCC4A88022A437439609B3019CDE1948665A548E420D1E
+Ctrl.key = hexkey:2BD66826C397A19618E3133ACE96F6168A04EF9AFA53F2F07CECDA9E0F6139C37CC6512551F523006B74D501C5DD1AE502689ECE8A43CE7B3D866C7372176B1D
+Ctrl.secret = hexsecret:F34450EC9F4B07881FF17DB4AE1681B26F2FC8CBECDB7EF0463B09C4FE79F8414FBEA9FD3E7C18C845D04E283E1EEB7824484C72354A7A9C418E69B8134D596E1ABCD2998EA5FABCA1FD156678BF7FB0F31C1158E812FD215837A23938BAC55B37C6E8BECEDF9435A03484326CD2D4E3C7A273D8A99135027AA17823DA9BF0263082394CA3475266F5BAE91D1577C3D15A7DD429E1F5DE70138B05214589EF8A519AA930A42F609CCC54CE8701488E80C2BEACCA2542C0D9B2DD7C04E41EBBC341EB65A3F786900747FA6CA2CF914E908FEA40014D3175B73DA1B63437A89638F69E184FD91E6A02C0F9FC9AFAFE7B6811B3AC7A57B2615A3B3FC26289500143
+Ctrl.mode = mode:1
+Output = 48E185DC18E52193E01ECA3C0D739C3070A73B89A4D0FAC7B40E4D51250EEAE7232C2031DAA700E3A2D570BA67ECA56F1DBE5DE5B96CD718FAF2FCC7EBCA08D1FEFA2DB5B024CC9A03F50EF310D43A3E66D53912AF846CFF6BB039CBFF37BDD1C2D329993A98D3FAF9026A32EBF6747E347115AA3C604D187A25204407DB7E3FD4E1D28300E898028542C4B8D3C4EB26BD0ADF87439CCB7C0230351D38C92772CA234B887CA8F7667B4FBB9619151D75FECB2C30F570BC0EEDD5C6D89F39DE1A547AC99CFB7CF608AD4C56C83077E97CE850BE40344177CBEF2F22E37353E6A164A2683DE957A48754E8E74331A07503069E8ED44C68F27C0A414D582AA2DD7A66098E3C4D0BE5F0CC5FE9EBC042C3E794E53639A452F0449685DC3FC34C0EAE58AF6C7E862FAF0FC2E2C8F57C889E1DC19E8DAE2E92F828A3F01A1D3DBDCF3C7A0F61828E0E5C26E559E8D1320110D8477FF8A28D90BC9693BB99E10B7A3EA62E3559D7CC2E54279012D2C3CC7FBA3349E098D6756BCC7EE62507B350DBF3A3
+
+# tgId = 13, tcId = 241, Rekey
+FIPSversion = >=4.1.0
+KDF = IKEV2KDF
+Ctrl.digest = digest:SHA512
+Ctrl.ni = hexni:834EA4753E9A06832072FA15E89E799035A1285CE241CAF3B5C724ECE8ECD0D2D1AC46FAB3D9D86BF2EBF4CC8F93E06C5342415E14DFCBC949574E1606F96F143E8AA8C80BCCD376FF3D3BAE0B134A04DD2AE557010E5D7A7552C6864FD8A82D99FFDFDA97BE97389A426D7259411B10DD9EEFAE2709141E654087A2056EB86DAF95EF262328A2CDD90C61152DC2BBFCF4CCF4084557C3892603023A8B7045FC589A35143E10DCD1A73406EA923B21687A12134B6A1007E4AA2E37FFFA4901DFF6F3514E2B350F08175E194D3C6DB75E03FD838D503CEFA9E9604A4E18F330C08142574A992465FEA063875ABAF144F47C50F32A0A83224E3EEA739033AF6B9F
+Ctrl.nr = hexnr:F833709DE457FB58ABE1D26E8DECC8FE889D503954C4812AC0F41271394AF7C148B15A241C2D6D6502C3C57DAE854A97BFB3CCDCEC650153578CCB51BDFE1C715E81F3D78488B1547A3C9E5617D9B78B46D06F56BB56423C88DEACCD82E7A2A11ADD56651091682F0987332EA28A32045A4D39609F364EB5E70468ECB7BBDCAD6B41E04ADD11D97F300E8D0A0C2941F1CB64885F940EE2FA273477E910983E96913F58E37BFD68E3ADCD6E813176E95FEE7985F5526EEDC3245C4746F5864D9E90BF80F6882F6A505ADACD81D106576F7A6C705E37CE551235E012E64EC3BE7B4F3F8889E664CC5ED7BCC4A88022A437439609B3019CDE1948665A548E420D1E
+Ctrl.key = hexkey:2BD66826C397A19618E3133ACE96F6168A04EF9AFA53F2F07CECDA9E0F6139C37CC6512551F523006B74D501C5DD1AE502689ECE8A43CE7B3D866C7372176B1D
+Ctrl.secret = hexsecret:F34450EC9F4B07881FF17DB4AE1681B26F2FC8CBECDB7EF0463B09C4FE79F8414FBEA9FD3E7C18C845D04E283E1EEB7824484C72354A7A9C418E69B8134D596E1ABCD2998EA5FABCA1FD156678BF7FB0F31C1158E812FD215837A23938BAC55B37C6E8BECEDF9435A03484326CD2D4E3C7A273D8A99135027AA17823DA9BF0263082394CA3475266F5BAE91D1577C3D15A7DD429E1F5DE70138B05214589EF8A519AA930A42F609CCC54CE8701488E80C2BEACCA2542C0D9B2DD7C04E41EBBC341EB65A3F786900747FA6CA2CF914E908FEA40014D3175B73DA1B63437A89638F69E184FD91E6A02C0F9FC9AFAFE7B6811B3AC7A57B2615A3B3FC26289500143
+Ctrl.mode = mode:2
+Output = 1CC9237EBB1704D703952B6EDBE275CA51AC17E2E224F13E38F4C49F5FA9AF00F8ECB96FA0ECD6FF282C08A29D3E313AB4A4EE1022580118B8DEFF0CD8432A00
diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm
index 207cc43070..69a57f11a3 100644
--- a/util/perl/OpenSSL/paramnames.pm
+++ b/util/perl/OpenSSL/paramnames.pm
@@ -226,6 +226,10 @@ my %params = (
'OSSL_KDF_PARAM_PKCS5' => "pkcs5", # int
'OSSL_KDF_PARAM_UKM' => "ukm", # octet string
'OSSL_KDF_PARAM_CEK_ALG' => "cekalg", # utf8 string
+ 'OSSL_KDF_PARAM_IKEV2KDF_NI' => "ni", # octet string
+ 'OSSL_KDF_PARAM_IKEV2KDF_NR' => "nr", # octet string
+ 'OSSL_KDF_PARAM_IKEV2KDF_SPII' => "spii", # octet string
+ 'OSSL_KDF_PARAM_IKEV2KDF_SPIR' => "spir", # octet string
'OSSL_KDF_PARAM_SCRYPT_N' => "n", # uint64_t
'OSSL_KDF_PARAM_SCRYPT_R' => "r", # uint32_t
'OSSL_KDF_PARAM_SCRYPT_P' => "p", # uint32_t