]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
dsa/dh: update keymanagers for DH and DSA to use generated param parsers
authorPauli <ppzgs1@gmail.com>
Thu, 28 Aug 2025 01:49:44 +0000 (11:49 +1000)
committerTomas Mraz <tomas@openssl.org>
Thu, 11 Sep 2025 15:54:45 +0000 (17:54 +0200)
Both are updates to reduce the OSSL_PARAM_locate related searching.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28360)

crypto/dh/dh_backend.c
crypto/ffc/ffc_params.c
include/crypto/dh.h
include/internal/ffc.h
providers/implementations/keymgmt/dh_kmgmt.c.in
providers/implementations/keymgmt/dsa_kmgmt.c.in

index 1aaa88dacae111e1d37db702a560e597282dc6a7..678934a8dbed021e54e45c83285b2c770126c72b 100644 (file)
@@ -88,20 +88,21 @@ int ossl_dh_key_fromdata(DH *dh, const OSSL_PARAM params[], int include_private)
     return 0;
 }
 
-int ossl_dh_params_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
+int ossl_dh_params_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM *privlen,
+                          const FFC_PARAM_PTRS *pp)
 {
-    long l = DH_get_length(dh);
+    const long l = DH_get_length(dh);
 
-    if (!ossl_ffc_params_todata(ossl_dh_get0_params(dh), bld, params))
+    if (!ossl_ffc_params_todata(ossl_dh_get0_params(dh), bld, pp))
         return 0;
     if (l > 0
-        && !ossl_param_build_set_long(bld, params, OSSL_PKEY_PARAM_DH_PRIV_LEN, l))
+        && !ossl_param_build_set_long(bld, privlen, OSSL_PKEY_PARAM_DH_PRIV_LEN, l))
         return 0;
     return 1;
 }
 
-int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[],
-                       int include_private)
+int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM *pubkey,
+                       OSSL_PARAM *privkey, int include_private)
 {
     const BIGNUM *priv = NULL, *pub = NULL;
 
@@ -111,10 +112,10 @@ int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[],
     DH_get0_key(dh, &pub, &priv);
     if (priv != NULL
         && include_private
-        && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PRIV_KEY, priv))
+        && !ossl_param_build_set_bn(bld, privkey, OSSL_PKEY_PARAM_PRIV_KEY, priv))
         return 0;
     if (pub != NULL
-        && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PUB_KEY, pub))
+        && !ossl_param_build_set_bn(bld, pubkey, OSSL_PKEY_PARAM_PUB_KEY, pub))
         return 0;
 
     return 1;
index 4101682a9a6d4a8404f4eb6382a8b5ae562e8d91..50e11fc367a2d1ffe826eb8def39138ab63e9ca5 100644 (file)
@@ -214,33 +214,34 @@ int ossl_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q)
 }
 
 int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld,
-                      OSSL_PARAM params[])
+                           const FFC_PARAM_PTRS *pp)
 {
     int test_flags;
 
+#define PP(f) (pp == NULL ? NULL : pp->f)
     if (ffc->p != NULL
-        && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_P, ffc->p))
+        && !ossl_param_build_set_bn(bld, PP(p), OSSL_PKEY_PARAM_FFC_P, ffc->p))
         return 0;
     if (ffc->q != NULL
-        && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_Q, ffc->q))
+        && !ossl_param_build_set_bn(bld, PP(q), OSSL_PKEY_PARAM_FFC_Q, ffc->q))
         return 0;
     if (ffc->g != NULL
-        && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_G, ffc->g))
+        && !ossl_param_build_set_bn(bld, PP(g), OSSL_PKEY_PARAM_FFC_G, ffc->g))
         return 0;
     if (ffc->j != NULL
-        && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_COFACTOR,
-                                    ffc->j))
+        && !ossl_param_build_set_bn(bld, PP(cofactor),
+                                    OSSL_PKEY_PARAM_FFC_COFACTOR, ffc->j))
         return 0;
-    if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_GINDEX,
+    if (!ossl_param_build_set_int(bld, PP(g_index), OSSL_PKEY_PARAM_FFC_GINDEX,
                                   ffc->gindex))
         return 0;
-    if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_PCOUNTER,
+    if (!ossl_param_build_set_int(bld, PP(p_counter), OSSL_PKEY_PARAM_FFC_PCOUNTER,
                                   ffc->pcounter))
         return 0;
