EVP_KDF-SS(7SSL)
β¨ EVP_KDF-SS β the Single Step / One Step EVP_KDF implementation π
okay bestie, settle in, because this one's actually so fun once it clicks π this page lives in the OpenSSL family and it's all about the EVP_KDF-SS algorithm, which is the Single Step key derivation function (aka SSKDF, say it with me). SSKDF takes input like a shared secret key (the kind you get from a key establishment scheme, iykyk) plus some fixedinfo, and from that it derives a key. People also call it Concat KDF casually β same thing, no cap.
And the output? That's keying material. periodt. π¦
πΈ Auxiliary function πΈ
The implementation uses a selectable auxiliary function H, and it can be one of these iconic options:
H(x) = hash(x, digest=md)
H(x) = HMAC_hash(x, key=salt, digest=md)
H(x) = KMACxxx(x, key=salt, custom="KDF", outlen=mac_size)
Both the HMAC and KMAC implementations set the key using the 'salt' value. And the hash and HMAC versions? They also require the digest to be set. don't forget it bestie π
β Identity β
"SSKDF" is the name for this implementation β that's the string you hand to the EVP_KDF_fetch() function. remember it, it's giving main character energy π
π Supported parameters π
These are the supported parameters, and yes, we're doing all of them:
"properties"(OSSL_KDF_PARAM_PROPERTIES)<UTF8 string>"digest"(OSSL_KDF_PARAM_DIGEST)<UTF8 string>β This parameter is ignored for KMAC. (not its moment, ig π)"mac"(OSSL_KDF_PARAM_MAC)<UTF8 string>"maclen"(OSSL_KDF_PARAM_MAC_SIZE)<unsigned integer>"salt"(OSSL_KDF_PARAM_SALT)<octet string>β These parameters work as described in"PARAMETERS"inEVP_KDF(3)."key"(OSSL_KDF_PARAM_KEY)<octet string>β This parameter sets the shared secret that is used for key derivation."secret"(OSSL_KDF_PARAM_SECRET)<octet string>β This parameter sets the shared secret that is used for key derivation."info"(OSSL_KDF_PARAM_INFO)<octet string>β This parameter sets an optional value for fixedinfo, also known as otherinfo.
π«Ά what the FIPS provider also supports π«Ά
The OpenSSL FIPS provider also supports the following parameters:
"fips-indicator"(OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR)<integer>β A getter that returns1if the operation is FIPS approved, or0otherwise. This may be used after callingEVP_KDF_derive. It returns0if"key-check"is set to0and the check fails."key-check"(OSSL_KDF_PARAM_FIPS_KEY_CHECK)<integer>β The default value of1causes an error duringEVP_KDF_CTX_set_params()if the length of used key-derivation key (OSSL_KDF_PARAM_KEY) is shorter than 112 bits. Setting this to zero will ignore the error and set the approved"fips-indicator"to0.
β οΈ This option breaks FIPS compliance if it causes the approved"fips-indicator"to return0. like, fr fr, be careful π
π NOTES π
A context for SSKDF can be obtained by calling:
EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL);
EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
The output length of an SSKDF is specified via the keylen parameter to the EVP_KDF_derive(3) function. that's the vibe check right there β¨
π EXAMPLES π
Example numero uno: this derives 10 bytes using H(x) = SHA-256, with the secret key "secret" and fixedinfo value "label":
EVP_KDF *kdf;
EVP_KDF_CTX *kctx;
unsigned char out[10];
OSSL_PARAM params[4], *p = params;
kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL);
kctx = EVP_KDF_CTX_new(kdf);
EVP_KDF_free(kdf);
*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,
"secret", (size_t)6);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
"label", (size_t)5);
*p = OSSL_PARAM_construct_end();
if (EVP_KDF_derive(kctx, out, sizeof(out), params) <= 0) {
error("EVP_KDF_derive");
}
EVP_KDF_CTX_free(kctx);
Example two, the glow up: this derives 10 bytes using H(x) = HMAC(SHA-256), with the secret key "secret", fixedinfo value "label" and salt "salt":
EVP_KDF *kdf;
EVP_KDF_CTX *kctx;
unsigned char out[10];
OSSL_PARAM params[6], *p = params;
kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL);
kctx = EVP_KDF_CTX_new(kdf);
EVP_KDF_free(kdf);
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC,
SN_hmac, strlen(SN_hmac));
*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,
"secret", (size_t)6);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
"label", (size_t)5);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
"salt", (size_t)4);
*p = OSSL_PARAM_construct_end();
if (EVP_KDF_derive(kctx, out, sizeof(out), params) <= 0) {
error("EVP_KDF_derive");
}
EVP_KDF_CTX_free(kctx);
Example three, the finale π₯: this derives 10 bytes using H(x) = KMAC128(x,salt,outlen), with the secret key "secret" fixedinfo value "label", salt of "salt" and KMAC outlen of 20:
EVP_KDF *kdf;
EVP_KDF_CTX *kctx;
unsigned char out[10];
OSSL_PARAM params[6], *p = params;
kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL);
kctx = EVP_KDF_CTX_new(kdf);
EVP_KDF_free(kdf);
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC,
SN_kmac128, strlen(SN_kmac128));
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
"secret", (size_t)6);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
"label", (size_t)5);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
"salt", (size_t)4);
*p++ = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_MAC_SIZE, (size_t)20);
*p = OSSL_PARAM_construct_end();
if (EVP_KDF_derive(kctx, out, sizeof(out), params) <= 0) {
error("EVP_KDF_derive");
}
EVP_KDF_CTX_free(kctx);
π CONFORMING TO π
NIST SP800-56Cr1. the standard said what it said π
π¦ SEE ALSO π¦
EVP_KDF(3), EVP_KDF_CTX_new(3), EVP_KDF_CTX_free(3), EVP_KDF_CTX_set_params(3), EVP_KDF_CTX_get_kdf_size(3), EVP_KDF_derive(3), "PARAMETERS" in EVP_KDF(3)
go read those too bestie, they're all connected π
πΈ HISTORY πΈ
This functionality was added in OpenSSL 3.0. a legend from the start, no notes β¨
π COPYRIGHT π
Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved.
Copyright (c) 2019, Oracle and/or its affiliates. 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>.
and that's the whole page, bestie!! π«Ά this was version 4.0.3, dated 2026-09-29 β catch you in the next manpage, mwah π β¨
π¦ where this page comes from
- ubuntu stonking: openssl 4.0.3-1ubuntu1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms