Add --fips-key configuration parameter to fipsinstall application.

Change default FIPS HMAC KEY from all-zero's
Use default FIPSKEY if not given on command line.
Make all -macopt in fipsinstall optional
Make all tests, except fipsinstall, use the default -macopt and
-mac_name flags.
Define and use FIPSDIR variable on VMS/MMS.
Also use SRCDIR/BLDDIR in SRCTOP/BLDTOP.

Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12235)
This commit is contained in:
Rich Salz 2020-06-29 12:20:41 +10:00 committed by Shane Lontis
parent 9afbb681ec
commit 3121425830
18 changed files with 112 additions and 34 deletions

1
.gitignore vendored
View File

@ -24,6 +24,7 @@
/include/crypto/*_conf.h
/include/openssl/configuration.h
/include/openssl/opensslv.h
/include/openssl/fipskey.h
# Auto generated doc files
doc/man1/openssl-*.pod

View File

@ -106,6 +106,7 @@ OPTIONS={- $config{options} -}
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.
@ -439,19 +440,21 @@ all : build_sw build_docs
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(); } "" -}

View File

@ -61,6 +61,7 @@ OPTIONS={- $config{options} -}
CONFIGURE_ARGS=({- join(", ",quotify_l(@{$config{perlargv}})) -})
SRCDIR={- $config{sourcedir} -}
BLDDIR={- $config{builddir} -}
FIPSKEY={- $config{FIPSKEY} -}
VERSION={- "$config{full_version}" -}
MAJOR={- $config{major} -}
@ -475,6 +476,7 @@ test: tests
( 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(); } "" -}

View File

@ -37,6 +37,7 @@
PLATFORM={- $config{target} -}
SRCDIR={- $config{sourcedir} -}
BLDDIR={- $config{builddir} -}
FIPSKEY={- $config{FIPSKEY} -}
VERSION={- "$config{full_version}" -}
MAJOR={- $config{major} -}
@ -405,6 +406,7 @@ test: tests
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"

View File

@ -244,6 +244,9 @@ my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
$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;
@ -934,6 +937,16 @@ while (@argvcopy)
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;

View File

@ -21,6 +21,7 @@ Table of Contents
- [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)
@ -465,6 +466,19 @@ at the end of this document.
[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
---------------------------

View File

@ -15,6 +15,7 @@
#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"
@ -266,7 +267,7 @@ end:
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;
@ -283,6 +284,8 @@ int fipsinstall_main(int argc, char **argv)
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) {
@ -327,10 +330,12 @@ opthelp:
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;
@ -341,7 +346,6 @@ opthelp:
if (module_fname == NULL
|| (verify && in_fname == NULL)
|| (!verify && (out_fname == NULL || prov_name == NULL))
|| opts == NULL
|| argc != 0)
goto opthelp;
@ -350,6 +354,12 @@ 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");

View File

@ -10,11 +10,13 @@ DEPEND[libssl]=libcrypto
# 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

View File

@ -94,7 +94,7 @@ C<openssl list -mac-algorithms>. The default is B<HMAC>.
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
@ -104,12 +104,16 @@ Specifies the MAC key as an alphanumeric string (use if the key contains
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>
@ -118,6 +122,7 @@ characters only).
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

View File

@ -0,0 +1,30 @@
/*
* {- 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

View File

@ -11,6 +11,7 @@
#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
@ -35,7 +36,7 @@
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)

View File

@ -27,18 +27,19 @@ plan skip_all => "Test only supported in a fips build" if disabled("fips");
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");
@ -46,56 +47,56 @@ ok(!run(app(['openssl', 'fipsinstall', '-in', 'dummy.tmp', '-module', $infile,
# 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");
@ -106,7 +107,7 @@ SKIP: {
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'])),
@ -119,7 +120,7 @@ SKIP: {
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'])),

View File

@ -32,8 +32,7 @@ plan tests => 2;
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");

View File

@ -85,8 +85,7 @@ unless ($no_fips) {
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");
}

View File

@ -47,8 +47,7 @@ unless ($no_fips) {
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"
};

View File

@ -118,8 +118,7 @@ unless ($no_fips) {
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");
}

View File

@ -86,8 +86,7 @@ unless ($no_fips) {
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");
}

View File

@ -40,8 +40,7 @@ unless ($no_fips) {
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");