-    if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_H, ffc->h))
+    if (!ossl_param_build_set_int(bld, PP(h), OSSL_PKEY_PARAM_FFC_H, ffc->h))
         return 0;
     if (ffc->seed != NULL
-        && !ossl_param_build_set_octet_string(bld, params,
+        && !ossl_param_build_set_octet_string(bld, PP(seed),
                                               OSSL_PKEY_PARAM_FFC_SEED,
                                               ffc->seed, ffc->seedlen))
         return 0;
@@ -249,35 +250,36 @@ int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld,
         const char *name = ossl_ffc_named_group_get_name(group);
 
         if (name == NULL
-            || !ossl_param_build_set_utf8_string(bld, params,
+            || !ossl_param_build_set_utf8_string(bld, PP(group_name),
                                                  OSSL_PKEY_PARAM_GROUP_NAME,
                                                  name))
             return 0;
     }
     test_flags = ((ffc->flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0);
-    if (!ossl_param_build_set_int(bld, params,
+    if (!ossl_param_build_set_int(bld, PP(validate_pq),
                                   OSSL_PKEY_PARAM_FFC_VALIDATE_PQ, test_flags))
         return 0;
     test_flags = ((ffc->flags & FFC_PARAM_FLAG_VALIDATE_G) != 0);
-    if (!ossl_param_build_set_int(bld, params,
+    if (!ossl_param_build_set_int(bld, PP(validate_g),
                                   OSSL_PKEY_PARAM_FFC_VALIDATE_G, test_flags))
         return 0;
     test_flags = ((ffc->flags & FFC_PARAM_FLAG_VALIDATE_LEGACY) != 0);
-    if (!ossl_param_build_set_int(bld, params,
+    if (!ossl_param_build_set_int(bld, PP(validate_legacy),
                                   OSSL_PKEY_PARAM_FFC_VALIDATE_LEGACY,
                                   test_flags))
         return 0;
 
     if (ffc->mdname != NULL
-        && !ossl_param_build_set_utf8_string(bld, params,
+        && !ossl_param_build_set_utf8_string(bld, PP(digest),
                                              OSSL_PKEY_PARAM_FFC_DIGEST,
                                              ffc->mdname))
        return 0;
     if (ffc->mdprops != NULL
-        && !ossl_param_build_set_utf8_string(bld, params,
+        && !ossl_param_build_set_utf8_string(bld, PP(propq),
                                              OSSL_PKEY_PARAM_FFC_DIGEST_PROPS,
                                              ffc->mdprops))
         return 0;
+#undef PP
     return 1;
 }
 
index b4a4a3c1fae8d2e480280e86b541cfaa82f19a29..7e9c3d076668fd3c9d837c8c316893ef8a287295 100644 (file)
@@ -33,9 +33,10 @@ FFC_PARAMS *ossl_dh_get0_params(DH *dh);
 int ossl_dh_get0_nid(const DH *dh);
 int ossl_dh_params_fromdata(DH *dh, const OSSL_PARAM params[]);
 int ossl_dh_key_fromdata(DH *dh, const OSSL_PARAM params[], int include_private);
-int ossl_dh_params_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]);
-int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[],
-                       int include_private);
+int ossl_dh_params_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM *privlen,
+                          const FFC_PARAM_PTRS *pp);
+int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM *pubkey,
+                       OSSL_PARAM *privkey, int include_private);
 DH *ossl_dh_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
                            OSSL_LIB_CTX *libctx, const char *propq);
 int ossl_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
index edd8381e8df432390c1a4b9571e7afa76f4e493b..f6006dbeace1367145f500cdbe844a0c580b76c4 100644 (file)
@@ -122,6 +122,23 @@ typedef struct ffc_params_st {
     int keylength;
 } FFC_PARAMS;
 
+typedef struct {
+    OSSL_PARAM *p;                  /* OSSL_PKEY_PARAM_FFC_P */
+    OSSL_PARAM *q;                  /* OSSL_PKEY_PARAM_FFC_Q */
+    OSSL_PARAM *g;                  /* OSSL_PKEY_PARAM_FFC_G */
+    OSSL_PARAM *cofactor;           /* OSSL_PKEY_PARAM_FFC_COFACTOR */
+    OSSL_PARAM *g_index;            /* OSSL_PKEY_PARAM_FFC_GINDEX */
+    OSSL_PARAM *p_counter;          /* OSSL_PKEY_PARAM_FFC_PCOUNTER */
+    OSSL_PARAM *h;                  /* OSSL_PKEY_PARAM_FFC_H */
+    OSSL_PARAM *seed;               /* OSSL_PKEY_PARAM_FFC_SEED */
+    OSSL_PARAM *group_name;         /* OSSL_PKEY_PARAM_GROUP_NAME */
+    OSSL_PARAM *validate_pq;        /* OSSL_PKEY_PARAM_FFC_VALIDATE_PQ */
+    OSSL_PARAM *validate_g;         /* OSSL_PKEY_PARAM_FFC_VALIDATE_G */
+    OSSL_PARAM *validate_legacy;    /* OSSL_PKEY_PARAM_FFC_VALIDATE_LEGACY */
+    OSSL_PARAM *digest;             /* OSSL_PKEY_PARAM_FFC_DIGEST */
+    OSSL_PARAM *propq;              /* OSSL_PKEY_PARAM_FFC_DIGEST_PROPS */
+} FFC_PARAM_PTRS;
+
 void ossl_ffc_params_init(FFC_PARAMS *params);
 void ossl_ffc_params_cleanup(FFC_PARAMS *params);
 void ossl_ffc_params_set0_pqg(FFC_PARAMS *params, BIGNUM *p, BIGNUM *q,
@@ -199,7 +216,7 @@ int ossl_ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv_key,
                                  int *ret);
 
 int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *tmpl,
-                           OSSL_PARAM params[]);
+                           const FFC_PARAM_PTRS *pp);
 int ossl_ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]);
 
 typedef struct dh_named_group_st DH_NAMED_GROUP;
