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