blob: 38ba27b5b1a036d1e880d2196e730c55de073244 [file] [log] [blame] [edit]
#! /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;
}