Commit 130b9414ad for openssl.org

commit 130b9414ad3000db6b8b4c3a7a468c8feff7e2bd
Author: Pauli <paul.dale@oracle.com>
Date:   Tue Sep 1 15:34:05 2026 +1000

    ssl: use generated parsers for TLS capabilities

    Replace repeated OSSL_PARAM lookups for provider TLS groups and signature algorithms with generated trie decoders.

    Assisted-by: ChatGPT:gpt-5.6Sol
    Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
    Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
    Merge-date: Fri Oct  2 08:01:02 2026
    Merged-from: https://github.com/openssl/openssl/pull/32621

diff --git a/.gitignore b/.gitignore
index 31efbf2b67..a929da336a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -98,6 +98,7 @@ providers/common/include/prov/der_sm2.h
 providers/common/include/prov/der_ml_dsa.h
 providers/common/include/prov/der_hkdf.h
 providers/fips/fipsparams.inc
+ssl/t1_lib.inc
 providers/implementations/asymciphers/rsa_enc.inc
 providers/implementations/asymciphers/sm2_enc.inc
 providers/implementations/exchange/dh_exch.inc
diff --git a/build.info b/build.info
index 710c47a2b3..a58317cf89 100644
--- a/build.info
+++ b/build.info
@@ -80,6 +80,7 @@ DEPEND[]=include/openssl/asn1.h \
          include/crypto/dso_conf.h \
          include/crypto/ec_params.h \
          include/crypto/rsa_params.h \
+         ssl/t1_lib.inc \
          providers/implementations/asymciphers/rsa_enc.inc \
          providers/implementations/asymciphers/sm2_enc.inc \
          providers/implementations/exchange/dh_exch.inc \
@@ -221,7 +222,8 @@ GENERATE[include/openssl/x509_acert.h]=include/openssl/x509_acert.h.in
 GENERATE[include/openssl/x509_vfy.h]=include/openssl/x509_vfy.h.in
 GENERATE[include/crypto/dso_conf.h]=include/crypto/dso_conf.h.in

-DEPEND[providers/implementations/asymciphers/rsa_enc.inc \
+DEPEND[ssl/t1_lib.inc \
+       providers/implementations/asymciphers/rsa_enc.inc \
        providers/implementations/asymciphers/sm2_enc.inc \
        providers/implementations/exchange/dh_exch.inc \
        providers/implementations/exchange/ecdh_exch.inc \
@@ -330,6 +332,7 @@ GENERATE[include/crypto/ec_params.h]=\
     include/crypto/ec_params.h.in
 GENERATE[include/crypto/rsa_params.h]=\
     include/crypto/rsa_params.h.in
+GENERATE[ssl/t1_lib.inc]=ssl/t1_lib.inc.in
 GENERATE[providers/implementations/asymciphers/rsa_enc.inc]=\
     providers/implementations/asymciphers/rsa_enc.inc.in
 GENERATE[providers/implementations/asymciphers/sm2_enc.inc]=\
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index dacc0169fe..04d8ecb97b 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -28,6 +28,7 @@
 #include "ssl_local.h"
 #include "quic/quic_local.h"
 #include <openssl/ct.h>
+#include "ssl/t1_lib.inc"

 #define MAX_SIGALGS 128

@@ -233,6 +234,7 @@ static OSSL_CALLBACK add_provider_groups;
 static int add_provider_groups(const OSSL_PARAM params[], void *data)
 {
     struct provider_ctx_data_st *pgd = data;
+    struct tls_group_params_st prms;
     SSL_CTX *ctx = pgd->ctx;
     const OSSL_PARAM *p;
     TLS_GROUP_INFO *ginf = NULL;
@@ -241,6 +243,9 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
     unsigned int is_kem = 0;
     int ret = 0;

+    if (!tls_group_params_decoder(params, &prms))
+        return 0;
+
     if (ctx->group_list_max_len == ctx->group_list_len) {
         TLS_GROUP_INFO *tmp = NULL;

@@ -263,7 +268,7 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)

     ginf = &ctx->group_list[ctx->group_list_len];

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME);
+    p = prms.name;
     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
@@ -272,7 +277,7 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
     if (ginf->tlsname == NULL)
         goto err;

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL);
+    p = prms.internal;
     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
@@ -281,14 +286,14 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
     if (ginf->realname == NULL)
         goto err;

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ID);
+    p = prms.id;
     if (p == NULL || !OSSL_PARAM_get_uint(p, &gid) || gid > UINT16_MAX) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
     }
     ginf->group_id = (uint16_t)gid;

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ALG);
+    p = prms.alg;
     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
@@ -297,38 +302,38 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
     if (ginf->algorithm == NULL)
         goto err;

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS);
+    p = prms.secbits;
     if (p == NULL || !OSSL_PARAM_get_uint(p, &ginf->secbits)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_IS_KEM);
+    p = prms.is_kem;
     if (p != NULL && (!OSSL_PARAM_get_uint(p, &is_kem) || is_kem > 1)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
     }
     ginf->is_kem = 1 & is_kem;

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_TLS);
+    p = prms.min_tls;
     if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mintls)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_TLS);
+    p = prms.max_tls;
     if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxtls)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS);
+    p = prms.min_dtls;
     if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mindtls)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS);
+    p = prms.max_dtls;
     if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxdtls)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
