Commit ee8da734a8 for openssl.org

commit ee8da734a879a235b18ae4752d25e5ffec1c4bc4
Author: Pauli <paul.dale@oracle.com>
Date:   Thu Aug 27 11:09:44 2026 +1000

    providers: convert non-legacy cipher parameter parsing

    Use generated trie decoders for common, CTS and TDES parameter handling.

    Assisted-by: ChatGPT:gpt-5.6Sol
    Reviewed-by: Simo Sorce <simo@redhat.com>
    Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
    Merge-date: Thu Sep  3 02:16:47 2026
    Merged-from: https://github.com/openssl/openssl/pull/32536

diff --git a/.gitignore b/.gitignore
index 520985702f..5f9dd45aca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -165,10 +165,12 @@ providers/implementations/ciphers/ciphercommon_ccm.inc
 providers/implementations/ciphers/ciphercommon_gcm.inc
 providers/implementations/ciphers/cipher_chacha20.inc
 providers/implementations/ciphers/cipher_chacha20_poly1305.inc
+providers/implementations/ciphers/cipher_cts.inc
 providers/implementations/ciphers/cipher_null.inc
 providers/implementations/ciphers/cipher_rc4_hmac_md5.inc
 providers/implementations/ciphers/cipher_sm2_xts.c
 providers/implementations/ciphers/cipher_sm4_xts.inc
+providers/implementations/ciphers/cipher_tdes.inc
 providers/implementations/digests/blake2_prov.inc
 providers/implementations/digests/digestcommon.inc
 providers/implementations/digests/mdc2_prov.inc
diff --git a/build.info b/build.info
index 0c1b19bb87..2f6c3d83dd 100644
--- a/build.info
+++ b/build.info
@@ -147,9 +147,11 @@ DEPEND[]=include/openssl/asn1.h \
          providers/implementations/ciphers/ciphercommon_gcm.inc \
          providers/implementations/ciphers/cipher_chacha20.inc \
          providers/implementations/ciphers/cipher_chacha20_poly1305.inc \
+         providers/implementations/ciphers/cipher_cts.inc \
          providers/implementations/ciphers/cipher_null.inc \
          providers/implementations/ciphers/cipher_rc4_hmac_md5.inc \
          providers/implementations/ciphers/cipher_sm4_xts.inc \
+         providers/implementations/ciphers/cipher_tdes.inc \
          providers/implementations/digests/blake2_prov.inc \
          providers/implementations/digests/digestcommon.inc \
          providers/implementations/digests/mdc2_prov.inc \
