Skip to content

Commit

Permalink
Simplify getting an EVP_MD for all OpenSSL forks
Browse files Browse the repository at this point in the history
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
  • Loading branch information
botovq authored and LDVG committed Mar 22, 2024
1 parent 5d14e82 commit d147c4b
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 90 deletions.
49 changes: 4 additions & 45 deletions src/rs1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
49 changes: 4 additions & 45 deletions src/rs256.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit d147c4b

Please sign in to comment.