index 4cc0920fac11b26396b885f3d91b3ba92afa04c8..01488b4612edad2185648243960436e8ec6bdd69 100644 (file)
@@ -6,6 +6,9 @@
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
  */
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+-}
 
 /*
  * DH low level APIs are deprecated for public use, but still ok for
@@ -20,6 +23,7 @@
 #include <openssl/bn.h>
 #include <openssl/err.h>
 #include <openssl/self_test.h>
+#include <openssl/proverr.h>
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
 #include "prov/provider_ctx.h"
@@ -233,13 +237,13 @@ static int dh_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
         return 0;
 
     if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)
-        ok = ok && ossl_dh_params_todata(dh, tmpl, NULL);
+        ok = ok && ossl_dh_params_todata(dh, tmpl, NULL, NULL);
 
     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
         int include_private =
             selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
 
-        ok = ok && ossl_dh_key_todata(dh, tmpl, NULL, include_private);
+        ok = ok && ossl_dh_key_todata(dh, tmpl, NULL, NULL, include_private);
     }
 
     if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
@@ -256,6 +260,7 @@ err:
 
 /* IMEXPORT = IMPORT + EXPORT */
 
+/* These must be kept in sync with the dh_get_params ones below */
 # define DH_IMEXPORTABLE_PARAMETERS                                            \
     OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0),                             \
     OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_Q, NULL, 0),                             \
@@ -314,72 +319,100 @@ static const OSSL_PARAM *dh_export_types(int selection)
     return dh_imexport_types(selection);
 }
 
-static ossl_inline int dh_get_params(void *key, OSSL_PARAM params[])
+struct dh_params_st {
+    FFC_PARAM_PTRS ffp;
+    OSSL_PARAM *bits;
+    OSSL_PARAM *secbits;
+    OSSL_PARAM *maxsize;
+    OSSL_PARAM *seccat;
+    OSSL_PARAM *privkey;
+    OSSL_PARAM *privlen;
+    OSSL_PARAM *pubkey;
+    OSSL_PARAM *encpubkey;
+};
+
+#define dh_get_params_st dh_params_st
+
+{- produce_param_decoder('dh_get_params',
+                         (['PKEY_PARAM_BITS',               'bits',           'int'],
+                          ['PKEY_PARAM_SECURITY_BITS',      'secbits',        'int'],
+                          ['PKEY_PARAM_MAX_SIZE',           'maxsize',        'int'],
+                          ['PKEY_PARAM_SECURITY_CATEGORY',  'seccat',         'int'],
+                          ['PKEY_PARAM_ENCODED_PUBLIC_KEY', 'encpubkey',      'octet_string'],
+                          ['PKEY_PARAM_FFC_P',              'ffp.p',          'BN'],
+                          ['PKEY_PARAM_FFC_Q',              'ffp.q',          'BN'],
+                          ['PKEY_PARAM_FFC_G',              'ffp.g',          'BN'],
+                          ['PKEY_PARAM_FFC_COFACTOR',       'ffp.cofactor',   'BN'],
+                          ['PKEY_PARAM_FFC_GINDEX',         'ffp.g_index',    'int'],
+                          ['PKEY_PARAM_FFC_PCOUNTER',       'ffp.p_counter',  'int'],
+                          ['PKEY_PARAM_FFC_H',              'ffp.h',          'int'],
+                          ['PKEY_PARAM_DH_PRIV_LEN',        'privlen',        'int'],
+                          ['PKEY_PARAM_FFC_SEED',           'ffp.seed',       'octet_string'],
+                          ['PKEY_PARAM_GROUP_NAME',         'ffp.group_name', 'utf8_string'],
+                          ['PKEY_PARAM_PUB_KEY',            'pubkey',         'BN'],
+                          ['PKEY_PARAM_PRIV_KEY',           'privkey',        'BN'],
+                         )); -}
+
+static int dh_get_params(void *key, OSSL_PARAM params[])
 {
     DH *dh = key;
-    OSSL_PARAM *p;
+    struct dh_params_st p;
 
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
-        && !OSSL_PARAM_set_int(p, DH_bits(dh)))
+    if (key == NULL || !dh_get_params_decoder(params, &p))
         return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
-        && !OSSL_PARAM_set_int(p, DH_security_bits(dh)))
+
+    if (p.bits != NULL && !OSSL_PARAM_set_int(p.bits, DH_bits(dh)))
+        return 0;
+
+    if (p.secbits != NULL && !OSSL_PARAM_set_int(p.secbits, DH_security_bits(dh)))
         return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
-        && !OSSL_PARAM_set_int(p, DH_size(dh)))
+
+    if (p.maxsize != NULL && !OSSL_PARAM_set_int(p.maxsize, DH_size(dh)))
         return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) {
-        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+
+    if (p.encpubkey != NULL) {
+        if (p.encpubkey->data_type != OSSL_PARAM_OCTET_STRING)
             return 0;
-        p->return_size = ossl_dh_key2buf(dh, (unsigned char **)&p->data,
-                                         p->data_size, 0);
-        if (p->return_size == 0)
+        p.encpubkey->return_size = ossl_dh_key2buf(dh, (unsigned char **)&p.encpubkey->data,
+                                                   p.encpubkey->data_size, 0);
+        if (p.encpubkey->return_size == 0)
             return 0;
     }
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_CATEGORY)) != NULL)
-        if (!OSSL_PARAM_set_int(p, 0))
+
+    if (p.seccat != NULL)
+        if (!OSSL_PARAM_set_int(p.seccat, 0))
             return 0;
 
