From defd2e8128d0caace4622286f4157646d121bc46 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Thu, 11 Apr 2019 22:10:43 +0200 Subject: [PATCH] Rewrite mdfour routines to not modify state when computing the result MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This makes the interface much more intuitive, at the minor expense of having to copy 32-96 extra bytes (unnecessary if the hash state won’t be fed with more bytes) when fetching the result. This change is also partly motivated by the code that handles several -arch options – it calls get_object_name_from_cpp multiple times to compute a combined hash, but that function also computes the hash result each time. --- src/hash.c | 9 ++------- src/mdfour.c | 29 ++++++++++++++++------------- src/mdfour.h | 3 +-- unittest/test_hash.c | 12 +++++++++++- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/hash.c b/src/hash.c index ae89e85fe..bf067620a 100644 --- a/src/hash.c +++ b/src/hash.c @@ -32,10 +32,6 @@ do_hash_buffer(struct hash *hash, const void *s, size_t len) { assert(s); - // The hash state cannot be updated after the result has been fetched via - // hash_result/hash_result_as_bytes. - assert(!hash->md.finalized); - mdfour_update(&hash->md, (const unsigned char *)s, len); if (len > 0 && hash->debug_binary) { (void) fwrite(s, 1, len, hash->debug_binary); @@ -90,7 +86,7 @@ void hash_enable_debug( size_t hash_input_size(struct hash *hash) { - return hash->md.totalN; + return hash->md.totalN + hash->md.tail_len; } void @@ -106,13 +102,12 @@ hash_result(struct hash *hash) unsigned char sum[16]; hash_result_as_bytes(hash, sum); - return format_hash_as_string(sum, (unsigned) hash->md.totalN); + return format_hash_as_string(sum, hash_input_size(hash)); } void hash_result_as_bytes(struct hash *hash, unsigned char *out) { - mdfour_update(&hash->md, NULL, 0); mdfour_result(&hash->md, out); } diff --git a/src/mdfour.c b/src/mdfour.c index 11e0fba1e..c0aec6bc2 100644 --- a/src/mdfour.c +++ b/src/mdfour.c @@ -1,5 +1,5 @@ // Copyright (C) 1997-1998 Andrew Tridgell -// Copyright (C) 2009-2018 Joel Rosdahl +// Copyright (C) 2009-2019 Joel Rosdahl // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free @@ -129,7 +129,6 @@ mdfour_begin(struct mdfour *md) md->D = 0x10325476; md->totalN = 0; md->tail_len = 0; - md->finalized = 0; } static @@ -160,13 +159,7 @@ void mdfour_tail(struct mdfour *md, const unsigned char *in, size_t n) void mdfour_update(struct mdfour *md, const unsigned char *in, size_t n) { - if (!in) { - if (!md->finalized) { - mdfour_tail(md, md->tail, md->tail_len); - md->finalized = 1; - } - return; - } + assert(in); uint32_t M[16]; if (md->tail_len) { @@ -203,8 +196,18 @@ mdfour_update(struct mdfour *md, const unsigned char *in, size_t n) void mdfour_result(struct mdfour *md, unsigned char *out) { - copy4(out, md->A); - copy4(out+4, md->B); - copy4(out+8, md->C); - copy4(out+12, md->D); + struct mdfour result; + result.A = md->A; + result.B = md->B; + result.C = md->C; + result.D = md->D; + result.totalN = md->totalN; + result.tail_len = md->tail_len; + memcpy(result.tail, md->tail, result.tail_len); + + mdfour_tail(&result, result.tail, result.tail_len); + copy4(out, result.A); + copy4(out+4, result.B); + copy4(out+8, result.C); + copy4(out+12, result.D); } diff --git a/src/mdfour.h b/src/mdfour.h index c196a09e9..761a19ee5 100644 --- a/src/mdfour.h +++ b/src/mdfour.h @@ -7,9 +7,8 @@ struct mdfour { uint32_t A, B, C, D; size_t totalN; - unsigned char tail[64]; size_t tail_len; - int finalized; + unsigned char tail[64]; }; void mdfour_begin(struct mdfour *md); diff --git a/unittest/test_hash.c b/unittest/test_hash.c index 5278560e2..2e9502dfd 100644 --- a/unittest/test_hash.c +++ b/unittest/test_hash.c @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl +// Copyright (C) 2010-2019 Joel Rosdahl // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free @@ -56,6 +56,16 @@ TEST(test_vectors_from_rfc_1320_should_be_correct) } } +TEST(hash_result_should_not_alter_state) +{ + struct hash *h = hash_init(); + hash_string(h, "message"); + free(hash_result(h)); + hash_string(h, " digest"); + CHECK_STR_EQ_FREE2("d9130a8164549fe818874806e1c7014b-14", hash_result(h)); + hash_free(h); +} + TEST(hash_result_should_be_idempotent) { struct hash *h = hash_init(); -- 2.47.2