For self signed root only indicate one error.
[oweals/openssl.git] / crypto / evp / digest.c
index a0d5763b9265735bb0b675d65b03e65db6052e32..af0044ff43d7486b1302c56b8e7d4e988d0b09b6 100644 (file)
 
 #ifdef OPENSSL_FIPS
 #include <openssl/fips.h>
+#include "evp_locl.h"
 #endif
 
 void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
@@ -145,6 +146,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 = evp_get_fips_md(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
@@ -244,7 +258,11 @@ skip_to_init:
 
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
        {
+#ifdef OPENSSL_FIPS
+       return FIPS_digestupdate(ctx, data, count);
+#else
        return ctx->update(ctx,data,count);
+#endif
        }
 
 /* The caller can assume that this removes any secret data from the context */
@@ -259,6 +277,9 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 /* The caller can assume that this removes any secret data from the context */
 int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
        {
+#ifdef OPENSSL_FIPS
+       return FIPS_digestfinal(ctx, md, size);
+#else
        int ret;
 
        OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
@@ -272,6 +293,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
                }
        memset(ctx->md_data,0,ctx->digest->ctx_size);
        return ret;
+#endif
        }
 
 int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
@@ -358,13 +380,17 @@ int EVP_Digest(const void *data, size_t count,
 
 void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
        {
-       EVP_MD_CTX_cleanup(ctx);
-       OPENSSL_free(ctx);
+       if (ctx)
+               {
+               EVP_MD_CTX_cleanup(ctx);
+               OPENSSL_free(ctx);
+               }
        }
 
 /* This call frees resources associated with the context */
 int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
        {
+#ifndef OPENSSL_FIPS
        /* Don't assume ctx->md_data was cleaned in EVP_Digest_Final,
         * because sometimes only copies of the context are ever finalised.
         */
@@ -377,6 +403,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
                OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
                OPENSSL_free(ctx->md_data);
                }
+#endif
        if (ctx->pctx)
                EVP_PKEY_CTX_free(ctx->pctx);
 #ifndef OPENSSL_NO_ENGINE
@@ -384,6 +411,9 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
                /* The EVP_MD we used belongs to an ENGINE, release the
                 * functional reference we held for this reason. */
                ENGINE_finish(ctx->engine);
+#endif
+#ifdef OPENSSL_FIPS
+       FIPS_md_ctx_cleanup(ctx);
 #endif
        memset(ctx,'\0',sizeof *ctx);