From 9a35f27363f2468e6b3f94b47bf2da1878cdf81b Mon Sep 17 00:00:00 2001 From: Theo Buehler Date: Fri, 22 Mar 2024 14:47:01 +1000 Subject: [PATCH] Simplify getting an EVP_MD for all OpenSSL forks In all versions of OpenSSL, EVP_sha{1,256}() return a pointer to static read-only data. There is no need to copy that data into a buffer that is immediately freed after use. In LibreSSL and OpenSSL 1.x, EVP_PKEY_CTX_set_signature_md() is a wrapper around EVP_PKEY_ctrl() whose void * argument isn't const (contrary to the documented signature), so we need to cast const away in some way. This preserves rs*_get_EVP_MD() to contain the pragma pollution necessary due to -Werror -Wcast-qual. The negative performance impact of calling EVP_sha*() multiple times called out in the OpenSSL 3.x application should not apply in this code. Closes: #794 --- src/rs1.c | 49 ++++--------------------------------------------- src/rs256.c | 49 ++++--------------------------------------------- 2 files changed, 8 insertions(+), 90 deletions(-) diff --git a/src/rs1.c b/src/rs1.c index 03636b5c..8871e91c 100644 --- a/src/rs1.c +++ b/src/rs1.c @@ -10,54 +10,14 @@ #include "fido.h" -#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050200fL static EVP_MD * rs1_get_EVP_MD(void) { - const EVP_MD *from; - EVP_MD *to = NULL; - - if ((from = EVP_sha1()) != NULL && (to = malloc(sizeof(*to))) != NULL) - memcpy(to, from, sizeof(*to)); - - return (to); -} - -static void -rs1_free_EVP_MD(EVP_MD *md) -{ - freezero(md, sizeof(*md)); -} -#elif OPENSSL_VERSION_NUMBER >= 0x30000000 -static EVP_MD * -rs1_get_EVP_MD(void) -{ - return (EVP_MD_fetch(NULL, "SHA-1", NULL)); -} - -static void -rs1_free_EVP_MD(EVP_MD *md) -{ - EVP_MD_free(md); -} -#else -static EVP_MD * -rs1_get_EVP_MD(void) -{ - const EVP_MD *md; - - if ((md = EVP_sha1()) == NULL) - return (NULL); - - return (EVP_MD_meth_dup(md)); -} - -static void -rs1_free_EVP_MD(EVP_MD *md) -{ - EVP_MD_meth_free(md); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" + return ((EVP_MD *)EVP_sha1()); +#pragma GCC diagnostic pop } -#endif /* LIBRESSL_VERSION_NUMBER */ int rs1_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey, @@ -94,7 +54,6 @@ rs1_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey, ok = 0; fail: EVP_PKEY_CTX_free(pctx); - rs1_free_EVP_MD(md); return (ok); } diff --git a/src/rs256.c b/src/rs256.c index 59ceb948..26d69187 100644 --- a/src/rs256.c +++ b/src/rs256.c @@ -18,54 +18,14 @@ #define get0_RSA(x) EVP_PKEY_get0((x)) #endif -#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050200fL static EVP_MD * rs256_get_EVP_MD(void) { - const EVP_MD *from; - EVP_MD *to = NULL; - - if ((from = EVP_sha256()) != NULL && (to = malloc(sizeof(*to))) != NULL) - memcpy(to, from, sizeof(*to)); - - return (to); -} - -static void -rs256_free_EVP_MD(EVP_MD *md) -{ - freezero(md, sizeof(*md)); -} -#elif OPENSSL_VERSION_NUMBER >= 0x30000000 -static EVP_MD * -rs256_get_EVP_MD(void) -{ - return (EVP_MD_fetch(NULL, "SHA2-256", NULL)); -} - -static void -rs256_free_EVP_MD(EVP_MD *md) -{ - EVP_MD_free(md); -} -#else -static EVP_MD * -rs256_get_EVP_MD(void) -{ - const EVP_MD *md; - - if ((md = EVP_sha256()) == NULL) - return (NULL); - - return (EVP_MD_meth_dup(md)); -} - -static void -rs256_free_EVP_MD(EVP_MD *md) -{ - EVP_MD_meth_free(md); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" + return ((EVP_MD *)EVP_sha256()); +#pragma GCC diagnostic pop } -#endif /* LIBRESSL_VERSION_NUMBER */ static int decode_bignum(const cbor_item_t *item, void *ptr, size_t len) @@ -290,7 +250,6 @@ rs256_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey, ok = 0; fail: EVP_PKEY_CTX_free(pctx); - rs256_free_EVP_MD(md); return (ok); }