From cddcea8c4b46ea610d928af899e394d9e323c617 Mon Sep 17 00:00:00 2001 From: Richard Levitte <levitte@openssl.org> Date: Mon, 30 Nov 2015 10:24:12 +0100 Subject: [PATCH] Adapt all engines that add new EVP_MDs Reviewed-by: Rich Salz <rsalz@openssl.org> --- crypto/engine/eng_openssl.c | 73 +++++++++--- engines/ccgost/gost_crypt.c | 45 ++++--- engines/ccgost/gost_eng.c | 34 ++++-- engines/ccgost/gost_lcl.h | 6 +- engines/ccgost/gost_md.c | 43 ++++--- engines/ccgost/gost_pmeth.c | 4 +- engines/e_dasync.c | 65 +++++++--- engines/e_ossltest.c | 232 ++++++++++++++++++++++++------------ 8 files changed, 347 insertions(+), 155 deletions(-) diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c index 3c046f28ea..b8850dcb0d 100644 --- a/crypto/engine/eng_openssl.c +++ b/crypto/engine/eng_openssl.c @@ -111,6 +111,8 @@ # undef TEST_ENG_OPENSSL_RC4_P_CIPHER #endif +static int openssl_destroy(ENGINE *e); + #ifdef TEST_ENG_OPENSSL_RC4 static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); @@ -144,6 +146,7 @@ static int bind_helper(ENGINE *e) { if (!ENGINE_set_id(e, engine_openssl_id) || !ENGINE_set_name(e, engine_openssl_name) + || !ENGINE_set_destroy_function(e, openssl_destroy) #ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS # ifndef OPENSSL_NO_RSA || !ENGINE_set_RSA(e, RSA_get_default_method()) @@ -326,9 +329,7 @@ static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, #ifdef TEST_ENG_OPENSSL_SHA /* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */ # include <openssl/sha.h> -static const int test_digest_nids[] = { NID_sha1 }; -static const int test_digest_nids_number = 1; static int test_sha1_init(EVP_MD_CTX *ctx) { # ifdef TEST_ENG_OPENSSL_SHA_P_INIT @@ -353,31 +354,60 @@ static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) return SHA1_Final(md, EVP_MD_CTX_md_data(ctx)); } -static const EVP_MD test_sha_md = { - NID_sha1, - NID_sha1WithRSAEncryption, - SHA_DIGEST_LENGTH, - 0, - test_sha1_init, - test_sha1_update, - test_sha1_final, - NULL, - NULL, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), -}; +static EVP_MD *sha1_md = NULL; +static const EVP_MD *test_sha_md(void) +{ + if (sha1_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH) + || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(EVP_MD *) + sizeof(SHA_CTX)) + || !EVP_MD_meth_set_flags(md, 0) + || !EVP_MD_meth_set_init(md, test_sha1_init) + || !EVP_MD_meth_set_update(md, test_sha1_update) + || !EVP_MD_meth_set_final(md, test_sha1_final)) { + EVP_MD_meth_free(md); + md = NULL; + } + sha1_md = md; + } + return sha1_md; +} +static void test_sha_md_destroy(void) +{ + EVP_MD_meth_free(sha1_md); + sha1_md = NULL; +} +static int test_digest_nids(const int **nids) +{ + static int digest_nids[2] = { 0, 0 }; + static int pos = 0; + static int init = 0; + + if (!init) { + const EVP_MD *md; + if ((md = test_sha_md()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + digest_nids[pos] = 0; + init = 1; + } + *nids = digest_nids; + return pos; +} static int openssl_digests(ENGINE *e, const EVP_MD **digest, const int **nids, int nid) { if (!digest) { /* We are returning a list of supported nids */ - *nids = test_digest_nids; - return test_digest_nids_number; + return test_digest_nids(nids); } /* We are being asked for a specific digest */ if (nid == NID_sha1) - *digest = &test_sha_md; + *digest = test_sha_md(); else { # ifdef TEST_ENG_OPENSSL_SHA_OTHERS fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for " @@ -617,3 +647,10 @@ static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth, } #endif + +int openssl_destroy(ENGINE *e) +{ + test_sha_md_destroy(); + return 1; +} + diff --git a/engines/ccgost/gost_crypt.c b/engines/ccgost/gost_crypt.c index 9483fa3b64..062884f62d 100644 --- a/engines/ccgost/gost_crypt.c +++ b/engines/ccgost/gost_crypt.c @@ -85,20 +85,37 @@ static int gost_imit_cleanup(EVP_MD_CTX *ctx); /* Control function, knows how to set MAC key.*/ static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr); -EVP_MD imit_gost_cpa = { - NID_id_Gost28147_89_MAC, - NID_undef, - 4, - 0, - gost_imit_init_cpa, - gost_imit_update, - gost_imit_final, - gost_imit_copy, - gost_imit_cleanup, - 8, - sizeof(struct ossl_gost_imit_ctx), - gost_imit_ctrl -}; +static EVP_MD *_hidden_Gost28147_89_MAC_md = NULL; +EVP_MD *imit_gost_cpa(void) +{ + + if (_hidden_Gost28147_89_MAC_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_id_Gost28147_89_MAC, NID_undef)) == NULL + || !EVP_MD_meth_set_result_size(md, 4) + || !EVP_MD_meth_set_input_blocksize(md, 8) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(struct ossl_gost_imit_ctx)) + || !EVP_MD_meth_set_flags(md, 0) + || !EVP_MD_meth_set_init(md, gost_imit_init_cpa) + || !EVP_MD_meth_set_update(md, gost_imit_update) + || !EVP_MD_meth_set_final(md, gost_imit_final) + || !EVP_MD_meth_set_copy(md, gost_imit_copy) + || !EVP_MD_meth_set_cleanup(md, gost_imit_cleanup) + || !EVP_MD_meth_set_ctrl(md, gost_imit_ctrl)) { + EVP_MD_meth_free(md); + md = NULL; + } + _hidden_Gost28147_89_MAC_md = md; + } + return _hidden_Gost28147_89_MAC_md; +} +void imit_gost_cpa_destroy(void) +{ + EVP_MD_meth_free(_hidden_Gost28147_89_MAC_md); + _hidden_Gost28147_89_MAC_md = NULL; +} /* * Correspondence between gost parameter OIDs and substitution blocks diff --git a/engines/ccgost/gost_eng.c b/engines/ccgost/gost_eng.c index 4129260286..fed3abed35 100644 --- a/engines/ccgost/gost_eng.c +++ b/engines/ccgost/gost_eng.c @@ -39,8 +39,24 @@ static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, static int gost_cipher_nids[] = { NID_id_Gost28147_89, NID_gost89_cnt, 0 }; -static int gost_digest_nids[] = - { NID_id_GostR3411_94, NID_id_Gost28147_89_MAC, 0 }; +static int gost_digest_nids(const int **nids) +{ + static int digest_nids[3] = { 0, 0, 0 }; + static int pos = 0; + static int init = 0; + + if (!init) { + const EVP_MD *md; + if ((md = digest_gost()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + if ((md = imit_gost_cpa()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + digest_nids[pos] = 0; + init = 1; + } + *nids = digest_nids; + return pos; +} static EVP_PKEY_METHOD *pmeth_GostR3410_2001 = NULL; static EVP_PKEY_METHOD *pmeth_Gost28147_MAC = NULL; @@ -60,6 +76,9 @@ static int gost_engine_finish(ENGINE *e) static int gost_engine_destroy(ENGINE *e) { + digest_gost_destroy(); + imit_gost_cpa_destroy(); + gost_param_free(); pmeth_GostR3410_2001 = NULL; @@ -136,8 +155,8 @@ static int bind_gost(ENGINE *e, const char *id) /* These two actually should go in LIST_ADD command */ || !EVP_add_cipher(&cipher_gost) || !EVP_add_cipher(&cipher_gost_cpacnt) - || !EVP_add_digest(&digest_gost) - || !EVP_add_digest(&imit_gost_cpa) + || !EVP_add_digest(digest_gost()) + || !EVP_add_digest(imit_gost_cpa()) ) { goto end; } @@ -157,16 +176,15 @@ static int gost_digests(ENGINE *e, const EVP_MD **digest, { int ok = 1; if (!digest) { - *nids = gost_digest_nids; - return 2; + return gost_digest_nids(nids); } /* * printf("Digest no %d requested\n",nid); */ if (nid == NID_id_GostR3411_94) { - *digest = &digest_gost; + *digest = digest_gost(); } else if (nid == NID_id_Gost28147_89_MAC) { - *digest = &imit_gost_cpa; + *digest = imit_gost_cpa(); } else { ok = 0; *digest = NULL; diff --git a/engines/ccgost/gost_lcl.h b/engines/ccgost/gost_lcl.h index b2541a79d8..1e047c6f0a 100644 --- a/engines/ccgost/gost_lcl.h +++ b/engines/ccgost/gost_lcl.h @@ -143,9 +143,11 @@ struct ossl_gost_digest_ctx { gost_ctx cctx; }; /* EVP_MD structure for GOST R 34.11 */ -extern EVP_MD digest_gost; +EVP_MD *digest_gost(void); +void digest_gost_destroy(void); /* EVP_MD structure for GOST 28147 in MAC mode */ -extern EVP_MD imit_gost_cpa; +EVP_MD *imit_gost_cpa(void); +void imit_gost_cpa_destroy(void); /* Cipher context used for EVP_CIPHER operation */ struct ossl_gost_cipher_ctx { int paramNID; diff --git a/engines/ccgost/gost_md.c b/engines/ccgost/gost_md.c index 7b780772b2..8c12d008c5 100644 --- a/engines/ccgost/gost_md.c +++ b/engines/ccgost/gost_md.c @@ -19,20 +19,35 @@ static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md); static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); static int gost_digest_cleanup(EVP_MD_CTX *ctx); -EVP_MD digest_gost = { - NID_id_GostR3411_94, - NID_undef, - 32, - 0, - gost_digest_init, - gost_digest_update, - gost_digest_final, - gost_digest_copy, - gost_digest_cleanup, - 32, - sizeof(struct ossl_gost_digest_ctx), - NULL -}; +static EVP_MD *_hidden_GostR3411_94_md = NULL; +EVP_MD *digest_gost(void) +{ + + if (_hidden_GostR3411_94_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_id_GostR3411_94, NID_undef)) == NULL + || !EVP_MD_meth_set_result_size(md, 32) + || !EVP_MD_meth_set_input_blocksize(md, 32) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(struct ossl_gost_digest_ctx)) + || !EVP_MD_meth_set_init(md, gost_digest_init) + || !EVP_MD_meth_set_update(md, gost_digest_update) + || !EVP_MD_meth_set_final(md, gost_digest_final) + || !EVP_MD_meth_set_copy(md, gost_digest_copy) + || !EVP_MD_meth_set_cleanup(md, gost_digest_cleanup)) { + EVP_MD_meth_free(md); + md = NULL; + } + _hidden_GostR3411_94_md = md; + } + return _hidden_GostR3411_94_md; +} +void digest_gost_destroy(void) +{ + EVP_MD_meth_free(_hidden_GostR3411_94_md); + _hidden_GostR3411_94_md = NULL; +} int gost_digest_init(EVP_MD_CTX *ctx) { diff --git a/engines/ccgost/gost_pmeth.c b/engines/ccgost/gost_pmeth.c index f0f331e5cc..7381c957fb 100644 --- a/engines/ccgost/gost_pmeth.c +++ b/engines/ccgost/gost_pmeth.c @@ -388,8 +388,8 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) } else { key = &(data->key); } - return EVP_MD_CTX_md(mctx)->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, - 32, key); + return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx)) + (mctx, EVP_MD_CTRL_SET_KEY, 32, key); } } return -2; diff --git a/engines/e_dasync.c b/engines/e_dasync.c index 7f6aa7568d..e22c6149d3 100644 --- a/engines/e_dasync.c +++ b/engines/e_dasync.c @@ -80,8 +80,6 @@ void ENGINE_load_dasync(void); static int dasync_digests(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); -static int dasync_digest_nids[] = { NID_sha1, 0 }; - static void dummy_pause_job(void); /* SHA1 */ @@ -90,19 +88,49 @@ static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count); static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md); -static const EVP_MD dasync_sha1 = { - NID_sha1, - NID_sha1WithRSAEncryption, - SHA_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - dasync_sha1_init, - dasync_sha1_update, - dasync_sha1_final, - NULL, - NULL, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), -}; +static EVP_MD *_hidden_sha1_md = NULL; +static const EVP_MD *dasync_sha1(void) +{ + if (_hidden_sha1_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH) + || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(EVP_MD *) + sizeof(SHA_CTX)) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT) + || !EVP_MD_meth_set_init(md, dasync_sha1_init) + || !EVP_MD_meth_set_update(md, dasync_sha1_update) + || !EVP_MD_meth_set_final(md, dasync_sha1_final)) { + EVP_MD_meth_free(md); + md = NULL; + } + _hidden_sha1_md = md; + } + return _hidden_sha1_md; +} +static void destroy_digests(void) +{ + EVP_MD_meth_free(_hidden_sha1_md); + _hidden_sha1_md = NULL; +} +static int dasync_digest_nids(const int **nids) +{ + static int digest_nids[2] = { 0, 0 }; + static int pos = 0; + static int init = 0; + + if (!init) { + const EVP_MD *md; + if ((md = dasync_sha1()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + digest_nids[pos] = 0; + init = 1; + } + *nids = digest_nids; + return pos; +} /* RSA */ @@ -207,6 +235,7 @@ static int dasync_finish(ENGINE *e) static int dasync_destroy(ENGINE *e) { + destroy_digests(); ERR_unload_DASYNC_strings(); return 1; } @@ -217,14 +246,12 @@ static int dasync_digests(ENGINE *e, const EVP_MD **digest, int ok = 1; if (!digest) { /* We are returning a list of supported nids */ - *nids = dasync_digest_nids; - return (sizeof(dasync_digest_nids) - - 1) / sizeof(dasync_digest_nids[0]); + return dasync_digest_nids(nids); } /* We are being asked for a specific digest */ switch (nid) { case NID_sha1: - *digest = &dasync_sha1; + *digest = dasync_sha1(); break; default: ok = 0; diff --git a/engines/e_ossltest.c b/engines/e_ossltest.c index 02c3c58570..5fdb23ed6a 100644 --- a/engines/e_ossltest.c +++ b/engines/e_ossltest.c @@ -87,29 +87,34 @@ void ENGINE_load_ossltest(void); static int ossltest_digests(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); -static int ossltest_digest_nids[] = { - NID_md5, NID_sha1, NID_sha256, NID_sha384, NID_sha512, 0 -}; - /* MD5 */ static int digest_md5_init(EVP_MD_CTX *ctx); static int digest_md5_update(EVP_MD_CTX *ctx, const void *data, size_t count); static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md); -static const EVP_MD digest_md5 = { - NID_md5, - NID_md5WithRSAEncryption, - MD5_DIGEST_LENGTH, - 0, - digest_md5_init, - digest_md5_update, - digest_md5_final, - NULL, - NULL, - MD5_CBLOCK, - sizeof(EVP_MD *) + sizeof(MD5_CTX), -}; +static EVP_MD *_hidden_md5_md = NULL; +static const EVP_MD *digest_md5(void) +{ + if (_hidden_md5_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_md5, NID_md5WithRSAEncryption)) == NULL + || !EVP_MD_meth_set_result_size(md, MD5_DIGEST_LENGTH) + || !EVP_MD_meth_set_input_blocksize(md, MD5_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(EVP_MD *) + sizeof(MD5_CTX)) + || !EVP_MD_meth_set_flags(md, 0) + || !EVP_MD_meth_set_init(md, digest_md5_init) + || !EVP_MD_meth_set_update(md, digest_md5_update) + || !EVP_MD_meth_set_final(md, digest_md5_final)) { + EVP_MD_meth_free(md); + md = NULL; + } + _hidden_md5_md = md; + } + return _hidden_md5_md; +} /* SHA1 */ static int digest_sha1_init(EVP_MD_CTX *ctx); @@ -117,19 +122,28 @@ static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count); static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md); -static const EVP_MD digest_sha1 = { - NID_sha1, - NID_sha1WithRSAEncryption, - SHA_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - digest_sha1_init, - digest_sha1_update, - digest_sha1_final, - NULL, - NULL, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), -}; +static EVP_MD *_hidden_sha1_md = NULL; +static const EVP_MD *digest_sha1(void) +{ + if (_hidden_sha1_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH) + || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(EVP_MD *) + sizeof(SHA_CTX)) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT) + || !EVP_MD_meth_set_init(md, digest_sha1_init) + || !EVP_MD_meth_set_update(md, digest_sha1_update) + || !EVP_MD_meth_set_final(md, digest_sha1_final)) { + EVP_MD_meth_free(md); + md = NULL; + } + _hidden_sha1_md = md; + } + return _hidden_sha1_md; +} /* SHA256 */ static int digest_sha256_init(EVP_MD_CTX *ctx); @@ -137,19 +151,28 @@ static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count); static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md); -static const EVP_MD digest_sha256 = { - NID_sha256, - NID_sha256WithRSAEncryption, - SHA256_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - digest_sha256_init, - digest_sha256_update, - digest_sha256_final, - NULL, - NULL, - SHA256_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA256_CTX), -}; +static EVP_MD *_hidden_sha256_md = NULL; +static const EVP_MD *digest_sha256(void) +{ + if (_hidden_sha256_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha256, NID_sha256WithRSAEncryption)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA256_DIGEST_LENGTH) + || !EVP_MD_meth_set_input_blocksize(md, SHA256_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(EVP_MD *) + sizeof(SHA256_CTX)) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT) + || !EVP_MD_meth_set_init(md, digest_sha256_init) + || !EVP_MD_meth_set_update(md, digest_sha256_update) + || !EVP_MD_meth_set_final(md, digest_sha256_final)) { + EVP_MD_meth_free(md); + md = NULL; + } + _hidden_sha256_md = md; + } + return _hidden_sha256_md; +} /* SHA384/SHA512 */ static int digest_sha384_init(EVP_MD_CTX *ctx); @@ -159,33 +182,87 @@ static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data, static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md); static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md); -static const EVP_MD digest_sha384 = { - NID_sha384, - NID_sha384WithRSAEncryption, - SHA384_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - digest_sha384_init, - digest_sha512_update, - digest_sha384_final, - NULL, - NULL, - SHA512_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA512_CTX), -}; - -static const EVP_MD digest_sha512 = { - NID_sha512, - NID_sha512WithRSAEncryption, - SHA512_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - digest_sha512_init, - digest_sha512_update, - digest_sha512_final, - NULL, - NULL, - SHA512_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA512_CTX), -}; +static EVP_MD *_hidden_sha384_md = NULL; +static const EVP_MD *digest_sha384(void) +{ + if (_hidden_sha384_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha384, NID_sha384WithRSAEncryption)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA384_DIGEST_LENGTH) + || !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(EVP_MD *) + sizeof(SHA512_CTX)) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT) + || !EVP_MD_meth_set_init(md, digest_sha384_init) + || !EVP_MD_meth_set_update(md, digest_sha512_update) + || !EVP_MD_meth_set_final(md, digest_sha384_final)) { + EVP_MD_meth_free(md); + md = NULL; + } + _hidden_sha384_md = md; + } + return _hidden_sha384_md; +} +static EVP_MD *_hidden_sha512_md = NULL; +static const EVP_MD *digest_sha512(void) +{ + if (_hidden_sha512_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha512, NID_sha512WithRSAEncryption)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA512_DIGEST_LENGTH) + || !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(EVP_MD *) + sizeof(SHA512_CTX)) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT) + || !EVP_MD_meth_set_init(md, digest_sha512_init) + || !EVP_MD_meth_set_update(md, digest_sha512_update) + || !EVP_MD_meth_set_final(md, digest_sha512_final)) { + EVP_MD_meth_free(md); + md = NULL; + } + _hidden_sha512_md = md; + } + return _hidden_sha512_md; +} +static void destroy_digests(void) +{ + EVP_MD_meth_free(_hidden_md5_md); + _hidden_md5_md = NULL; + EVP_MD_meth_free(_hidden_sha1_md); + _hidden_sha1_md = NULL; + EVP_MD_meth_free(_hidden_sha256_md); + _hidden_sha256_md = NULL; + EVP_MD_meth_free(_hidden_sha384_md); + _hidden_sha384_md = NULL; + EVP_MD_meth_free(_hidden_sha512_md); + _hidden_sha512_md = NULL; +} +static int ossltest_digest_nids(const int **nids) +{ + static int digest_nids[6] = { 0, 0, 0, 0, 0, 0 }; + static int pos = 0; + static int init = 0; + + if (!init) { + const EVP_MD *md; + if ((md = digest_md5()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + if ((md = digest_sha1()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + if ((md = digest_sha256()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + if ((md = digest_sha384()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + if ((md = digest_sha512()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + digest_nids[pos] = 0; + init = 1; + } + *nids = digest_nids; + return pos; +} /* Setup ciphers */ static int ossltest_ciphers(ENGINE *, const EVP_CIPHER **, @@ -287,6 +364,7 @@ static int ossltest_finish(ENGINE *e) static int ossltest_destroy(ENGINE *e) { + destroy_digests(); ERR_unload_OSSLTEST_strings(); return 1; } @@ -297,26 +375,24 @@ static int ossltest_digests(ENGINE *e, const EVP_MD **digest, int ok = 1; if (!digest) { /* We are returning a list of supported nids */ - *nids = ossltest_digest_nids; - return (sizeof(ossltest_digest_nids) - - 1) / sizeof(ossltest_digest_nids[0]); + return ossltest_digest_nids(nids); } /* We are being asked for a specific digest */ switch (nid) { case NID_md5: - *digest = &digest_md5; + *digest = digest_md5(); break; case NID_sha1: - *digest = &digest_sha1; + *digest = digest_sha1(); break; case NID_sha256: - *digest = &digest_sha256; + *digest = digest_sha256(); break; case NID_sha384: - *digest = &digest_sha384; + *digest = digest_sha384(); break; case NID_sha512: - *digest = &digest_sha512; + *digest = digest_sha512(); break; default: ok = 0; -- 2.25.1