diff --git a/include/villas/utils.h b/include/villas/utils.h index 164ce0d96..8a1089825 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -14,6 +14,8 @@ #include #include +#include + #include "log.h" #ifdef __GNUC__ @@ -229,3 +231,10 @@ void rdtsc_sleep(uint64_t nanosecs, uint64_t start); /** Register a exit callback for program termination (SIGINT / SIGKILL). */ void signals_init(void (*cb)(int signal, siginfo_t *sinfo, void *ctx)); + +/** Calculate SHA1 hash of complete file \p f and place it into \p sha1. + * + * @param sha1[out] Must be SHA_DIGEST_LENGTH (20) in size. + * @retval 0 Everything was okay. + */ +int sha1sum(FILE *f, unsigned char *sha1); diff --git a/lib/Makefile.inc b/lib/Makefile.inc index b35a12e26..84ae00d09 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -18,6 +18,8 @@ LIB_LDLIBS = $(LDLIBS) -ldl -lrt -include lib/apis/Makefile.inc -include lib/fpga/Makefile.inc +LIB_PKGS = openssl + ######## Node types ######## # Enable Socket node type when libnl3 is available diff --git a/lib/utils.c b/lib/utils.c index 05848b065..8732a3335 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -350,4 +350,25 @@ void signals_init(void (*cb)(int signal, siginfo_t *sinfo, void *ctx)) sigemptyset(&sa_quit.sa_mask); sigaction(SIGINT, &sa_quit, NULL); sigaction(SIGTERM, &sa_quit, NULL); +} + +int sha1sum(FILE *f, unsigned char *sha1) +{ + SHA_CTX c; + char buf[512]; + ssize_t bytes; + + rewind(f); /* Rewind the file in order to calculate over the whole file. */ + + SHA1_Init(&c); + + bytes = fread(buf, 1, 512, f); + while (bytes > 0) { + SHA1_Update(&c, buf, bytes); + bytes = fread(buf, 1, 512, f); + } + + SHA1_Final(sha1, &c); + + return 0; } \ No newline at end of file diff --git a/tests/utils.c b/tests/utils.c index 552099757..688d3ff70 100644 --- a/tests/utils.c +++ b/tests/utils.c @@ -59,4 +59,27 @@ Test(utils, version) cr_assert_eq(version_cmp(&v1, &v1), 0); cr_assert_gt(version_cmp(&v2, &v1), 0); cr_assert_lt(version_cmp(&v3, &v4), 0); +} + +Test(utils, sha1sum) +{ + int ret; + FILE *f = tmpfile(); + + unsigned char hash[SHA_DIGEST_LENGTH]; + unsigned char expected[SHA_DIGEST_LENGTH] = { 0x69, 0xdf, 0x29, 0xdf, 0x1f, 0xf2, 0xd2, 0x5d, 0xb8, 0x68, 0x6c, 0x02, 0x8d, 0xdf, 0x40, 0xaf, 0xb3, 0xc1, 0xc9, 0x4d }; + + /* Write the first 512 fibonaccia numbers to the file */ + for (int i = 0, a = 0, b = 1, c; i < 512; i++, a = b, b = c) { + c = a + b; + + fwrite((void *) &c, sizeof(c), 1, f); + } + + ret = sha1sum(f, hash); + + cr_assert_eq(ret, 0); + cr_assert_arr_eq(hash, expected, SHA_DIGEST_LENGTH); + + fclose(f); } \ No newline at end of file