From 752c1a0ce952eb21b5c1e90a7529f52b819b8b2b Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 9 Jun 2011 13:54:09 +0000 Subject: [PATCH] Redirect DSA operations to FIPS module in FIPS mode. --- CHANGES | 3 +++ crypto/dsa/dsa.h | 17 +++++++++++++++++ crypto/dsa/dsa_err.c | 4 +++- crypto/dsa/dsa_gen.c | 19 +++++++++++++++++++ crypto/dsa/dsa_lib.c | 15 +++++++++++++-- crypto/dsa/dsa_sign.c | 16 ++++++++++++++++ crypto/dsa/dsa_vrf.c | 8 ++++++++ 7 files changed, 79 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 386ca46276..647836b89b 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,9 @@ Changes between 1.0.0d and 1.0.1 [xx XXX xxxx] + *) Redirect DSA and DH operations to FIPS module in FIPS mode. + [Steve Henson] + *) Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use FIPS EC methods unconditionally for now. [Steve Henson] diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h index 3d362d140a..6a21b2cce2 100644 --- a/crypto/dsa/dsa.h +++ b/crypto/dsa/dsa.h @@ -97,6 +97,21 @@ * be used for all exponents. */ +/* If this flag is set the DSA 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 DSA_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 DSA_FLAG_NON_FIPS_ALLOW 0x0400 + #ifdef __cplusplus extern "C" { #endif @@ -272,6 +287,7 @@ void ERR_load_DSA_strings(void); #define DSA_F_DSAPARAMS_PRINT_FP 101 #define DSA_F_DSA_DO_SIGN 112 #define DSA_F_DSA_DO_VERIFY 113 +#define DSA_F_DSA_GENERATE_PARAMETERS_EX 123 #define DSA_F_DSA_NEW_METHOD 103 #define DSA_F_DSA_PARAM_DECODE 119 #define DSA_F_DSA_PRINT_FP 105 @@ -299,6 +315,7 @@ void ERR_load_DSA_strings(void); #define DSA_R_MISSING_PARAMETERS 101 #define DSA_R_MODULUS_TOO_LARGE 103 #define DSA_R_NEED_NEW_SETUP_VALUES 110 +#define DSA_R_NON_FIPS_DSA_METHOD 111 #define DSA_R_NO_PARAMETERS_SET 107 #define DSA_R_PARAMETER_ENCODING_ERROR 105 diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c index 2981eabeaf..bada41fcce 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -1,6 +1,6 @@ /* crypto/dsa/dsa_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 @@ -76,6 +76,7 @@ static ERR_STRING_DATA DSA_str_functs[]= {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, +{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX), "DSA_generate_parameters_ex"}, {ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"}, {ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "DSA_PARAM_DECODE"}, {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"}, @@ -106,6 +107,7 @@ static ERR_STRING_DATA DSA_str_reasons[]= {ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, {ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES) ,"need new setup values"}, +{ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD) ,"non fips dsa method"}, {ERR_REASON(DSA_R_NO_PARAMETERS_SET) ,"no parameters set"}, {ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"}, {0,NULL} diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c index e6a5452016..cc73a23724 100644 --- a/crypto/dsa/dsa_gen.c +++ b/crypto/dsa/dsa_gen.c @@ -81,13 +81,32 @@ #include #include "dsa_locl.h" +#ifdef OPENSSL_FIPS +#include +#endif + int DSA_generate_parameters_ex(DSA *ret, int bits, const unsigned char *seed_in, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { + if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW)) + { + DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD); + return 0; + } + if(ret->meth->dsa_paramgen) return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, counter_ret, h_ret, cb); +#ifdef OPENSSL_FIPS + else if (FIPS_mode()) + { + return FIPS_dsa_generate_parameters_ex(ret, bits, + seed_in, seed_len, + counter_ret, h_ret, cb); + } +#endif else { const EVP_MD *evpmd; diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index e9b75902db..f7960901a0 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -70,6 +70,10 @@ #include #endif +#ifdef OPENSSL_FIPS +#include +#endif + const char DSA_version[]="DSA" OPENSSL_VERSION_PTEXT; static const DSA_METHOD *default_DSA_method = NULL; @@ -82,7 +86,14 @@ void DSA_set_default_method(const DSA_METHOD *meth) const DSA_METHOD *DSA_get_default_method(void) { if(!default_DSA_method) - default_DSA_method = DSA_OpenSSL(); + { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + default_DSA_method = FIPS_dsa_openssl(); + else +#endif + default_DSA_method = DSA_OpenSSL(); + } return default_DSA_method; } @@ -163,7 +174,7 @@ DSA *DSA_new_method(ENGINE *engine) ret->method_mont_p=NULL; ret->references=1; - ret->flags=ret->meth->flags; + ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index e02365a8b1..c3cc3642ce 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -65,11 +65,27 @@ DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) + { + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_NON_FIPS_DSA_METHOD); + return NULL; + } +#endif return dsa->meth->dsa_do_sign(dgst, dlen, dsa); } int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) + { + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NON_FIPS_DSA_METHOD); + return 0; + } +#endif return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); } diff --git a/crypto/dsa/dsa_vrf.c b/crypto/dsa/dsa_vrf.c index 286ed28cfa..674cb5fa5f 100644 --- a/crypto/dsa/dsa_vrf.c +++ b/crypto/dsa/dsa_vrf.c @@ -64,5 +64,13 @@ int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) + { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_NON_FIPS_DSA_METHOD); + return -1; + } +#endif return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa); } -- 2.25.1