Commit df8f3cc534 for openssl.org
commit df8f3cc5342b848f8e6e00b866847e67684ce89e
Author: Tomas Mraz <tomas@openssl.org>
Date: Thu Dec 18 11:43:41 2025 +0100
ECH: Properly apply libctx and propq from SSL_CTX
And further minor refactoring.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
MergeDate: Thu Jan 8 09:59:56 2026
(Merged from https://github.com/openssl/openssl/pull/29439)
diff --git a/ssl/ech/ech_internal.c b/ssl/ech/ech_internal.c
index b20aca50c4..366637bab0 100644
--- a/ssl/ech/ech_internal.c
+++ b/ssl/ech/ech_internal.c
@@ -9,12 +9,13 @@
#include <openssl/ssl.h>
#include <openssl/ech.h>
-#include "../ssl_local.h"
-#include "ech_local.h"
#include <openssl/rand.h>
-#include "../statem/statem_local.h"
-#include "internal/ech_helpers.h"
#include <openssl/kdf.h>
+#include "internal/ech_helpers.h"
+#include "internal/ssl_unwrap.h"
+#include "../ssl_local.h"
+#include "../statem/statem_local.h"
+#include "ech_local.h"
#ifndef OPENSSL_NO_ECH
@@ -296,16 +297,11 @@ int ossl_ech_send_grease(SSL_CONNECTION *s, WPACKET *pkt)
size_t cipher_len = 0, cipher_len_jitter = 0;
unsigned char cid, senderpub[OSSL_ECH_MAX_GREASE_PUB];
unsigned char cipher[OSSL_ECH_MAX_GREASE_CT];
+ SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
- if (s == NULL)
- return 0;
- if (s->ssl.ctx == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- return 0;
- }
WPACKET_get_total_written(pkt, &pp_at_start);
/* randomly select cipher_len to be one of 144, 176, 208, 244 */
- if (RAND_bytes_ex(s->ssl.ctx->libctx, &cid, 1, 0) <= 0) {
+ if (RAND_bytes_ex(sctx->libctx, &cid, 1, 0) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -313,7 +309,7 @@ int ossl_ech_send_grease(SSL_CONNECTION *s, WPACKET *pkt)
cipher_len = 144;
cipher_len += 32 * cipher_len_jitter;
/* generate a random (1 octet) client id */
- if (RAND_bytes_ex(s->ssl.ctx->libctx, &cid, 1, 0) <= 0) {
+ if (RAND_bytes_ex(sctx->libctx, &cid, 1, 0) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -329,7 +325,7 @@ int ossl_ech_send_grease(SSL_CONNECTION *s, WPACKET *pkt)
if (OSSL_HPKE_get_grease_value(hpke_suite_in_p, &hpke_suite,
senderpub, &senderpub_len,
cipher, cipher_len,
- s->ssl.ctx->libctx, NULL)
+ sctx->libctx, sctx->propq)
!= 1) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
@@ -1028,6 +1024,7 @@ int ossl_ech_calc_confirm(SSL_CONNECTION *s, int for_hrr,
+ SSL3_RANDOM_SIZE - OSSL_ECH_SIGNAL_LEN;
unsigned int hashlen = 0;
unsigned char hashval[EVP_MAX_MD_SIZE];
+ SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
if ((md = (EVP_MD *)ssl_handshake_md(s)) == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_ECH_REQUIRED);
@@ -1055,7 +1052,7 @@ int ossl_ech_calc_confirm(SSL_CONNECTION *s, int for_hrr,
} else {
if (s->ext.ech.hrrsignal_p == NULL) {
/* No ECH found so we'll exit, but set random output */
- if (RAND_bytes_ex(s->ssl.ctx->libctx, acbuf,
+ if (RAND_bytes_ex(sctx->libctx, acbuf,
OSSL_ECH_SIGNAL_LEN, 0)
<= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_ECH_REQUIRED);
@@ -1747,6 +1744,7 @@ static unsigned char *hpke_decrypt_encch(SSL_CONNECTION *s,
size_t info_len = OSSL_ECH_MAX_INFO_LEN;
int rv = 0;
OSSL_HPKE_CTX *hctx = NULL;
+ SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
#ifdef OSSL_ECH_SUPERVERBOSE
size_t publen = 0;
unsigned char *pub = NULL;
@@ -1800,7 +1798,7 @@ static unsigned char *hpke_decrypt_encch(SSL_CONNECTION *s,
ERR_set_mark();
/* Use OSSL_HPKE_* APIs */
hctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, OSSL_HPKE_ROLE_RECEIVER,
- NULL, NULL);
+ sctx->libctx, sctx->propq);
if (hctx == NULL)
goto clearerrs;
rv = OSSL_HPKE_decap(hctx, senderpub, senderpublen, ee->keyshare,
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index cc0b5d9f34..e323e21cf3 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -1449,7 +1449,7 @@ dopsksess:
return EXT_RETURN_FAIL;
}
/* for outer CH allocate a similar sized random value */
- if (RAND_bytes_ex(s->ssl.ctx->libctx, rndbuf, totalrndsize, 0) <= 0) {
+ if (RAND_bytes_ex(sctx->libctx, rndbuf, totalrndsize, 0) <= 0) {
OPENSSL_free(rndbuf);
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
@@ -2569,6 +2569,7 @@ EXT_RETURN tls_construct_ctos_ech(SSL_CONNECTION *s, WPACKET *pkt,
size_t chainidx)
{
int rv = 0, hpke_mode = OSSL_HPKE_MODE_BASE;
+ SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
OSSL_ECHSTORE_ENTRY *ee = NULL;
OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT;
unsigned char config_id_to_use = 0x00, info[OSSL_ECH_MAX_INFO_LEN];
@@ -2650,7 +2651,7 @@ EXT_RETURN tls_construct_ctos_ech(SSL_CONNECTION *s, WPACKET *pkt,
OSSL_TRACE_END(TLS);
config_id_to_use = ee->config_id; /* if requested, use a random config_id instead */
if ((s->options & SSL_OP_ECH_IGNORE_CID) != 0) {
- if (RAND_bytes_ex(s->ssl.ctx->libctx, &config_id_to_use, 1, 0) <= 0) {
+ if (RAND_bytes_ex(sctx->libctx, &config_id_to_use, 1, 0) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -2691,7 +2692,7 @@ EXT_RETURN tls_construct_ctos_ech(SSL_CONNECTION *s, WPACKET *pkt,
#endif
s->ext.ech.hpke_ctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite,
OSSL_HPKE_ROLE_SENDER,
- NULL, NULL);
+ sctx->libctx, sctx->propq);
if (s->ext.ech.hpke_ctx == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 3535d06483..51159de03f 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -2514,6 +2514,7 @@ EXT_RETURN tls_construct_stoc_ech(SSL_CONNECTION *s, WPACKET *pkt,
{
unsigned char *rcfgs = NULL;
size_t rcfgslen = 0;
+ SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
if (context == SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST
&& (s->ext.ech.success == 1 || s->ext.ech.backend == 1)
@@ -2538,7 +2539,7 @@ EXT_RETURN tls_construct_stoc_ech(SSL_CONNECTION *s, WPACKET *pkt,
&& s->ext.ech.attempted == 1) {
unsigned char randomconf[8];
- if (RAND_bytes_ex(s->ssl.ctx->libctx, randomconf, 8,
+ if (RAND_bytes_ex(sctx->libctx, randomconf, 8,
RAND_DRBG_STRENGTH)
<= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index b65aded0b6..e4d77a0980 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1216,6 +1216,7 @@ __owur CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s,
BUF_MEM *inner_mem = NULL;
PACKET rpkt; /* we'll decode back the inner ch to help make the outer */
SSL_SESSION *sess = NULL;
+ SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
size_t sess_id_len = 0, innerlen = 0;
int mt = SSL3_MT_CLIENT_HELLO, rv = 0;
OSSL_HPKE_SUITE suite;
@@ -1273,7 +1274,7 @@ __owur CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s,
sess_id_len = sizeof(s->tmp_session_id);
s->tmp_session_id_len = sess_id_len;
if (s->hello_retry_request == SSL_HRR_NONE
- && RAND_bytes_ex(s->ssl.ctx->libctx, s->tmp_session_id,
+ && RAND_bytes_ex(sctx->libctx, s->tmp_session_id,
sess_id_len, 0)
<= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);