X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=fips%2Ffips.c;h=5cb4bfd48e4fd690636854634f3ea3f9462368cd;hp=a4ed4f28fbe33521de967de5cec54e880ac460c0;hb=5e4eb9954b415fd685bfda69603bec52c5843778;hpb=3d607309e63ea88d5a8bd1caebeeca40a0dba0ca diff --git a/fips/fips.c b/fips/fips.c index a4ed4f28fb..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; @@ -96,7 +100,7 @@ static void fips_set_mode(int onoff) } } -int FIPS_mode(void) +int FIPS_module_mode(void) { int ret = 0; int owning_thread = fips_is_owning_thread(); @@ -142,23 +146,10 @@ void fips_set_selftest_fail(void) fips_selftest_fail = 1; } -int FIPS_selftest(void) - { - - return FIPS_selftest_sha1() - && FIPS_selftest_hmac() - && FIPS_selftest_cmac() - && FIPS_selftest_aes() - && FIPS_selftest_aes_gcm() - && FIPS_selftest_des() - && FIPS_selftest_rsa() - && FIPS_selftest_ecdsa() - && FIPS_selftest_dsa(); - } - 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) @@ -192,6 +183,9 @@ unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len) else HMAC_Update(&c,p3,(size_t)p4-(size_t)p3); + if (!fips_post_corrupt(FIPS_TEST_INTEGRITY, 0, NULL)) + HMAC_Update(&c, (unsigned char *)FIPS_hmac_key, 1); + HMAC_Final(&c,sig,&len); HMAC_CTX_cleanup(&c); @@ -202,19 +196,23 @@ int FIPS_check_incore_fingerprint(void) { unsigned char sig[EVP_MAX_MD_SIZE]; unsigned int len; + int rv = 0; #if defined(__sgi) && (defined(__mips) || defined(mips)) extern int __dso_displacement[]; #else extern int OPENSSL_NONPIC_relocated; #endif + if (!fips_post_started(FIPS_TEST_INTEGRITY, 0, NULL)) + return 1; + if (FIPS_text_start()==NULL) { FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_UNSUPPORTED_PLATFORM); - return 0; + goto err; } - len=FIPS_incore_fingerprint (sig,sizeof(sig)); + len=FIPS_incore_fingerprint(sig,sizeof(sig)); if (len!=sizeof(FIPS_signature) || memcmp(FIPS_signature,sig,sizeof(FIPS_signature))) @@ -230,18 +228,61 @@ int FIPS_check_incore_fingerprint(void) else FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH); #ifdef OPENSSL_FIPS_DEBUGGER - return 1; -#else - return 0; + rv = 1; #endif + goto err; } + rv = 1; + err: + if (rv == 0) + fips_post_failed(FIPS_TEST_INTEGRITY, 0, NULL); + else + if (!fips_post_success(FIPS_TEST_INTEGRITY, 0, NULL)) + return 0; + return rv; + } + +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; } -int FIPS_mode_set(int onoff) +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(); @@ -252,12 +293,19 @@ int FIPS_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 */ - if(FIPS_mode()) + if(FIPS_module_mode()) { - FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET); + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET); fips_selftest_fail = 1; ret = 0; goto end; @@ -266,7 +314,7 @@ int FIPS_mode_set(int onoff) #ifdef OPENSSL_IA32_SSE2 if ((OPENSSL_ia32cap & (1<<25|1<<26)) != (1<<25|1<<26)) { - FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM); + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM); fips_selftest_fail = 1; ret = 0; goto end; @@ -275,36 +323,14 @@ int FIPS_mode_set(int onoff) if(fips_signature_witness() != FIPS_signature) { - FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE); - fips_selftest_fail = 1; - ret = 0; - goto end; - } - - if(!FIPS_check_incore_fingerprint()) - { - fips_selftest_fail = 1; - ret = 0; - goto end; - } - - if (!FIPS_selftest_drbg()) - { - fips_selftest_fail = 1; - ret = 0; - goto end; - } - - /* Perform RNG KAT before seeding */ - if (!FIPS_selftest_x931()) - { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE); fips_selftest_fail = 1; ret = 0; goto end; } if(FIPS_selftest()) - fips_set_mode(1); + fips_set_mode(onoff); else { fips_selftest_fail = 1; @@ -388,145 +414,14 @@ unsigned char *fips_signature_witness(void) return FIPS_signature; } -/* Generalized public key test routine. Signs and verifies the data - * supplied in tbs using mesage digest md and setting RSA padding mode - * pad_mode. If the 'kat' parameter is not NULL it will - * additionally check the signature matches it: a known answer test - * The string "fail_str" is used for identification purposes in case - * of failure. - */ - -int fips_pkey_signature_test(EVP_PKEY *pkey, - const unsigned char *tbs, int tbslen, - const unsigned char *kat, unsigned int katlen, - const EVP_MD *digest, int pad_mode, - const char *fail_str) - { - int ret = 0; - unsigned char sigtmp[256], *sig = sigtmp; - unsigned int siglen; - DSA_SIG *dsig = NULL; - ECDSA_SIG *esig = NULL; - EVP_MD_CTX mctx; - FIPS_md_ctx_init(&mctx); - - if ((pkey->type == EVP_PKEY_RSA) - && ((size_t)RSA_size(pkey->pkey.rsa) > sizeof(sigtmp))) - { - sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa)); - if (!sig) - { - FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE); - return 0; - } - } - - if (tbslen == -1) - tbslen = strlen((char *)tbs); - - if (digest == NULL) - digest = EVP_sha256(); - - if (!FIPS_digestinit(&mctx, digest)) - goto error; - if (!FIPS_digestupdate(&mctx, tbs, tbslen)) - goto error; - if (pkey->type == EVP_PKEY_RSA) - { - if (!FIPS_rsa_sign_ctx(pkey->pkey.rsa, &mctx, - pad_mode, 0, NULL, sig, &siglen)) - goto error; - } - else if (pkey->type == EVP_PKEY_DSA) - { - dsig = FIPS_dsa_sign_ctx(pkey->pkey.dsa, &mctx); - if (!dsig) - goto error; - } - else if (pkey->type == EVP_PKEY_EC) - { - esig = FIPS_ecdsa_sign_ctx(pkey->pkey.ec, &mctx); - if (!esig) - goto error; - } - - if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen))) - goto error; -#if 0 +unsigned long FIPS_module_version(void) { - /* Debug code to print out self test KAT discrepancies */ - unsigned int i; - fprintf(stderr, "%s=", fail_str); - for (i = 0; i < siglen; i++) - fprintf(stderr, "%02X", sig[i]); - fprintf(stderr, "\n"); - goto error; - } -#endif - if (!FIPS_digestinit(&mctx, digest)) - goto error; - if (!FIPS_digestupdate(&mctx, tbs, tbslen)) - goto error; - if (pkey->type == EVP_PKEY_RSA) - { - ret = FIPS_rsa_verify_ctx(pkey->pkey.rsa, &mctx, - pad_mode, 0, NULL, sig, siglen); - } - else if (pkey->type == EVP_PKEY_DSA) - { - ret = FIPS_dsa_verify_ctx(pkey->pkey.dsa, &mctx, dsig); - } - else if (pkey->type == EVP_PKEY_EC) - { - ret = FIPS_ecdsa_verify_ctx(pkey->pkey.ec, &mctx, esig); - } - - error: - if (dsig != NULL) - FIPS_dsa_sig_free(dsig); - if (esig != NULL) - FIPS_ecdsa_sig_free(esig); - if (sig != sigtmp) - OPENSSL_free(sig); - FIPS_md_ctx_cleanup(&mctx); - if (ret != 1) - { - FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE); - if (fail_str) - FIPS_add_error_data(2, "Type=", fail_str); - return 0; - } - return 1; + return FIPS_MODULE_VERSION_NUMBER; } -/* Generalized symmetric cipher test routine. Encrypt data, verify result - * against known answer, decrypt and compare with original plaintext. - */ - -int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - const unsigned char *key, - const unsigned char *iv, - const unsigned char *plaintext, - const unsigned char *ciphertext, - int len) +const char *FIPS_module_version_text(void) { - unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE]; - unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE]; - OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE); - memset(pltmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); - memset(citmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); - if (FIPS_cipherinit(ctx, cipher, key, iv, 1) <= 0) - return 0; - if (!FIPS_cipher(ctx, citmp, plaintext, len)) - return 0; - if (memcmp(citmp, ciphertext, len)) - return 0; - if (FIPS_cipherinit(ctx, cipher, key, iv, 0) <= 0) - return 0; - FIPS_cipher(ctx, pltmp, citmp, len); - if (memcmp(pltmp, plaintext, len)) - return 0; - return 1; + return FIPS_MODULE_VERSION_TEXT; } #if 0