@@ -278,9 +280,11 @@ DEPEND[providers/implementations/asymciphers/rsa_enc.inc \
        providers/implementations/ciphers/ciphercommon_gcm.inc \
        providers/implementations/ciphers/cipher_chacha20.inc \
        providers/implementations/ciphers/cipher_chacha20_poly1305.inc \
+       providers/implementations/ciphers/cipher_cts.inc \
        providers/implementations/ciphers/cipher_null.inc \
        providers/implementations/ciphers/cipher_rc4_hmac_md5.inc \
        providers/implementations/ciphers/cipher_sm4_xts.inc \
+       providers/implementations/ciphers/cipher_tdes.inc \
        providers/implementations/digests/blake2_prov.inc \
        providers/implementations/digests/ml_dsa_mu_prov.inc \
        providers/implementations/digests/digestcommon.inc \
@@ -446,12 +450,16 @@ GENERATE[providers/implementations/ciphers/cipher_chacha20.inc]=\
     providers/implementations/ciphers/cipher_chacha20.inc.in
 GENERATE[providers/implementations/ciphers/cipher_chacha20_poly1305.inc]=\
     providers/implementations/ciphers/cipher_chacha20_poly1305.inc.in
+GENERATE[providers/implementations/ciphers/cipher_cts.inc]=\
+    providers/implementations/ciphers/cipher_cts.inc.in
 GENERATE[providers/implementations/ciphers/cipher_null.inc]=\
     providers/implementations/ciphers/cipher_null.inc.in
 GENERATE[providers/implementations/ciphers/cipher_rc4_hmac_md5.inc]=\
     providers/implementations/ciphers/cipher_rc4_hmac_md5.inc.in
 GENERATE[providers/implementations/ciphers/cipher_sm4_xts.inc]=\
     providers/implementations/ciphers/cipher_sm4_xts.inc.in
+GENERATE[providers/implementations/ciphers/cipher_tdes.inc]=\
+    providers/implementations/ciphers/cipher_tdes.inc.in
 GENERATE[providers/implementations/digests/blake2_prov.inc]=\
     providers/implementations/digests/blake2_prov.inc.in
 GENERATE[providers/implementations/digests/digestcommon.inc]=\
diff --git a/providers/implementations/ciphers/cipher_aes_cts.inc b/providers/implementations/ciphers/cipher_aes_cts.inc
index 1fb5ec3553..2fff8e917d 100644
--- a/providers/implementations/ciphers/cipher_aes_cts.inc
+++ b/providers/implementations/ciphers/cipher_aes_cts.inc
@@ -9,21 +9,12 @@

 /* Dispatch functions for AES CBC CTS ciphers */

-#include <openssl/proverr.h>
 #include "cipher_cts.h"

 #define CTS_FLAGS PROV_CIPHER_FLAG_CTS

 static OSSL_FUNC_cipher_encrypt_init_fn aes_cbc_cts_einit;
 static OSSL_FUNC_cipher_decrypt_init_fn aes_cbc_cts_dinit;
-static OSSL_FUNC_cipher_get_ctx_params_fn aes_cbc_cts_get_ctx_params;
-static OSSL_FUNC_cipher_set_ctx_params_fn aes_cbc_cts_set_ctx_params;
-static OSSL_FUNC_cipher_gettable_ctx_params_fn aes_cbc_cts_gettable_ctx_params;
-static OSSL_FUNC_cipher_settable_ctx_params_fn aes_cbc_cts_settable_ctx_params;
-
-CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(aes_cbc_cts)
-OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0),
-CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(aes_cbc_cts)

 static int aes_cbc_cts_einit(void *ctx, const unsigned char *key, size_t keylen,
                              const unsigned char *iv, size_t ivlen,
@@ -31,7 +22,7 @@ static int aes_cbc_cts_einit(void *ctx, const unsigned char *key, size_t keylen,
 {
     if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL))
         return 0;
-    return aes_cbc_cts_set_ctx_params(ctx, params);
+    return ossl_cipher_cbc_cts_set_ctx_params(ctx, params);
 }

 static int aes_cbc_cts_dinit(void *ctx, const unsigned char *key, size_t keylen,
@@ -40,50 +31,7 @@ static int aes_cbc_cts_dinit(void *ctx, const unsigned char *key, size_t keylen,
 {
     if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL))
         return 0;
-    return aes_cbc_cts_set_ctx_params(ctx, params);
-}
-
-static int aes_cbc_cts_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
-    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
-    OSSL_PARAM *p;
-
-    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS_MODE);
-    if (p != NULL) {
-        const char *name = ossl_cipher_cbc_cts_mode_id2name(ctx->cts_mode);
-
-        if (name == NULL || !OSSL_PARAM_set_utf8_string(p, name)) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-            return 0;
-        }
-    }
-    return ossl_cipher_generic_get_ctx_params(vctx, params);
-}
-
-CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(aes_cbc_cts)
-OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0),
-CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(aes_cbc_cts)
-
-static int aes_cbc_cts_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
-    const OSSL_PARAM *p;
-    int id;
-
-    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_CTS_MODE);
-    if (p != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            goto err;
-        id = ossl_cipher_cbc_cts_mode_name2id(p->data);
-        if (id < 0)
-            goto err;
-
-        ctx->cts_mode = (unsigned int)id;
-    }
-    return ossl_cipher_generic_set_ctx_params(vctx, params);
-err:
-    ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-    return 0;
+    return ossl_cipher_cbc_cts_set_ctx_params(ctx, params);
 }

 /* ossl_aes256cbc_cts_functions */
diff --git a/providers/implementations/ciphers/cipher_camellia_cts.inc b/providers/implementations/ciphers/cipher_camellia_cts.inc
index 84ea992b8d..9e29827e02 100644
--- a/providers/implementations/ciphers/cipher_camellia_cts.inc
+++ b/providers/implementations/ciphers/cipher_camellia_cts.inc
@@ -9,21 +9,12 @@

 /* Dispatch functions for CAMELLIA CBC CTS ciphers */

