Commit babab8e7 authored by Viktor Dukhovni's avatar Viktor Dukhovni
Browse files

Avoid fragile aliasing of SHA224/384 update/final



This is purported to save a few cycles, but makes the code less
obvious and more brittle, and in fact breaks on platforms where for
ABI continuity reasons there is a SHA2 implementation in libc, and
so EVP needs to call those to avoid conflicts.

A sufficiently good optimizer could simply generate the same entry
points for:

        foo(...) { ... }
    and
        bar(...) { return foo(...); }

but, even without that, the different is negligible, with the
"winner" varying from run to run (openssl speed -evp sha384):

    Old:
    type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes 16384 bytes
    sha384           28864.28k   117362.62k   266469.21k   483258.03k   635144.87k 649123.16k

    New:
    type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes 16384 bytes
    sha384           30055.18k   120725.98k   272057.26k   482847.40k   634585.09k 650308.27k

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent 72960279
Loading
Loading
Loading
Loading
+24 −9
Original line number Diff line number Diff line
@@ -116,16 +116,21 @@ static int init224(EVP_MD_CTX *ctx)
    return SHA224_Init(EVP_MD_CTX_md_data(ctx));
}

static int update224(EVP_MD_CTX *ctx, const void *data, size_t count)
{
    return SHA224_Update(EVP_MD_CTX_md_data(ctx), data, count);
}

static int final224(EVP_MD_CTX *ctx, unsigned char *md)
{
    return SHA224_Final(md, EVP_MD_CTX_md_data(ctx));
}

static int init256(EVP_MD_CTX *ctx)
{
    return SHA256_Init(EVP_MD_CTX_md_data(ctx));
}

/*
 * Even though there're separate SHA224_[Update|Final], we call
 * SHA256 functions even in SHA224 context. This is what happens
 * there anyway, so we can spare few CPU cycles:-)
 */
static int update256(EVP_MD_CTX *ctx, const void *data, size_t count)
{
    return SHA256_Update(EVP_MD_CTX_md_data(ctx), data, count);
@@ -142,8 +147,8 @@ static const EVP_MD sha224_md = {
    SHA224_DIGEST_LENGTH,
    EVP_MD_FLAG_DIGALGID_ABSENT,
    init224,
    update256,
    final256,
    update224,
    final224,
    NULL,
    NULL,
    SHA256_CBLOCK,
@@ -189,6 +194,16 @@ static int init384(EVP_MD_CTX *ctx)
    return SHA384_Init(EVP_MD_CTX_md_data(ctx));
}

static int update384(EVP_MD_CTX *ctx, const void *data, size_t count)
{
    return SHA384_Update(EVP_MD_CTX_md_data(ctx), data, count);
}

static int final384(EVP_MD_CTX *ctx, unsigned char *md)
{
    return SHA384_Final(md, EVP_MD_CTX_md_data(ctx));
}

static int init512(EVP_MD_CTX *ctx)
{
    return SHA512_Init(EVP_MD_CTX_md_data(ctx));
@@ -249,8 +264,8 @@ static const EVP_MD sha384_md = {
    SHA384_DIGEST_LENGTH,
    EVP_MD_FLAG_DIGALGID_ABSENT,
    init384,
    update512,
    final512,
    update384,
    final384,
    NULL,
    NULL,
    SHA512_CBLOCK,