| #! /usr/bin/env perl |
| # 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 |
| |
| package OpenSSL::fipsparams; |
| |
| use strict; |
| use warnings; |
| use Exporter; |
| |
| our @ISA = qw(Exporter); |
| our @EXPORT_OK = qw(produce_fips_params); |
| |
| sub produce_fips_params { |
| my @params = @_; |
| my $s; |
| open(local *STDOUT, '>', \$s); |
| |
| print "/* Machine generated by util/perl/OpenSSL/fipsparams.pm */\n"; |
| print "\n"; |
| |
| print "#ifdef FIPSPARAMS_AS_HEADER\n"; |
| print "enum fips_config_id {\n"; |
| my $first = " = 1"; |
| foreach my $p (@params) { |
| my $name = $p->[1]; |
| my $use = $p->[4]; |
| if ($use eq 'indicator') { |
| print " FIPS_CONFIG_$name$first,\n"; |
| $first = ""; |
| } |
| } |
| print "};\n"; |
| |
| print "#else /* FIPSPARAMS_AS_HEADER */\n"; |
| print "\n"; |
| print "typedef struct fips_params_st {\n"; |
| foreach my $p (@params) { |
| my $field = $p->[0]; |
| my $type = $p->[2]; |
| my $sep = $type =~ /\*$/ ? "" : " "; |
| printf " $type$sep$field;\n"; |
| } |
| print "} FIPS_PARAMS;\n"; |
| |
| print "\n"; |
| print "static void init_fips_params(FIPS_PARAMS *fp)\n"; |
| print "{\n"; |
| foreach my $p (@params) { |
| my $field = $p->[0]; |
| my $default = $p->[3]; |
| printf " fp->$field = $default;\n"; |
| } |
| print "}\n"; |
| |
| print "\n"; |
| print "/*\n"; |
| print " * Parameters to retrieve from the core provider\n"; |
| print " * NOTE: inside core_get_params() these will be loaded from config items\n"; |
| print " * stored inside prov->parameters\n"; |
| print " */\n"; |
| print "static int fips_get_params_from_core(\n"; |
| print " const OSSL_CORE_HANDLE *handle, FIPS_PARAMS *fp)\n"; |
| print "{\n"; |
| foreach my $p (@params) { |
| my $field = $p->[0]; |
| print " const char *$field = NULL;\n"; |
| } |
| print " OSSL_PARAM core_params[] = {\n"; |
| foreach my $p (@params) { |
| my $field = $p->[0]; |
| my $name = $p->[1]; |
| my $type = $p->[2]; |
| my $use = $p->[4]; |
| if ($use eq 'indicator') { |
| $name = "OSSL_PROV_PARAM_" . $name; |
| } |
| print " OSSL_PARAM_construct_utf8_ptr($name,\n"; |
| print " (char **)&$field, 0),\n"; |
| } |
| print " OSSL_PARAM_construct_end()\n"; |
| print " };\n"; |
| print " OSSL_PARAM *p = core_params;\n"; |
| print "\n"; |
| print " if (!c_get_params(handle, core_params)) {\n"; |
| print " return 0;\n"; |
| print " }\n"; |
| print "\n"; |
| print " for (;p->key != NULL; p++) {\n"; |
| print " if (OSSL_PARAM_modified(p)) {\n"; |
| foreach my $p (@params) { |
| my $field = $p->[0]; |
| my $name = $p->[1]; |
| my $type = $p->[2]; |
| my $use = $p->[4]; |
| if ($use eq 'indicator') { |
| $name = "OSSL_PROV_PARAM_" . $name; |
| } |
| print " if (strcmp($name, p->key) == 0) {\n"; |
| if ($type eq 'const char *') { |
| print " fp->$field = $field;\n"; |
| } elsif ($type eq 'unsigned char') { |
| print " if ($field != NULL\n"; |
| print " && strcmp($field, \"1\") == 0)\n"; |
| print " fp->$field = 1;\n"; |
| print " else if ($field != NULL\n"; |
| print " && strcmp($field, \"0\") == 0)\n"; |
| print " fp->$field = 0;\n"; |
| print " else\n"; |
| print " return 0;\n"; |
| } |
| print " }\n"; |
| } |
| print " }\n"; |
| print " }\n"; |
| print " return 1;\n"; |
| print "}\n"; |
| |
| print "\n"; |
| print "#define OSSL_FIPS_PARAMS_DEFN_TYPES \\\n"; |
| my $cnt = 0; |
| my $sep = ""; |
| foreach my $p (@params) { |
| my $use = $p->[4]; |
| if ($use eq 'indicator') { |
| my $name = "OSSL_PROV_PARAM_" . $p->[1]; |
| print "$sep OSSL_PARAM_DEFN($name, OSSL_PARAM_INTEGER, NULL, 0)"; |
| $sep = ", \\\n"; |
| } |
| } |
| print "\n"; |
| |
| print "\n"; |
| print "static int return_fips_params(OSSL_PARAM *params, FIPS_PARAMS *fp)\n"; |
| print "{\n"; |
| print " OSSL_PARAM *p = params;\n"; |
| print "\n"; |
| print " for (;p->key != NULL; p++) {\n"; |
| foreach my $p (@params) { |
| my $field = $p->[0]; |
| my $use = $p->[4]; |
| if ($use eq 'indicator') { |
| my $name = "OSSL_PROV_PARAM_" . $p->[1]; |
| print " if (strcmp($name, p->key) == 0)\n"; |
| print " if (!OSSL_PARAM_set_int(p, fp->$field))\n"; |
| print " return 0;\n"; |
| } |
| } |
| print " }\n"; |
| print " return 1;\n"; |
| print "}\n"; |
| |
| print "\n"; |
| print "struct fips_global_st;\n"; |
| print "static FIPS_PARAMS *get_fips_params(struct fips_global_st *fgbl);\n"; |
| print "int ossl_fips_config(OSSL_LIB_CTX *libctx, enum fips_config_id id)\n"; |
| print "{\n"; |
| print " struct fips_global_st *fgbl = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_FIPS_PROV_INDEX);\n"; |
| print " FIPS_PARAMS *params = get_fips_params(fgbl);\n"; |
| print " switch (id) {\n"; |
| foreach my $p (@params) { |
| my $field = $p->[0]; |
| my $use = $p->[4]; |
| if ($use eq 'indicator') { |
| my $id = "FIPS_CONFIG_" . $p->[1]; |
| print " case $id:\n"; |
| print " return params->$field;\n"; |
| } |
| } |
| print " default:\n"; |
| print " return -1;\n"; |
| print " }\n"; |
| print "}\n"; |
| |
| print "\n"; |
| print "#endif /* FIPSPARAMS_AS_HEADER */\n"; |
| |
| return $s; |
| } |