Path: blob/main/crypto/openssl/providers/implementations/kdfs/hkdf.c
106846 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)336== 0)337return 0;338339#ifdef FIPS_MODULE340if (OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY) != NULL)341if (!fips_hkdf_key_check_passed(ctx))342return 0;343#endif344345return 1;346}347348static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *ctx,349ossl_unused void *provctx)350{351static const OSSL_PARAM known_settable_ctx_params[] = {352HKDF_COMMON_SETTABLES,353OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),354OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)355OSSL_PARAM_END356};357return known_settable_ctx_params;358}359360static int hkdf_common_get_ctx_params(KDF_HKDF *ctx, OSSL_PARAM params[])361{362OSSL_PARAM *p;363364if (ossl_param_is_empty(params))365return 1;366367if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {368size_t sz = kdf_hkdf_size(ctx);369370if (sz == 0)371return 0;372if (!OSSL_PARAM_set_size_t(p, sz))373return 0;374}375376if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_INFO)) != NULL) {377if (ctx->info == NULL || ctx->info_len == 0)378p->return_size = 0;379else if (!OSSL_PARAM_set_octet_string(p, ctx->info, ctx->info_len))380return 0;381}382383return 1;384}385386static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])387{388KDF_HKDF *ctx = (KDF_HKDF *)vctx;389390if (ossl_param_is_empty(params))391return 1;392393if (!hkdf_common_get_ctx_params(ctx, params))394return 0;395396if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))397return 0;398399return 1;400}401402static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,403ossl_unused void *provctx)404{405static const OSSL_PARAM known_gettable_ctx_params[] = {406HKDF_COMMON_GETTABLES,407OSSL_FIPS_IND_GETTABLE_CTX_PARAM()408OSSL_PARAM_END409};410return known_gettable_ctx_params;411}412413const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = {414{ OSSL_FUNC_KDF_NEWCTX, (void (*)(void))kdf_hkdf_new },415{ OSSL_FUNC_KDF_DUPCTX, (void (*)(void))kdf_hkdf_dup },416{ OSSL_FUNC_KDF_FREECTX, (void (*)(void))kdf_hkdf_free },417{ OSSL_FUNC_KDF_RESET, (void (*)(void))kdf_hkdf_reset },418{ OSSL_FUNC_KDF_DERIVE, (void (*)(void))kdf_hkdf_derive },419{ OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,420(void (*)(void))kdf_hkdf_settable_ctx_params },421{ OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))kdf_hkdf_set_ctx_params },422{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,423(void (*)(void))kdf_hkdf_gettable_ctx_params },424{ OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))kdf_hkdf_get_ctx_params },425OSSL_DISPATCH_END426};427428/*429* Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"430* Section 2 (https://tools.ietf.org/html/rfc5869#section-2) and431* "Cryptographic Extraction and Key Derivation: The HKDF Scheme"432* Section 4.2 (https://eprint.iacr.org/2010/264.pdf).433*434* From the paper:435* The scheme HKDF is specified as:436* HKDF(XTS, SKM, CTXinfo, L) = K(1) | K(2) | ... | K(t)437*438* where:439* SKM is source key material440* XTS is extractor salt (which may be null or constant)441* CTXinfo is context information (may be null)442* L is the number of key bits to be produced by KDF443* k is the output length in bits of the hash function used with HMAC444* t = ceil(L/k)445* the value K(t) is truncated to its first d = L mod k bits.446*447* From RFC 5869:448* 2.2. Step 1: Extract449* HKDF-Extract(salt, IKM) -> PRK450* 2.3. Step 2: Expand451* HKDF-Expand(PRK, info, L) -> OKM452*/453static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,454const unsigned char *salt, size_t salt_len,455const unsigned char *ikm, size_t ikm_len,456const unsigned char *info, size_t info_len,457unsigned char *okm, size_t okm_len)458{459unsigned char prk[EVP_MAX_MD_SIZE];460int ret, sz;461size_t prk_len;462463sz = EVP_MD_get_size(evp_md);464if (sz <= 0)465return 0;466prk_len = (size_t)sz;467468/* Step 1: HKDF-Extract(salt, IKM) -> PRK */469if (!HKDF_Extract(libctx, evp_md,470salt, salt_len, ikm, ikm_len, prk, prk_len))471return 0;472473/* Step 2: HKDF-Expand(PRK, info, L) -> OKM */474ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);475OPENSSL_cleanse(prk, sizeof(prk));476477return ret;478}479480/*481* Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"482* Section 2.2 (https://tools.ietf.org/html/rfc5869#section-2.2).483*484* 2.2. Step 1: Extract485*486* HKDF-Extract(salt, IKM) -> PRK487*488* Options:489* Hash a hash function; HashLen denotes the length of the490* hash function output in octets491*492* Inputs:493* salt optional salt value (a non-secret random value);494* if not provided, it is set to a string of HashLen zeros.495* IKM input keying material496*497* Output:498* PRK a pseudorandom key (of HashLen octets)499*500* The output PRK is calculated as follows:501*502* PRK = HMAC-Hash(salt, IKM)503*/504static int HKDF_Extract(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,505const unsigned char *salt, size_t salt_len,506const unsigned char *ikm, size_t ikm_len,507unsigned char *prk, size_t prk_len)508{509int sz = EVP_MD_get_size(evp_md);510511if (sz <= 0)512return 0;513if (prk_len != (size_t)sz) {514ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE);515return 0;516}517/* calc: PRK = HMAC-Hash(salt, IKM) */518return EVP_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) ? okm_len - done_len : dig_len;615616memcpy(okm + done_len, prev, copy_len);617618done_len += copy_len;619}620ret = 1;621622err:623OPENSSL_cleanse(prev, sizeof(prev));624HMAC_CTX_free(hmac);625return ret;626}627628/*629* TLS uses slight variations of the above and for FIPS validation purposes,630* they need to be present here.631* Refer to RFC 8446 section 7 for specific details.632*/633634/*635* Given a |secret|; a |label| of length |labellen|; and |data| of length636* |datalen| (e.g. typically a hash of the handshake messages), derive a new637* secret |outlen| bytes long and store it in the location pointed to be |out|.638* The |data| value may be zero length. Returns 1 on success and 0 on failure.639*/640static int prov_tls13_hkdf_expand(const EVP_MD *md,641const unsigned char *key, size_t keylen,642const unsigned char *prefix, size_t prefixlen,643const unsigned char *label, size_t labellen,644const unsigned char *data, size_t datalen,645unsigned char *out, size_t outlen)646{647size_t hkdflabellen;648unsigned char hkdflabel[HKDF_MAXBUF];649WPACKET pkt;650651/*652* 2 bytes for length of derived secret + 1 byte for length of combined653* prefix and label + bytes for the label itself + 1 byte length of hash654* + bytes for the hash itself. We've got the maximum the KDF can handle655* which should always be sufficient.656*/657if (!WPACKET_init_static_len(&pkt, hkdflabel, sizeof(hkdflabel), 0)658|| !WPACKET_put_bytes_u16(&pkt, outlen)659|| !WPACKET_start_sub_packet_u8(&pkt)660|| !WPACKET_memcpy(&pkt, prefix, prefixlen)661|| !WPACKET_memcpy(&pkt, label, labellen)662|| !WPACKET_close(&pkt)663|| !WPACKET_sub_memcpy_u8(&pkt, data, (data == NULL) ? 0 : datalen)664|| !WPACKET_get_total_written(&pkt, &hkdflabellen)665|| !WPACKET_finish(&pkt)) {666WPACKET_cleanup(&pkt);667return 0;668}669670return HKDF_Expand(md, key, keylen, hkdflabel, hkdflabellen,671out, outlen);672}673674static int prov_tls13_hkdf_generate_secret(OSSL_LIB_CTX *libctx,675const EVP_MD *md,676const unsigned char *prevsecret,677size_t prevsecretlen,678const unsigned char *insecret,679size_t insecretlen,680const unsigned char *prefix,681size_t prefixlen,682const unsigned char *label,683size_t labellen,684unsigned char *out, size_t outlen)685{686size_t mdlen;687int ret;688unsigned char preextractsec[EVP_MAX_MD_SIZE];689/* Always filled with zeros */690static const unsigned char default_zeros[EVP_MAX_MD_SIZE];691692ret = EVP_MD_get_size(md);693/* Ensure cast to size_t is safe */694if (ret <= 0)695return 0;696mdlen = (size_t)ret;697698if (insecret == NULL) {699insecret = default_zeros;700insecretlen = mdlen;701}702if (prevsecret == NULL) {703prevsecret = default_zeros;704prevsecretlen = mdlen;705} else {706EVP_MD_CTX *mctx = EVP_MD_CTX_new();707unsigned char hash[EVP_MAX_MD_SIZE];708709/* The pre-extract derive step uses a hash of no messages */710if (mctx == NULL711|| EVP_DigestInit_ex(mctx, md, NULL) <= 0712|| EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) {713EVP_MD_CTX_free(mctx);714return 0;715}716EVP_MD_CTX_free(mctx);717718/* Generate the pre-extract secret */719if (!prov_tls13_hkdf_expand(md, prevsecret, prevsecretlen,720prefix, prefixlen, label, labellen,721hash, mdlen, preextractsec, mdlen))722return 0;723prevsecret = preextractsec;724prevsecretlen = mdlen;725}726727ret = HKDF_Extract(libctx, md, prevsecret, prevsecretlen,728insecret, insecretlen, out, outlen);729730if (prevsecret == preextractsec)731OPENSSL_cleanse(preextractsec, mdlen);732return ret;733}734735#ifdef FIPS_MODULE736static int fips_tls1_3_digest_check_passed(KDF_HKDF *ctx, const EVP_MD *md)737{738OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);739/*740* Perform digest check741*742* According to RFC 8446 appendix B.4, the valid hash functions are743* specified in FIPS 180-4. However, it only lists SHA2-256 and SHA2-384 in744* the table. ACVP also only lists the same set of hash functions.745*/746int digest_unapproved = !EVP_MD_is_a(md, SN_sha256)747&& !EVP_MD_is_a(md, SN_sha384);748749if (digest_unapproved) {750if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,751libctx, "TLS13 KDF", "Digest",752ossl_fips_config_tls13_kdf_digest_check)) {753ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);754return 0;755}756}757return 1;758}759760/*761* Calculate the correct length of the secret key.762*763* RFC 8446:764* If a given secret is not available, then the 0-value consisting of a765* string of Hash.length bytes set to zeros is used.766*/767static size_t fips_tls1_3_key_size(KDF_HKDF *ctx)768{769const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);770size_t key_size = 0;771772if (ctx->key != NULL)773key_size = ctx->key_len;774else if (md != NULL)775key_size = EVP_MD_size(md);776777return key_size;778}779780static int fips_tls1_3_key_check_passed(KDF_HKDF *ctx)781{782OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);783int key_approved = ossl_kdf_check_key_size(fips_tls1_3_key_size(ctx));784785if (!key_approved) {786if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,787libctx, "TLS13 KDF", "Key size",788ossl_fips_config_tls13_kdf_key_check)) {789ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);790return 0;791}792}793return 1;794}795#endif796797static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen,798const OSSL_PARAM params[])799{800KDF_HKDF *ctx = (KDF_HKDF *)vctx;801const EVP_MD *md;802803if (!ossl_prov_is_running() || !kdf_tls1_3_set_ctx_params(ctx, params))804return 0;805806md = ossl_prov_digest_md(&ctx->digest);807if (md == NULL) {808ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);809return 0;810}811812switch (ctx->mode) {813default:814return 0;815816case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:817return prov_tls13_hkdf_generate_secret(PROV_LIBCTX_OF(ctx->provctx),818md,819ctx->salt, ctx->salt_len,820ctx->key, ctx->key_len,821ctx->prefix, ctx->prefix_len,822ctx->label, ctx->label_len,823key, keylen);824825case EVP_KDF_HKDF_MODE_EXPAND_ONLY:826return prov_tls13_hkdf_expand(md, ctx->key, ctx->key_len,827ctx->prefix, ctx->prefix_len,828ctx->label, ctx->label_len,829ctx->data, ctx->data_len,830key, keylen);831}832}833834static int kdf_tls1_3_set_ctx_params(void *vctx, const OSSL_PARAM params[])835{836const OSSL_PARAM *p;837KDF_HKDF *ctx = vctx;838839if (ossl_param_is_empty(params))840return 1;841842if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,843OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))844return 0;845if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,846OSSL_KDF_PARAM_FIPS_KEY_CHECK))847return 0;848849if (!hkdf_common_set_ctx_params(ctx, params))850return 0;851852if (ctx->mode == EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND) {853ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);854return 0;855}856857if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PREFIX)) != NULL) {858OPENSSL_free(ctx->prefix);859ctx->prefix = NULL;860if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->prefix, 0,861&ctx->prefix_len))862return 0;863}864865if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_LABEL)) != NULL) {866OPENSSL_free(ctx->label);867ctx->label = NULL;868if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->label, 0,869&ctx->label_len))870return 0;871}872873OPENSSL_clear_free(ctx->data, ctx->data_len);874ctx->data = NULL;875if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DATA)) != NULL876&& !OSSL_PARAM_get_octet_string(p, (void **)&ctx->data, 0,877&ctx->data_len))878return 0;879880#ifdef FIPS_MODULE881if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {882const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);883884if (!fips_tls1_3_digest_check_passed(ctx, md))885return 0;886}887888if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)889if (!fips_tls1_3_key_check_passed(ctx))890return 0;891#endif892893return 1;894}895896static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx,897ossl_unused void *provctx)898{899static const OSSL_PARAM known_settable_ctx_params[] = {900HKDF_COMMON_SETTABLES,901OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PREFIX, NULL, 0),902OSSL_PARAM_octet_string(OSSL_KDF_PARAM_LABEL, NULL, 0),903OSSL_PARAM_octet_string(OSSL_KDF_PARAM_DATA, NULL, 0),904OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)905OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)906OSSL_PARAM_END907};908return known_settable_ctx_params;909}910911static int kdf_tls1_3_get_ctx_params(void *vctx, OSSL_PARAM params[])912{913KDF_HKDF *ctx = (KDF_HKDF *)vctx;914915if (ossl_param_is_empty(params))916return 1;917918if (!hkdf_common_get_ctx_params(ctx, params))919return 0;920921if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))922return 0;923924return 1;925}926927static const OSSL_PARAM *kdf_tls1_3_gettable_ctx_params(ossl_unused void *ctx,928ossl_unused void *provctx)929{930static const OSSL_PARAM known_gettable_ctx_params[] = {931HKDF_COMMON_GETTABLES,932OSSL_FIPS_IND_GETTABLE_CTX_PARAM()933OSSL_PARAM_END934};935return known_gettable_ctx_params;936}937938const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = {939{ OSSL_FUNC_KDF_NEWCTX, (void (*)(void))kdf_hkdf_new },940{ OSSL_FUNC_KDF_DUPCTX, (void (*)(void))kdf_hkdf_dup },941{ OSSL_FUNC_KDF_FREECTX, (void (*)(void))kdf_hkdf_free },942{ OSSL_FUNC_KDF_RESET, (void (*)(void))kdf_hkdf_reset },943{ OSSL_FUNC_KDF_DERIVE, (void (*)(void))kdf_tls1_3_derive },944{ OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,945(void (*)(void))kdf_tls1_3_settable_ctx_params },946{ OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))kdf_tls1_3_set_ctx_params },947{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,948(void (*)(void))kdf_tls1_3_gettable_ctx_params },949{ OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))kdf_tls1_3_get_ctx_params },950OSSL_DISPATCH_END951};952953954