Commit 946391aa5a for openssl.org
commit 946391aa5a8945c72df0197392f2466702d6f405
Author: Viktor Dukhovni <openssl-users@dukhovni.org>
Date: Mon Feb 9 20:28:39 2026 +1100
New decoder generator returns matched field count
It can be useful to know how many parameters matched a decoded field,
(or at least whether that number is non-zero).
Tne new `produce_param_decoder_with_count` generator produces code that
updates a count output variable.
In particular, an RSA parameter handler did not handle requests for only
unexpected parameter as gracefully as one might want. It can now
return early when none of the provided parameters are relevant.
[ The number reported is a count of matching parameter values, not a
count of the resulting decoded fields, so if a parameter key occurs
more than once, the count can be larger than the number of fields
actually set. ]
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Yang <paulyang.inf@gmail.com>
MergeDate: Sat Feb 21 13:25:11 2026
(Merged from https://github.com/openssl/openssl/pull/29953)
diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c
index 075209cdbe..3b26105db4 100644
--- a/providers/implementations/asymciphers/rsa_enc.c
+++ b/providers/implementations/asymciphers/rsa_enc.c
@@ -458,9 +458,12 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
char mdname[OSSL_MAX_NAME_SIZE];
char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' };
char *str = NULL;
+ int count = 0;
- if (prsactx == NULL || !rsa_set_ctx_params_decoder(params, &p))
+ if (prsactx == NULL || !rsa_set_ctx_params_decoder(params, &p, &count))
return 0;
+ if (count == 0)
+ return 1;
if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE0, p.ind_k))
return 0;
diff --git a/providers/implementations/asymciphers/rsa_enc.inc.in b/providers/implementations/asymciphers/rsa_enc.inc.in
index baa9bdc8c6..c79aa49f16 100644
--- a/providers/implementations/asymciphers/rsa_enc.inc.in
+++ b/providers/implementations/asymciphers/rsa_enc.inc.in
@@ -8,7 +8,7 @@
*/
{-
-use OpenSSL::paramnames qw(produce_param_decoder);
+use OpenSSL::paramnames qw(produce_param_decoder produce_param_decoder_with_count);
-}
{- produce_param_decoder('rsa_get_ctx_params',
@@ -23,7 +23,7 @@ use OpenSSL::paramnames qw(produce_param_decoder);
['OSSL_ASYM_CIPHER_PARAM_FIPS_APPROVED_INDICATOR', 'ind', 'int', 'fips'],
)); -}
-{- produce_param_decoder('rsa_set_ctx_params',
+{- produce_param_decoder_with_count('rsa_set_ctx_params',
(['OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST', 'oaep', 'utf8_string'],
['OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS', 'oaep_pq', 'utf8_string'],
['OSSL_ASYM_CIPHER_PARAM_PAD_MODE', 'pad', 'utf8_string'],
diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
index 4426543897..5f4a1c3b0c 100644
--- a/providers/implementations/signature/rsa_sig.c
+++ b/providers/implementations/signature/rsa_sig.c
@@ -1520,6 +1520,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
struct rsa_set_ctx_params_st p;
int pad_mode;
int saltlen;
+ int count = 0;
char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = NULL;
char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = NULL;
char mgf1mdname[OSSL_MAX_NAME_SIZE] = "", *pmgf1mdname = NULL;
@@ -1532,12 +1533,14 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
return 1;
if (prsactx->flag_allow_md) {
- if (!rsa_set_ctx_params_decoder(params, &p))
+ if (!rsa_set_ctx_params_decoder(params, &p, &count))
return 0;
} else {
- if (!rsa_set_ctx_params_no_digest_decoder(params, &p))
+ if (!rsa_set_ctx_params_no_digest_decoder(params, &p, &count))
return 0;
}
+ if (count == 0)
+ return 1;
if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE0,
p.ind_k))
diff --git a/providers/implementations/signature/rsa_sig.inc.in b/providers/implementations/signature/rsa_sig.inc.in
index e73e26d819..36a49740b7 100644
--- a/providers/implementations/signature/rsa_sig.inc.in
+++ b/providers/implementations/signature/rsa_sig.inc.in
@@ -8,7 +8,7 @@
*/
{-
-use OpenSSL::paramnames qw(produce_param_decoder);
+use OpenSSL::paramnames qw(produce_param_decoder produce_param_decoder_with_count);
-}
{- produce_param_decoder('rsa_get_ctx_params',
@@ -23,7 +23,7 @@ use OpenSSL::paramnames qw(produce_param_decoder);
['OSSL_SIGNATURE_PARAM_FIPS_APPROVED_INDICATOR', 'ind', 'int', 'fips'],
)); -}
-{- produce_param_decoder('rsa_set_ctx_params',
+{- produce_param_decoder_with_count('rsa_set_ctx_params',
(['OSSL_SIGNATURE_PARAM_DIGEST', 'digest', 'utf8_string'],
['OSSL_SIGNATURE_PARAM_PROPERTIES', 'propq', 'utf8_string'],
['OSSL_SIGNATURE_PARAM_PAD_MODE', 'pad', 'utf8_string'],
@@ -38,7 +38,7 @@ use OpenSSL::paramnames qw(produce_param_decoder);
['OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK', 'ind_xpad', 'int', 'fips'],
)); -}
-{- produce_param_decoder('rsa_set_ctx_params_no_digest',
+{- produce_param_decoder_with_count('rsa_set_ctx_params_no_digest',
(['OSSL_SIGNATURE_PARAM_PAD_MODE', 'pad', 'utf8_string'],
['OSSL_SIGNATURE_PARAM_PAD_MODE', 'pad', 'int'],
['OSSL_SIGNATURE_PARAM_MGF1_DIGEST', 'mgf1', 'utf8_string'],
diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm
index a36f5dbe25..680f4f3317 100644
--- a/util/perl/OpenSSL/paramnames.pm
+++ b/util/perl/OpenSSL/paramnames.pm
@@ -14,7 +14,8 @@ use warnings;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(generate_public_macros
- produce_param_decoder);
+ produce_param_decoder
+ produce_param_decoder_with_count);
my $case_sensitive = 1;
my $need_break = 0;
@@ -690,6 +691,7 @@ sub generate_public_macros {
}
sub trie_matched {
+ my $with_count = shift;
my $field = shift;
my $num = shift;
my $indent1 = shift;
@@ -705,6 +707,7 @@ sub trie_matched {
printf "%s \"param %%s present >%%d times\", s, $num);\n", $indent2;
printf "%sreturn 0;\n", $indent2;
printf "%s}\n", $indent1;
+ printf "%s++*count;\n", $indent1 if $with_count;
printf "%sr->%s[r->num_%s++] = (OSSL_PARAM *)p;\n", $indent1, $field, $field;
} else {
printf "%sif (ossl_unlikely(r->%s != NULL)) {\n", $indent1, $field;
@@ -712,11 +715,13 @@ sub trie_matched {
printf "%s \"param %%s is repeated\", s);\n", $indent2;
printf "%sreturn 0;\n", $indent2;
printf "%s}\n", $indent1;
+ printf "%s++*count;\n", $indent1 if $with_count;
printf "%sr->%s = (OSSL_PARAM *)p;\n", $indent1, $field;
}
}
sub generate_decoder_from_trie {
+ my $with_count = shift;
my $n = shift;
my $trieref = shift;
my $identmap = shift;
@@ -743,7 +748,7 @@ sub generate_decoder_from_trie {
}
print ")) {\n";
printf "%s/* %s */\n", $indent1, $trieref->{'name'};
- trie_matched($field, $num, $indent1, $indent2);
+ trie_matched($with_count, $field, $num, $indent1, $indent2);
printf "%s}\n", $indent0;
# If this is at the top level and it's conditional, we have to
@@ -765,7 +770,7 @@ sub generate_decoder_from_trie {
printf "%sbreak;\n", $indent1;
printf "%scase '\\0':\n", $indent0;
output_ifdef($ifdefs->{$field});
- trie_matched($field, $num, $indent1, $indent2);
+ trie_matched($with_count, $field, $num, $indent1, $indent2);
output_endifdef($ifdefs->{$field});
} else {
printf "%sbreak;\n", $indent1;
@@ -775,7 +780,7 @@ sub generate_decoder_from_trie {
printf " case '%s':", uc $l if ($l =~ /[a-z]/);
}
print "\n";
- generate_decoder_from_trie($n + 1, $trieref->{$l}, $identmap, $concat_num, $ifdefs);
+ generate_decoder_from_trie($with_count, $n + 1, $trieref->{$l}, $identmap, $concat_num, $ifdefs);
}
}
if ($need_break) {
@@ -848,8 +853,7 @@ sub locate_long_endings {
}
sub output_param_decoder {
- my $decoder_name_base = shift;
- my @params = @_;
+ my ($with_count, $decoder_name_base, @params) = @_;
my @keys = ();
my %prms = ();
my %concat_num = ();
@@ -930,13 +934,15 @@ sub output_param_decoder {
printf "#ifndef %s_decoder\n", $decoder_name_base;
printf "static int %s_decoder\n", $decoder_name_base;
- printf " (const OSSL_PARAM *p, struct %s_st *r)\n", $decoder_name_base;
+ printf " (const OSSL_PARAM *p, struct %s_st *r", $decoder_name_base;
+ printf "%s)\n", ($with_count ? ", int *count" : "");
print "{\n";
print " const char *s;\n\n";
+ print " *count = 0;\n" if $with_count;
print " memset(r, 0, sizeof(*r));\n";
print " if (p != NULL)\n";
print " for (; (s = p->key) != NULL; p++)\n";
- generate_decoder_from_trie(0, \%t, \%prms, \%concat_num, \%ifdefs);
+ generate_decoder_from_trie($with_count, 0, \%t, \%prms, \%concat_num, \%ifdefs);
print " return 1;\n";
print "}\n#endif\n";
print "/* End of machine generated */";
@@ -946,6 +952,14 @@ sub produce_param_decoder {
my $s;
open(local *STDOUT, '>', \$s);
- output_param_decoder(@_);
+ output_param_decoder(0, @_);
+ return $s;
+}
+
+sub produce_param_decoder_with_count {
+ my $s;
+
+ open(local *STDOUT, '>', \$s);
+ output_param_decoder(1, @_);
return $s;
}