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 <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/28461)
This commit is contained in:
Neil Horman 2025-09-09 09:47:34 -04:00 committed by Pauli
parent d7104f0f93
commit 9831200edf
5 changed files with 60 additions and 8 deletions

View File

@ -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;

View File

@ -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;

View File

@ -19,6 +19,7 @@
#include "../ssl_local.h"
#include "statem_local.h"
#include <openssl/ocsp.h>
#include <openssl/core_names.h>
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) {

View File

@ -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);

View File

@ -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;