summaryrefslogtreecommitdiffstats
path: root/crypto/dh
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2011-06-08 15:58:59 +0000
committerDr. Stephen Henson <steve@openssl.org>2011-06-08 15:58:59 +0000
commit03e16611a3768c9562e3072bcef1b606f9ce2bae (patch)
treef80a3cfab842fabc8adc709e1c95ba7791947972 /crypto/dh
parent8e2f3c1c838b1e30a2eab0e41cb015419727378a (diff)
Redirect DH operations to FIPS module. Block non-FIPS methods.
Sync DH error codes with HEAD.
Diffstat (limited to 'crypto/dh')
-rw-r--r--crypto/dh/dh.h19
-rw-r--r--crypto/dh/dh_err.c6
-rw-r--r--crypto/dh/dh_key.c16
-rw-r--r--crypto/dh/dh_lib.c15
4 files changed, 53 insertions, 3 deletions
diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
index 849309a489..b6d367bb6a 100644
--- a/crypto/dh/dh.h
+++ b/crypto/dh/dh.h
@@ -86,6 +86,21 @@
* be used for all exponents.
*/
+/* If this flag is set the DH method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its reposibility
+ * to ensure the result is compliant.
+ */
+
+#define DH_FLAG_FIPS_METHOD 0x0400
+
+/* If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+#define DH_FLAG_NON_FIPS_ALLOW 0x0400
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -230,6 +245,8 @@ void ERR_load_DH_strings(void);
#define DH_F_COMPUTE_KEY 102
#define DH_F_DHPARAMS_PRINT_FP 101
#define DH_F_DH_BUILTIN_GENPARAMS 106
+#define DH_F_DH_COMPUTE_KEY 114
+#define DH_F_DH_GENERATE_KEY 115
#define DH_F_DH_NEW_METHOD 105
#define DH_F_DH_PARAM_DECODE 107
#define DH_F_DH_PRIV_DECODE 110
@@ -249,7 +266,9 @@ void ERR_load_DH_strings(void);
#define DH_R_DECODE_ERROR 104
#define DH_R_INVALID_PUBKEY 102
#define DH_R_KEYS_NOT_SET 108
+#define DH_R_KEY_SIZE_TOO_SMALL 110
#define DH_R_MODULUS_TOO_LARGE 103
+#define DH_R_NON_FIPS_METHOD 111
#define DH_R_NO_PARAMETERS_SET 107
#define DH_R_NO_PRIVATE_VALUE 100
#define DH_R_PARAMETER_ENCODING_ERROR 105
diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c
index d5cf0c22a3..1da2c12cff 100644
--- a/crypto/dh/dh_err.c
+++ b/crypto/dh/dh_err.c
@@ -1,6 +1,6 @@
/* crypto/dh/dh_err.c */
/* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -73,6 +73,8 @@ static ERR_STRING_DATA DH_str_functs[]=
{ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"},
{ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"},
{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"},
+{ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"},
+{ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"},
{ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"},
{ERR_FUNC(DH_F_DH_PARAM_DECODE), "DH_PARAM_DECODE"},
{ERR_FUNC(DH_F_DH_PRIV_DECODE), "DH_PRIV_DECODE"},
@@ -95,7 +97,9 @@ static ERR_STRING_DATA DH_str_reasons[]=
{ERR_REASON(DH_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"},
{ERR_REASON(DH_R_KEYS_NOT_SET) ,"keys not set"},
+{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL) ,"key size too small"},
{ERR_REASON(DH_R_MODULUS_TOO_LARGE) ,"modulus too large"},
+{ERR_REASON(DH_R_NON_FIPS_METHOD) ,"non fips method"},
{ERR_REASON(DH_R_NO_PARAMETERS_SET) ,"no parameters set"},
{ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"},
{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index e7db440342..dd4cd6b593 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -73,11 +73,27 @@ static int dh_finish(DH *dh);
int DH_generate_key(DH *dh)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
+ && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW))
+ {
+ DHerr(DH_F_DH_GENERATE_KEY, DH_R_NON_FIPS_METHOD);
+ return 0;
+ }
+#endif
return dh->meth->generate_key(dh);
}
int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
+ && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW))
+ {
+ DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD);
+ return 0;
+ }
+#endif
return dh->meth->compute_key(key, pub_key, dh);
}
diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c
index 7aef080e7a..edb4bb31fb 100644
--- a/crypto/dh/dh_lib.c
+++ b/crypto/dh/dh_lib.c
@@ -64,6 +64,10 @@
#include <openssl/engine.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
const char DH_version[]="Diffie-Hellman" OPENSSL_VERSION_PTEXT;
static const DH_METHOD *default_DH_method = NULL;
@@ -76,7 +80,14 @@ void DH_set_default_method(const DH_METHOD *meth)
const DH_METHOD *DH_get_default_method(void)
{
if(!default_DH_method)
- default_DH_method = DH_OpenSSL();
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ default_DH_method = FIPS_dh_openssl();
+ else
+#endif
+ default_DH_method = DH_OpenSSL();
+ }
return default_DH_method;
}
@@ -156,7 +167,7 @@ DH *DH_new_method(ENGINE *engine)
ret->counter = NULL;
ret->method_mont_p=NULL;
ret->references = 1;
- ret->flags=ret->meth->flags;
+ ret->flags=ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
if ((ret->meth->init != NULL) && !ret->meth->init(ret))
{