X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=fips%2Futl%2Ffips_md.c;h=5e9fe4e4ee2d7afde8be988f99e3439faaacaf97;hp=0038646f58f9d70492f413be7bb9490afd557037;hb=3a98f9cf20c6af604799ee079bec496b296bb5cc;hpb=7cc684f4f7fbcdc5cf4683eaf025d4f915acbf3c diff --git a/fips/utl/fips_md.c b/fips/utl/fips_md.c index 0038646f58..5e9fe4e4ee 100644 --- a/fips/utl/fips_md.c +++ b/fips/utl/fips_md.c @@ -135,9 +135,53 @@ EVP_MD_CTX *FIPS_md_ctx_create(void) return ctx; } +/* 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,size_t 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}, + }; + int FIPS_digestinit(EVP_MD_CTX *ctx, const EVP_MD *type) { M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_FIPS_DIGESTINIT,FIPS_R_FIPS_SELFTEST_FAILED); + ctx->digest = &bad_md; + ctx->update = bad_update; + return 0; + } + if(FIPS_module_mode() && !(type->flags & EVP_MD_FLAG_FIPS) && + !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) + { + EVPerr(EVP_F_FIPS_DIGESTINIT, EVP_R_DISABLED_FOR_FIPS); + ctx->digest = &bad_md; + ctx->update = bad_update; + return 0; + } if (ctx->digest != type) { if (ctx->digest && ctx->digest->ctx_size) @@ -149,7 +193,7 @@ int FIPS_digestinit(EVP_MD_CTX *ctx, const EVP_MD *type) ctx->md_data=OPENSSL_malloc(type->ctx_size); if (ctx->md_data == NULL) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, + EVPerr(EVP_F_FIPS_DIGESTINIT, ERR_R_MALLOC_FAILURE); return 0; } @@ -162,6 +206,11 @@ int FIPS_digestinit(EVP_MD_CTX *ctx, const EVP_MD *type) int FIPS_digestupdate(EVP_MD_CTX *ctx, const void *data, size_t count) { + if (FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_FIPS_DIGESTUPDATE, FIPS_R_SELFTEST_FAILED); + return 0; + } return ctx->update(ctx,data,count); } @@ -170,6 +219,12 @@ int FIPS_digestfinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { int ret; + if (FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_FIPS_DIGESTFINAL, FIPS_R_SELFTEST_FAILED); + return 0; + } + OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); ret=ctx->digest->final(ctx,md); if (size != NULL) @@ -208,7 +263,7 @@ void FIPS_md_ctx_destroy(EVP_MD_CTX *ctx) /* This call frees resources associated with the context */ int FIPS_md_ctx_cleanup(EVP_MD_CTX *ctx) { - /* Don't assume ctx->md_data was cleaned in EVP_Digest_Final, + /* Don't assume ctx->md_data was cleaned in FIPS_digest_Final, * because sometimes only copies of the context are ever finalised. */ if (ctx->digest && ctx->digest->cleanup @@ -230,7 +285,7 @@ int FIPS_md_ctx_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) unsigned char *tmp_buf; if ((in == NULL) || (in->digest == NULL)) { - EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,EVP_R_INPUT_NOT_INITIALIZED); + EVPerr(EVP_F_FIPS_MD_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED); return 0; } @@ -252,7 +307,7 @@ int FIPS_md_ctx_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) out->md_data=OPENSSL_malloc(out->digest->ctx_size); if (!out->md_data) { - EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_MALLOC_FAILURE); + EVPerr(EVP_F_FIPS_MD_CTX_COPY,ERR_R_MALLOC_FAILURE); return 0; } } @@ -266,3 +321,27 @@ int FIPS_md_ctx_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) return 1; } + +const EVP_MD *FIPS_get_digestbynid(int nid) + { + switch (nid) + { + case NID_sha1: + return EVP_sha1(); + + case NID_sha224: + return EVP_sha224(); + + case NID_sha256: + return EVP_sha256(); + + case NID_sha384: + return EVP_sha384(); + + case NID_sha512: + return EVP_sha512(); + + default: + return NULL; + } + }