summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2012-05-13 18:40:12 +0000
committerDr. Stephen Henson <steve@openssl.org>2012-05-13 18:40:12 +0000
commit1dded7f7e8e9f737ef9d7e3c3ef165a78fd7fa1d (patch)
tree0fcbb557ce0e1398a1564e16545e46fc16a552a7
parent482f2380693213b219de06357e435186121ca731 (diff)
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.
-rw-r--r--CHANGES7
-rw-r--r--crypto/evp/Makefile4
-rw-r--r--crypto/evp/digest.c13
-rw-r--r--crypto/evp/e_aes.c11
-rw-r--r--crypto/evp/e_des3.c3
-rw-r--r--crypto/evp/e_null.c3
-rw-r--r--crypto/evp/evp_enc.c7
-rw-r--r--crypto/evp/m_dss.c2
-rw-r--r--crypto/evp/m_dss1.c3
-rw-r--r--crypto/evp/m_ecdsa.c2
-rw-r--r--crypto/evp/m_sha1.c3
-rw-r--r--crypto/hmac/hmac.c12
-rw-r--r--crypto/rsa/rsa_pmeth.c16
13 files changed, 61 insertions, 25 deletions
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 <assert.h>
#include <openssl/aes.h>
#include "evp_locl.h"
-#ifndef OPENSSL_FIPS
#include "modes_lcl.h"
#include <openssl/rand.h>
+#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 || len<AES_BLOCK_SIZE)
return 0;
-#ifdef OPENSSL_FIPS
+#ifdef OPENSSL_FIPSCANISTER
/* Requirement of SP800-38E */
if (FIPS_module_mode() && !(ctx->flags & 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 <openssl/des.h>
#include <openssl/rand.h>
-#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 <openssl/evp.h>
#include <openssl/objects.h>
-#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 <openssl/dsa.h>
#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 <openssl/x509.h>
#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 <stdio.h>
#include "cryptlib.h"
-#ifndef OPENSSL_FIPS
-
#ifndef OPENSSL_NO_SHA
#include <openssl/evp.h>
@@ -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