From 6be00c7e16f27111e6dcc77da3bb01fa98b8f4a9 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 27 Jan 2005 01:49:42 +0000 Subject: [PATCH] More FIPS algorithm blocking. Catch attempted use of non FIPS algorithms with HMAC. Give an assertion error for applications that ignore FIPS digest errors. Make -non-fips-allow work with dgst and HMAC. --- apps/dgst.c | 14 +++++++++----- crypto/crypto.h | 3 +++ crypto/evp/digest.c | 34 ++++++++++++++++++++++++++++++++++ crypto/hmac/hmac.c | 9 +++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/apps/dgst.c b/apps/dgst.c index 9106b13fd9..b30bf4e009 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -78,7 +78,7 @@ static HMAC_CTX hmac_ctx; int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title, - const char *file,BIO *bmd,const char *hmac_key); + const char *file,BIO *bmd,const char *hmac_key, int non_fips_allow); int MAIN(int, char **); @@ -366,7 +366,7 @@ int MAIN(int argc, char **argv) { BIO_set_fp(in,stdin,BIO_NOCLOSE); err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf, - siglen,"","(stdin)",bmd,hmac_key); + siglen,"","(stdin)",bmd,hmac_key, non_fips_allow); } else { @@ -392,7 +392,7 @@ int MAIN(int argc, char **argv) else tmp=""; r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf, - siglen,tmp,argv[i],bmd,hmac_key); + siglen,tmp,argv[i],bmd,hmac_key,non_fips_allow); if(r) err=r; if(tofree) @@ -419,7 +419,7 @@ end: int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title, - const char *file,BIO *bmd,const char *hmac_key) + const char *file,BIO *bmd,const char *hmac_key, int non_fips_allow) { unsigned int len; int i; @@ -430,7 +430,11 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, EVP_MD *md; BIO_get_md(bmd,&md); - HMAC_Init(&hmac_ctx,hmac_key,strlen(hmac_key),md); + HMAC_CTX_init(&hmac_ctx); + if (non_fips_allow) + HMAC_CTX_set_flags(&hmac_ctx, + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + HMAC_Init_ex(&hmac_ctx,hmac_key,strlen(hmac_key),md, NULL); BIO_get_md_ctx(bmd,&md_ctx); BIO_set_md_ctx(bmd,&hmac_ctx.md_ctx); } diff --git a/crypto/crypto.h b/crypto/crypto.h index 383090c327..4d1dfac7f1 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -440,6 +440,9 @@ void OpenSSLDie(const char *file,int line,const char *assertion); int FIPS_mode(void); void *FIPS_rand_check(void); +#define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \ + alg " previous FIPS forbidden algorithm error ignored"); + #define FIPS_BAD_ABORT(alg) OpenSSLDie(__FILE__, __LINE__, \ #alg " Algorithm forbidden in FIPS mode"); diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 2b6480fddc..f21c63842c 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -137,6 +137,39 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) return EVP_DigestInit_ex(ctx, type, NULL); } +#ifdef OPENSSL_FIPS + +/* The purpose of these is to trap programs that attempt to use non FIPS + * algorithms in FIPS mode and ignore the errors. + */ + +static int bad_init(EVP_MD_CTX *ctx) + { FIPS_ERROR_IGNORED("Digest init"); return 0;} + +static int bad_update(EVP_MD_CTX *ctx,const void *data,unsigned long count) + { FIPS_ERROR_IGNORED("Digest update"); return 0;} + +static int bad_final(EVP_MD_CTX *ctx,unsigned char *md) + { FIPS_ERROR_IGNORED("Digest Final"); return 0;} + +static const EVP_MD bad_md = + { + 0, + 0, + 0, + 0, + bad_init, + bad_update, + bad_final, + NULL, + NULL, + NULL, + 0, + {0,0,0,0}, + }; + +#endif + 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); @@ -202,6 +235,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) { EVPerr(EVP_F_EVP_DIGESTINIT, EVP_R_DISABLED_FOR_FIPS); + ctx->digest = &bad_md; return 0; } } diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c index f4ea6ab29f..06ee80761f 100644 --- a/crypto/hmac/hmac.c +++ b/crypto/hmac/hmac.c @@ -77,6 +77,15 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, if (key != NULL) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(md->flags & EVP_MD_FLAG_FIPS) + && (!(ctx->md_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->i_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->o_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))) + OpenSSLDie(__FILE__,__LINE__, + "HMAC: digest not allowed in FIPS mode"); +#endif + reset=1; j=EVP_MD_block_size(md); OPENSSL_assert(j <= sizeof ctx->key); -- 2.25.1