]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Rewrite mdfour routines to not modify state when computing the result
authorJoel Rosdahl <joel@rosdahl.net>
Thu, 11 Apr 2019 20:10:43 +0000 (22:10 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 11 Apr 2019 20:16:21 +0000 (22:16 +0200)
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
src/mdfour.c
src/mdfour.h
unittest/test_hash.c

index ae89e85fe8e668e1d256f24d86ffd21f8b24e317..bf067620a36a59ede53e1c980c4306bf2054f58f 100644 (file)
@@ -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);
 }
 
index 11e0fba1ef5f910f5c237f316401c9a9fdfbeccb..c0aec6bc28a59e31f8a029b3ce2f46cfc0714f93 100644 (file)
@@ -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);
 }
index c196a09e952ef7b164caa94d272ca031d02e32f4..761a19ee569000d08d0637ad5037385103e7e41d 100644 (file)
@@ -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);
index 5278560e2e32377a28c5b8f422d31e8d0f29595c..2e9502dfd2592b5185002e0b0c236b77405ab719 100644 (file)
@@ -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();