From 9fc07111603c6e892ed768f900465282314b2982 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 25 May 2015 15:11:56 +0930 Subject: [PATCH 1/1] crypto/shachain: detect if we're inserting a bogus hash. Signed-off-by: Rusty Russell --- ccan/crypto/shachain/shachain.c | 13 +++++++-- ccan/crypto/shachain/shachain.h | 2 +- ccan/crypto/shachain/test/run-8bit.c | 4 +-- ccan/crypto/shachain/test/run-badhash.c | 38 +++++++++++++++++++++++++ ccan/crypto/shachain/test/run.c | 4 +-- 5 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 ccan/crypto/shachain/test/run-badhash.c diff --git a/ccan/crypto/shachain/shachain.c b/ccan/crypto/shachain/shachain.c index c66196f7..a14d95b8 100644 --- a/ccan/crypto/shachain/shachain.c +++ b/ccan/crypto/shachain/shachain.c @@ -49,7 +49,7 @@ void shachain_init(struct shachain *shachain) shachain->num_valid = 0; } -void shachain_add_hash(struct shachain *chain, +bool shachain_add_hash(struct shachain *chain, shachain_index_t index, const struct sha256 *hash) { int i; @@ -57,8 +57,16 @@ void shachain_add_hash(struct shachain *chain, for (i = 0; i < chain->num_valid; i++) { /* If we could derive this value, we don't need it, * not any others (since they're in order). */ - if (can_derive(index, chain->known[i].index)) + if (can_derive(index, chain->known[i].index)) { + struct sha256 expect; + + /* Make sure the others derive as expected! */ + derive(index, chain->known[i].index, hash, &expect); + if (memcmp(&expect, &chain->known[i].hash, + sizeof(expect)) != 0) + return false; break; + } } /* This can happen if you skip indices! */ @@ -66,6 +74,7 @@ void shachain_add_hash(struct shachain *chain, chain->known[i].index = index; chain->known[i].hash = *hash; chain->num_valid = i+1; + return true; } bool shachain_get_hash(const struct shachain *chain, diff --git a/ccan/crypto/shachain/shachain.h b/ccan/crypto/shachain/shachain.h index b0f947e9..39d6f3c4 100644 --- a/ccan/crypto/shachain/shachain.h +++ b/ccan/crypto/shachain/shachain.h @@ -24,7 +24,7 @@ struct shachain { void shachain_init(struct shachain *shachain); -void shachain_add_hash(struct shachain *shachain, +bool shachain_add_hash(struct shachain *shachain, shachain_index_t index, const struct sha256 *hash); bool shachain_get_hash(const struct shachain *shachain, diff --git a/ccan/crypto/shachain/test/run-8bit.c b/ccan/crypto/shachain/test/run-8bit.c index 10520bc3..64b1c7f4 100644 --- a/ccan/crypto/shachain/test/run-8bit.c +++ b/ccan/crypto/shachain/test/run-8bit.c @@ -17,7 +17,7 @@ int main(void) size_t i, j; /* This is how many tests you plan to run */ - plan_tests(NUM_TESTS + NUM_TESTS * (NUM_TESTS + 1) + NUM_TESTS); + plan_tests(NUM_TESTS * 3 + NUM_TESTS * (NUM_TESTS + 1)); memset(&seed, 0, sizeof(seed)); /* Generate a whole heap. */ @@ -34,7 +34,7 @@ int main(void) for (i = 0; i < NUM_TESTS; i++) { struct sha256 hash; - shachain_add_hash(&chain, i, &expect[i]); + ok1(shachain_add_hash(&chain, i, &expect[i])); for (j = 0; j <= i; j++) { ok1(shachain_get_hash(&chain, j, &hash)); ok1(memcmp(&hash, &expect[j], sizeof(hash)) == 0); diff --git a/ccan/crypto/shachain/test/run-badhash.c b/ccan/crypto/shachain/test/run-badhash.c new file mode 100644 index 00000000..bc978512 --- /dev/null +++ b/ccan/crypto/shachain/test/run-badhash.c @@ -0,0 +1,38 @@ +#include +/* Include the C files directly. */ +#include +#include + +#define NUM_TESTS 1000 + +int main(void) +{ + struct sha256 seed; + struct shachain chain; + size_t i; + + plan_tests(NUM_TESTS); + + memset(&seed, 0xFF, sizeof(seed)); + shachain_init(&chain); + + for (i = 0; i < NUM_TESTS; i++) { + struct sha256 expect; + unsigned int num_known = chain.num_valid; + + shachain_from_seed(&seed, i, &expect); + /* Screw it up. */ + expect.u.u8[0]++; + + /* Either it should fail, or it couldn't derive any others. */ + if (shachain_add_hash(&chain, i, &expect)) { + ok1(chain.num_valid == num_known + 1); + /* Fix it up in-place */ + chain.known[num_known].hash.u.u8[0]--; + } else { + expect.u.u8[0]--; + ok1(shachain_add_hash(&chain, i, &expect)); + } + } + return exit_status(); +} diff --git a/ccan/crypto/shachain/test/run.c b/ccan/crypto/shachain/test/run.c index 39391685..16fc5e87 100644 --- a/ccan/crypto/shachain/test/run.c +++ b/ccan/crypto/shachain/test/run.c @@ -13,7 +13,7 @@ int main(void) size_t i, j; /* This is how many tests you plan to run */ - plan_tests(NUM_TESTS + NUM_TESTS * (NUM_TESTS + 1) + NUM_TESTS); + plan_tests(NUM_TESTS * 3 + NUM_TESTS * (NUM_TESTS + 1)); memset(&seed, 0, sizeof(seed)); /* Generate a whole heap. */ @@ -30,7 +30,7 @@ int main(void) for (i = 0; i < NUM_TESTS; i++) { struct sha256 hash; - shachain_add_hash(&chain, i, &expect[i]); + ok1(shachain_add_hash(&chain, i, &expect[i])); for (j = 0; j <= i; j++) { ok1(shachain_get_hash(&chain, j, &hash)); ok1(memcmp(&hash, &expect[j], sizeof(hash)) == 0); -- 2.39.2