X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=fips%2Ffips.c;h=36ac8d1b0c18650dfd82d75f64523bc5537c65ef;hp=ef9c0bddaabbc650c231c6e755e368e5eeadcea9;hb=8ea92ddd13495e63855a61dcc96963ffdf6df495;hpb=01a9a7592e332cf4853bc84c33407d384a1a14ba diff --git a/fips/fips.c b/fips/fips.c index ef9c0bddaa..36ac8d1b0c 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; @@ -145,6 +149,7 @@ void fips_set_selftest_fail(void) extern const void *FIPS_text_start(), *FIPS_text_end(); extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[]; unsigned char FIPS_signature [20] = { 0 }; +__fips_constseg static const char FIPS_hmac_key[]="etaonrishdlcupfm"; unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len) @@ -237,10 +242,47 @@ 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 fips_set_owning_thread(); - int fips_clear_owning_thread(); int ret = 0; fips_w_lock(); @@ -251,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 */ @@ -263,13 +312,18 @@ int FIPS_module_mode_set(int onoff) } #ifdef OPENSSL_IA32_SSE2 - if ((OPENSSL_ia32cap & (1<<25|1<<26)) != (1<<25|1<<26)) + { + extern unsigned int OPENSSL_ia32cap_P[2]; + if ((OPENSSL_ia32cap_P[0] & (1<<25|1<<26)) != (1<<25|1<<26)) { FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM); fips_selftest_fail = 1; ret = 0; goto end; } + OPENSSL_ia32cap_P[0] |= (1<<28); /* set "shared cache" */ + OPENSSL_ia32cap_P[1] &= ~(1<<(60-32)); /* clear AVX */ + } #endif if(fips_signature_witness() != FIPS_signature)