-#include <openssl/proverr.h>
 #include "cipher_cts.h"

 #define CTS_FLAGS PROV_CIPHER_FLAG_CTS

 static OSSL_FUNC_cipher_encrypt_init_fn camellia_cbc_cts_einit;
 static OSSL_FUNC_cipher_decrypt_init_fn camellia_cbc_cts_dinit;
-static OSSL_FUNC_cipher_get_ctx_params_fn camellia_cbc_cts_get_ctx_params;
-static OSSL_FUNC_cipher_set_ctx_params_fn camellia_cbc_cts_set_ctx_params;
-static OSSL_FUNC_cipher_gettable_ctx_params_fn camellia_cbc_cts_gettable_ctx_params;
-static OSSL_FUNC_cipher_settable_ctx_params_fn camellia_cbc_cts_settable_ctx_params;
-
-CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(camellia_cbc_cts)
-OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0),
-CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(camellia_cbc_cts)

 static int camellia_cbc_cts_einit(void *ctx, const unsigned char *key, size_t keylen,
                              const unsigned char *iv, size_t ivlen,
@@ -31,7 +22,7 @@ static int camellia_cbc_cts_einit(void *ctx, const unsigned char *key, size_t ke
 {
     if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL))
         return 0;
-    return camellia_cbc_cts_set_ctx_params(ctx, params);
+    return ossl_cipher_cbc_cts_set_ctx_params(ctx, params);
 }

 static int camellia_cbc_cts_dinit(void *ctx, const unsigned char *key, size_t keylen,
@@ -40,50 +31,7 @@ static int camellia_cbc_cts_dinit(void *ctx, const unsigned char *key, size_t ke
 {
     if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL))
         return 0;
-    return camellia_cbc_cts_set_ctx_params(ctx, params);
-}
-
-static int camellia_cbc_cts_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
-    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
-    OSSL_PARAM *p;
-
-    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS_MODE);
-    if (p != NULL) {
-        const char *name = ossl_cipher_cbc_cts_mode_id2name(ctx->cts_mode);
-
-        if (name == NULL || !OSSL_PARAM_set_utf8_string(p, name)) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-            return 0;
-        }
-    }
-    return ossl_cipher_generic_get_ctx_params(vctx, params);
-}
-
-CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(camellia_cbc_cts)
-OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0),
-CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(camellia_cbc_cts)
-
-static int camellia_cbc_cts_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
-    const OSSL_PARAM *p;
-    int id;
-
-    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_CTS_MODE);
-    if (p != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            goto err;
-        id = ossl_cipher_cbc_cts_mode_name2id(p->data);
-        if (id < 0)
-            goto err;
-
-        ctx->cts_mode = (unsigned int)id;
-    }
-    return ossl_cipher_generic_set_ctx_params(vctx, params);
-err:
-    ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-    return 0;
+    return ossl_cipher_cbc_cts_set_ctx_params(ctx, params);
 }

 /* ossl_camellia256cbc_cts_functions */
diff --git a/providers/implementations/ciphers/cipher_cts.c b/providers/implementations/ciphers/cipher_cts.c
index 54c6d49d9f..e292d37fc6 100644
--- a/providers/implementations/ciphers/cipher_cts.c
+++ b/providers/implementations/ciphers/cipher_cts.c
@@ -47,10 +47,25 @@
  */

 #include <openssl/core_names.h>
+#include <openssl/proverr.h>
 #include "prov/ciphercommon.h"
 #include "internal/nelem.h"
 #include "cipher_cts.h"

+struct cipher_cts_get_ctx_param_list_st {
+    struct ossl_cipher_get_ctx_param_list_st common;
+    OSSL_PARAM *mode;
+};
+
+struct cipher_cts_set_ctx_param_list_st {
+    OSSL_PARAM *mode;
+};
+
+#define cipher_cts_get_ctx_params_st cipher_cts_get_ctx_param_list_st
+#define cipher_cts_set_ctx_params_st cipher_cts_set_ctx_param_list_st
+
+#include "providers/implementations/ciphers/cipher_cts.inc"
+
 /* The value assigned to 0 is the default */
 #define CTS_CS1 0
 #define CTS_CS2 1
@@ -96,6 +111,63 @@ int ossl_cipher_cbc_cts_mode_name2id(const char *name)
     return -1;
 }