-    return ossl_dh_params_todata(dh, NULL, params)
-        && ossl_dh_key_todata(dh, NULL, params, 1);
+    return ossl_dh_params_todata(dh, NULL, p.privlen, &p.ffp)
+        && ossl_dh_key_todata(dh, NULL, p.pubkey, p.privkey, 1);
 }
 
-static const OSSL_PARAM dh_params[] = {
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL),
-    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
-    DH_IMEXPORTABLE_PARAMETERS,
-    DH_IMEXPORTABLE_PUBLIC_KEY,
-    DH_IMEXPORTABLE_PRIVATE_KEY,
-    OSSL_PARAM_END
-};
-
 static const OSSL_PARAM *dh_gettable_params(void *provctx)
 {
-    return dh_params;
+    return dh_get_params_list;
 }
 
-static const OSSL_PARAM dh_known_settable_params[] = {
-    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
-    OSSL_PARAM_END
-};
+{- produce_param_decoder('dh_set_params',
+                         (['PKEY_PARAM_ENCODED_PUBLIC_KEY', 'encpubkey', 'octet_string'],
+                         )); -}
 
 static const OSSL_PARAM *dh_settable_params(void *provctx)
 {
-    return dh_known_settable_params;
+    return dh_set_params_list;
 }
 
 static int dh_set_params(void *key, const OSSL_PARAM params[])
 {
     DH *dh = key;
-    const OSSL_PARAM *p;
+    struct dh_set_params_st p;
+
+    if (key == NULL || !dh_set_params_decoder(params, &p))
+        return 0;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
-    if (p != NULL
-            && (p->data_type != OSSL_PARAM_OCTET_STRING
-                || !ossl_dh_buf2key(dh, p->data, p->data_size)))
+    if (p.encpubkey != NULL
+            && (p.encpubkey->data_type != OSSL_PARAM_OCTET_STRING
+                || !ossl_dh_buf2key(dh, p.encpubkey->data,
+                                    p.encpubkey->data_size)))
         return 0;
 
     return 1;
@@ -529,46 +562,88 @@ static int dh_set_gen_seed(struct dh_gen_ctx *gctx, unsigned char *seed,
     return 1;
 }
 
-static int dh_gen_common_set_params(void *genctx, const OSSL_PARAM params[])
+struct dh_gen_set_params_st {
+    OSSL_PARAM *type;
+    OSSL_PARAM *group_name;
+    OSSL_PARAM *privlen;
+    OSSL_PARAM *pbits;
+    OSSL_PARAM *qbits;      /* DHX only */
+    OSSL_PARAM *digest;     /* DHX only */
+    OSSL_PARAM *propq;      /* DHX only */
+    OSSL_PARAM *g_index;    /* DHX only */
+    OSSL_PARAM *seed;       /* DHX only */
+    OSSL_PARAM *p_counter;  /* DHX only */
+    OSSL_PARAM *h;          /* DHX only */
+    OSSL_PARAM *generator;  /* DH only */
+};
+
+#define dhx_gen_set_params_st dh_gen_set_params_st
+
+{- produce_param_decoder('dhx_gen_set_params',
+                         (['PKEY_PARAM_FFC_TYPE',          'type',       'utf8_string'],
+                          ['PKEY_PARAM_GROUP_NAME',        'group_name', 'utf8_string'],
+                          ['PKEY_PARAM_DH_PRIV_LEN',       'privlen',    'int'],
+                          ['PKEY_PARAM_FFC_PBITS',         'pbits',      'size_t'],
+                          ['PKEY_PARAM_FFC_QBITS',         'qbits',      'size_t'],
+                          ['PKEY_PARAM_FFC_DIGEST',        'digest',     'utf8_string'],
+                          ['PKEY_PARAM_FFC_DIGEST_PROPS',  'propq',      'utf8_string'],
+                          ['PKEY_PARAM_FFC_GINDEX',        'g_index',    'int'],
+                          ['PKEY_PARAM_FFC_SEED',          'seed',       'octet_string'],
+                          ['PKEY_PARAM_FFC_PCOUNTER',      'p_counter',  'int'],
+                          ['PKEY_PARAM_FFC_H',             'h',          'int'],
+                          ['PKEY_PARAM_DH_GENERATOR',      'invalid param'],
+                         )); -}
+
+#define dh_gen_set_params_st dh_gen_set_params_st
+
+{- produce_param_decoder('dh_gen_set_params',
+                         (['PKEY_PARAM_FFC_TYPE',          'type',       'utf8_string'],
+                          ['PKEY_PARAM_GROUP_NAME',        'group_name', 'utf8_string'],
+                          ['PKEY_PARAM_DH_PRIV_LEN',       'privlen',    'int'],
+                          ['PKEY_PARAM_FFC_PBITS',         'pbits',      'size_t'],
+                          ['PKEY_PARAM_DH_GENERATOR',      'generator',  'int'],
+                          ['PKEY_PARAM_FFC_GINDEX',        'invalid param'],
+                          ['PKEY_PARAM_FFC_PCOUNTER',      'invalid param'],
+                          ['PKEY_PARAM_FFC_H',             'invalid param'],
+                          ['PKEY_PARAM_FFC_SEED',          'invalid param'],
+                          ['PKEY_PARAM_FFC_QBITS',         'invalid param'],
+                          ['PKEY_PARAM_FFC_DIGEST',        'invalid param'],
+                          ['PKEY_PARAM_FFC_DIGEST_PROPS',  'invalid param'],
+                         )); -}
+
+static int dh_gen_common_set_params(struct dh_gen_ctx *gctx,
+                                    const struct dhx_gen_set_params_st *p)
 {
-    struct dh_gen_ctx *gctx = genctx;
-    const OSSL_PARAM *p;
     int gen_type = -1;
 
-    if (gctx == NULL)
-        return 0;
-    if (ossl_param_is_empty(params))
-        return 1;
-
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_TYPE);
-    if (p != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING
+    if (p->type != NULL) {
+        if (p->type->data_type != OSSL_PARAM_UTF8_STRING
             || ((gen_type =
-                 dh_gen_type_name2id_w_default(p->data, gctx->dh_type)) == -1)) {
+                 dh_gen_type_name2id_w_default(p->type->data, gctx->dh_type)) == -1)) {
             ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
             return 0;
         }
         if (gen_type != -1)
             gctx->gen_type = gen_type;
     }
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
-    if (p != NULL) {
+
+    if (p->group_name != NULL) {
         const DH_NAMED_GROUP *group = NULL;
 
-        if (p->data_type != OSSL_PARAM_UTF8_STRING
-            || p->data == NULL
-            || (group = ossl_ffc_name_to_dh_named_group(p->data)) == NULL
+        if (p->group_name->data_type != OSSL_PARAM_UTF8_STRING
+            || p->group_name->data == NULL
+            || (group = ossl_ffc_name_to_dh_named_group(p->group_name->data)) == NULL
             || ((gctx->group_nid =
                  ossl_ffc_named_group_get_uid(group)) == NID_undef)) {
             ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
             return 0;
         }
     }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PBITS)) != NULL
