Commit 19131e16ba for openssl.org

commit 19131e16ba83b31438d0f438425a2ce1c237448e
Author: Pauli <paul.dale@oracle.com>
Date:   Tue Aug 25 12:01:25 2026 +1000

    ec: define generated parameter tries

    Assisted-by: ChatGPT:gpt-5.6Sol

    Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
    Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
    (Merged from https://github.com/openssl/openssl/pull/32502)

diff --git a/.gitignore b/.gitignore
index d9eb14a8bb..450812dbf9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,7 @@
 # Auto generated headers
 /crypto/buildinf.h
 /include/crypto/*_conf.h
+/include/crypto/ec_params.h
 /include/crypto/rsa_params.h
 /include/openssl/asn1.h
 /include/openssl/asn1t.h
diff --git a/build.info b/build.info
index cb30708f5f..79cf495022 100644
--- a/build.info
+++ b/build.info
@@ -45,6 +45,7 @@ DEPEND[]=include/openssl/asn1.h \
          include/openssl/x509_acert.h \
          include/openssl/x509_vfy.h \
          include/crypto/dso_conf.h \
+         include/crypto/ec_params.h \
          include/crypto/rsa_params.h \
          providers/implementations/asymciphers/rsa_enc.inc \
          providers/implementations/asymciphers/sm2_enc.inc \
@@ -263,9 +264,12 @@ DEPEND[providers/implementations/asymciphers/rsa_enc.inc \
        providers/implementations/rands/seed_src.inc \
        providers/implementations/rands/seed_src_jitter.inc \
        providers/implementations/rands/test_rng.inc \
+       include/crypto/ec_params.h \
        include/crypto/rsa_params.h \
        include/openssl/core_names.h]=util/perl|OpenSSL/paramnames.pm

+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[providers/implementations/asymciphers/rsa_enc.inc]=\
diff --git a/include/crypto/ec.h b/include/crypto/ec.h
index 22f614cccd..cb648bcf95 100644
--- a/include/crypto/ec.h
+++ b/include/crypto/ec.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-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
@@ -26,6 +26,55 @@ int evp_pkey_ctx_set_ec_param_enc_prov(EVP_PKEY_CTX *ctx, int param_enc);
 #include <openssl/ec.h>
 #include "crypto/types.h"

+typedef struct ec_params_st {
+    /* Domain parameters */
+    OSSL_PARAM *group_name;
+    OSSL_PARAM *encoding;
+    OSSL_PARAM *pt_format;
+    OSSL_PARAM *field_type;
+    OSSL_PARAM *p;
+    OSSL_PARAM *a;
+    OSSL_PARAM *b;
+    OSSL_PARAM *generator;
+    OSSL_PARAM *order;
+    OSSL_PARAM *cofactor;
+    OSSL_PARAM *seed;
+    OSSL_PARAM *decoded;
+
+    /* Key and other parameters */
+    OSSL_PARAM *pub;
+    OSSL_PARAM *priv;
+    OSSL_PARAM *pub_x;
+    OSSL_PARAM *pub_y;
+    OSSL_PARAM *encoded_pub;
+    OSSL_PARAM *use_cofactor;
+    OSSL_PARAM *include_public;
+    OSSL_PARAM *group_check;
+
+    /* Key information */
+    OSSL_PARAM *bits;
+    OSSL_PARAM *field_degree;
+    OSSL_PARAM *secbits;
+    OSSL_PARAM *maxsize;
+    OSSL_PARAM *seccat;
+    OSSL_PARAM *default_digest;
+
+    /* Characteristic two field information */
+    OSSL_PARAM *char2_m;
+    OSSL_PARAM *char2_type;
+    OSSL_PARAM *char2_tp;
+    OSSL_PARAM *char2_k1;
+    OSSL_PARAM *char2_k2;
+    OSSL_PARAM *char2_k3;
+
+    /* Generation parameters */
+    OSSL_PARAM *dhkem_ikm;
+#ifdef FIPS_MODULE
+    OSSL_PARAM *fips_key_check;
+    OSSL_PARAM *fips_indicator;
+#endif
+} EC_PARAMS;
+
 /*-
  * Computes the multiplicative inverse of x in the range
  * [1,EC_GROUP::order), where EC_GROUP::order is the cardinality of the
@@ -72,11 +121,23 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl,
     OSSL_PARAM params[], OSSL_LIB_CTX *libctx,
     const char *propq,
     BN_CTX *bnctx, unsigned char **genbuf);
+int ossl_ec_group_todata_parsed(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl,
+    const EC_PARAMS *params, OSSL_LIB_CTX *libctx,
+    const char *propq,
+    BN_CTX *bnctx, unsigned char **genbuf);
 int ossl_ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]);
+int ossl_ec_group_fromdata_parsed(EC_KEY *ec, const EC_PARAMS *params);
 int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]);
+int ossl_ec_group_set_params_parsed(EC_GROUP *group, const EC_PARAMS *params);
+EC_GROUP *ossl_ec_group_new_from_params_parsed(const EC_PARAMS *params,
+    OSSL_LIB_CTX *libctx, const char *propq);
 int ossl_ec_key_fromdata(EC_KEY *ecx, const OSSL_PARAM params[],
     int include_private);
+int ossl_ec_key_fromdata_parsed(EC_KEY *ecx, const EC_PARAMS *params,
+    int include_private);
 int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]);
+int ossl_ec_key_otherparams_fromdata_parsed(EC_KEY *ec,
+    const EC_PARAMS *params);
 int ossl_ec_key_is_foreign(const EC_KEY *ec);
 EC_KEY *ossl_ec_key_dup(const EC_KEY *key, int selection);
 int ossl_x509_algor_is_sm2(const X509_ALGOR *palg);
diff --git a/include/crypto/ec_params.h.in b/include/crypto/ec_params.h.in
new file mode 100644
index 0000000000..a1d6798778
--- /dev/null
+++ b/include/crypto/ec_params.h.in
@@ -0,0 +1,179 @@
+/*
+ * 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);
+-}
+
+#include "crypto/ec.h"
+#include <openssl/core_names.h>
+#include <openssl/err.h>
+#include <openssl/proverr.h>
+
+{-
+our @EC_DOMAIN_TYPES = (
+    ['OSSL_PKEY_PARAM_GROUP_NAME',                      'group_name', 'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_ENCODING',                     'encoding',   'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT',      'pt_format',  'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_FIELD_TYPE',                   'field_type', 'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_P',                            'p',          'BN'],
+    ['OSSL_PKEY_PARAM_EC_A',                            'a',          'BN'],
+    ['OSSL_PKEY_PARAM_EC_B',                            'b',          'BN'],
+    ['OSSL_PKEY_PARAM_EC_GENERATOR',                    'generator',  'octet_string'],
+    ['OSSL_PKEY_PARAM_EC_ORDER',                        'order',      'BN'],
+    ['OSSL_PKEY_PARAM_EC_COFACTOR',                     'cofactor',   'BN'],
+    ['OSSL_PKEY_PARAM_EC_SEED',                         'seed',       'octet_string'],
+    ['OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS', 'decoded',    'int'],
+);
+
+our @EC_KEY_TYPES = (
+    ['OSSL_PKEY_PARAM_PUB_KEY',  'pub',  'octet_string'],
+    ['OSSL_PKEY_PARAM_PRIV_KEY', 'priv', 'BN'],
+);
+
+our @EC_OTHER_TYPES = (
+    ['OSSL_PKEY_PARAM_USE_COFACTOR_ECDH',   'use_cofactor',   'int'],
+    ['OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC',   'include_public', 'int'],
+    ['OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE', 'group_check',    'utf8_string'],
+);
+
+our @EC_INFO_TYPES = (
+    ['OSSL_PKEY_PARAM_BITS',               'bits',           'int'],
+    ['OSSL_PKEY_PARAM_EC_FIELD_DEGREE',    'field_degree',   'int'],
+    ['OSSL_PKEY_PARAM_SECURITY_BITS',      'secbits',        'int'],
+    ['OSSL_PKEY_PARAM_MAX_SIZE',           'maxsize',        'int'],
+    ['OSSL_PKEY_PARAM_SECURITY_CATEGORY',  'seccat',         'int'],
+    ['OSSL_PKEY_PARAM_DEFAULT_DIGEST',     'default_digest', 'utf8_string'],
+    ['OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY', 'encoded_pub',    'octet_string'],
+    ['OSSL_PKEY_PARAM_EC_PUB_X',           'pub_x',          'BN'],
+    ['OSSL_PKEY_PARAM_EC_PUB_Y',           'pub_y',          'BN'],
+);
+
+our @EC2M_INFO_TYPES = (
+    ['OSSL_PKEY_PARAM_EC_CHAR2_M',        'char2_m',    'int',
+     '#if !defined(OPENSSL_NO_EC2M)'],
+    ['OSSL_PKEY_PARAM_EC_CHAR2_TYPE',     'char2_type', 'utf8_string',
+     '#if !defined(OPENSSL_NO_EC2M)'],
+    ['OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS', 'char2_tp',   'int',
+     '#if !defined(OPENSSL_NO_EC2M)'],
+    ['OSSL_PKEY_PARAM_EC_CHAR2_PP_K1',    'char2_k1',   'int',
+     '#if !defined(OPENSSL_NO_EC2M)'],
+    ['OSSL_PKEY_PARAM_EC_CHAR2_PP_K2',    'char2_k2',   'int',
+     '#if !defined(OPENSSL_NO_EC2M)'],
+    ['OSSL_PKEY_PARAM_EC_CHAR2_PP_K3',    'char2_k3',   'int',
+     '#if !defined(OPENSSL_NO_EC2M)'],
+);
+
+our @EC_SETTABLE_TYPES = (
+    ['OSSL_PKEY_PARAM_USE_COFACTOR_ECDH',          'use_cofactor',   'int'],
+    ['OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY',         'encoded_pub',    'octet_string'],
+    ['OSSL_PKEY_PARAM_EC_ENCODING',                'encoding',       'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT', 'pt_format',      'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_SEED',                    'seed',           'octet_string'],
+    ['OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC',          'include_public', 'int'],
+    ['OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE',        'group_check',    'utf8_string'],
+);
+
+our @EC_GEN_TYPES = (
+    ['OSSL_PKEY_PARAM_GROUP_NAME',                 'group_name',     'utf8_string'],
+    ['OSSL_PKEY_PARAM_USE_COFACTOR_ECDH',          'use_cofactor',   'int'],
+    ['OSSL_PKEY_PARAM_EC_ENCODING',                'encoding',       'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT', 'pt_format',      'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_FIELD_TYPE',              'field_type',     'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE',        'group_check',    'utf8_string'],
+    ['OSSL_PKEY_PARAM_EC_P',                       'p',              'BN'],
+    ['OSSL_PKEY_PARAM_EC_A',                       'a',              'BN'],
+    ['OSSL_PKEY_PARAM_EC_B',                       'b',              'BN'],
+    ['OSSL_PKEY_PARAM_EC_GENERATOR',               'generator',      'octet_string'],
+    ['OSSL_PKEY_PARAM_EC_ORDER',                   'order',          'BN'],
+    ['OSSL_PKEY_PARAM_EC_COFACTOR',                'cofactor',       'BN'],
+    ['OSSL_PKEY_PARAM_EC_SEED',                    'seed',           'octet_string'],
+    ['OSSL_PKEY_PARAM_DHKEM_IKM',                  'dhkem_ikm',      'octet_string',
+     '!fips'],
+    ['OSSL_PKEY_PARAM_FIPS_KEY_CHECK',             'fips_key_check', 'int',
+     'fips'],
+);
+
+return "";
+-}
+
+/* Selection-specific provider import and export declarations. */
+{-
+my $imexport = "";
+
+for my $selection (1..15) {
+    my @types = ();
+
+    push @types, $EC_KEY_TYPES[1] if ($selection & 1);
+    push @types, $EC_KEY_TYPES[0] if ($selection & 2);
+    push @types, @EC_DOMAIN_TYPES if ($selection & 4);
+    push @types, @EC_OTHER_TYPES if ($selection & 8);
+    $imexport .= "#define ec_imexport_types_${selection}_st\n";
+    $imexport .= "#define ec_imexport_types_${selection}_decoder\n";
+    $imexport .= produce_param_decoder("ec_imexport_types_${selection}",
+                                       @types);
+    $imexport .= "\n";
+}
+$imexport;
+-}
+
+/* Public EC compatibility functions retain their existing signatures. */
+#define ec_group_fromdata_st ec_params_st
+{- produce_param_decoder('ec_group_fromdata', @EC_DOMAIN_TYPES); -}
+
+#define ec_group_todata_st ec_params_st
+{- produce_param_decoder('ec_group_todata', @EC_DOMAIN_TYPES); -}
+
+#define ec_key_fromdata_st ec_params_st
+{- produce_param_decoder('ec_key_fromdata', @EC_KEY_TYPES); -}
+
+#define ec_key_otherparams_fromdata_st ec_params_st
+{- produce_param_decoder('ec_key_otherparams_fromdata', @EC_OTHER_TYPES,
+                         $EC_DOMAIN_TYPES[2]); -}
+
+/* Provider and legacy import paths parse all their input only once. */
+#define ec_import_st ec_params_st
+{- produce_param_decoder('ec_import',
+                         (@EC_DOMAIN_TYPES, @EC_KEY_TYPES, @EC_OTHER_TYPES)); -}
+
+#define ec_pkey_import_from_st ec_params_st
+{- produce_param_decoder('ec_pkey_import_from',
+                         (@EC_DOMAIN_TYPES, @EC_KEY_TYPES, @EC_OTHER_TYPES)); -}
+
+/* Keymgmt get and set parameter surfaces. */
+#define ec_get_params_st ec_params_st
+{- produce_param_decoder('ec_get_params',
+                         (@EC_INFO_TYPES, @EC_DOMAIN_TYPES, @EC2M_INFO_TYPES,
+                          @EC_KEY_TYPES, @EC_OTHER_TYPES)); -}
+
+#define sm2_get_params_st ec_params_st
+{- produce_param_decoder('sm2_get_params',
+                         (@EC_INFO_TYPES[0..3], $EC_INFO_TYPES[5],
+                          $EC_INFO_TYPES[6], @EC_DOMAIN_TYPES,
+                          @EC_KEY_TYPES, @EC_INFO_TYPES[7..8])); -}
+
+#define ec_set_params_st ec_params_st
+{- produce_param_decoder('ec_set_params', @EC_SETTABLE_TYPES); -}
+
+#define sm2_set_params_st ec_params_st
+{- produce_param_decoder('sm2_set_params', $EC_SETTABLE_TYPES[1]); -}
+
+/* Key generation context parameters. */
+#define ec_gen_set_params_st ec_params_st
+{- produce_param_decoder('ec_gen_set_params', @EC_GEN_TYPES); -}
+
+#define sm2_gen_set_params_st ec_params_st
+{- produce_param_decoder('sm2_gen_set_params',
+                         ($EC_GEN_TYPES[0], @EC_GEN_TYPES[2..4],
+                          @EC_GEN_TYPES[6..12])); -}
+
+#define ec_gen_get_params_st ec_params_st
+{- produce_param_decoder('ec_gen_get_params',
+                         ['OSSL_PKEY_PARAM_FIPS_APPROVED_INDICATOR',
+                          'fips_indicator', 'int', 'fips']); -}