+int ossl_cipher_cbc_cts_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+    struct cipher_cts_get_ctx_param_list_st p;
+
+    if (ctx == NULL || !cipher_cts_get_ctx_params_decoder(params, &p))
+        return 0;
+
+    if (!ossl_cipher_common_get_ctx_params(ctx, &p.common))
+        return 0;
+
+    if (p.mode != NULL) {
+        const char *name = ossl_cipher_cbc_cts_mode_id2name(ctx->cts_mode);
+
+        if (name == NULL || !OSSL_PARAM_set_utf8_string(p.mode, name)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+const OSSL_PARAM *ossl_cipher_cbc_cts_gettable_ctx_params(
+    ossl_unused void *cctx, ossl_unused void *provctx)
+{
+    return cipher_cts_get_ctx_params_list;
+}
+
+int ossl_cipher_cbc_cts_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+    struct cipher_cts_set_ctx_param_list_st p;
+
+    if (ctx == NULL || !cipher_cts_set_ctx_params_decoder(params, &p))
+        return 0;
+
+    if (p.mode != NULL) {
+        int id;
+
+        if (p.mode->data_type != OSSL_PARAM_UTF8_STRING
+            || p.mode->data == NULL
+            || (id = ossl_cipher_cbc_cts_mode_name2id(p.mode->data)) < 0) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
+        }
+        ctx->cts_mode = (unsigned int)id;
+    }
+
+    return 1;
+}
+
+const OSSL_PARAM *ossl_cipher_cbc_cts_settable_ctx_params(
+    ossl_unused void *cctx, ossl_unused void *provctx)
+{
+    return cipher_cts_set_ctx_params_list;
+}
+
 static size_t cts128_cs1_encrypt(PROV_CIPHER_CTX *ctx, const unsigned char *in,
     unsigned char *out, size_t len)
 {
diff --git a/providers/implementations/ciphers/cipher_cts.h b/providers/implementations/ciphers/cipher_cts.h
index 8bae4f8d3b..80a4ddcebe 100644
--- a/providers/implementations/ciphers/cipher_cts.h
+++ b/providers/implementations/ciphers/cipher_cts.h
@@ -38,18 +38,22 @@
         { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                      \
             (void (*)(void))ossl_cipher_generic_gettable_params },               \
         { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                       \
-            (void (*)(void))alg##_cbc_cts_get_ctx_params },                      \
+            (void (*)(void))ossl_cipher_cbc_cts_get_ctx_params },                \
         { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                       \
-            (void (*)(void))alg##_cbc_cts_set_ctx_params },                      \
+            (void (*)(void))ossl_cipher_cbc_cts_set_ctx_params },                \
         { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                  \
-            (void (*)(void))alg##_cbc_cts_gettable_ctx_params },                 \
+            (void (*)(void))ossl_cipher_cbc_cts_gettable_ctx_params },           \
         { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                  \
-            (void (*)(void))alg##_cbc_cts_settable_ctx_params },                 \
+            (void (*)(void))ossl_cipher_cbc_cts_settable_ctx_params },           \
         OSSL_DISPATCH_END                                                        \
     };

 OSSL_FUNC_cipher_update_fn ossl_cipher_cbc_cts_block_update;
 OSSL_FUNC_cipher_final_fn ossl_cipher_cbc_cts_block_final;
+OSSL_FUNC_cipher_get_ctx_params_fn ossl_cipher_cbc_cts_get_ctx_params;
+OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_cbc_cts_set_ctx_params;
+OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_cbc_cts_gettable_ctx_params;
+OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_cbc_cts_settable_ctx_params;

 const char *ossl_cipher_cbc_cts_mode_id2name(unsigned int id);
 int ossl_cipher_cbc_cts_mode_name2id(const char *name);
