More FIPS algorithm blocking.
authorDr. Stephen Henson <steve@openssl.org>
Thu, 27 Jan 2005 01:49:42 +0000 (01:49 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 27 Jan 2005 01:49:42 +0000 (01:49 +0000)
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
crypto/crypto.h
crypto/evp/digest.c
crypto/hmac/hmac.c

index 9106b13fd9bb3bed1890c7fad62ba7bc97ef84c0..b30bf4e009329d4063029adf63bea6849b47cb05 100644 (file)
@@ -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);
                }
index 383090c327babc0e9353c0cc591f5b4c56a303c3..4d1dfac7f1eed7dfd84e7932b3d1d69272313b41 100644 (file)
@@ -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");
 
index 2b6480fddc36555109b7831a43b871e353c7f146..f21c63842ca66024c4473ddb4b2388622d4a9a1e 100644 (file)
@@ -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;
                                }
                        }
index f4ea6ab29faaf567e4c8fc890005c9453b3b2859..06ee80761ff46741122e97f5dcd285a2eaf21b77 100644 (file)
@@ -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);