The branch master has been updated via 2b407d050868c24ee36172e1abcfbfa0f003a98d (commit) via 5de9863bf33e6103264507b8ff87cd58b9c97a52 (commit) via 8d8dd09b969dd22112137634125e1634bb8e5c4c (commit) via 39fde64a85c93d2b3c6c58d5bde383f5f3932e5f (commit) from e109aaa9797c16b0902f8f3302243283828fcfc1 (commit)
- Log ----------------------------------------------------------------- commit 2b407d050868c24ee36172e1abcfbfa0f003a98d Author: Tomas Mraz <tm...@fedoraproject.org> Date: Wed Nov 18 16:22:08 2020 +0100 Documentation improvements for EVP_DigestInit_ex and related functions Documenting when EVP_MD_CTX_reset() is implicitly called and when type can be set to NULL. Reviewed-by: Dmitry Belyavskiy <beld...@gmail.com> Reviewed-by: Shane Lontis <shane.lon...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/13402) commit 5de9863bf33e6103264507b8ff87cd58b9c97a52 Author: Tomas Mraz <tm...@fedoraproject.org> Date: Fri Nov 13 15:57:27 2020 +0100 Fix regression in EVP_DigestInit_ex: crash when called with NULL type Reviewed-by: Dmitry Belyavskiy <beld...@gmail.com> Reviewed-by: Shane Lontis <shane.lon...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/13402) commit 8d8dd09b969dd22112137634125e1634bb8e5c4c Author: Tomas Mraz <tm...@fedoraproject.org> Date: Fri Nov 13 14:16:35 2020 +0100 Add test for no reset after DigestFinal_ex and DigestFinalXOF Reviewed-by: Dmitry Belyavskiy <beld...@gmail.com> Reviewed-by: Shane Lontis <shane.lon...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/13402) commit 39fde64a85c93d2b3c6c58d5bde383f5f3932e5f Author: Tomas Mraz <tm...@fedoraproject.org> Date: Fri Nov 13 13:42:31 2020 +0100 EVP_DigestFinalXOF must not reset the EVP_MD_CTX It does not do it in legacy path and 1.1.1 so that must not change. Reviewed-by: Dmitry Belyavskiy <beld...@gmail.com> Reviewed-by: Shane Lontis <shane.lon...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/13402) ----------------------------------------------------------------------- Summary of changes: crypto/evp/digest.c | 17 +++++++++-------- doc/man3/EVP_DigestInit.pod | 11 ++++++++--- test/evp_extra_test.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 3872bb68fb..b0ce61f935 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -170,8 +170,15 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) ctx->provctx = NULL; } - if (type != NULL) + if (type != NULL) { ctx->reqdigest = type; + } else { + if (ctx->digest == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_DIGEST_SET); + return 0; + } + type = ctx->digest; + } /* TODO(3.0): Legacy work around code below. Remove this */ #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) @@ -292,12 +299,6 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) ctx->engine = impl; } else ctx->engine = NULL; - } else { - if (!ctx->digest) { - ERR_raise(ERR_LIB_EVP, EVP_R_NO_DIGEST_SET); - return 0; - } - type = ctx->digest; } #endif if (ctx->digest != type) { @@ -455,7 +456,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size) if (EVP_MD_CTX_set_params(ctx, params) > 0) ret = ctx->digest->dfinal(ctx->provctx, md, &size, size); - EVP_MD_CTX_reset(ctx); + return ret; legacy: diff --git a/doc/man3/EVP_DigestInit.pod b/doc/man3/EVP_DigestInit.pod index 0af06869aa..082f26370c 100644 --- a/doc/man3/EVP_DigestInit.pod +++ b/doc/man3/EVP_DigestInit.pod @@ -208,6 +208,10 @@ value explicitly fetched with EVP_MD_fetch(). If I<impl> is non-NULL, its implementation of the digest I<type> is used if there is one, and if not, the default implementation is used. +The I<type> parameter can be NULL if I<ctx> has been already initialized +with another EVP_DigestInit_ex() call and has not been reset with +EVP_MD_CTX_reset(). + =item EVP_DigestUpdate() Hashes I<cnt> bytes of data at I<d> into the digest context I<ctx>. This @@ -239,12 +243,13 @@ few bytes. =item EVP_DigestInit() Behaves in the same way as EVP_DigestInit_ex() except it always uses the -default digest implementation and calls EVP_MD_CTX_reset(). +default digest implementation and calls EVP_MD_CTX_reset() so it cannot +be used with an I<type> of NULL. =item EVP_DigestFinal() -Similar to EVP_DigestFinal_ex() except the digest context I<ctx> is -automatically cleaned up. +Similar to EVP_DigestFinal_ex() except after computing the digest +the digest context I<ctx> is automatically cleaned up with EVP_MD_CTX_reset(). =item EVP_MD_CTX_copy() diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index a52b472ba6..fa6d173e30 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -686,6 +686,51 @@ static int test_EVP_DigestVerifyInit(void) return ret; } +/* + * Test corner cases of EVP_DigestInit/Update/Final API call behavior. + */ +static int test_EVP_Digest(void) +{ + int ret = 0; + EVP_MD_CTX *md_ctx = NULL; + unsigned char md[EVP_MAX_MD_SIZE]; + + if (!TEST_ptr(md_ctx = EVP_MD_CTX_new())) + goto out; + + if (!TEST_true(EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL)) + || !TEST_true(EVP_DigestUpdate(md_ctx, kMsg, sizeof(kMsg))) + || !TEST_true(EVP_DigestFinal(md_ctx, md, NULL)) + /* EVP_DigestFinal resets the EVP_MD_CTX. */ + || !TEST_ptr_eq(EVP_MD_CTX_md(md_ctx), NULL)) + goto out; + + if (!TEST_true(EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL)) + || !TEST_true(EVP_DigestUpdate(md_ctx, kMsg, sizeof(kMsg))) + || !TEST_true(EVP_DigestFinal_ex(md_ctx, md, NULL)) + /* EVP_DigestFinal_ex does not reset the EVP_MD_CTX. */ + || !TEST_ptr(EVP_MD_CTX_md(md_ctx)) + /* + * EVP_DigestInit_ex with NULL type should work on + * pre-initialized context. + */ + || !TEST_true(EVP_DigestInit_ex(md_ctx, NULL, NULL))) + goto out; + + if (!TEST_true(EVP_DigestInit_ex(md_ctx, EVP_shake256(), NULL)) + || !TEST_true(EVP_DigestUpdate(md_ctx, kMsg, sizeof(kMsg))) + || !TEST_true(EVP_DigestFinalXOF(md_ctx, md, sizeof(md))) + /* EVP_DigestFinalXOF does not reset the EVP_MD_CTX. */ + || !TEST_ptr(EVP_MD_CTX_md(md_ctx)) + || !TEST_true(EVP_DigestInit_ex(md_ctx, NULL, NULL))) + goto out; + ret = 1; + + out: + EVP_MD_CTX_free(md_ctx); + return ret; +} + static int test_d2i_AutoPrivateKey(int i) { int ret = 0; @@ -2109,6 +2154,7 @@ int setup_tests(void) ADD_TEST(test_EVP_set_default_properties); ADD_ALL_TESTS(test_EVP_DigestSignInit, 9); ADD_TEST(test_EVP_DigestVerifyInit); + ADD_TEST(test_EVP_Digest); ADD_TEST(test_EVP_Enveloped); ADD_ALL_TESTS(test_d2i_AutoPrivateKey, OSSL_NELEM(keydata)); ADD_TEST(test_privatekey_to_pkcs8);