@@ -400,6 +405,7 @@ static OSSL_CALLBACK add_provider_sigalgs;
 static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
 {
     struct provider_ctx_data_st *pgd = data;
+    struct tls_sigalg_params_st prms;
     SSL_CTX *ctx = pgd->ctx;
     OSSL_PROVIDER *provider = pgd->provider;
     const OSSL_PARAM *p;
@@ -409,6 +415,9 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
     unsigned int code_point = 0;
     int ret = 0;

+    if (!tls_sigalg_params_decoder(params, &prms))
+        return 0;
+
     if (ctx->sigalg_list_max_len == ctx->sigalg_list_len) {
         TLS_SIGALG_INFO *tmp = NULL;

@@ -431,7 +440,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
     sinf = &ctx->sigalg_list[ctx->sigalg_list_len];

     /* First, mandatory parameters */
-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_NAME);
+    p = prms.name;
     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
@@ -441,7 +450,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
     if (sinf->sigalg_name == NULL)
         goto err;

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME);
+    p = prms.iana_name;
     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
@@ -451,8 +460,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
     if (sinf->name == NULL)
         goto err;

-    p = OSSL_PARAM_locate_const(params,
-        OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT);
+    p = prms.code_point;
     if (p == NULL
         || !OSSL_PARAM_get_uint(p, &code_point)
         || code_point > UINT16_MAX) {
@@ -461,15 +469,14 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
     }
     sinf->code_point = (uint16_t)code_point;

-    p = OSSL_PARAM_locate_const(params,
-        OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS);
+    p = prms.secbits;
     if (p == NULL || !OSSL_PARAM_get_uint(p, &sinf->secbits)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
     }

     /* Now, optional parameters */
-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_OID);
+    p = prms.oid;
     if (p == NULL) {
         sinf->sigalg_oid = NULL;
     } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -481,7 +488,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
             goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME);
+    p = prms.sig_name;
     if (p == NULL) {
         sinf->sig_name = NULL;
     } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -493,7 +500,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
             goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_SIG_OID);
+    p = prms.sig_oid;
     if (p == NULL) {
         sinf->sig_oid = NULL;
     } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -505,7 +512,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
             goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME);
+    p = prms.hash_name;
     if (p == NULL) {
         sinf->hash_name = NULL;
     } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -517,7 +524,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
             goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_HASH_OID);
+    p = prms.hash_oid;
     if (p == NULL) {
         sinf->hash_oid = NULL;
     } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -529,7 +536,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
             goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE);
+    p = prms.keytype;
     if (p == NULL) {
         sinf->keytype = NULL;
     } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -541,7 +548,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
             goto err;
     }

-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID);
+    p = prms.keytype_oid;
     if (p == NULL) {
         sinf->keytype_oid = NULL;
     } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -555,12 +562,12 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)

     /* Optional, not documented prior to 3.5 */
     sinf->mindtls = sinf->maxdtls = -1;
-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS);
+    p = prms.min_dtls;
     if (p != NULL && !OSSL_PARAM_get_int(p, &sinf->mindtls)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
     }
-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS);
+    p = prms.max_dtls;
     if (p != NULL && !OSSL_PARAM_get_int(p, &sinf->maxdtls)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
@@ -572,12 +579,12 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
     }

     /* The remaining parameters below are mandatory again */
-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS);
+    p = prms.min_tls;
     if (p == NULL || !OSSL_PARAM_get_int(p, &sinf->mintls)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
     }
-    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS);
+    p = prms.max_tls;
     if (p == NULL || !OSSL_PARAM_get_int(p, &sinf->maxtls)) {
         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
         goto err;
diff --git a/ssl/t1_lib.inc.in b/ssl/t1_lib.inc.in
new file mode 100644
index 0000000000..bde00d638e
--- /dev/null
+++ b/ssl/t1_lib.inc.in
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+
+sub produce_ssl_param_decoder {
+    my $decoder = produce_param_decoder(@_);
+
+    # Remove the unavailable header inclusion.
+    $decoder =~ s|#include "prov/proverr.h"||;
+    return $decoder;
+}
+-}
+
+/*
+ * There is no need to produce a list of gettables/settables because libssl
+ * doesn't support these query functions.
+ */
+#define tls_group_params_list
+#define tls_sigalg_params_list
+
+{- produce_ssl_param_decoder('tls_group_params',
+                         (['OSSL_CAPABILITY_TLS_GROUP_NAME',          'name',     'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL', 'internal', 'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_GROUP_ID',            'id',       'uint',        'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_GROUP_ALG',           'alg',      'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS', 'secbits',  'uint',        'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_GROUP_IS_KEM',        'is_kem',   'uint',        'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_GROUP_MIN_TLS',       'min_tls',  'int',         'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_GROUP_MAX_TLS',       'max_tls',  'int',         'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS',      'min_dtls', 'int',         'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS',      'max_dtls', 'int',         'duplicate: first'],
+                         )); -}
+
+{- produce_ssl_param_decoder('tls_sigalg_params',
+                         (['OSSL_CAPABILITY_TLS_SIGALG_NAME',        'name',        'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME',   'iana_name',   'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT',  'code_point',  'uint',        'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS', 'secbits',   'uint',        'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_OID',         'oid',         'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME',    'sig_name',    'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_SIG_OID',     'sig_oid',     'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME',   'hash_name',   'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_HASH_OID',    'hash_oid',    'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE',     'keytype',     'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID', 'keytype_oid', 'utf8_string', 'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS',    'min_dtls',    'int',         'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS',    'max_dtls',    'int',         'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS',     'min_tls',     'int',         'duplicate: first'],
+                          ['OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS',     'max_tls',     'int',         'duplicate: first'],
+                         )); -}