X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=fips%2Ffips.c;h=823a042f504df68669bbe940c49337a45a71981f;hp=6a88661a0ca5c0961bd181b05d0ec4269a4fbd82;hb=e6133727fb7cea2d67a28eada59db67ef1470f8a;hpb=7e95116064658bfbcedaceee60c0db43a02942e9 diff --git a/fips/fips.c b/fips/fips.c index 6a88661a0c..823a042f50 100644 --- a/fips/fips.c +++ b/fips/fips.c @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * 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 @@ -49,6 +49,7 @@ #define OPENSSL_FIPSAPI +#include #include #include #include @@ -56,6 +57,7 @@ #include #include #include +#include #include #include #include "fips_locl.h" @@ -68,20 +70,19 @@ #define PATH_MAX 1024 #endif -static int fips_selftest_fail; -static int fips_mode; +static int fips_selftest_fail = 0; +static int fips_mode = 0; static int fips_started = 0; -static const void *fips_rand_check; static int fips_is_owning_thread(void); static int fips_set_owning_thread(void); static int fips_clear_owning_thread(void); static unsigned char *fips_signature_witness(void); -static void fips_w_lock(void) { CRYPTO_w_lock(CRYPTO_LOCK_FIPS); } -static void fips_w_unlock(void) { CRYPTO_w_unlock(CRYPTO_LOCK_FIPS); } -static void fips_r_lock(void) { CRYPTO_r_lock(CRYPTO_LOCK_FIPS); } -static void fips_r_unlock(void) { CRYPTO_r_unlock(CRYPTO_LOCK_FIPS); } +#define fips_w_lock() CRYPTO_w_lock(CRYPTO_LOCK_FIPS) +#define fips_w_unlock() CRYPTO_w_unlock(CRYPTO_LOCK_FIPS) +#define fips_r_lock() CRYPTO_r_lock(CRYPTO_LOCK_FIPS) +#define fips_r_unlock() CRYPTO_r_unlock(CRYPTO_LOCK_FIPS) static void fips_set_mode(int onoff) { @@ -95,19 +96,7 @@ static void fips_set_mode(int onoff) } } -static void fips_set_rand_check(const void *rand_check) - { - int owning_thread = fips_is_owning_thread(); - - if (fips_started) - { - if (!owning_thread) fips_w_lock(); - fips_rand_check = rand_check; - if (!owning_thread) fips_w_unlock(); - } - } - -int FIPS_mode(void) +int FIPS_module_mode(void) { int ret = 0; int owning_thread = fips_is_owning_thread(); @@ -121,20 +110,6 @@ int FIPS_mode(void) return ret; } -const void *FIPS_rand_check(void) - { - const void *ret = 0; - int owning_thread = fips_is_owning_thread(); - - if (fips_started) - { - if (!owning_thread) fips_r_lock(); - ret = fips_rand_check; - if (!owning_thread) fips_r_unlock(); - } - return ret; - } - int FIPS_selftest_failed(void) { int ret = 0; @@ -167,17 +142,6 @@ void fips_set_selftest_fail(void) fips_selftest_fail = 1; } -int FIPS_selftest(void) - { - - return FIPS_selftest_sha1() - && FIPS_selftest_hmac() - && FIPS_selftest_aes() - && FIPS_selftest_des() - && FIPS_selftest_rsa() - && 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 }; @@ -214,6 +178,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); @@ -224,19 +191,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))) @@ -252,18 +223,22 @@ 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; } - return 1; + 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; } -int FIPS_mode_set(int onoff) +int FIPS_module_mode_set(int onoff) { - int fips_set_owning_thread(); - int fips_clear_owning_thread(); int ret = 0; fips_w_lock(); @@ -272,15 +247,14 @@ int FIPS_mode_set(int onoff) if(onoff) { - unsigned char buf[48]; fips_selftest_fail = 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; @@ -289,7 +263,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; @@ -298,45 +272,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; - } - - /* Perform RNG KAT before seeding */ - if (!FIPS_selftest_rng()) - { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE); fips_selftest_fail = 1; ret = 0; goto end; } - /* automagically seed PRNG if not already seeded */ - if(!FIPS_rand_status()) - { - if(RAND_bytes(buf,sizeof buf) <= 0) - { - fips_selftest_fail = 1; - ret = 0; - goto end; - } - FIPS_rand_set_key(buf,32); - FIPS_rand_seed(buf+32,16); - } - - /* now switch into FIPS mode */ - fips_set_rand_check(FIPS_rand_method()); - RAND_set_rand_method(FIPS_rand_method()); if(FIPS_selftest()) - fips_set_mode(1); + fips_set_mode(onoff); else { fips_selftest_fail = 1; @@ -388,6 +331,7 @@ int fips_set_owning_thread(void) { CRYPTO_THREADID_current(&fips_thread); ret = 1; + fips_thread_set = 1; } CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2); } @@ -419,124 +363,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; - EVP_MD_CTX mctx; - EVP_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 (!EVP_DigestInit_ex(&mctx, digest, NULL)) - goto error; - if (!EVP_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; - } -#if 0 - else if (!EVP_SignFinal(&mctx, sig, &siglen, pkey)) - goto error; -#endif - - if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen))) - goto error; - - if (!EVP_DigestInit_ex(&mctx, digest, NULL)) - goto error; - if (!EVP_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); - } -#if 0 - else - ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey); -#endif - - error: - if (dsig != NULL) - DSA_SIG_free(dsig); - if (sig != sigtmp) - OPENSSL_free(sig); - EVP_MD_CTX_cleanup(&mctx); - if (ret != 1) - { - FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE); - if (fail_str) - ERR_add_error_data(2, "Type=", fail_str); - return 0; - } - return 1; +unsigned long FIPS_module_version(void) + { + 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); - if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0) - return 0; - EVP_Cipher(ctx, citmp, plaintext, len); - if (memcmp(citmp, ciphertext, len)) - return 0; - if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0) - return 0; - EVP_Cipher(ctx, pltmp, citmp, len); - if (memcmp(pltmp, plaintext, len)) - return 0; - return 1; + return FIPS_MODULE_VERSION_TEXT; } #if 0