Path: blob/main/crypto/openssl/providers/implementations/kdfs/hkdf.c
48383 views
/*1* Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89/*10* HMAC low level APIs are deprecated for public use, but still ok for internal11* use.12*/13#include "internal/deprecated.h"1415#include <stdlib.h>16#include <stdarg.h>17#include <string.h>18#include <openssl/hmac.h>19#include <openssl/evp.h>20#include <openssl/kdf.h>21#include <openssl/core_names.h>22#include <openssl/proverr.h>23#include "internal/cryptlib.h"24#include "internal/numbers.h"25#include "internal/packet.h"26#include "crypto/evp.h"27#include "prov/provider_ctx.h"28#include "prov/providercommon.h"29#include "prov/implementations.h"30#include "prov/provider_util.h"31#include "prov/securitycheck.h"32#include "internal/e_os.h"33#include "internal/params.h"3435#define HKDF_MAXBUF 204836#define HKDF_MAXINFO (32*1024)3738static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_new;39static OSSL_FUNC_kdf_dupctx_fn kdf_hkdf_dup;40static OSSL_FUNC_kdf_freectx_fn kdf_hkdf_free;41static OSSL_FUNC_kdf_reset_fn kdf_hkdf_reset;42static OSSL_FUNC_kdf_derive_fn kdf_hkdf_derive;43static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params;44static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params;45static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;46static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params;47static OSSL_FUNC_kdf_derive_fn kdf_tls1_3_derive;48static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_3_settable_ctx_params;49static OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_3_set_ctx_params;50static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_tls1_3_gettable_ctx_params;51static OSSL_FUNC_kdf_get_ctx_params_fn kdf_tls1_3_get_ctx_params;5253static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,54const unsigned char *salt, size_t salt_len,55const unsigned char *key, size_t key_len,56const unsigned char *info, size_t info_len,57unsigned char *okm, size_t okm_len);58static int HKDF_Extract(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,59const unsigned char *salt, size_t salt_len,60const unsigned char *ikm, size_t ikm_len,61unsigned char *prk, size_t prk_len);62static int HKDF_Expand(const EVP_MD *evp_md,63const unsigned char *prk, size_t prk_len,64const unsigned char *info, size_t info_len,65unsigned char *okm, size_t okm_len);6667/* Settable context parameters that are common across HKDF and the TLS KDF */68#define HKDF_COMMON_SETTABLES \69OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), \70OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL), \71OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), \72OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), \73OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), \74OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0)7576/* Gettable context parameters that are common across HKDF and the TLS KDF */77#define HKDF_COMMON_GETTABLES \78OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), \79OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0)8081typedef struct {82void *provctx;83int mode;84PROV_DIGEST digest;85unsigned char *salt;86size_t salt_len;87unsigned char *key;88size_t key_len;89unsigned char *prefix;90size_t prefix_len;91unsigned char *label;92size_t label_len;93unsigned char *data;94size_t data_len;95unsigned char *info;96size_t info_len;97OSSL_FIPS_IND_DECLARE98} KDF_HKDF;99100static void *kdf_hkdf_new(void *provctx)101{102KDF_HKDF *ctx;103104if (!ossl_prov_is_running())105return NULL;106107if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL) {108ctx->provctx = provctx;109OSSL_FIPS_IND_INIT(ctx)110}111return ctx;112}113114static void kdf_hkdf_free(void *vctx)115{116KDF_HKDF *ctx = (KDF_HKDF *)vctx;117118if (ctx != NULL) {119kdf_hkdf_reset(ctx);120OPENSSL_free(ctx);121}122}123124static void kdf_hkdf_reset(void *vctx)125{126KDF_HKDF *ctx = (KDF_HKDF *)vctx;127void *provctx = ctx->provctx;128129ossl_prov_digest_reset(&ctx->digest);130#ifdef OPENSSL_PEDANTIC_ZEROIZATION131OPENSSL_clear_free(ctx->salt, ctx->salt_len);132#else133OPENSSL_free(ctx->salt);134#endif135OPENSSL_free(ctx->prefix);136OPENSSL_free(ctx->label);137OPENSSL_clear_free(ctx->data, ctx->data_len);138OPENSSL_clear_free(ctx->key, ctx->key_len);139OPENSSL_clear_free(ctx->info, ctx->info_len);140memset(ctx, 0, sizeof(*ctx));141ctx->provctx = provctx;142}143144static void *kdf_hkdf_dup(void *vctx)145{146const KDF_HKDF *src = (const KDF_HKDF *)vctx;147KDF_HKDF *dest;148149dest = kdf_hkdf_new(src->provctx);150if (dest != NULL) {151if (!ossl_prov_memdup(src->salt, src->salt_len, &dest->salt,152&dest->salt_len)153|| !ossl_prov_memdup(src->key, src->key_len,154&dest->key , &dest->key_len)155|| !ossl_prov_memdup(src->prefix, src->prefix_len,156&dest->prefix, &dest->prefix_len)157|| !ossl_prov_memdup(src->label, src->label_len,158&dest->label, &dest->label_len)159|| !ossl_prov_memdup(src->data, src->data_len,160&dest->data, &dest->data_len)161|| !ossl_prov_memdup(src->info, src->info_len,162&dest->info, &dest->info_len)163|| !ossl_prov_digest_copy(&dest->digest, &src->digest))164goto err;165dest->mode = src->mode;166OSSL_FIPS_IND_COPY(dest, src)167}168return dest;169170err:171kdf_hkdf_free(dest);172return NULL;173}174175static size_t kdf_hkdf_size(KDF_HKDF *ctx)176{177int sz;178const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);179180if (ctx->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY)181return SIZE_MAX;182183if (md == NULL) {184ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);185return 0;186}187sz = EVP_MD_get_size(md);188if (sz <= 0)189return 0;190191return sz;192}193194#ifdef FIPS_MODULE195static int fips_hkdf_key_check_passed(KDF_HKDF *ctx)196{197OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);198int key_approved = ossl_kdf_check_key_size(ctx->key_len);199200if (!key_approved) {201if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,202libctx, "HKDF", "Key size",203ossl_fips_config_hkdf_key_check)) {204ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);205return 0;206}207}208return 1;209}210#endif211212static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,213const OSSL_PARAM params[])214{215KDF_HKDF *ctx = (KDF_HKDF *)vctx;216OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);217const EVP_MD *md;218219if (!ossl_prov_is_running() || !kdf_hkdf_set_ctx_params(ctx, params))220return 0;221222md = ossl_prov_digest_md(&ctx->digest);223if (md == NULL) {224ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);225return 0;226}227if (ctx->key == NULL) {228ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);229return 0;230}231if (keylen == 0) {232ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);233return 0;234}235236switch (ctx->mode) {237case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:238default:239return HKDF(libctx, md, ctx->salt, ctx->salt_len,240ctx->key, ctx->key_len, ctx->info, ctx->info_len, key, keylen);241242case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:243return HKDF_Extract(libctx, md, ctx->salt, ctx->salt_len,244ctx->key, ctx->key_len, key, keylen);245246case EVP_KDF_HKDF_MODE_EXPAND_ONLY:247return HKDF_Expand(md, ctx->key, ctx->key_len, ctx->info,248ctx->info_len, key, keylen);249}250}251252static int hkdf_common_set_ctx_params(KDF_HKDF *ctx, const OSSL_PARAM params[])253{254OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);255const OSSL_PARAM *p;256int n;257258if (ossl_param_is_empty(params))259return 1;260261if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {262const EVP_MD *md = NULL;263264if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))265return 0;266267md = ossl_prov_digest_md(&ctx->digest);268if (EVP_MD_xof(md)) {269ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);270return 0;271}272}273274if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL) {275if (p->data_type == OSSL_PARAM_UTF8_STRING) {276if (OPENSSL_strcasecmp(p->data, "EXTRACT_AND_EXPAND") == 0) {277ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND;278} else if (OPENSSL_strcasecmp(p->data, "EXTRACT_ONLY") == 0) {279ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;280} else if (OPENSSL_strcasecmp(p->data, "EXPAND_ONLY") == 0) {281ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;282} else {283ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);284return 0;285}286} else if (OSSL_PARAM_get_int(p, &n)) {287if (n != EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND288&& n != EVP_KDF_HKDF_MODE_EXTRACT_ONLY289&& n != EVP_KDF_HKDF_MODE_EXPAND_ONLY) {290ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);291return 0;292}293ctx->mode = n;294} else {295ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);296return 0;297}298}299300if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) {301OPENSSL_clear_free(ctx->key, ctx->key_len);302ctx->key = NULL;303if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->key, 0,304&ctx->key_len))305return 0;306}307308if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {309OPENSSL_free(ctx->salt);310ctx->salt = NULL;311if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,312&ctx->salt_len))313return 0;314}315316return 1;317}318319static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])320{321KDF_HKDF *ctx = vctx;322323if (ossl_param_is_empty(params))324return 1;325326if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,327OSSL_KDF_PARAM_FIPS_KEY_CHECK))328return 0;329330if (!hkdf_common_set_ctx_params(ctx, params))331return 0;332333if (ossl_param_get1_concat_octet_string(params, OSSL_KDF_PARAM_INFO,334&ctx->info, &ctx->info_len,335HKDF_MAXINFO) == 0)336return 0;337338#ifdef FIPS_MODULE339if (OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY) != NULL)340if (!fips_hkdf_key_check_passed(ctx))341return 0;342#endif343344return 1;345}346347static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *ctx,348ossl_unused void *provctx)349{350static const OSSL_PARAM known_settable_ctx_params[] = {351HKDF_COMMON_SETTABLES,352OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),353OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)354OSSL_PARAM_END355};356return known_settable_ctx_params;357}358359static int hkdf_common_get_ctx_params(KDF_HKDF *ctx, OSSL_PARAM params[])360{361OSSL_PARAM *p;362363if (ossl_param_is_empty(params))364return 1;365366if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {367size_t sz = kdf_hkdf_size(ctx);368369if (sz == 0)370return 0;371if (!OSSL_PARAM_set_size_t(p, sz))372return 0;373}374375if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_INFO)) != NULL) {376if (ctx->info == NULL || ctx->info_len == 0)377p->return_size = 0;378else if (!OSSL_PARAM_set_octet_string(p, ctx->info, ctx->info_len))379return 0;380}381382return 1;383}384385static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])386{387KDF_HKDF *ctx = (KDF_HKDF *)vctx;388389if (ossl_param_is_empty(params))390return 1;391392if (!hkdf_common_get_ctx_params(ctx, params))393return 0;394395if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))396return 0;397398return 1;399}400401static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,402ossl_unused void *provctx)403{404static const OSSL_PARAM known_gettable_ctx_params[] = {405HKDF_COMMON_GETTABLES,406OSSL_FIPS_IND_GETTABLE_CTX_PARAM()407OSSL_PARAM_END408};409return known_gettable_ctx_params;410}411412const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = {413{ OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new },414{ OSSL_FUNC_KDF_DUPCTX, (void(*)(void))kdf_hkdf_dup },415{ OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free },416{ OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset },417{ OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_hkdf_derive },418{ OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,419(void(*)(void))kdf_hkdf_settable_ctx_params },420{ OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_hkdf_set_ctx_params },421{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,422(void(*)(void))kdf_hkdf_gettable_ctx_params },423{ OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params },424OSSL_DISPATCH_END425};426427/*428* Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"429* Section 2 (https://tools.ietf.org/html/rfc5869#section-2) and430* "Cryptographic Extraction and Key Derivation: The HKDF Scheme"431* Section 4.2 (https://eprint.iacr.org/2010/264.pdf).432*433* From the paper:434* The scheme HKDF is specified as:435* HKDF(XTS, SKM, CTXinfo, L) = K(1) | K(2) | ... | K(t)436*437* where:438* SKM is source key material439* XTS is extractor salt (which may be null or constant)440* CTXinfo is context information (may be null)441* L is the number of key bits to be produced by KDF442* k is the output length in bits of the hash function used with HMAC443* t = ceil(L/k)444* the value K(t) is truncated to its first d = L mod k bits.445*446* From RFC 5869:447* 2.2. Step 1: Extract448* HKDF-Extract(salt, IKM) -> PRK449* 2.3. Step 2: Expand450* HKDF-Expand(PRK, info, L) -> OKM451*/452static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,453const unsigned char *salt, size_t salt_len,454const unsigned char *ikm, size_t ikm_len,455const unsigned char *info, size_t info_len,456unsigned char *okm, size_t okm_len)457{458unsigned char prk[EVP_MAX_MD_SIZE];459int ret, sz;460size_t prk_len;461462sz = EVP_MD_get_size(evp_md);463if (sz <= 0)464return 0;465prk_len = (size_t)sz;466467/* Step 1: HKDF-Extract(salt, IKM) -> PRK */468if (!HKDF_Extract(libctx, evp_md,469salt, salt_len, ikm, ikm_len, prk, prk_len))470return 0;471472/* Step 2: HKDF-Expand(PRK, info, L) -> OKM */473ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);474OPENSSL_cleanse(prk, sizeof(prk));475476return ret;477}478479/*480* Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"481* Section 2.2 (https://tools.ietf.org/html/rfc5869#section-2.2).482*483* 2.2. Step 1: Extract484*485* HKDF-Extract(salt, IKM) -> PRK486*487* Options:488* Hash a hash function; HashLen denotes the length of the489* hash function output in octets490*491* Inputs:492* salt optional salt value (a non-secret random value);493* if not provided, it is set to a string of HashLen zeros.494* IKM input keying material495*496* Output:497* PRK a pseudorandom key (of HashLen octets)498*499* The output PRK is calculated as follows:500*501* PRK = HMAC-Hash(salt, IKM)502*/503static int HKDF_Extract(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,504const unsigned char *salt, size_t salt_len,505const unsigned char *ikm, size_t ikm_len,506unsigned char *prk, size_t prk_len)507{508int sz = EVP_MD_get_size(evp_md);509510if (sz <= 0)511return 0;512if (prk_len != (size_t)sz) {513ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE);514return 0;515}516/* calc: PRK = HMAC-Hash(salt, IKM) */517return518EVP_Q_mac(libctx, "HMAC", NULL, EVP_MD_get0_name(evp_md), NULL, salt,519salt_len, ikm, ikm_len, prk, EVP_MD_get_size(evp_md), NULL)520!= NULL;521}522523/*524* Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"525* Section 2.3 (https://tools.ietf.org/html/rfc5869#section-2.3).526*527* 2.3. Step 2: Expand528*529* HKDF-Expand(PRK, info, L) -> OKM530*531* Options:532* Hash a hash function; HashLen denotes the length of the533* hash function output in octets534*535* Inputs:536* PRK a pseudorandom key of at least HashLen octets537* (usually, the output from the extract step)538* info optional context and application specific information539* (can be a zero-length string)540* L length of output keying material in octets541* (<= 255*HashLen)542*543* Output:544* OKM output keying material (of L octets)545*546* The output OKM is calculated as follows:547*548* N = ceil(L/HashLen)549* T = T(1) | T(2) | T(3) | ... | T(N)550* OKM = first L octets of T551*552* where:553* T(0) = empty string (zero length)554* T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)555* T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)556* T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)557* ...558*559* (where the constant concatenated to the end of each T(n) is a560* single octet.)561*/562static int HKDF_Expand(const EVP_MD *evp_md,563const unsigned char *prk, size_t prk_len,564const unsigned char *info, size_t info_len,565unsigned char *okm, size_t okm_len)566{567HMAC_CTX *hmac;568int ret = 0, sz;569unsigned int i;570unsigned char prev[EVP_MAX_MD_SIZE];571size_t done_len = 0, dig_len, n;572573sz = EVP_MD_get_size(evp_md);574if (sz <= 0)575return 0;576dig_len = (size_t)sz;577578/* calc: N = ceil(L/HashLen) */579n = okm_len / dig_len;580if (okm_len % dig_len)581n++;582583if (n > 255 || okm == NULL)584return 0;585586if ((hmac = HMAC_CTX_new()) == NULL)587return 0;588589if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))590goto err;591592for (i = 1; i <= n; i++) {593size_t copy_len;594const unsigned char ctr = i;595596/* calc: T(i) = HMAC-Hash(PRK, T(i - 1) | info | i) */597if (i > 1) {598if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))599goto err;600601if (!HMAC_Update(hmac, prev, dig_len))602goto err;603}604605if (!HMAC_Update(hmac, info, info_len))606goto err;607608if (!HMAC_Update(hmac, &ctr, 1))609goto err;610611if (!HMAC_Final(hmac, prev, NULL))612goto err;613614copy_len = (dig_len > okm_len - done_len) ?615okm_len - done_len :616dig_len;617618memcpy(okm + done_len, prev, copy_len);619620done_len += copy_len;621}622ret = 1;623624err:625OPENSSL_cleanse(prev, sizeof(prev));626HMAC_CTX_free(hmac);627return ret;628}629630/*631* TLS uses slight variations of the above and for FIPS validation purposes,632* they need to be present here.633* Refer to RFC 8446 section 7 for specific details.634*/635636/*637* Given a |secret|; a |label| of length |labellen|; and |data| of length638* |datalen| (e.g. typically a hash of the handshake messages), derive a new639* secret |outlen| bytes long and store it in the location pointed to be |out|.640* The |data| value may be zero length. Returns 1 on success and 0 on failure.641*/642static int prov_tls13_hkdf_expand(const EVP_MD *md,643const unsigned char *key, size_t keylen,644const unsigned char *prefix, size_t prefixlen,645const unsigned char *label, size_t labellen,646const unsigned char *data, size_t datalen,647unsigned char *out, size_t outlen)648{649size_t hkdflabellen;650unsigned char hkdflabel[HKDF_MAXBUF];651WPACKET pkt;652653/*654* 2 bytes for length of derived secret + 1 byte for length of combined655* prefix and label + bytes for the label itself + 1 byte length of hash656* + bytes for the hash itself. We've got the maximum the KDF can handle657* which should always be sufficient.658*/659if (!WPACKET_init_static_len(&pkt, hkdflabel, sizeof(hkdflabel), 0)660|| !WPACKET_put_bytes_u16(&pkt, outlen)661|| !WPACKET_start_sub_packet_u8(&pkt)662|| !WPACKET_memcpy(&pkt, prefix, prefixlen)663|| !WPACKET_memcpy(&pkt, label, labellen)664|| !WPACKET_close(&pkt)665|| !WPACKET_sub_memcpy_u8(&pkt, data, (data == NULL) ? 0 : datalen)666|| !WPACKET_get_total_written(&pkt, &hkdflabellen)667|| !WPACKET_finish(&pkt)) {668WPACKET_cleanup(&pkt);669return 0;670}671672return HKDF_Expand(md, key, keylen, hkdflabel, hkdflabellen,673out, outlen);674}675676static int prov_tls13_hkdf_generate_secret(OSSL_LIB_CTX *libctx,677const EVP_MD *md,678const unsigned char *prevsecret,679size_t prevsecretlen,680const unsigned char *insecret,681size_t insecretlen,682const unsigned char *prefix,683size_t prefixlen,684const unsigned char *label,685size_t labellen,686unsigned char *out, size_t outlen)687{688size_t mdlen;689int ret;690unsigned char preextractsec[EVP_MAX_MD_SIZE];691/* Always filled with zeros */692static const unsigned char default_zeros[EVP_MAX_MD_SIZE];693694ret = EVP_MD_get_size(md);695/* Ensure cast to size_t is safe */696if (ret <= 0)697return 0;698mdlen = (size_t)ret;699700if (insecret == NULL) {701insecret = default_zeros;702insecretlen = mdlen;703}704if (prevsecret == NULL) {705prevsecret = default_zeros;706prevsecretlen = mdlen;707} else {708EVP_MD_CTX *mctx = EVP_MD_CTX_new();709unsigned char hash[EVP_MAX_MD_SIZE];710711/* The pre-extract derive step uses a hash of no messages */712if (mctx == NULL713|| EVP_DigestInit_ex(mctx, md, NULL) <= 0714|| EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) {715EVP_MD_CTX_free(mctx);716return 0;717}718EVP_MD_CTX_free(mctx);719720/* Generate the pre-extract secret */721if (!prov_tls13_hkdf_expand(md, prevsecret, prevsecretlen,722prefix, prefixlen, label, labellen,723hash, mdlen, preextractsec, mdlen))724return 0;725prevsecret = preextractsec;726prevsecretlen = mdlen;727}728729ret = HKDF_Extract(libctx, md, prevsecret, prevsecretlen,730insecret, insecretlen, out, outlen);731732if (prevsecret == preextractsec)733OPENSSL_cleanse(preextractsec, mdlen);734return ret;735}736737#ifdef FIPS_MODULE738static int fips_tls1_3_digest_check_passed(KDF_HKDF *ctx, const EVP_MD *md)739{740OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);741/*742* Perform digest check743*744* According to RFC 8446 appendix B.4, the valid hash functions are745* specified in FIPS 180-4. However, it only lists SHA2-256 and SHA2-384 in746* the table. ACVP also only lists the same set of hash functions.747*/748int digest_unapproved = !EVP_MD_is_a(md, SN_sha256)749&& !EVP_MD_is_a(md, SN_sha384);750751if (digest_unapproved) {752if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,753libctx, "TLS13 KDF", "Digest",754ossl_fips_config_tls13_kdf_digest_check)) {755ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);756return 0;757}758}759return 1;760}761762/*763* Calculate the correct length of the secret key.764*765* RFC 8446:766* If a given secret is not available, then the 0-value consisting of a767* string of Hash.length bytes set to zeros is used.768*/769static size_t fips_tls1_3_key_size(KDF_HKDF *ctx)770{771const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);772size_t key_size = 0;773774if (ctx->key != NULL)775key_size = ctx->key_len;776else if (md != NULL)777key_size = EVP_MD_size(md);778779return key_size;780}781782static int fips_tls1_3_key_check_passed(KDF_HKDF *ctx)783{784OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);785int key_approved = ossl_kdf_check_key_size(fips_tls1_3_key_size(ctx));786787if (!key_approved) {788if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,789libctx, "TLS13 KDF", "Key size",790ossl_fips_config_tls13_kdf_key_check)) {791ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);792return 0;793}794}795return 1;796}797#endif798799static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen,800const OSSL_PARAM params[])801{802KDF_HKDF *ctx = (KDF_HKDF *)vctx;803const EVP_MD *md;804805if (!ossl_prov_is_running() || !kdf_tls1_3_set_ctx_params(ctx, params))806return 0;807808md = ossl_prov_digest_md(&ctx->digest);809if (md == NULL) {810ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);811return 0;812}813814switch (ctx->mode) {815default:816return 0;817818case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:819return prov_tls13_hkdf_generate_secret(PROV_LIBCTX_OF(ctx->provctx),820md,821ctx->salt, ctx->salt_len,822ctx->key, ctx->key_len,823ctx->prefix, ctx->prefix_len,824ctx->label, ctx->label_len,825key, keylen);826827case EVP_KDF_HKDF_MODE_EXPAND_ONLY:828return prov_tls13_hkdf_expand(md, ctx->key, ctx->key_len,829ctx->prefix, ctx->prefix_len,830ctx->label, ctx->label_len,831ctx->data, ctx->data_len,832key, keylen);833}834}835836static int kdf_tls1_3_set_ctx_params(void *vctx, const OSSL_PARAM params[])837{838const OSSL_PARAM *p;839KDF_HKDF *ctx = vctx;840841if (ossl_param_is_empty(params))842return 1;843844if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,845OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))846return 0;847if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,848OSSL_KDF_PARAM_FIPS_KEY_CHECK))849return 0;850851if (!hkdf_common_set_ctx_params(ctx, params))852return 0;853854if (ctx->mode == EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND) {855ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);856return 0;857}858859if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PREFIX)) != NULL) {860OPENSSL_free(ctx->prefix);861ctx->prefix = NULL;862if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->prefix, 0,863&ctx->prefix_len))864return 0;865}866867if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_LABEL)) != NULL) {868OPENSSL_free(ctx->label);869ctx->label = NULL;870if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->label, 0,871&ctx->label_len))872return 0;873}874875OPENSSL_clear_free(ctx->data, ctx->data_len);876ctx->data = NULL;877if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DATA)) != NULL878&& !OSSL_PARAM_get_octet_string(p, (void **)&ctx->data, 0,879&ctx->data_len))880return 0;881882#ifdef FIPS_MODULE883if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {884const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);885886if (!fips_tls1_3_digest_check_passed(ctx, md))887return 0;888}889890if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)891if (!fips_tls1_3_key_check_passed(ctx))892return 0;893#endif894895return 1;896}897898static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx,899ossl_unused void *provctx)900{901static const OSSL_PARAM known_settable_ctx_params[] = {902HKDF_COMMON_SETTABLES,903OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PREFIX, NULL, 0),904OSSL_PARAM_octet_string(OSSL_KDF_PARAM_LABEL, NULL, 0),905OSSL_PARAM_octet_string(OSSL_KDF_PARAM_DATA, NULL, 0),906OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)907OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)908OSSL_PARAM_END909};910return known_settable_ctx_params;911}912913static int kdf_tls1_3_get_ctx_params(void *vctx, OSSL_PARAM params[])914{915KDF_HKDF *ctx = (KDF_HKDF *)vctx;916917if (ossl_param_is_empty(params))918return 1;919920if (!hkdf_common_get_ctx_params(ctx, params))921return 0;922923if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))924return 0;925926return 1;927}928929static const OSSL_PARAM *kdf_tls1_3_gettable_ctx_params(ossl_unused void *ctx,930ossl_unused void *provctx)931{932static const OSSL_PARAM known_gettable_ctx_params[] = {933HKDF_COMMON_GETTABLES,934OSSL_FIPS_IND_GETTABLE_CTX_PARAM()935OSSL_PARAM_END936};937return known_gettable_ctx_params;938}939940const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = {941{ OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new },942{ OSSL_FUNC_KDF_DUPCTX, (void(*)(void))kdf_hkdf_dup },943{ OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free },944{ OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset },945{ OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_tls1_3_derive },946{ OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,947(void(*)(void))kdf_tls1_3_settable_ctx_params },948{ OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_tls1_3_set_ctx_params },949{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,950(void(*)(void))kdf_tls1_3_gettable_ctx_params },951{ OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_tls1_3_get_ctx_params },952OSSL_DISPATCH_END953};954955956