-        && !OSSL_PARAM_get_size_t(p, &gctx->pbits))
+
+    if (p->pbits != NULL && !OSSL_PARAM_get_size_t(p->pbits, &gctx->pbits))
         return 0;
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_LEN);
-    if (p != NULL && !OSSL_PARAM_get_int(p, &gctx->priv_len))
+
+    if (p->privlen != NULL && !OSSL_PARAM_get_int(p->privlen, &gctx->priv_len))
         return 0;
     return 1;
 }
@@ -576,115 +651,79 @@ static int dh_gen_common_set_params(void *genctx, const OSSL_PARAM params[])
 static const OSSL_PARAM *dh_gen_settable_params(ossl_unused void *genctx,
                                                 ossl_unused void *provctx)
 {
-    static const OSSL_PARAM dh_gen_settable[] = {
-        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
-        OSSL_PARAM_int(OSSL_PKEY_PARAM_DH_PRIV_LEN, NULL),
-        OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS, NULL),
-        OSSL_PARAM_int(OSSL_PKEY_PARAM_DH_GENERATOR, NULL),
-        OSSL_PARAM_END
-    };
-    return dh_gen_settable;
+    return dh_gen_set_params_list;
 }
 
 static const OSSL_PARAM *dhx_gen_settable_params(ossl_unused void *genctx,
                                                  ossl_unused void *provctx)
 {
-    static const OSSL_PARAM dhx_gen_settable[] = {
-        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
-        OSSL_PARAM_int(OSSL_PKEY_PARAM_DH_PRIV_LEN, NULL),
-        OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS, NULL),
-        OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_QBITS, NULL),
-        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, NULL, 0),
-        OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL),
-        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0),
-        OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL),
-        OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL),
-        OSSL_PARAM_END
-    };
-    return dhx_gen_settable;
+    return dhx_gen_set_params_list;
 }
 
 static int dhx_gen_set_params(void *genctx, const OSSL_PARAM params[])
 {
     struct dh_gen_ctx *gctx = genctx;
-    const OSSL_PARAM *p;
+    struct dhx_gen_set_params_st p;
 
-    if (!dh_gen_common_set_params(genctx, params))
+    if (gctx == NULL || !dhx_gen_set_params_decoder(params, &p))
+        return 0;
+
+    if (!dh_gen_common_set_params(gctx, &p))
         return 0;
 
     /* Parameters related to fips186-4 and fips186-2 */
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX);
-    if (p != NULL && !OSSL_PARAM_get_int(p, &gctx->gindex))
+    if (p.g_index != NULL && !OSSL_PARAM_get_int(p.g_index, &gctx->gindex))
         return 0;
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PCOUNTER);
-    if (p != NULL && !OSSL_PARAM_get_int(p, &gctx->pcounter))
+
+    if (p.p_counter != NULL && !OSSL_PARAM_get_int(p.p_counter, &gctx->pcounter))
         return 0;
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H);
-    if (p != NULL && !OSSL_PARAM_get_int(p, &gctx->hindex))
+
+    if (p.h != NULL && !OSSL_PARAM_get_int(p.h, &gctx->hindex))
         return 0;
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED);
-    if (p != NULL
-        && (p->data_type != OSSL_PARAM_OCTET_STRING
-            || !dh_set_gen_seed(gctx, p->data, p->data_size)))
+
+    if (p.seed != NULL
+        && (p.seed->data_type != OSSL_PARAM_OCTET_STRING
+            || !dh_set_gen_seed(gctx, p.seed->data, p.seed->data_size)))
             return 0;
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_QBITS)) != NULL
-        && !OSSL_PARAM_get_size_t(p, &gctx->qbits))
+
+    if (p.qbits != NULL && !OSSL_PARAM_get_size_t(p.qbits, &gctx->qbits))
         return 0;
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);
-    if (p != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+
+    if (p.digest != NULL) {
+        if (p.digest->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
         OPENSSL_free(gctx->mdname);
-        gctx->mdname = OPENSSL_strdup(p->data);
+        gctx->mdname = OPENSSL_strdup(p.digest->data);
         if (gctx->mdname == NULL)
             return 0;
     }
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
-    if (p != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+
+    if (p.propq != NULL) {
+        if (p.propq->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
         OPENSSL_free(gctx->mdprops);
-        gctx->mdprops = OPENSSL_strdup(p->data);
+        gctx->mdprops = OPENSSL_strdup(p.propq->data);
         if (gctx->mdprops == NULL)
             return 0;
     }
 
-    /* Parameters that are not allowed for DHX */
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_GENERATOR);
-    if (p != NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED);
-        return 0;
-    }
     return 1;
 }
 
 static int dh_gen_set_params(void *genctx, const OSSL_PARAM params[])
 {
     struct dh_gen_ctx *gctx = genctx;
-    const OSSL_PARAM *p;
+    struct dhx_gen_set_params_st p;
 
-    if (!dh_gen_common_set_params(genctx, params))
+    if (gctx == NULL || !dh_gen_set_params_decoder(params, &p))
         return 0;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_GENERATOR);
-    if (p != NULL && !OSSL_PARAM_get_int(p, &gctx->generator))
+    if (!dh_gen_common_set_params(gctx, &p))
         return 0;
 
-    /* Parameters that are not allowed for DH */
-    if (OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX) != NULL
-        || OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PCOUNTER) != NULL
-        || OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H) != NULL
-        || OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED) != NULL
-        || OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_QBITS) != NULL
-        || OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST) != NULL
-        || OSSL_PARAM_locate_const(params,
-                                   OSSL_PKEY_PARAM_FFC_DIGEST_PROPS) != NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+    if (p.generator != NULL && !OSSL_PARAM_get_int(p.generator, &gctx->generator))
         return 0;
