From 5e4eb9954b415fd685bfda69603bec52c5843778 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 19 Oct 2011 22:34:53 +0000 Subject: [PATCH] add authentication parameter to FIPS_module_mode_set --- CHANGES | 3 +++ Configure | 19 +++++++++++++++ crypto/fips_err.h | 3 ++- fips/.cvsignore | 1 + fips/Makefile | 2 +- fips/fips.c | 52 +++++++++++++++++++++++++++++++++++++++++- fips/fips.h | 6 ++++- fips/fips_auth.in | 52 ++++++++++++++++++++++++++++++++++++++++++ fips/fips_test_suite.c | 11 +++++++-- fips/fips_utl.h | 11 ++++++++- 10 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 fips/fips_auth.in diff --git a/CHANGES b/CHANGES index 1bcd6f37ee..0d70e034da 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,9 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] + *) Add authorisation parameter to FIPS_module_mode_set(). + [Steve Henson] + *) Add FIPS selftest for ECDH algorithm using P-224 and B-233 curves. [Steve Henson] diff --git a/Configure b/Configure index 63558b3e9a..10ef8cd115 100755 --- a/Configure +++ b/Configure @@ -1169,6 +1169,10 @@ $perl=$ENV{'PERL'} or $perl=&which("perl5") or $perl=&which("perl") or $perl="perl"; my $make = $ENV{'MAKE'} || "make"; +my $fips_auth_key = $ENV{'FIPS_AUTH_KEY'}; +my $fips_auth_officer = $ENV{'FIPS_AUTH_OFFICER'}; +my $fips_auth_user = $ENV{'FIPS_AUTH_USER'}; + $cross_compile_prefix=$ENV{'CROSS_COMPILE'} if $cross_compile_prefix eq ""; chop $openssldir if $openssldir =~ /\/$/; @@ -1621,6 +1625,21 @@ if ($strict_warnings) } } +if ($fipscanisterinternal eq "y") + { + open(IN,"fips/fips_auth.h") || die "can't open fips_auth.h"; + while() + { + s/FIPS_AUTH_KEY.*$/FIPS_AUTH_KEY $fips_auth_key/ if defined $fips_auth_key; + s/FIPS_AUTH_CRYPTO_OFFICER.*$/FIPS_AUTH_CRYPTO_OFFICER $fips_auth_officer/ if defined $fips_auth_officer; + s/FIPS_AUTH_CRYPTO_USER.*$/FIPS_AUTH_CRYPTO_USER $fips_auth_user/ if defined $fips_auth_user; + print OUT $_; + } + close IN; + close OUT; + } + my $mforg = $fipscanisteronly ? "Makefile.fips" : "Makefile.org"; open(IN,"<$mforg") || die "unable to read $mforg:$!\n"; diff --git a/crypto/fips_err.h b/crypto/fips_err.h index 202084a17a..d345f3d511 100644 --- a/crypto/fips_err.h +++ b/crypto/fips_err.h @@ -93,7 +93,7 @@ static ERR_STRING_DATA FIPS_str_functs[]= {ERR_FUNC(FIPS_F_FIPS_DRBG_CHECK), "FIPS_DRBG_CHECK"}, {ERR_FUNC(FIPS_F_FIPS_DRBG_CPRNG_TEST), "FIPS_DRBG_CPRNG_TEST"}, {ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE), "FIPS_drbg_generate"}, -{ERR_FUNC(FIPS_F_FIPS_DRBG_HEALTH_CHECK), "FIPS_DRBG_HEALTH_CHECK"}, +{ERR_FUNC(FIPS_F_FIPS_DRBG_HEALTH_CHECK), "FIPS_drbg_health_check"}, {ERR_FUNC(FIPS_F_FIPS_DRBG_INIT), "FIPS_drbg_init"}, {ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE), "FIPS_drbg_instantiate"}, {ERR_FUNC(FIPS_F_FIPS_DRBG_NEW), "FIPS_drbg_new"}, @@ -140,6 +140,7 @@ static ERR_STRING_DATA FIPS_str_reasons[]= {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED),"additional input error undetected"}, {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_TOO_LONG),"additional input too long"}, {ERR_REASON(FIPS_R_ALREADY_INSTANTIATED) ,"already instantiated"}, +{ERR_REASON(FIPS_R_AUTHENTICATION_FAILURE),"authentication failure"}, {ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"}, {ERR_REASON(FIPS_R_DRBG_STUCK) ,"drbg stuck"}, {ERR_REASON(FIPS_R_ENTROPY_ERROR_UNDETECTED),"entropy error undetected"}, diff --git a/fips/.cvsignore b/fips/.cvsignore index 31b368ef1b..315c039713 100644 --- a/fips/.cvsignore +++ b/fips/.cvsignore @@ -4,5 +4,6 @@ fips_test_suite fips_premain_dso fips_standalone_sha1 fipscanister.o.sha1 +fips_auth.h *.flc semantic.cache diff --git a/fips/Makefile b/fips/Makefile index 1371102722..fb5083810a 100644 --- a/fips/Makefile +++ b/fips/Makefile @@ -50,7 +50,7 @@ FIPS_OBJ_LISTS=sha/lib hmac/lib rand/lib des/lib aes/lib dsa/lib rsa/lib \ SRC= $(LIBSRC) EXHEADER=fips.h fipssyms.h -HEADER=$(EXHEADER) fips_utl.h fips_locl.h +HEADER=$(EXHEADER) fips_utl.h fips_locl.h fips_auth.h EXE=fipsld fips_standalone_sha1 ALL= $(GENERAL) $(SRC) $(HEADER) diff --git a/fips/fips.c b/fips/fips.c index a8f0f0374d..5cb4bfd48e 100644 --- a/fips/fips.c +++ b/fips/fips.c @@ -61,6 +61,7 @@ #include #include #include "fips_locl.h" +#include "fips_auth.h" #ifdef OPENSSL_FIPS @@ -70,7 +71,10 @@ #define PATH_MAX 1024 #endif +#define atox(c) ((c)>='a'?((c)-'a'+10):((c)>='A'?(c)-'A'+10:(c)-'0')) + static int fips_selftest_fail = 0; +static int fips_auth_fail = 0; static int fips_mode = 0; static int fips_started = 0; @@ -238,7 +242,46 @@ int FIPS_check_incore_fingerprint(void) return rv; } -int FIPS_module_mode_set(int onoff) +static int fips_asc_check(const unsigned char *sig, const char *asc_sig) + { + char tsig[20]; + const char *p; + int i; + if (strlen(asc_sig) != 40) + return 0; + for (i = 0, p = asc_sig; i < 20; i++, p += 2) + tsig[i] = (atox(p[0]) << 4) | atox(p[1]); + if (memcmp(tsig, sig, 20)) + return 0; + return 1; + } + +static int fips_check_auth(const char *auth) + { + unsigned char auth_hmac[20]; + unsigned int hmac_len; + if (fips_auth_fail) + return 0; + if (strlen(auth) < FIPS_AUTH_MIN_LEN) + return 0; + if (!HMAC(EVP_sha1(), FIPS_AUTH_KEY, strlen(FIPS_AUTH_KEY), + (unsigned char *)auth, strlen(auth), auth_hmac, &hmac_len)) + return 0; + if (hmac_len != sizeof(auth_hmac)) + return 0; + + if (fips_asc_check(auth_hmac, FIPS_AUTH_CRYPTO_OFFICER)) + return 1; + + if (fips_asc_check(auth_hmac, FIPS_AUTH_CRYPTO_USER)) + return 1; + + return 0; + } + + + +int FIPS_module_mode_set(int onoff, const char *auth) { int ret = 0; @@ -250,6 +293,13 @@ int FIPS_module_mode_set(int onoff) { fips_selftest_fail = 0; + if (!fips_check_auth(auth)) + { + fips_auth_fail = 1; + fips_selftest_fail = 1; + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_AUTHENTICATION_FAILURE); + return 0; + } /* Don't go into FIPS mode twice, just so we can do automagic seeding */ diff --git a/fips/fips.h b/fips/fips.h index 7a079ef7ff..aaeadf5b51 100644 --- a/fips/fips.h +++ b/fips/fips.h @@ -81,7 +81,7 @@ struct hmac_ctx_st; unsigned long FIPS_module_version(void); const char *FIPS_module_version_text(void); -int FIPS_module_mode_set(int onoff); +int FIPS_module_mode_set(int onoff, const char *auth); int FIPS_module_mode(void); const void *FIPS_rand_check(void); int FIPS_selftest(void); @@ -174,6 +174,9 @@ void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr); /* ECDH test */ #define FIPS_TEST_ECDH 14 +/* Minimum authorisation string length */ +#define FIPS_AUTH_MIN_LEN 16 + void FIPS_post_set_callback( int (*post_cb)(int op, int id, int subid, void *ex)); @@ -406,6 +409,7 @@ void ERR_load_FIPS_strings(void); #define FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED 150 #define FIPS_R_ADDITIONAL_INPUT_TOO_LONG 100 #define FIPS_R_ALREADY_INSTANTIATED 101 +#define FIPS_R_AUTHENTICATION_FAILURE 151 #define FIPS_R_CONTRADICTING_EVIDENCE 102 #define FIPS_R_DRBG_STUCK 103 #define FIPS_R_ENTROPY_ERROR_UNDETECTED 104 diff --git a/fips/fips_auth.in b/fips/fips_auth.in new file mode 100644 index 0000000000..1895ee8b2c --- /dev/null +++ b/fips/fips_auth.in @@ -0,0 +1,52 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define FIPS_AUTH_KEY "etaonrishdlcupfm" +#define FIPS_AUTH_CRYPTO_OFFICER "7f92562d409c903322c0f94a1188ae8178339a4f" +#define FIPS_AUTH_CRYPTO_USER "cb6cbdaad26cd210a8b31a5d56a876ee1d51a96c" diff --git a/fips/fips_test_suite.c b/fips/fips_test_suite.c index 0046b9b0d5..bca185666c 100644 --- a/fips/fips_test_suite.c +++ b/fips/fips_test_suite.c @@ -1002,6 +1002,7 @@ int main(int argc,char **argv) int do_drbg_stick = 0; int no_exit = 0; int no_dh = 0; + char *pass = FIPS_AUTH_USER_PASS; FIPS_post_set_callback(post_cb); @@ -1077,13 +1078,19 @@ int main(int argc,char **argv) do_drbg_stick = 1; no_exit = 1; printf("DRBG test with stuck continuous test...\n"); + } else if (!strcmp(argv[1], "user")) { + pass = FIPS_AUTH_USER_PASS; + } else if (!strcmp(argv[1], "officer")) { + pass = FIPS_AUTH_OFFICER_PASS; + } else if (!strcmp(argv[1], "badpass")) { + pass = "bad invalid password"; } else { printf("Bad argument \"%s\"\n", argv[1]); exit(1); } if (!no_exit) { fips_algtest_init_nofips(); - if (!FIPS_module_mode_set(1)) { + if (!FIPS_module_mode_set(1, pass)) { printf("Power-up self test failed\n"); exit(1); } @@ -1105,7 +1112,7 @@ int main(int argc,char **argv) /* Power-up self test */ ERR_clear_error(); - test_msg("2. Automatic power-up self test", FIPS_module_mode_set(1)); + test_msg("2. Automatic power-up self test", FIPS_module_mode_set(1, pass)); if (!FIPS_module_mode()) exit(1); if (do_drbg_stick) diff --git a/fips/fips_utl.h b/fips/fips_utl.h index c0ce613f47..1ed133c5c9 100644 --- a/fips/fips_utl.h +++ b/fips/fips_utl.h @@ -58,6 +58,15 @@ #define RESP_EOL "\r\n" #endif +#ifndef FIPS_AUTH_OFFICER_PASS +#define FIPS_AUTH_OFFICER_PASS "Default FIPS Crypto Officer Password" +#endif + +#ifndef FIPS_AUTH_USER_PASS +#define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password" +#endif + + int hex2bin(const char *in, unsigned char *out); unsigned char *hex2bin_m(const char *in, long *plen); int do_hex2bn(BIGNUM **pr, const char *in); @@ -144,7 +153,7 @@ void do_entropy_stick(void) void fips_algtest_init(void) { fips_algtest_init_nofips(); - if (!FIPS_module_mode_set(1)) + if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS)) { fprintf(stderr, "Error entering FIPS mode\n"); exit(1); -- 2.34.1