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)
This commit is contained in:
Helen Zhang 2026-03-13 17:25:31 +00:00 committed by Tomas Mraz
parent 7703de2772
commit 0dd1c50fc0
32 changed files with 1889 additions and 20 deletions

View file

@ -70,6 +70,7 @@ jobs:
no-hmac-drbg-kdf,
no-hw,
no-idea,
no-ikev2kdf,
no-kbkdf,
no-krb5kdf,
enable-lms,

1
.gitignore vendored
View file

@ -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

View file

@ -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`

View file

@ -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",

View file

@ -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|

View file

@ -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]=\

View file

@ -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

View file

@ -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 \

View file

@ -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:

View file

@ -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

View file

@ -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>)

View file

@ -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)>

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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" },

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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;
}

View file

@ -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[];

View file

@ -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"

View file

@ -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

View file

@ -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;
}

View file

@ -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'],
)); -}

View file

@ -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
}

View file

@ -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"

View file

@ -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;

View file

@ -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

View file

@ -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