-    }
+
     return 1;
 }
 
index 04245bf555a46aafd3b08e87ce1f28a31381cb75..554903990f153c0d56d464d63aeb1c809dcb71fb 100644 (file)
@@ -6,6 +6,9 @@
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
  */
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+-}
 
 /*
  * DSA low level APIs are deprecated for public use, but still ok for
@@ -17,6 +20,7 @@
 #include <openssl/core_names.h>
 #include <openssl/bn.h>
 #include <openssl/err.h>
+#include <openssl/proverr.h>
 #include "prov/securitycheck.h"
 #include "prov/providercommon.h"
 #include "prov/implementations.h"
@@ -98,8 +102,8 @@ static int dsa_gen_type_name2id(const char *name)
     return -1;
 }
 
-static int dsa_key_todata(DSA *dsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[],
-                          int include_private)
+static int dsa_key_todata(DSA *dsa, OSSL_PARAM_BLD *bld, OSSL_PARAM *pubkey,
+                          OSSL_PARAM *privkey, int include_private)
 {
     const BIGNUM *priv = NULL, *pub = NULL;
 
@@ -109,10 +113,10 @@ static int dsa_key_todata(DSA *dsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[],
     DSA_get0_key(dsa, &pub, &priv);
     if (include_private
         && priv != NULL
-        && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PRIV_KEY, priv))
+        && !ossl_param_build_set_bn(bld, privkey, OSSL_PKEY_PARAM_PRIV_KEY, priv))
         return 0;
     if (pub != NULL
-        && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PUB_KEY, pub))
+        && !ossl_param_build_set_bn(bld, pubkey, OSSL_PKEY_PARAM_PUB_KEY, pub))
         return 0;
 
     return 1;
@@ -239,7 +243,7 @@ static int dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
         int include_private =
             selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
 
-        ok = ok && dsa_key_todata(dsa, tmpl, NULL, include_private);
+        ok = ok && dsa_key_todata(dsa, tmpl, NULL, NULL, include_private);
     }
 
     if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
@@ -312,45 +316,67 @@ static const OSSL_PARAM *dsa_export_types(int selection)
     return dsa_imexport_types(selection);
 }
 
+struct dsa_params_st {
+    FFC_PARAM_PTRS ffp;
+    OSSL_PARAM *bits;
+    OSSL_PARAM *secbits;
+    OSSL_PARAM *maxsize;
+    OSSL_PARAM *seccat;
+    OSSL_PARAM *digest;
+    OSSL_PARAM *privkey;
+    OSSL_PARAM *pubkey;
+};
+
+#define dsa_get_params_st dsa_params_st
+
+{- produce_param_decoder('dsa_get_params',
+                         (['PKEY_PARAM_BITS',               'bits',           'int'],
+                          ['PKEY_PARAM_SECURITY_BITS',      'secbits',        'int'],
+                          ['PKEY_PARAM_MAX_SIZE',           'maxsize',        'int'],
+                          ['PKEY_PARAM_SECURITY_CATEGORY',  'seccat',         'int'],
+                          ['PKEY_PARAM_DEFAULT_DIGEST',     'digest',         'utf8_string'],
+                          ['PKEY_PARAM_FFC_P',              'ffp.p',          'BN'],
+                          ['PKEY_PARAM_FFC_Q',              'ffp.q',          'BN'],
+                          ['PKEY_PARAM_FFC_G',              'ffp.g',          'BN'],
+                          ['PKEY_PARAM_FFC_COFACTOR',       'ffp.cofactor',   'BN'],
+                          ['PKEY_PARAM_FFC_GINDEX',         'ffp.g_index',    'int'],
+                          ['PKEY_PARAM_FFC_PCOUNTER',       'ffp.p_counter',  'int'],
+                          ['PKEY_PARAM_FFC_H',              'ffp.h',          'int'],
+                          ['PKEY_PARAM_FFC_SEED',           'ffp.seed',       'octet_string'],
+                          ['PKEY_PARAM_PUB_KEY',            'pubkey',         'BN'],
+                          ['PKEY_PARAM_PRIV_KEY',           'privkey',        'BN'],
+                         )); -}
+
 static ossl_inline int dsa_get_params(void *key, OSSL_PARAM params[])
 {
     DSA *dsa = key;
-    OSSL_PARAM *p;
+    struct dsa_params_st p;
 
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
-        && !OSSL_PARAM_set_int(p, DSA_bits(dsa)))
+    if (key == NULL || !dsa_get_params_decoder(params, &p))
         return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
-        && !OSSL_PARAM_set_int(p, DSA_security_bits(dsa)))
+
+    if (p.bits != NULL && !OSSL_PARAM_set_int(p.bits, DSA_bits(dsa)))
         return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
-        && !OSSL_PARAM_set_int(p, DSA_size(dsa)))
+
+    if (p.secbits != NULL && !OSSL_PARAM_set_int(p.secbits, DSA_security_bits(dsa)))
         return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL
-        && !OSSL_PARAM_set_utf8_string(p, DSA_DEFAULT_MD))
+
+    if (p.maxsize != NULL && !OSSL_PARAM_set_int(p.maxsize, DSA_size(dsa)))
         return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_CATEGORY)) != NULL
-        && !OSSL_PARAM_set_int(p, 0))
+
+    if (p.digest != NULL && !OSSL_PARAM_set_utf8_string(p.digest, DSA_DEFAULT_MD))
         return 0;
-    return ossl_ffc_params_todata(ossl_dsa_get0_params(dsa), NULL, params)
-           && dsa_key_todata(dsa, NULL, params, 1);
-}
 
-static const OSSL_PARAM dsa_params[] = {
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL),
-    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),
-    DSA_IMEXPORTABLE_PARAMETERS,
-    DSA_IMEXPORTABLE_PUBLIC_KEY,
-    DSA_IMEXPORTABLE_PRIVATE_KEY,
-    OSSL_PARAM_END
-};
+    if (p.seccat != NULL && !OSSL_PARAM_set_int(p.seccat, 0))
+        return 0;
+
+    return ossl_ffc_params_todata(ossl_dsa_get0_params(dsa), NULL, &p.ffp)
+           && dsa_key_todata(dsa, NULL, p.pubkey, p.privkey, 1);
+}
 
 static const OSSL_PARAM *dsa_gettable_params(void *provctx)
 {
-    return dsa_params;
+    return dsa_get_params_list;
 }
 
 static int dsa_validate_domparams(const DSA *dsa, int checktype)
@@ -466,25 +492,35 @@ static int dsa_set_gen_seed(struct dsa_gen_ctx *gctx, unsigned char *seed,
     return 1;
 }
 
+{- produce_param_decoder('dsa_gen_set_params',
+                         (['PKEY_PARAM_FFC_TYPE',         'type',      'utf8_string'],
+                          ['PKEY_PARAM_FFC_PBITS',        'pbits',     'size_t'],
+                          ['PKEY_PARAM_FFC_QBITS',        'qbits',     'size_t'],
+                          ['PKEY_PARAM_FFC_DIGEST',       'digest',    'utf8_string'],
+                          ['PKEY_PARAM_FFC_DIGEST_PROPS', 'propq',     'utf8_string'],
+                          ['PKEY_PARAM_FFC_GINDEX',       'g_index',   'int'],
+                          ['PKEY_PARAM_FFC_SEED',         'seed',      'octet_string'],
+                          ['PKEY_PARAM_FFC_PCOUNTER',     'p_counter', 'int'],
+                          ['PKEY_PARAM_FFC_H',            'h',         'int'],
+                          ['PKEY_PARAM_FIPS_SIGN_CHECK',  'ind_sign',  'int', 'fips'],
+                         )); -}
+
 static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
 {
     struct dsa_gen_ctx *gctx = genctx;
-    const OSSL_PARAM *p;
+    struct dsa_gen_set_params_st p;
     int gen_type = -1;
 
-    if (gctx == NULL)
+    if (gctx == NULL || !dsa_gen_set_params_decoder(params, &p))
         return 0;
-    if (ossl_param_is_empty(params))
-        return 1;
 
-    if (!OSSL_FIPS_IND_SET_CTX_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, params,
-                                     OSSL_PKEY_PARAM_FIPS_SIGN_CHECK))
+    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0,
+                                          p.ind_sign))
         return 0;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_TYPE);
-    if (p != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING
-            || ((gen_type = dsa_gen_type_name2id(p->data)) == -1)) {
+    if (p.type != NULL) {
+        if (p.type->data_type != OSSL_PARAM_UTF8_STRING
+            || ((gen_type = dsa_gen_type_name2id(p.type->data)) == -1)) {
             ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
             return 0;
         }
@@ -497,44 +533,41 @@ static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
         if (gen_type != -1)
             gctx->gen_type = gen_type;
     }
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX);
-    if (p != NULL
-        && !OSSL_PARAM_get_int(p, &gctx->gindex))
+
+    if (p.g_index != NULL && !OSSL_PARAM_get_int(p.g_index, &gctx->gindex))
         return 0;
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PCOUNTER);
-    if (p != NULL
-        && !OSSL_PARAM_get_int(p, &gctx->pcounter))
+
+    if (p.p_counter != NULL && !OSSL_PARAM_get_int(p.p_counter, &gctx->pcounter))
         return 0;
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H);
-    if (p != NULL
-        && !OSSL_PARAM_get_int(p, &gctx->hindex))
+
+    if (p.h != NULL && !OSSL_PARAM_get_int(p.h, &gctx->hindex))
         return 0;
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED);
-    if (p != NULL
-        && (p->data_type != OSSL_PARAM_OCTET_STRING
-            || !dsa_set_gen_seed(gctx, p->data, p->data_size)))
+
+    if (p.seed != NULL
+        && (p.seed->data_type != OSSL_PARAM_OCTET_STRING
+            || !dsa_set_gen_seed(gctx, p.seed->data, p.seed->data_size)))
             return 0;
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PBITS)) != NULL
-        && !OSSL_PARAM_get_size_t(p, &gctx->pbits))
+
+    if (p.pbits != NULL && !OSSL_PARAM_get_size_t(p.pbits, &gctx->pbits))
         return 0;
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_QBITS)) != NULL
-        && !OSSL_PARAM_get_size_t(p, &gctx->qbits))
+
+    if (p.qbits != NULL && !OSSL_PARAM_get_size_t(p.qbits, &gctx->qbits))
         return 0;
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);
-    if (p != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+
+    if (p.digest != NULL) {
+        if (p.digest->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
         OPENSSL_free(gctx->mdname);
-        gctx->mdname = OPENSSL_strdup(p->data);
+        gctx->mdname = OPENSSL_strdup(p.digest->data);
         if (gctx->mdname == NULL)
             return 0;
     }
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
-    if (p != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+
+    if (p.propq != NULL) {
+        if (p.propq->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
         OPENSSL_free(gctx->mdprops);
-        gctx->mdprops = OPENSSL_strdup(p->data);
+        gctx->mdprops = OPENSSL_strdup(p.propq->data);
         if (gctx->mdprops == NULL)
             return 0;
     }
@@ -544,31 +577,22 @@ static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
 static const OSSL_PARAM *dsa_gen_settable_params(ossl_unused void *genctx,
                                                  ossl_unused void *provctx)
 {
-    static OSSL_PARAM settable[] = {
-        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, NULL, 0),
-        OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS, NULL),
-        OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_QBITS, NULL),
-        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, NULL, 0),
-        OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL),
-        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0),
-        OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL),
-        OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL),
-        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_PKEY_PARAM_FIPS_SIGN_CHECK)
-        OSSL_PARAM_END
-    };
-    return settable;
+    return dsa_gen_set_params_list;
 }
 
+{- produce_param_decoder('dsa_gen_get_params',
+                         (['PKEY_PARAM_FIPS_APPROVED_INDICATOR', 'ind', 'int', 'fips'],
+                         )); -}
+
 static int dsa_gen_get_params(void *genctx, OSSL_PARAM *params)
 {
     struct dsa_gen_ctx *gctx = genctx;
+    struct dsa_gen_get_params_st p;
 
-    if (gctx == NULL)
+    if (gctx == NULL || !dsa_gen_get_params_decoder(params, &p))
         return 0;
-    if (ossl_param_is_empty(params))
-        return 1;
-    if (!OSSL_FIPS_IND_GET_CTX_PARAM(gctx, params))
+
+    if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM(gctx, p.ind))
         return 0;
     return 1;
 }
@@ -576,12 +600,7 @@ static int dsa_gen_get_params(void *genctx, OSSL_PARAM *params)
 static const OSSL_PARAM *dsa_gen_gettable_params(ossl_unused void *ctx,
                                                  ossl_unused void *provctx)
 {
-    static const OSSL_PARAM dsa_gen_gettable_params_table[] = {
-        OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
-        OSSL_PARAM_END
-    };
-
-    return dsa_gen_gettable_params_table;
+    return dsa_gen_get_params_list;
 }
 
 static int dsa_gencb(int p, int n, BN_GENCB *cb)