/include/crypto/*_conf.h
/include/openssl/configuration.h
/include/openssl/opensslv.h
+/include/openssl/fipskey.h
# Auto generated doc files
doc/man1/openssl-*.pod
CONFIGURE_ARGS=({- join(", ",quotify_l(@{$config{perlargv}})) -})
SRCDIR={- $config{sourcedir} -}
BLDDIR={- $config{builddir} -}
+FIPSKEY={- $config{FIPSKEY} -}
# Allow both V and VERBOSE to indicate verbosity. This only applies
# to testing.
test : tests
{- dependmagic('tests'); -} : build_programs_nodep, build_modules_nodep copy-utils
@ ! {- output_off() if $disabled{tests}; "" -}
- DEFINE SRCTOP {- sourcedir() -}
- DEFINE BLDTOP {- builddir() -}
+ DEFINE SRCTOP "$(SRCDIR)"
+ DEFINE BLDTOP "$(BLDDIR)"
+ DEFINE FIPSKEY "$(FIPSKEY)"
IF "$(VERBOSE)" .NES. "" THEN DEFINE VERBOSE "$(VERBOSE)"
$(PERL) {- sourcefile("test", "run_tests.pl") -} $(TESTS)
DEASSIGN BLDTOP
DEASSIGN SRCTOP
+ DEASSIGN FIPSKEY
@ ! {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -}
@ WRITE SYS$OUTPUT "Tests are not supported with your chosen Configure options"
@ ! {- output_on() if !$disabled{tests}; "" -}
list-tests :
@ ! {- output_off() if $disabled{tests}; "" -}
- @ DEFINE SRCTOP {- sourcedir() -}
+ @ DEFINE SRCTOP "$(SRCDIR)"
@ $(PERL) {- sourcefile("test", "run_tests.pl") -} list
@ DEASSIGN SRCTOP
@ ! {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -}
CONFIGURE_ARGS=({- join(", ",quotify_l(@{$config{perlargv}})) -})
SRCDIR={- $config{sourcedir} -}
BLDDIR={- $config{builddir} -}
+FIPSKEY={- $config{FIPSKEY} -}
VERSION={- "$config{full_version}" -}
MAJOR={- $config{major} -}
( SRCTOP=$(SRCDIR) \
BLDTOP=$(BLDDIR) \
PERL="$(PERL)" \
+ FIPSKEY="$(FIPSKEY)" \
EXE_EXT={- platform->binext() -} \
$(PERL) $(SRCDIR)/test/run_tests.pl $(TESTS) )
@ : {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -}
PLATFORM={- $config{target} -}
SRCDIR={- $config{sourcedir} -}
BLDDIR={- $config{builddir} -}
+FIPSKEY={- $config{FIPSKEY} -}
VERSION={- "$config{full_version}" -}
MAJOR={- $config{major} -}
set SRCTOP=$(SRCDIR)
set BLDTOP=$(BLDDIR)
set PERL=$(PERL)
+ set FIPSKEY=$(FIPSKEY) \
"$(PERL)" "$(SRCDIR)\test\run_tests.pl" $(TESTS)
@{- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -}
@$(ECHO) "Tests are not supported with your chosen Configure options"
$config{sourcedir} = abs2rel($srcdir);
$config{builddir} = abs2rel($blddir);
+# echo -n 'holy hand grenade of antioch' | openssl sha256
+$config{FIPSKEY} =
+ 'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813';
# Collect reconfiguration information if needed
my @argvcopy=@ARGV;
push @seed_sources, $x;
}
}
+ elsif (/^--fips-key=(.*)$/)
+ {
+ $user{FIPSKEY}=lc($1);
+ die "Non-hex character in FIPS key\n"
+ if $user{FIPSKEY} =~ /[^a-f0-9]/;
+ die "FIPS key must have even number of characters\n"
+ if length $1 & 1;
+ die "FIPS key too long (64 bytes max)\n"
+ if length $1 > 64;
+ }
elsif (/^--cross-compile-prefix=(.*)$/)
{
$user{CROSS_COMPILE}=$1;
- [Compiler Warnings](#compiler-warnings)
- [ZLib Flags](#zlib-flags)
- [Seeding the Random Generator](#seeding-the-random-generator)
+ - [Setting the FIPS HMAC key](#setting-the-FIPS-HMAC-key)
- [Enable and Disable Features](#enable-and-disable-features)
- [Displaying configuration data](#displaying-configuration-data)
- [Installation Steps in Detail](#installation-steps-in-detail)
[rng]: #notes-on-random-number-generation
+Setting the FIPS HMAC key
+-------------------------
+
+ --fips-key=value
+
+As part of its self-test validation, the FIPS module must verify itself
+by performing a SHA-256 HMAC computation on itself. The default key is
+the SHA256 value of "the holy handgrenade of antioch" and is sufficient
+for meeting the FIPS requirements.
+
+To change the key to a different value, use this flag. The value should
+be a hex string no more than 64 characters.
+
Enable and Disable Features
---------------------------
#include <openssl/fips_names.h>
#include <openssl/core_names.h>
#include <openssl/self_test.h>
+#include <openssl/fipskey.h>
#include "apps.h"
#include "progs.h"
int fipsinstall_main(int argc, char **argv)
{
- int ret = 1, verify = 0;
+ int ret = 1, verify = 0, gotkey = 0, gotdigest = 0;
BIO *module_bio = NULL, *mem_bio = NULL, *fout = NULL;
char *in_fname = NULL, *out_fname = NULL, *prog, *section_name = NULL;
char *prov_name = NULL, *module_fname = NULL;
CONF *conf = NULL;
section_name = DEFAULT_FIPS_SECTION;
+ if ((opts = sk_OPENSSL_STRING_new_null()) == NULL)
+ goto end;
prog = opt_init(argc, argv, fipsinstall_options);
while ((o = opt_next()) != OPT_EOF) {
mac_name = opt_arg();
break;
case OPT_MACOPT:
- if (opts == NULL)
- opts = sk_OPENSSL_STRING_new_null();
- if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg()))
+ if (!sk_OPENSSL_STRING_push(opts, opt_arg()))
goto opthelp;
+ if (strncmp(opt_arg(), "hexkey:", 7) == 0)
+ gotkey = 1;
+ else if (strncmp(opt_arg(), "digest:", 7) == 0)
+ gotdigest = 1;
break;
case OPT_VERIFY:
verify = 1;
if (module_fname == NULL
|| (verify && in_fname == NULL)
|| (!verify && (out_fname == NULL || prov_name == NULL))
- || opts == NULL
|| argc != 0)
goto opthelp;
|| self_test_corrupt_type != NULL)
OSSL_SELF_TEST_set_callback(NULL, self_test_events, NULL);
+ /* Use the default FIPS HMAC digest and key if not specified. */
+ if (!gotdigest && !sk_OPENSSL_STRING_push(opts, "digest:SHA256"))
+ goto end;
+ if (!gotkey && !sk_OPENSSL_STRING_push(opts, "hexkey:" FIPS_KEY_STRING))
+ goto end;
+
module_bio = bio_open_default(module_fname, 'r', FORMAT_BINARY);
if (module_bio == NULL) {
BIO_printf(bio_err, "Failed to open module file\n");
# Empty DEPEND "indices" means the dependencies are expected to be built
# unconditionally before anything else.
DEPEND[]=include/openssl/configuration.h include/openssl/opensslv.h \
+ include/openssl/fipskey.h \
include/crypto/bn_conf.h include/crypto/dso_conf.h \
doc/man7/openssl_user_macros.pod
GENERATE[include/openssl/configuration.h]=include/openssl/configuration.h.in
GENERATE[include/openssl/opensslv.h]=include/openssl/opensslv.h.in
+GENERATE[include/openssl/fipskey.h]=include/openssl/fipskey.h.in
GENERATE[include/crypto/bn_conf.h]=include/crypto/bn_conf.h.in
GENERATE[include/crypto/dso_conf.h]=include/crypto/dso_conf.h.in
GENERATE[doc/man7/openssl_user_macros.pod]=doc/man7/openssl_user_macros.pod.in
Passes options to the MAC algorithm.
A comprehensive list of controls can be found in the EVP_MAC implementation
documentation.
-Common control strings used for fipsinstall are:
+Common control strings used for this command are:
=over 4
printable characters only).
The string length must conform to any restrictions of the MAC algorithm.
A key must be specified for every MAC algorithm.
+If no key is provided, the default that was specified when OpenSSL was
+configured is used.
=item B<hexkey>:I<string>
Specifies the MAC key in hexadecimal form (two hex digits per byte).
The key length must conform to any restrictions of the MAC algorithm.
A key must be specified for every MAC algorithm.
+If no key is provided, the default that was specified when OpenSSL was
+configured is used.
=item B<digest>:I<string>
The string length must conform to any restrictions of the MAC algorithm.
To see the list of supported digests, use the command
C<openssl list -digest-commands>.
+The default digest is SHA-256.
=back
--- /dev/null
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020 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
+ */
+
+#ifndef OPENSSL_FIPSKEY_H
+# define OPENSSL_FIPSKEY_H
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/*
+ * The FIPS validation HMAC key, usable as an array initializer.
+ */
+#define FIPS_KEY_ELEMENTS \
+ {- join(', ', map { "0x$_" } unpack("(A2)*", $config{FIPSKEY})) -}
+
+/*
+ * The FIPS validation key, as a string.
+ */
+#define FIPS_KEY_STRING "{- $config{FIPSKEY} -}"
+
+#endif
#include <openssl/evp.h>
#include <openssl/params.h>
#include <openssl/crypto.h>
+#include <openssl/fipskey.h>
#include "e_os.h"
/*
* We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS
static int FIPS_state = FIPS_STATE_INIT;
static CRYPTO_RWLOCK *self_test_lock = NULL;
-static unsigned char fixed_key[32] = { 0 };
+static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS };
static CRYPTO_ONCE fips_self_test_init = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init)
plan tests => 12;
my $infile = bldtop_file('providers', platform->dso('fips'));
+my $fipskey = $ENV{FIPSKEY} // '00';
# fail if no module name
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module',
'-provider_name', 'fips',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install'])),
"fipsinstall fail");
# fail to verify if the configuration file is missing
ok(!run(app(['openssl', 'fipsinstall', '-in', 'dummy.tmp', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install', '-verify'])),
"fipsinstall verify fail");
# output a fips.cnf file containing mac data
ok(run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install'])),
"fipsinstall");
# verify the fips.cnf file
ok(run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install', '-verify'])),
"fipsinstall verify");
# fail to verify the fips.cnf file if a different key is used
ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:01',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_install', '-verify'])),
"fipsinstall verify fail bad key");
# fail to verify the fips.cnf file if a different mac digest is used
ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA512', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA512', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install', '-verify'])),
"fipsinstall verify fail incorrect digest");
# corrupt the module hmac
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install', '-corrupt_desc', 'HMAC'])),
"fipsinstall fails when the module integrity is corrupted");
# corrupt the first digest
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install', '-corrupt_desc', 'SHA1'])),
"fipsinstall fails when the digest result is corrupted");
# corrupt another digest
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install', '-corrupt_desc', 'SHA3'])),
"fipsinstall fails when the digest result is corrupted");
# corrupt DRBG
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install', '-corrupt_desc', 'CTR'])),
"fipsinstall fails when the DRBG CTR result is corrupted");
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.conf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install',
'-corrupt_desc', 'DH',
'-corrupt_type', 'KAT_KA'])),
if disabled("dsa");
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.conf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_install',
'-corrupt_desc', 'DSA',
'-corrupt_type', 'KAT_Signature'])),
ok(run(app(['openssl', 'fipsinstall',
'-out', bldtop_file('providers', 'fipsmodule.cnf'),
'-module', $infile,
- '-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-provider_name', 'fips',
'-section_name', 'fips_sect'])),
"fipsinstall");
ok(run(app(['openssl', 'fipsinstall',
'-out', bldtop_file('providers', 'fipsmodule.cnf'),
'-module', $infile,
- '-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-provider_name', 'fips',
'-section_name', 'fips_sect'])),
"fipsinstall");
}
cmd => app(['openssl', 'fipsinstall',
'-out', bldtop_file('providers', 'fipsmodule.cnf'),
'-module', bldtop_file('providers', platform->dso('fips')),
- '-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-provider_name', 'fips',
'-section_name', 'fips_sect']),
message => "fipsinstall"
};
ok(run(app(['openssl', 'fipsinstall',
'-out', bldtop_file('providers', 'fipsmodule.cnf'),
'-module', bldtop_file('providers', platform->dso('fips')),
- '-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-provider_name', 'fips',
'-section_name', 'fips_sect'])),
"fipsinstall");
}
ok(run(app(['openssl', 'fipsinstall',
'-out', bldtop_file('providers', 'fipsmodule.cnf'),
'-module', bldtop_file('providers', platform->dso('fips')),
- '-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-provider_name', 'fips',
'-section_name', 'fips_sect'])),
"fipsinstall");
}
ok(run(app(['openssl', 'fipsinstall',
'-out', bldtop_file('providers', 'fipsmodule.cnf'),
'-module', bldtop_file('providers', platform->dso('fips')),
- '-provider_name', 'fips', '-mac_name', 'HMAC',
- '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+ '-provider_name', 'fips',
'-section_name', 'fips_sect'])),
"fipsinstall");