diff --git a/CHANGES b/CHANGES index fb0bf2cba0..405c314c4c 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,13 @@ Changes between 1.0.1 and 1.0.2 [xx XXX xxxx] + *) Experimental multi-implementation support for FIPS capable OpenSSL. + When in FIPS mode the approved implementations are used as normal, + when not in FIPS mode the internal unapproved versions are used instead. + This means that the FIPS capable OpenSSL isn't forced to use the + (often lower perfomance) FIPS implementations outside FIPS mode. + [Steve Henson] + *) Transparently support X9.42 DH parameters when calling PEM_read_bio_DHparameters. This means existing applications can handle the new parameter format automatically. diff --git a/crypto/evp/Makefile b/crypto/evp/Makefile index 9c79f66f56..229536ef53 100644 --- a/crypto/evp/Makefile +++ b/crypto/evp/Makefile @@ -28,7 +28,7 @@ LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c \ bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \ c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \ evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \ - e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c evp_fips.c \ + e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \ e_aes_cbc_hmac_sha1.c e_rc4_hmac_md5.c LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \ @@ -41,7 +41,7 @@ LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \ bio_md.o bio_b64.o bio_enc.o evp_err.o e_null.o \ c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \ evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o \ - e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o evp_fips.o \ + e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o \ e_aes_cbc_hmac_sha1.o e_rc4_hmac_md5.o SRC= $(LIBSRC) diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 467e6b5ae9..feab0831be 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -145,6 +145,19 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); +#ifdef OPENSSL_FIPS_ + /* If FIPS mode switch to approved implementation if possible */ + if (FIPS_mode()) + { + const EVP_MD *fipsmd; + if (type) + { + fipsmd = FIPS_get_digestbynid(EVP_MD_type(type)); + if (fipsmd) + type = fipsmd; + } + } +#endif #ifndef OPENSSL_NO_ENGINE /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts * so this context may already have an ENGINE! Try to avoid releasing diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index 1e4af0cb75..a0c27ef139 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -56,10 +56,14 @@ #include #include #include "evp_locl.h" -#ifndef OPENSSL_FIPS #include "modes_lcl.h" #include +#ifndef OPENSSL_FIPSCANISTER +#undef EVP_CIPH_FLAG_FIPS +#define EVP_CIPH_FLAG_FIPS 0 +#endif + typedef struct { AES_KEY ks; @@ -715,7 +719,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_GCM_SET_IVLEN: if (arg <= 0) return 0; -#ifdef OPENSSL_FIPS +#ifdef OPENSSL_FIPSCANISTER if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && arg < 12) return 0; @@ -1126,7 +1130,7 @@ static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 0; if (!out || !in || lenflags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && (len > (1UL<<20)*16)) @@ -1310,4 +1314,3 @@ BLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) #endif -#endif diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c index 1e69972662..3232cfe024 100644 --- a/crypto/evp/e_des3.c +++ b/crypto/evp/e_des3.c @@ -65,8 +65,6 @@ #include #include -#ifndef OPENSSL_FIPS - static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv,int enc); @@ -313,4 +311,3 @@ const EVP_CIPHER *EVP_des_ede3(void) return &des_ede3_ecb; } #endif -#endif diff --git a/crypto/evp/e_null.c b/crypto/evp/e_null.c index f0c1f78b5f..98a78499f9 100644 --- a/crypto/evp/e_null.c +++ b/crypto/evp/e_null.c @@ -61,8 +61,6 @@ #include #include -#ifndef OPENSSL_FIPS - static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv,int enc); static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, @@ -101,4 +99,3 @@ static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, memcpy((char *)out,(const char *)in,inl); return 1; } -#endif diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 0c54f05e6e..6da323077a 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -171,7 +171,14 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp #ifdef OPENSSL_FIPS if (FIPS_mode()) + { + const EVP_CIPHER *fcipher; + if (cipher) + fcipher = FIPS_get_cipherbynid(EVP_CIPHER_type(cipher)); + if (fcipher) + cipher = fcipher; return FIPS_cipherinit(ctx, cipher, key, iv, enc); + } #endif ctx->cipher=cipher; if (ctx->cipher->ctx_size) diff --git a/crypto/evp/m_dss.c b/crypto/evp/m_dss.c index 4ad63ada6f..48c2689504 100644 --- a/crypto/evp/m_dss.c +++ b/crypto/evp/m_dss.c @@ -66,7 +66,6 @@ #endif #ifndef OPENSSL_NO_SHA -#ifndef OPENSSL_FIPS static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -98,4 +97,3 @@ const EVP_MD *EVP_dss(void) return(&dsa_md); } #endif -#endif diff --git a/crypto/evp/m_dss1.c b/crypto/evp/m_dss1.c index f80170efeb..4f03fb70e0 100644 --- a/crypto/evp/m_dss1.c +++ b/crypto/evp/m_dss1.c @@ -68,8 +68,6 @@ #include #endif -#ifndef OPENSSL_FIPS - static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -100,4 +98,3 @@ const EVP_MD *EVP_dss1(void) return(&dss1_md); } #endif -#endif diff --git a/crypto/evp/m_ecdsa.c b/crypto/evp/m_ecdsa.c index 4b15fb0f6c..a6ed24b0b6 100644 --- a/crypto/evp/m_ecdsa.c +++ b/crypto/evp/m_ecdsa.c @@ -116,7 +116,6 @@ #include #ifndef OPENSSL_NO_SHA -#ifndef OPENSSL_FIPS static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -148,4 +147,3 @@ const EVP_MD *EVP_ecdsa(void) return(&ecdsa_md); } #endif -#endif diff --git a/crypto/evp/m_sha1.c b/crypto/evp/m_sha1.c index 3cb11f1ebb..9492a544d9 100644 --- a/crypto/evp/m_sha1.c +++ b/crypto/evp/m_sha1.c @@ -59,8 +59,6 @@ #include #include "cryptlib.h" -#ifndef OPENSSL_FIPS - #ifndef OPENSSL_NO_SHA #include @@ -206,4 +204,3 @@ const EVP_MD *EVP_sha512(void) { return(&sha512_md); } #endif /* ifndef OPENSSL_NO_SHA512 */ -#endif diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c index ba27cbf56f..45335a1f7a 100644 --- a/crypto/hmac/hmac.c +++ b/crypto/hmac/hmac.c @@ -72,6 +72,18 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, unsigned char pad[HMAC_MAX_MD_CBLOCK]; #ifdef OPENSSL_FIPS + /* If FIPS mode switch to approved implementation if possible */ + if (FIPS_mode()) + { + const EVP_MD *fipsmd; + if (md) + { + fipsmd = FIPS_get_digestbynid(EVP_MD_type(md)); + if (fipsmd) + md = fipsmd; + } + } + if (FIPS_mode()) { /* If we have an ENGINE need to allow non FIPS */ diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c index 5b2ecf56ad..b654b00ea8 100644 --- a/crypto/rsa/rsa_pmeth.c +++ b/crypto/rsa/rsa_pmeth.c @@ -174,10 +174,20 @@ static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx) rv = 0; if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv) return -1; - if (rctx->md && !(rctx->md->flags & EVP_MD_FLAG_FIPS)) - return rv; + if (rctx->md) + { + const EVP_MD *fmd; + fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->md)); + if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + return rv; + } if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS)) - return rv; + { + const EVP_MD *fmd; + fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->mgf1md)); + if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + return rv; + } return 1; } #endif