From 8269e44f9e40831a497fe9f31ba1d65aeb49a5c1 Mon Sep 17 00:00:00 2001 From: Antoine Salon Date: Mon, 7 Jan 2019 15:09:55 -0800 Subject: [PATCH] blake2: avoid writing to output buffer when using default digest length Signed-off-by: Antoine Salon Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/7726) --- crypto/blake2/blake2b.c | 17 ++++++++++++----- crypto/blake2/blake2s.c | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/crypto/blake2/blake2b.c b/crypto/blake2/blake2b.c index b5eb928708..73ba0b6b8a 100644 --- a/crypto/blake2/blake2b.c +++ b/crypto/blake2/blake2b.c @@ -304,19 +304,26 @@ int BLAKE2b_Update(BLAKE2B_CTX *c, const void *data, size_t datalen) int BLAKE2b_Final(unsigned char *md, BLAKE2B_CTX *c) { uint8_t outbuffer[BLAKE2B_OUTBYTES] = {0}; + uint8_t *target = outbuffer; + int iter = (c->outlen + 7) / 8; int i; + /* Avoid writing to the temporary buffer if possible */ + if ((c->outlen % sizeof(c->h[0])) == 0) + target = md; + blake2b_set_lastblock(c); /* Padding */ memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen); blake2b_compress(c, c->buf, c->buflen); - /* Output full hash to temp buffer */ - for (i = 0; i < 8; ++i) { - store64(outbuffer + sizeof(c->h[i]) * i, c->h[i]); - } + /* Output full hash to buffer */ + for (i = 0; i < iter; ++i) + store64(target + sizeof(c->h[i]) * i, c->h[i]); + + if (target != md) + memcpy(md, target, c->outlen); - memcpy(md, outbuffer, c->outlen); OPENSSL_cleanse(c, sizeof(BLAKE2B_CTX)); return 1; } diff --git a/crypto/blake2/blake2s.c b/crypto/blake2/blake2s.c index 94333d18c8..121f0d1a85 100644 --- a/crypto/blake2/blake2s.c +++ b/crypto/blake2/blake2s.c @@ -295,19 +295,26 @@ int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen) int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c) { uint8_t outbuffer[BLAKE2S_OUTBYTES] = {0}; + uint8_t *target = outbuffer; + int iter = (c->outlen + 3) / 4; int i; + /* Avoid writing to the temporary buffer if possible */ + if ((c->outlen % sizeof(c->h[0])) == 0) + target = md; + blake2s_set_lastblock(c); /* Padding */ memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen); blake2s_compress(c, c->buf, c->buflen); - /* Output full hash to temp buffer */ - for (i = 0; i < 8; ++i) { - store32(outbuffer + sizeof(c->h[i]) * i, c->h[i]); - } + /* Output full hash to buffer */ + for (i = 0; i < iter; ++i) + store32(target + sizeof(c->h[i]) * i, c->h[i]); + + if (target != md) + memcpy(md, target, c->outlen); - memcpy(md, outbuffer, c->outlen); OPENSSL_cleanse(c, sizeof(BLAKE2S_CTX)); return 1; } -- 2.25.1