diff --git a/providers/implementations/ciphers/cipher_cts.inc.in b/providers/implementations/ciphers/cipher_cts.inc.in
new file mode 100644
index 0000000000..d5b921729b
--- /dev/null
+++ b/providers/implementations/ciphers/cipher_cts.inc.in
@@ -0,0 +1,24 @@
+/*
+ * 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);
+-}
+
+{- produce_param_decoder('cipher_cts_get_ctx_params',
+                         (['OSSL_CIPHER_PARAM_KEYLEN',     'common.keylen', 'size_t'],
+                          ['OSSL_CIPHER_PARAM_IVLEN',      'common.ivlen',  'size_t'],
+                          ['OSSL_CIPHER_PARAM_IV',         'common.iv',     'octet_string'],
+                          ['OSSL_CIPHER_PARAM_UPDATED_IV', 'common.updiv',  'octet_string'],
+                          ['OSSL_CIPHER_PARAM_CTS_MODE',   'mode',          'utf8_string'],
+                         )); -}
+
+{- produce_param_decoder('cipher_cts_set_ctx_params',
+                         (['OSSL_CIPHER_PARAM_CTS_MODE', 'mode', 'utf8_string'],
+                         )); -}
diff --git a/providers/implementations/ciphers/cipher_tdes.h b/providers/implementations/ciphers/cipher_tdes.h
index d3c383506f..1cf22ec56c 100644
--- a/providers/implementations/ciphers/cipher_tdes.h
+++ b/providers/implementations/ciphers/cipher_tdes.h
@@ -65,7 +65,7 @@ typedef struct prov_tdes_ctx_st {
         { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
             (void (*)(void))tdes_##type##_##lcmode##_get_params },                 \
         { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
-            (void (*)(void))ossl_cipher_generic_gettable_params },                 \
+            (void (*)(void))ossl_tdes_gettable_params },                           \
         { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
             (void (*)(void))ossl_tdes_get_ctx_params },                            \
         { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
@@ -87,6 +87,7 @@ OSSL_FUNC_cipher_freectx_fn ossl_tdes_freectx;
 OSSL_FUNC_cipher_encrypt_init_fn ossl_tdes_einit;
 OSSL_FUNC_cipher_decrypt_init_fn ossl_tdes_dinit;
 OSSL_FUNC_cipher_get_ctx_params_fn ossl_tdes_get_ctx_params;
+OSSL_FUNC_cipher_gettable_params_fn ossl_tdes_gettable_params;
 OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_tdes_gettable_ctx_params;
 OSSL_FUNC_cipher_set_ctx_params_fn ossl_tdes_set_ctx_params;
 OSSL_FUNC_cipher_settable_ctx_params_fn ossl_tdes_settable_ctx_params;
diff --git a/providers/implementations/ciphers/cipher_tdes.inc.in b/providers/implementations/ciphers/cipher_tdes.inc.in
new file mode 100644
index 0000000000..a05efdd112
--- /dev/null
+++ b/providers/implementations/ciphers/cipher_tdes.inc.in
@@ -0,0 +1,43 @@
+/*
+ * 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);
+-}
+
+{- produce_param_decoder('tdes_get_params',
+                         (['OSSL_CIPHER_PARAM_MODE',             'common.mode',   'uint'],
+                          ['OSSL_CIPHER_PARAM_KEYLEN',           'common.keylen', 'size_t'],
+                          ['OSSL_CIPHER_PARAM_IVLEN',            'common.ivlen',  'size_t'],
+                          ['OSSL_CIPHER_PARAM_BLOCK_SIZE',       'common.bsize',  'size_t'],
+                          ['OSSL_CIPHER_PARAM_CUSTOM_IV',        'common.custiv', 'int'],
+                          ['OSSL_CIPHER_PARAM_HAS_RAND_KEY',     'common.rand',   'int'],
+                          ['OSSL_CIPHER_PARAM_DECRYPT_ONLY',     'decrypt',       'int'],
+                         )); -}
+
+{- produce_param_decoder('tdes_get_ctx_params',
+                         (['OSSL_CIPHER_PARAM_KEYLEN',                 'common.keylen', 'size_t'],
+                          ['OSSL_CIPHER_PARAM_IVLEN',                  'common.ivlen',  'size_t'],
+                          ['OSSL_CIPHER_PARAM_PADDING',                'common.pad',    'uint'],
+                          ['OSSL_CIPHER_PARAM_NUM',                    'common.num',    'uint'],
+                          ['OSSL_CIPHER_PARAM_IV',                     'common.iv',     'octet_string'],
+                          ['OSSL_CIPHER_PARAM_UPDATED_IV',             'common.updiv',  'octet_string'],
+                          ['OSSL_CIPHER_PARAM_TLS_MAC',                'common.tlsmac', 'octet_ptr'],
+                          ['OSSL_CIPHER_PARAM_RANDOM_KEY',             'rand',          'octet_string'],
+                          ['OSSL_CIPHER_PARAM_FIPS_APPROVED_INDICATOR', 'ind',          'int', 'fips'],
+                         )); -}
+
+{- produce_param_decoder('tdes_set_ctx_params',
+                         (['OSSL_CIPHER_PARAM_PADDING',            'common.pad',        'uint'],
+                          ['OSSL_CIPHER_PARAM_NUM',                'common.num',        'uint'],
+                          ['OSSL_CIPHER_PARAM_USE_BITS',           'common.bits',       'uint'],
+                          ['OSSL_CIPHER_PARAM_TLS_VERSION',        'common.tlsvers',    'uint'],
+                          ['OSSL_CIPHER_PARAM_TLS_MAC_SIZE',       'common.tlsmacsize', 'size_t'],
+                          ['OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK', 'ind',                'int', 'fips'],
+                         )); -}
diff --git a/providers/implementations/ciphers/cipher_tdes_common.c b/providers/implementations/ciphers/cipher_tdes_common.c
index 20dc77f32c..765ed5b8e7 100644
--- a/providers/implementations/ciphers/cipher_tdes_common.c
+++ b/providers/implementations/ciphers/cipher_tdes_common.c
@@ -20,6 +20,32 @@
 #include "prov/implementations.h"
 #include "prov/providercommon.h"

+struct tdes_get_param_list_st {
+    struct ossl_cipher_get_param_list_st common;
+    OSSL_PARAM *decrypt;
+};
+
+struct tdes_get_ctx_param_list_st {
+    struct ossl_cipher_get_ctx_param_list_st common;
+    OSSL_PARAM *rand;
+#ifdef FIPS_MODULE
+    OSSL_PARAM *ind;
+#endif
+};
+
+struct tdes_set_ctx_param_list_st {
+    struct ossl_cipher_set_ctx_param_list_st common;
+#ifdef FIPS_MODULE
+    OSSL_PARAM *ind;
+#endif
+};
+
+#define tdes_get_params_st tdes_get_param_list_st
+#define tdes_get_ctx_params_st tdes_get_ctx_param_list_st
+#define tdes_set_ctx_params_st tdes_set_ctx_param_list_st
+
+#include "providers/implementations/ciphers/cipher_tdes.inc"
+
 void *ossl_tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
     size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw)
 {
@@ -130,12 +156,7 @@ int ossl_tdes_dinit(void *vctx, const unsigned char *key, size_t keylen,
     return tdes_init(vctx, key, keylen, iv, ivlen, params, 0);
 }

-CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_tdes)
-OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0),
-    OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
-        CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(ossl_tdes)
-
-            static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr)
+static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr)
 {
     DES_cblock *deskey = ptr;
     size_t kl = ctx->keylen;
@@ -151,35 +172,54 @@ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0),
     return 1;
 }

+const OSSL_PARAM *ossl_tdes_gettable_ctx_params(ossl_unused void *cctx,
+    ossl_unused void *provctx)
+{
+    return tdes_get_ctx_params_list;
+}
+
 int ossl_tdes_get_ctx_params(void *vctx, OSSL_PARAM params[])
 {
     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
-    OSSL_PARAM *p;
+    struct tdes_get_ctx_param_list_st p;

-    if (!ossl_cipher_generic_get_ctx_params(vctx, params))
+    if (ctx == NULL || !tdes_get_ctx_params_decoder(params, &p))
         return 0;

-    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY);
-    if (p != NULL && !tdes_generatekey(ctx, p->data)) {
+    if (!ossl_cipher_common_get_ctx_params(ctx, &p.common))
+        return 0;
+
+    if (p.rand != NULL && !tdes_generatekey(ctx, p.rand->data)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY);
         return 0;
     }
-    if (!OSSL_FIPS_IND_GET_CTX_PARAM((PROV_TDES_CTX *)vctx, params))
+    if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM((PROV_TDES_CTX *)vctx, p.ind))
         return 0;
     return 1;
 }

-CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_tdes)
-OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK)
-CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_tdes)
+const OSSL_PARAM *ossl_tdes_settable_ctx_params(ossl_unused void *cctx,
+    ossl_unused void *provctx)
+{
+    return tdes_set_ctx_params_list;
+}

 int ossl_tdes_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 {
-    if (!OSSL_FIPS_IND_SET_CTX_PARAM((PROV_TDES_CTX *)vctx,
-            OSSL_FIPS_IND_SETTABLE0, params,
-            OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK))
+    PROV_TDES_CTX *ctx = (PROV_TDES_CTX *)vctx;
+    struct tdes_set_ctx_param_list_st p;
+
+    if (ctx == NULL || !tdes_set_ctx_params_decoder(params, &p))
+        return 0;
+    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p.ind))
         return 0;
-    return ossl_cipher_generic_set_ctx_params(vctx, params);
+
+    return ossl_cipher_common_set_ctx_params(&ctx->base, &p.common);
+}
+
+const OSSL_PARAM *ossl_tdes_gettable_params(ossl_unused void *provctx)
+{
+    return tdes_get_params_list;
 }

 int ossl_tdes_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags,
@@ -190,14 +230,16 @@ int ossl_tdes_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags,
 #else
     const int decrypt_only = 0;
 #endif
-    OSSL_PARAM *p;
+    struct tdes_get_param_list_st p;
+
+    if (!tdes_get_params_decoder(params, &p))
+        return 0;

-    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_DECRYPT_ONLY);
-    if (p != NULL && !OSSL_PARAM_set_int(p, decrypt_only)) {
+    if (p.decrypt != NULL && !OSSL_PARAM_set_int(p.decrypt, decrypt_only)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }

-    return ossl_cipher_generic_get_params(params, md, flags,
-        kbits, blkbits, ivbits);
+    return ossl_cipher_common_get_params(&p.common, md, flags, kbits, blkbits,
+        ivbits);
 }
diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c
index 01b34e4ea0..cedfe05465 100644
--- a/providers/implementations/ciphers/ciphercommon.c
+++ b/providers/implementations/ciphers/ciphercommon.c
@@ -22,6 +22,7 @@
 #include "internal/e_os.h"
 #include "crypto/types.h"

+#define ossl_cipher_generic_get_params_st ossl_cipher_get_param_list_st
 #define cipher_generic_get_ctx_params_st ossl_cipher_get_ctx_param_list_st
 #define cipher_generic_set_ctx_params_st ossl_cipher_set_ctx_param_list_st
 #define cipher_var_keylen_set_ctx_params_st ossl_cipher_set_ctx_param_list_st
@@ -41,54 +42,69 @@ int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
     uint64_t flags,
     size_t kbits, size_t blkbits, size_t ivbits)
 {
-    struct ossl_cipher_generic_get_params_st p;
+    struct ossl_cipher_get_param_list_st p;

     if (!ossl_cipher_generic_get_params_decoder(params, &p))
         return 0;

-    if (p.mode != NULL && !OSSL_PARAM_set_uint(p.mode, md)) {
+    return ossl_cipher_common_get_params(&p, md, flags, kbits, blkbits,
+        ivbits);
+}
+
+int ossl_cipher_common_get_params(const struct ossl_cipher_get_param_list_st *p,
+    unsigned int md, uint64_t flags, size_t kbits, size_t blkbits,
+    size_t ivbits)
+{
+    if (p->mode != NULL && !OSSL_PARAM_set_uint(p->mode, md)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-    if (p.aead != NULL
-        && !OSSL_PARAM_set_int(p.aead, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) {
+    if (p->aead != NULL
+        && !OSSL_PARAM_set_int(p->aead, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-    if (p.custiv != NULL
-        && !OSSL_PARAM_set_int(p.custiv, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) {
+    if (p->custiv != NULL
+        && !OSSL_PARAM_set_int(p->custiv,
+            (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-    if (p.cts != NULL
-        && !OSSL_PARAM_set_int(p.cts, (flags & PROV_CIPHER_FLAG_CTS) != 0)) {
+    if (p->cts != NULL
+        && !OSSL_PARAM_set_int(p->cts, (flags & PROV_CIPHER_FLAG_CTS) != 0)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-    if (p.mb != NULL
-        && !OSSL_PARAM_set_int(p.mb, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) {
+    if (p->mb != NULL
+        && !OSSL_PARAM_set_int(p->mb,
+            (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-    if (p.rand != NULL
-        && !OSSL_PARAM_set_int(p.rand, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) {
+    if (p->rand != NULL
+        && !OSSL_PARAM_set_int(p->rand,
+            (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-    if (p.etm != NULL
-        && !OSSL_PARAM_set_int(p.etm, (flags & EVP_CIPH_FLAG_ENC_THEN_MAC) != 0)) {
+    if (p->etm != NULL
+        && !OSSL_PARAM_set_int(p->etm,
+            (flags & EVP_CIPH_FLAG_ENC_THEN_MAC) != 0)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-    if (p.keylen != NULL && !OSSL_PARAM_set_size_t(p.keylen, kbits / 8)) {
+    if (p->keylen != NULL
+        && !OSSL_PARAM_set_size_t(p->keylen, kbits / 8)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-    if (p.bsize != NULL && !OSSL_PARAM_set_size_t(p.bsize, blkbits / 8)) {
+    if (p->bsize != NULL
+        && !OSSL_PARAM_set_size_t(p->bsize, blkbits / 8)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-    if (p.ivlen != NULL && !OSSL_PARAM_set_size_t(p.ivlen, ivbits / 8)) {
+    if (p->ivlen != NULL
+        && !OSSL_PARAM_set_size_t(p->ivlen, ivbits / 8)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
@@ -119,24 +135,9 @@ int ossl_cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
     struct ossl_cipher_set_ctx_param_list_st p;

-    if (ctx == NULL
-        || !cipher_var_keylen_set_ctx_params_decoder(params, &p)
-        || !ossl_cipher_common_set_ctx_params(ctx, &p))
+    if (ctx == NULL || !cipher_var_keylen_set_ctx_params_decoder(params, &p))
         return 0;
-
-    if (p.keylen != NULL) {
-        size_t keylen;
-
-        if (!OSSL_PARAM_get_size_t(p.keylen, &keylen)) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
-            return 0;
-        }
-        if (ctx->keylen != keylen) {
-            ctx->keylen = keylen;
-            ctx->key_set = 0;
-        }
-    }
-    return 1;
+    return ossl_cipher_common_set_ctx_params(ctx, &p);
 }

 void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx)
@@ -669,6 +670,19 @@ int ossl_cipher_common_set_ctx_params(PROV_CIPHER_CTX *ctx, const struct ossl_ci
         }
         ctx->num = num;
     }
+
+    if (p->keylen != NULL) {
+        size_t keylen;
+
+        if (!OSSL_PARAM_get_size_t(p->keylen, &keylen)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        if (ctx->keylen != keylen) {
+            ctx->keylen = keylen;
+            ctx->key_set = 0;
+        }
+    }
     return 1;
 }

diff --git a/providers/implementations/include/prov/ciphercommon.h b/providers/implementations/include/prov/ciphercommon.h
index b34d62946a..802333e2ec 100644
--- a/providers/implementations/include/prov/ciphercommon.h
+++ b/providers/implementations/include/prov/ciphercommon.h
@@ -381,6 +381,19 @@ PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_ofb128;
         return name##_known_settable_ctx_params;                         \
     }

+struct ossl_cipher_get_param_list_st {
+    OSSL_PARAM *mode;
+    OSSL_PARAM *keylen;
+    OSSL_PARAM *ivlen;
+    OSSL_PARAM *bsize;
+    OSSL_PARAM *aead;
+    OSSL_PARAM *custiv;
+    OSSL_PARAM *cts;
+    OSSL_PARAM *mb;
+    OSSL_PARAM *rand;
+    OSSL_PARAM *etm;
+};
+
 struct ossl_cipher_get_ctx_param_list_st {
     OSSL_PARAM *keylen; /* all ciphers */
     OSSL_PARAM *ivlen; /* all ciphers */
@@ -400,8 +413,13 @@ struct ossl_cipher_set_ctx_param_list_st {
     OSSL_PARAM *keylen; /* variable key length ciphers */
 };

-int ossl_cipher_common_get_ctx_params(PROV_CIPHER_CTX *ctx, const struct ossl_cipher_get_ctx_param_list_st *p);
-int ossl_cipher_common_set_ctx_params(PROV_CIPHER_CTX *ctx, const struct ossl_cipher_set_ctx_param_list_st *p);
+int ossl_cipher_common_get_params(const struct ossl_cipher_get_param_list_st *p,
+    unsigned int md, uint64_t flags, size_t kbits, size_t blkbits,
+    size_t ivbits);
+int ossl_cipher_common_get_ctx_params(PROV_CIPHER_CTX *ctx,
+    const struct ossl_cipher_get_ctx_param_list_st *p);
+int ossl_cipher_common_set_ctx_params(PROV_CIPHER_CTX *ctx,
+    const struct ossl_cipher_set_ctx_param_list_st *p);

 int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
     size_t ivlen);