From ab8ee0b24335790e49127b1330f9d7bcca7f6bfa Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Wed, 16 Aug 2023 18:15:14 +0200 Subject: include: Revise printing hashes The code was a bit convoluted to print hashes as hex strings. Renamed to HASH_FMT32 and HASH_VAL32 to make clear we are printing the first 32 bits only, and added options to print 64 up to 512 bits as well. This doesn't depend on endianness anymore. Adds a small test for the hash (printing) functions. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- include/ouroboros/hash.h | 36 +++++++-- src/ipcpd/eth/eth.c | 11 +-- src/ipcpd/local/main.c | 11 +-- src/ipcpd/shim-data.c | 4 +- src/ipcpd/udp/main.c | 11 +-- src/ipcpd/unicast/dir/dht.c | 1 + src/ipcpd/unicast/fa.c | 1 + src/irmd/main.c | 18 ++--- src/lib/frct.c | 2 + src/lib/tests/CMakeLists.txt | 1 + src/lib/tests/hash_test.c | 182 +++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 245 insertions(+), 33 deletions(-) create mode 100644 src/lib/tests/hash_test.c diff --git a/include/ouroboros/hash.h b/include/ouroboros/hash.h index 70d2eba0..6e438f50 100644 --- a/include/ouroboros/hash.h +++ b/include/ouroboros/hash.h @@ -25,7 +25,6 @@ #include "config.h" -#include #include #include @@ -41,12 +40,35 @@ enum hash_algo { HASH_MD5, }; -#define HASH_FMT "%02x%02x%02x%02x" -#define HASH_VAL(hash) \ - (betoh32(*(uint32_t *) hash) & 0xFF000000) >> 24, \ - (betoh32(*(uint32_t *) hash) & 0x00FF0000) >> 16, \ - (betoh32(*(uint32_t *) hash) & 0x0000FF00) >> 8, \ - (betoh32(*(uint32_t *) hash) & 0x000000FF) +#define HASH_FMT32 "%02x%02x%02x%02x" +#define HASH_VAL32(hash) \ + (hash)[0], (hash)[1], (hash)[2], (hash)[3] + +#define HASH_FMT64 HASH_FMT32 HASH_FMT32 +#define HASH_VAL64(hash64) \ + HASH_VAL32(hash64), HASH_VAL32(hash64 + 4) + +#define HASH_FMT128 HASH_FMT64 HASH_FMT64 +#define HASH_VAL128(hash128) \ + HASH_VAL64(hash128), HASH_VAL64(hash128 + 8) + +#define HASH_FMT224 HASH_FMT128 HASH_FMT64 HASH_FMT32 +#define HASH_VAL224(hash224) \ + HASH_VAL128(hash224), HASH_VAL64(hash224 + 16), \ + HASH_VAL32(hash224 + 24) + +#define HASH_FMT256 HASH_FMT128 HASH_FMT128 +#define HASH_VAL256(hash256) \ + HASH_VAL128(hash256), HASH_VAL128(hash256 + 16) + +#define HASH_FMT384 HASH_FMT256 HASH_FMT128 +#define HASH_VAL384(hash384) \ + HASH_VAL256(hash384), HASH_VAL128(hash384 + 32) + +#define HASH_FMT512 HASH_FMT256 HASH_FMT256 +#define HASH_VAL512(hash512) \ + HASH_VAL256(hash512), HASH_VAL256(hash512 + 32) + uint16_t hash_len(enum hash_algo algo); diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c index 15082ee3..a429c0a0 100644 --- a/src/ipcpd/eth/eth.c +++ b/src/ipcpd/eth/eth.c @@ -37,6 +37,7 @@ #include "config.h" +#include #include #include #include @@ -1470,7 +1471,7 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf) #endif if (bind(eth_data.s_fd, (struct sockaddr *) ð_data.device, - sizeof(eth_data.device))) { + sizeof(eth_data.device))) { log_err("Failed to bind socket to interface."); goto fail_device; } @@ -1560,12 +1561,12 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf) static int eth_ipcp_reg(const uint8_t * hash) { if (shim_data_reg_add_entry(eth_data.shim_data, hash)) { - log_err("Failed to add " HASH_FMT " to local registry.", - HASH_VAL(hash)); + log_err("Failed to add " HASH_FMT32 " to local registry.", + HASH_VAL32(hash)); return -1; } - log_dbg("Registered " HASH_FMT ".", HASH_VAL(hash)); + log_dbg("Registered " HASH_FMT32 ".", HASH_VAL32(hash)); return 0; } @@ -1645,7 +1646,7 @@ static int eth_ipcp_flow_alloc(int fd, uint8_t r_addr[MAC_SIZE]; uint64_t addr = 0; - log_dbg("Allocating flow to " HASH_FMT ".", HASH_VAL(hash)); + log_dbg("Allocating flow to " HASH_FMT32 ".", HASH_VAL32(hash)); assert(hash); diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index 2fae01fd..e0ba04be 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -164,12 +164,12 @@ static int local_ipcp_bootstrap(const struct ipcp_config * conf) static int local_ipcp_reg(const uint8_t * hash) { if (shim_data_reg_add_entry(local_data.shim_data, hash)) { - log_dbg("Failed to add " HASH_FMT " to local registry.", - HASH_VAL(hash)); + log_dbg("Failed to add " HASH_FMT32 " to local registry.", + HASH_VAL32(hash)); return -1; } - log_info("Registered " HASH_FMT ".", HASH_VAL(hash)); + log_info("Registered " HASH_FMT32 ".", HASH_VAL32(hash)); return 0; } @@ -178,7 +178,7 @@ static int local_ipcp_unreg(const uint8_t * hash) { shim_data_reg_del_entry(local_data.shim_data, hash); - log_info("Unregistered " HASH_FMT ".", HASH_VAL(hash)); + log_info("Unregistered " HASH_FMT32 ".", HASH_VAL32(hash)); return 0; } @@ -203,7 +203,8 @@ static int local_ipcp_flow_alloc(int fd, int out_fd = -1; time_t mpl = IPCP_LOCAL_MPL; - log_dbg("Allocating flow to " HASH_FMT " on fd %d.", HASH_VAL(dst), fd); + log_dbg("Allocating flow to " HASH_FMT32 " on fd %d.", + HASH_VAL32(dst), fd); assert(dst); clock_gettime(PTHREAD_COND_CLOCK, &abstime); diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c index 9f720e32..840b8224 100644 --- a/src/ipcpd/shim-data.c +++ b/src/ipcpd/shim-data.c @@ -297,8 +297,8 @@ int shim_data_reg_add_entry(struct shim_data * data, if (find_reg_entry_by_hash(data, hash)) { pthread_rwlock_unlock(&data->reg_lock); - log_dbg(HASH_FMT " was already in the directory.", - HASH_VAL(hash)); + log_dbg(HASH_FMT32 " was already in the directory.", + HASH_VAL32(hash)); return 0; } diff --git a/src/ipcpd/udp/main.c b/src/ipcpd/udp/main.c index ee7e2f8f..62cd3181 100644 --- a/src/ipcpd/udp/main.c +++ b/src/ipcpd/udp/main.c @@ -31,6 +31,7 @@ #define OUROBOROS_PREFIX "ipcpd/udp" #include +#include #include #include #include @@ -858,8 +859,8 @@ static int udp_ipcp_reg(const uint8_t * hash) ipcp_hash_str(hashstr, hash); if (shim_data_reg_add_entry(udp_data.shim_data, hash)) { - log_err("Failed to add " HASH_FMT " to local registry.", - HASH_VAL(hash)); + log_err("Failed to add " HASH_FMT32 " to local registry.", + HASH_VAL32(hash)); free(hashstr); return -1; } @@ -892,7 +893,7 @@ static int udp_ipcp_reg(const uint8_t * hash) } } #endif - log_dbg("Registered " HASH_FMT ".", HASH_VAL(hash)); + log_dbg("Registered " HASH_FMT32 ".", HASH_VAL32(hash)); free(hashstr); @@ -936,7 +937,7 @@ static int udp_ipcp_unreg(const uint8_t * hash) shim_data_reg_del_entry(udp_data.shim_data, hash); - log_dbg("Unregistered " HASH_FMT ".", HASH_VAL(hash)); + log_dbg("Unregistered " HASH_FMT32 ".", HASH_VAL32(hash)); free(hashstr); @@ -1009,7 +1010,7 @@ static int udp_ipcp_flow_alloc(int fd, uint32_t ip_addr = 0; char ipstr[INET_ADDRSTRLEN]; - log_dbg("Allocating flow to " HASH_FMT ".", HASH_VAL(dst)); + log_dbg("Allocating flow to " HASH_FMT32 ".", HASH_VAL32(dst)); (void) qs; diff --git a/src/ipcpd/unicast/dir/dht.c b/src/ipcpd/unicast/dir/dht.c index e97d5c5f..adc6feb2 100644 --- a/src/ipcpd/unicast/dir/dht.c +++ b/src/ipcpd/unicast/dir/dht.c @@ -31,6 +31,7 @@ #define DHT "dht" #define OUROBOROS_PREFIX DHT +#include #include #include #include diff --git a/src/ipcpd/unicast/fa.c b/src/ipcpd/unicast/fa.c index 90550ebc..2591a162 100644 --- a/src/ipcpd/unicast/fa.c +++ b/src/ipcpd/unicast/fa.c @@ -31,6 +31,7 @@ #define FA "flow-allocator" #define OUROBOROS_PREFIX FA +#include #include #include #include diff --git a/src/irmd/main.c b/src/irmd/main.c index bb65297f..b5184ade 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -1201,14 +1201,14 @@ int name_reg(const char * name, pthread_rwlock_unlock(&irmd.reg_lock); if (ipcp_reg(pid, hash, len)) { - log_err("Could not register " HASH_FMT " with IPCP %d.", - HASH_VAL(hash), pid); + log_err("Could not register " HASH_FMT32 " with IPCP %d.", + HASH_VAL32(hash), pid); free(hash); return -1; } - log_info("Registered %s with IPCP %d as " HASH_FMT ".", - name, pid, HASH_VAL(hash)); + log_info("Registered %s with IPCP %d as " HASH_FMT32 ".", + name, pid, HASH_VAL32(hash)); free(hash); @@ -1736,8 +1736,8 @@ static int flow_req_arr(pid_t pid, struct timespec wt = {IRMD_REQ_ARR_TIMEOUT / 1000, (IRMD_REQ_ARR_TIMEOUT % 1000) * MILLION}; - log_dbg("Flow req arrived from IPCP %d for " HASH_FMT ".", - pid, HASH_VAL(hash)); + log_dbg("Flow req arrived from IPCP %d for " HASH_FMT32 ".", + pid, HASH_VAL32(hash)); pthread_rwlock_rdlock(&irmd.reg_lock); @@ -1751,7 +1751,7 @@ static int flow_req_arr(pid_t pid, hash, IPCP_HASH_LEN(ipcp)); if (n == NULL) { pthread_rwlock_unlock(&irmd.reg_lock); - log_err("Unknown hash: " HASH_FMT ".", HASH_VAL(hash)); + log_err("Unknown hash: " HASH_FMT32 ".", HASH_VAL32(hash)); return -1; } @@ -1761,7 +1761,7 @@ static int flow_req_arr(pid_t pid, /* Give the process a bit of slop time to call accept */ if (reg_name_leave_state(n, NAME_IDLE, &wt) == -1) { - log_err("No processes for " HASH_FMT ".", HASH_VAL(hash)); + log_err("No processes for " HASH_FMT32 ".", HASH_VAL32(hash)); return -1; } @@ -1770,7 +1770,7 @@ static int flow_req_arr(pid_t pid, switch (reg_name_get_state(n)) { case NAME_IDLE: pthread_rwlock_unlock(&irmd.reg_lock); - log_err("No processes for " HASH_FMT ".", HASH_VAL(hash)); + log_err("No processes for " HASH_FMT32 ".", HASH_VAL32(hash)); return -1; case NAME_AUTO_ACCEPT: c_pid = malloc(sizeof(*c_pid)); diff --git a/src/lib/frct.c b/src/lib/frct.c index 7451e9e9..a00b1acd 100644 --- a/src/lib/frct.c +++ b/src/lib/frct.c @@ -20,6 +20,8 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ +#include + #define DELT_RDV (100 * MILLION) /* ns */ #define MAX_RDV (1 * BILLION) /* ns */ diff --git a/src/lib/tests/CMakeLists.txt b/src/lib/tests/CMakeLists.txt index 9e23b0ee..b3b79760 100644 --- a/src/lib/tests/CMakeLists.txt +++ b/src/lib/tests/CMakeLists.txt @@ -6,6 +6,7 @@ create_test_sourcelist(${PARENT_DIR}_tests test_suite.c bitmap_test.c btree_test.c crc32_test.c + hash_test.c md5_test.c sha3_test.c shm_rbuff_test.c diff --git a/src/lib/tests/hash_test.c b/src/lib/tests/hash_test.c new file mode 100644 index 00000000..7dc0701a --- /dev/null +++ b/src/lib/tests/hash_test.c @@ -0,0 +1,182 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2023 + * + * Test of the hashing functions + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#include + +#include +#include +#include +#include +#include + +/* + * Test vectors calculated at + * https://www.lammertbies.nl/comm/info/crc-calculation.html + */ + +struct vec_entry { + char * in; + char * out; +}; + +static int test_crc32(void) +{ + struct vec_entry vec [] = { + { "0", "f4dbdf21" }, + { "123456789", "cbf43926" }, + { "987654321", "015f0201" }, + { NULL, NULL } + }; + + struct vec_entry * cur = vec; + + while (cur->in != NULL) { + uint8_t crc[4]; + char res[9]; + + str_hash(HASH_CRC32, crc, cur->in); + + sprintf(res, HASH_FMT32, HASH_VAL32(crc)); + if (strcmp(res, cur->out) != 0) { + printf("Hash failed %s != %s", res, cur->out); + return -1; + } + + ++cur; + } + + return 0; +} + +static int test_md5(void) +{ + struct vec_entry vec [] = {{ + "abc", + "900150983cd24fb0d6963f7d28e17f72" + }, { + "The quick brown fox jumps over the lazy dog", + "9e107d9d372bb6826bd81d3542a419d6" + }, { + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "8215ef0796a20bcaaae116d3876c664a" + }, { + NULL, + NULL + }}; + + struct vec_entry * cur = vec; + + while (cur->in != NULL) { + uint8_t md5[16]; + char res[33]; + + str_hash(HASH_MD5, md5, cur->in); + + sprintf(res, HASH_FMT128, HASH_VAL128(md5)); + if (strcmp(res, cur->out) != 0) { + printf("Hash failed %s != %s", res, cur->out); + return -1; + } + + ++cur; + } + + return 0; +} + +static int test_sha3(void) +{ + uint8_t sha3[64]; + char res[129]; + + char * in = "abc"; + + char * out = + "e642824c3f8cf24ad09234ee7d3c766f" + "c9a3a5168d0c94ad73b46fdf"; + + str_hash(HASH_SHA3_224, sha3, in); + + sprintf(res, HASH_FMT224, HASH_VAL224(sha3)); + if (strcmp(res, out) != 0) { + printf("SHA3-224 failed %s != %s", res, out); + return -1; + } + + out = + "3a985da74fe225b2045c172d6bd390bd" + "855f086e3e9d525b46bfe24511431532"; + + str_hash(HASH_SHA3_256, sha3, in); + + sprintf(res, HASH_FMT256, HASH_VAL256(sha3)); + if (strcmp(res, out) != 0) { + printf("SHA3-256 failed %s != %s", res, out); + return -1; + } + + out = + "ec01498288516fc926459f58e2c6ad8d" + "f9b473cb0fc08c2596da7cf0e49be4b2" + "98d88cea927ac7f539f1edf228376d25"; + + str_hash(HASH_SHA3_384, sha3, in); + + sprintf(res, HASH_FMT384, HASH_VAL384(sha3)); + if (strcmp(res, out) != 0) { + printf("SHA3-384failed %s != %s", res, out); + return -1; + } + + out = + "b751850b1a57168a5693cd924b6b096e" + "08f621827444f70d884f5d0240d2712e" + "10e116e9192af3c91a7ec57647e39340" + "57340b4cf408d5a56592f8274eec53f0"; + + str_hash(HASH_SHA3_512, sha3, in); + + sprintf(res, HASH_FMT512, HASH_VAL512(sha3)); + if (strcmp(res, out) != 0) { + printf("SHA3-512 failed %s != %s", res, out); + return -1; + } + + return 0; +} + +int hash_test(int argc, + char ** argv) +{ + int ret = 0; + + (void) argc; + (void) argv; + + ret |= test_crc32(); + + ret |= test_md5(); + + ret |= test_sha3(); + + return ret; +} \ No newline at end of file -- cgit v1.2.3