From: Neil Horman Date: Tue, 9 Sep 2025 13:47:34 +0000 (-0400) Subject: support passing prop querys to composite algs X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9831200edfe71ad676799a06673d80e6ea3990e2;p=thirdparty%2Fopenssl.git support passing prop querys to composite algs We have several composite alg usages (i.e. MAC/KDF) which pick the right digest implementation when using an engine, but fail to get the right one when using a provider because we don't pass the propquery in a parameter to their instantiation. Fix them up by constructing the appropriate parameters Reviewed-by: Matt Caswell Reviewed-by: Shane Lontis Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/28461) --- diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c index 58ddf76151d..2a7fa120430 100644 --- a/crypto/evp/mac_lib.c +++ b/crypto/evp/mac_lib.c @@ -259,8 +259,9 @@ unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, unsigned char *out, size_t outsize, size_t *outlen) { EVP_MAC *mac = EVP_MAC_fetch(libctx, name, propq); - OSSL_PARAM subalg_param[] = { OSSL_PARAM_END, OSSL_PARAM_END }; - EVP_MAC_CTX *ctx = NULL; + OSSL_PARAM subalg_param[3]; + OSSL_PARAM *p = subalg_param; + EVP_MAC_CTX *ctx = NULL; size_t len = 0; unsigned char *res = NULL; @@ -284,9 +285,26 @@ unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, goto err; } } - subalg_param[0] = - OSSL_PARAM_construct_utf8_string(param_name, (char *)subalg, 0); + *p++ = OSSL_PARAM_construct_utf8_string(param_name, (char *)subalg, 0); } + + /* + * If we passed in a property query, make sure the underlying algorithm uses it. + * Compound algorithms may fetch other underlying algorithms (i.e. a MAC algorithm + * may use a digest algorithm as part of its internal work), and the MAC decides which + * implementation of the underlying digest to use based on the + * OSSL_ALG_PARAM_PROPERTIES parameter, rather than the propq value passed in the + * EVP_MAC_fetch call above. + * If we don't set this parameter, then the MAC alg may use the default provider + * to allocate an underlying digest, rather than the one that we would have gotten + * by using the propq value here. + */ + if (propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_PROPERTIES, + (char *)propq, 0); + + *p = OSSL_PARAM_construct_end(); + /* Single-shot - on NULL key input, set dummy key value for EVP_MAC_Init. */ if (key == NULL && keylen == 0) key = data; diff --git a/ssl/record/methods/tls1_meth.c b/ssl/record/methods/tls1_meth.c index f369d9246de..ac31d359c91 100644 --- a/ssl/record/methods/tls1_meth.c +++ b/ssl/record/methods/tls1_meth.c @@ -28,6 +28,7 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, { EVP_CIPHER_CTX *ciph_ctx; EVP_PKEY *mac_key; + OSSL_PARAM params[3], *p = params; int enc = (rl->direction == OSSL_RECORD_DIRECTION_WRITE) ? 1 : 0; if (level != OSSL_RECORD_PROTECTION_LEVEL_APPLICATION) @@ -73,10 +74,24 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, mac_key = EVP_PKEY_new_mac_key(mactype, NULL, mackey, (int)mackeylen); } + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + (char *)EVP_MD_get0_name(md), 0); + + /* + * We want the underlying mac to use our passed property query when allocating + * its internal digest as well + */ + if (rl->propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES, + (char *)rl->propq, 0); + + *p = OSSL_PARAM_construct_end(); + if (mac_key == NULL || EVP_DigestSignInit_ex(rl->md_ctx, NULL, EVP_MD_get0_name(md), rl->libctx, rl->propq, mac_key, - NULL) <= 0) { + params) <= 0) { EVP_PKEY_free(mac_key); ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return OSSL_RECORD_RETURN_FATAL; diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index b3158dfd77c..d637e06d538 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -19,6 +19,7 @@ #include "../ssl_local.h" #include "statem_local.h" #include +#include static int final_renegotiate(SSL_CONNECTION *s, unsigned int context, int sent); static int init_server_name(SSL_CONNECTION *s, unsigned int context); @@ -1536,6 +1537,7 @@ int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md, int ret = -1; int usepskfored = 0; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + OSSL_PARAM params[3] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; /* Ensure cast to size_t is safe */ if (!ossl_assert(hashsizei > 0)) { @@ -1666,9 +1668,15 @@ int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md, if (!sign) binderout = tmpbinder; + if (sctx->propq != NULL) { + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + (char *)EVP_MD_get0_name(md), 0); + params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES, + (char *)sctx->propq, 0); + } bindersize = hashsize; if (EVP_DigestSignInit_ex(mctx, NULL, EVP_MD_get0_name(md), sctx->libctx, - sctx->propq, mackey, NULL) <= 0 + sctx->propq, mackey, params) <= 0 || EVP_DigestSignUpdate(mctx, hash, hashsize) <= 0 || EVP_DigestSignFinal(mctx, binderout, &bindersize) <= 0 || bindersize != hashsize) { diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index a28a1532f10..a53a8c290f5 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -35,7 +35,7 @@ static int tls1_PRF(SSL_CONNECTION *s, const EVP_MD *md = ssl_prf_md(s); EVP_KDF *kdf; EVP_KDF_CTX *kctx = NULL; - OSSL_PARAM params[8], *p = params; + OSSL_PARAM params[9], *p = params; const char *mdname; if (md == NULL) { @@ -71,6 +71,13 @@ static int tls1_PRF(SSL_CONNECTION *s, (void *)seed4, (size_t)seed4_len); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void *)seed5, (size_t)seed5_len); + /* + * If we have a propery query string, the kdf needs to know about it in the event + * the specific kdf in use allocated a digest as part of its implementation + */ + if (SSL_CONNECTION_GET_CTX(s)->propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_PROPERTIES, + (char *)SSL_CONNECTION_GET_CTX(s)->propq, 0); *p = OSSL_PARAM_construct_end(); if (EVP_KDF_derive(kctx, out, olen, params)) { EVP_KDF_CTX_free(kctx); diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 5953de32330..489fafd5214 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -39,7 +39,7 @@ int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq, { EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_TLS1_3_KDF, propq); EVP_KDF_CTX *kctx; - OSSL_PARAM params[7], *p = params; + OSSL_PARAM params[8], *p = params; int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; const char *mdname = EVP_MD_get0_name(md); int ret; @@ -84,6 +84,10 @@ int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq, *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_DATA, (unsigned char *)data, datalen); + if (propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_PROPERTIES, + (char *)propq, 0); + *p++ = OSSL_PARAM_construct_end(); ret = EVP_KDF_derive(kctx, out, outlen, params) <= 0;