.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.48) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "EVP_KDF-IKEV2KDF 7ssl" .TH EVP_KDF-IKEV2KDF 7ssl 2026-10-23 4.1.0 OpenSSL .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME EVP_KDF\-IKEV2KDF \- The IKEV2KDF EVP_KDF implementation .SH DESCRIPTION .IX Header "DESCRIPTION" Support for computing the \fBIKEV2KDF\fR KDF through the \fBEVP_KDF\fR API. .PP 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. .SS Identity .IX Subsection "Identity" "IKEV2KDF" is the name for this implementation; it can be used with the \fBEVP_KDF_fetch()\fR function. .SS "Supported parameters" .IX Subsection "Supported parameters" The supported parameters are: .IP """properties"" (\fBOSSL_KDF_PARAM_PROPERTIES\fR) " 4 .IX Item """properties"" (OSSL_KDF_PARAM_PROPERTIES) " .PD 0 .IP """digest"" (\fBOSSL_KDF_PARAM_DIGEST\fR) " 4 .IX Item """digest"" (OSSL_KDF_PARAM_DIGEST) " .PD These parameters work as described in "PARAMETERS" in \fBEVP_KDF\fR\|(3). 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. .IP """secret"" (\fBOSSL_KDF_PARAM_SECRET\fR) " 4 .IX Item """secret"" (OSSL_KDF_PARAM_SECRET) " 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 (). If a value is already set, the contents are replaced. .IP """ni"" (\fBOSSL_KDF_PARAM_IKEV2_NI\fR) " 4 .IX Item """ni"" (OSSL_KDF_PARAM_IKEV2_NI) " This parameter sets the initiator\*(Aqs nonce (Ni) value for the KDF. The nonce length is in the range of 8 to 256 bytes as specified in NIST ACVP draft (). If a value is already set, the contents are replaced. .IP """nr"" (\fBOSSL_KDF_PARAM_IKEV2_NR\fR) " 4 .IX Item """nr"" (OSSL_KDF_PARAM_IKEV2_NR) " This parameter sets the responder\*(Aqs nonce (Nr) value for the KDF. The nonce length is in the range of 8 to 256 bytes as specified in NIST ACVP draft (). If a value is already set, the contents are replaced. .IP """spii"" (\fBOSSL_KDF_PARAM_IKEV2_SPII\fR) " 4 .IX Item """spii"" (OSSL_KDF_PARAM_IKEV2_SPII) " This parameter sets the initiator\*(Aqs Security Parameter Index (SPIi) value for the KDF. If a value is already set, the contents are replaced. .IP """spir"" (\fBOSSL_KDF_PARAM_IKEV2_SPIR\fR) " 4 .IX Item """spir"" (OSSL_KDF_PARAM_IKEV2_SPIR) " This parameter sets the responder\*(Aqs Security Parameter Index (SPIr) value for the KDF. If a value is already set, the contents are replaced. .IP """seedkey"" (\fBOSSL_KDF_PARAM_SEEDKEY\fR) " 4 .IX Item """seedkey"" (OSSL_KDF_PARAM_SEEDKEY) " This parameter sets the SEEDKEY used for deriving DKM(Initial SA). If a value is already set, the contents are replaced. .IP """key"" (\fBOSSL_KDF_PARAM_KEY\fR) " 4 .IX Item """key"" (OSSL_KDF_PARAM_KEY) " This parameter sets the SK_d used for deriving DKM(Child_SA) or REKEY. If a value is already set, the contents are replaced. .IP """mode"" (\fBOSSL_KDF_PARAM_MODE\fR) " 4 .IX Item """mode"" (OSSL_KDF_PARAM_MODE) " This parameter sets the IKEv2 KDF mode. The IKEV2KDF implementation supports three different modes of operation: .RS 4 .IP EVP_KDF_IKEV2_MODE_GEN 8 .IX 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. .IP EVP_KDF_IKEV2_MODE_DKM 8 .IX Item "EVP_KDF_IKEV2_MODE_DKM" It operates in three stages, based on the input parameter sets. .Sp 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). .Sp Then, it derives keying material for the Child_SA, using the SK_d as input along with new nonces. .Sp 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). .IP EVP_KDF_IKEV2_MODE_REKEY 8 .IX 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). .RE .RS 4 .RE .IP """fips\-indicator"" (\fBOSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR\fR) " 4 .IX Item """fips-indicator"" (OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR) " The OpenSSL FIPS provider returns 1 if the operation is FIPS approved, or 0 otherwise. See "FIPS indicators" in \fBfips_module\fR\|(7) for more information. .SH NOTES .IX Header "NOTES" A context for IKEV2KDF can be obtained by calling: .PP .Vb 2 \& EVP_KDF *kdf = EVP_KDF_fetch(NULL, "IKEV2KDF", NULL); \& EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); .Ve .PP 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. .SH EXAMPLES .IX Header "EXAMPLES" .SS "Example of SEEDKEY generation" .IX Subsection "Example of SEEDKEY generation" This example derives a 32\-byte SEEDKEY using SHA\-256 with the appropriate shared secret and nonces: .PP .Vb 9 \& 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); .Ve .SS "Example of deriving key material DKM(Initial SA)" .IX Subsection "Example of deriving key material DKM(Initial SA)" .Vb 10 \& 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); .Ve .SS "Example of generating DKM(Child_SA)" .IX Subsection "Example of generating DKM(Child_SA)" .Vb 8 \& 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); .Ve .SS "Example of generating DKM(Child_DH)" .IX Subsection "Example of generating DKM(Child_DH)" .Vb 9 \& 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); .Ve .SS "Example of rekeying the IKE SA" .IX Subsection "Example of rekeying the IKE SA" .Vb 9 \& 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); .Ve .SH "CONFORMING TO" .IX Header "CONFORMING TO" RFC 7296 and SP800\-135 .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fBEVP_KDF\fR\|(3), \&\fBEVP_KDF_CTX_new\fR\|(3), \&\fBEVP_KDF_CTX_dup\fR\|(3), \&\fBEVP_KDF_CTX_free\fR\|(3), \&\fBEVP_KDF_CTX_set_params\fR\|(3), \&\fBEVP_KDF_CTX_get_kdf_size\fR\|(3), \&\fBEVP_KDF_derive\fR\|(3), "PARAMETERS" in \fBEVP_KDF\fR\|(3) .SH HISTORY .IX Header "HISTORY" This functionality was added in OpenSSL 4.1. .SH COPYRIGHT .IX Header "COPYRIGHT" Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. .PP 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 .