From b8b6100c78a039c9ae02013860b1e1a93ac1783a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 May 2018 13:19:07 +0200 Subject: [PATCH] all: replace systemd's siphash24 with c-siphash Originally, we used "nm-utils/siphash24.c", which was copied from systemd's source tree. It was both used by our own NetworkManager code, and by our internal systemd fork. Then, we added "shared/c-siphash" as a dependency for n-acd. Now, drop systemd's implementation and use c-siphash also for our internal purpose. Also, let systemd code use c-siphash, by patching "src/systemd/src/basic/siphash24.h". --- Makefile.am | 46 ++++--- libnm-core/meson.build | 8 +- shared/meson.build | 3 +- shared/nm-utils/nm-hash-utils.c | 16 +-- shared/nm-utils/nm-hash-utils.h | 10 +- shared/nm-utils/siphash24.c | 204 ------------------------------ shared/nm-utils/siphash24.h | 23 ---- src/systemd/sd-adapt/siphash24.h | 3 - src/systemd/src/basic/siphash24.h | 53 ++++++++ src/tests/meson.build | 2 +- 10 files changed, 101 insertions(+), 267 deletions(-) delete mode 100644 shared/nm-utils/siphash24.c delete mode 100644 shared/nm-utils/siphash24.h delete mode 100644 src/systemd/sd-adapt/siphash24.h create mode 100644 src/systemd/src/basic/siphash24.h diff --git a/Makefile.am b/Makefile.am index 362d768769..79b046280d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -445,7 +445,6 @@ libnm_core_lib_h_priv = \ shared/nm-utils/nm-shared-utils.h \ shared/nm-utils/nm-random-utils.h \ shared/nm-utils/nm-udev-utils.h \ - shared/nm-utils/siphash24.h \ shared/nm-meta-setting.h \ libnm-core/crypto.h \ libnm-core/nm-connection-private.h \ @@ -606,9 +605,11 @@ nodist_libnm_core_libnm_core_la_SOURCES = \ $(libnm_core_lib_c_mkenums) libnm_core_libnm_core_la_LIBADD = \ + shared/libcsiphash.la \ $(GLIB_LIBS) \ $(UUID_LIBS) \ - $(LIBUDEV_LIBS) + $(LIBUDEV_LIBS) \ + $(NULL) libnm_core_libnm_core_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ @@ -1238,24 +1239,34 @@ noinst_LTLIBRARIES += \ ############################################################################### -shared_libcsiphash_la_CPPFLAGS = $(src_cppflags) +noinst_LTLIBRARIES += shared/libcsiphash.la + +shared_libcsiphash_la_CPPFLAGS = \ + $(CODE_COVERAGE_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ + $(NULL) + shared_libcsiphash_la_SOURCES = \ shared/c-siphash/src/c-siphash.c \ shared/c-siphash/src/c-siphash.h +############################################################################### + +noinst_LTLIBRARIES += shared/libnacd.la + shared_libnacd_la_CFLAGS = -std=gnu99 + shared_libnacd_la_CPPFLAGS = \ - $(src_cppflags) \ - -I $(srcdir)/shared/c-list/src \ - -I $(srcdir)/shared/c-siphash/src + $(CODE_COVERAGE_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ + -I$(srcdir)/shared/c-list/src \ + -I$(srcdir)/shared/c-siphash/src \ + $(NULL) + shared_libnacd_la_SOURCES = \ shared/n-acd/src/n-acd.c \ shared/n-acd/src/n-acd.h -noinst_LTLIBRARIES += \ - shared/libcsiphash.la \ - shared/libnacd.la - EXTRA_DIST += shared/c-list/src/c-list.h ############################################################################### @@ -1309,7 +1320,6 @@ src_libsystemd_nm_la_SOURCES = \ src/systemd/sd-adapt/procfs-util.h \ src/systemd/sd-adapt/raw-clone.h \ src/systemd/sd-adapt/sd-daemon.h \ - src/systemd/sd-adapt/siphash24.h \ src/systemd/sd-adapt/stat-util.h \ src/systemd/sd-adapt/terminal-util.h \ src/systemd/sd-adapt/udev-util.h \ @@ -1362,6 +1372,7 @@ src_libsystemd_nm_la_SOURCES = \ src/systemd/src/basic/refcnt.h \ src/systemd/src/basic/set.h \ src/systemd/src/basic/signal-util.h \ + src/systemd/src/basic/siphash24.h \ src/systemd/src/basic/socket-util.c \ src/systemd/src/basic/socket-util.h \ src/systemd/src/basic/sparse-endian.h \ @@ -1689,7 +1700,6 @@ src_libNetworkManager_la_SOURCES = \ src_libNetworkManager_la_LIBADD = \ src/libNetworkManagerBase.la \ src/libsystemd-nm.la \ - shared/libcsiphash.la \ shared/libnacd.la \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ @@ -3201,11 +3211,12 @@ src_tests_test_systemd_CPPFLAGS = \ $(src_libsystemd_nm_la_cppflags) \ -DNETWORKMANAGER_COMPILATION_TEST src_tests_test_systemd_SOURCES = \ - shared/nm-utils/siphash24.c \ src/tests/test-systemd.c src_tests_test_systemd_LDADD = \ src/libsystemd-nm.la \ - $(src_libsystemd_nm_la_libadd) + shared/libcsiphash.la \ + $(src_libsystemd_nm_la_libadd) \ + $(NULL) $(src_tests_test_systemd_OBJECTS): $(libnm_core_lib_h_pub_mkenums) @@ -3415,7 +3426,6 @@ clients_common_libnmc_base_la_SOURCES = \ shared/nm-utils/nm-random-utils.h \ shared/nm-utils/nm-shared-utils.c \ shared/nm-utils/nm-shared-utils.h \ - shared/nm-utils/siphash24.h \ \ clients/common/nm-secret-agent-simple.c \ clients/common/nm-secret-agent-simple.h \ @@ -3431,7 +3441,9 @@ clients_common_libnmc_base_la_CPPFLAGS = \ clients_common_libnmc_base_la_LIBADD = \ libnm/libnm.la \ - $(GLIB_LIBS) + shared/libcsiphash.la \ + $(GLIB_LIBS) \ + $(NULL) $(clients_common_libnmc_base_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(clients_common_libnmc_base_la_OBJECTS): $(libnm_lib_h_pub_mkenums) @@ -4783,8 +4795,6 @@ EXTRA_DIST += \ shared/nm-utils/nm-vpn-plugin-macros.h \ shared/nm-utils/nm-vpn-plugin-utils.c \ shared/nm-utils/nm-vpn-plugin-utils.h \ - shared/nm-utils/siphash24.c \ - shared/nm-utils/siphash24.h \ shared/nm-utils/unaligned.h \ shared/nm-version-macros.h.in \ shared/meson.build \ diff --git a/libnm-core/meson.build b/libnm-core/meson.build index 71557f8a71..533e59063c 100644 --- a/libnm-core/meson.build +++ b/libnm-core/meson.build @@ -131,7 +131,8 @@ deps = [ dl_dep, libudev_dep, shared_dep, - uuid_dep + uuid_dep, + shared_c_siphash_dep, ] cflags = [ @@ -160,7 +161,10 @@ libnm_core = static_library( nm_core_dep = declare_dependency( sources: libnm_core_enum[1], include_directories: libnm_core_inc, - dependencies: shared_dep + dependencies: [ + shared_dep, + shared_c_siphash_dep, + ], ) enums_to_docbook = join_paths(meson.source_root(), 'tools', 'enums-to-docbook.pl') diff --git a/shared/meson.build b/shared/meson.build index 98243435da..e83dec3b7f 100644 --- a/shared/meson.build +++ b/shared/meson.build @@ -42,11 +42,10 @@ shared_meta_setting = files('nm-meta-setting.c') shared_test_utils = files('nm-test-utils-impl.c') -shared_siphash = files('nm-utils/siphash24.c') - shared_udev_utils = files('nm-utils/nm-udev-utils.c') shared_utils = files( + 'c-siphash/src/c-siphash.c', 'nm-utils/nm-enum-utils.c', 'nm-utils/nm-hash-utils.c', 'nm-utils/nm-random-utils.c', diff --git a/shared/nm-utils/nm-hash-utils.c b/shared/nm-utils/nm-hash-utils.c index 8d8c21ce55..4bc12b7c3a 100644 --- a/shared/nm-utils/nm-hash-utils.c +++ b/shared/nm-utils/nm-hash-utils.c @@ -28,8 +28,6 @@ #include "nm-shared-utils.h" #include "nm-random-utils.h" -#include "siphash24.c" - /*****************************************************************************/ #define HASH_KEY_SIZE 16u @@ -49,7 +47,7 @@ _get_hash_key_init (void) } g_arr _nm_alignas (guint64); static gsize g_lock; const guint8 *g; - struct siphash siph_state; + CSipHash siph_state; uint64_t h; guint *p; @@ -66,9 +64,9 @@ _get_hash_key_init (void) /* use siphash() of the key-size, to mangle the first guint. Otherwise, * the first guint has only the entropy that nm_utils_random_bytes() * generated for the first 4 bytes and relies on a good random generator. */ - siphash24_init (&siph_state, g_arr.v8); - siphash24_compress (g_arr.v8, sizeof (g_arr.v8), &siph_state); - h = siphash24_finalize (&siph_state); + c_siphash_init (&siph_state, g_arr.v8); + c_siphash_append (&siph_state, g_arr.v8, sizeof (g_arr.v8)); + h = c_siphash_finalize (&siph_state); p = (guint *) g_arr.v8; if (sizeof (guint) < sizeof (h)) *p = *p ^ ((guint) (h & 0xFFFFFFFFu)) ^ ((guint) (h >> 32)); @@ -97,10 +95,10 @@ guint nm_hash_static (guint static_seed) { /* note that we only xor the static_seed with the key. - * We don't use siphash24(), which would mix the bits better. + * We don't use siphash, which would mix the bits better. * Note that this doesn't matter, because static_seed is not * supposed to be a value that you are hashing (for that, use - * full siphash24()). + * full siphash). * Instead, different callers may set a different static_seed * so that nm_hash_str(NULL) != nm_hash_ptr(NULL). * @@ -121,7 +119,7 @@ nm_hash_init (NMHashState *state, guint static_seed) g = _get_hash_key (); memcpy (seed, g, HASH_KEY_SIZE); seed[0] ^= static_seed; - siphash24_init (&state->_state, (const guint8 *) seed); + c_siphash_init (&state->_state, (const guint8 *) seed); } guint diff --git a/shared/nm-utils/nm-hash-utils.h b/shared/nm-utils/nm-hash-utils.h index 3bd3f652fb..b7742e0fe3 100644 --- a/shared/nm-utils/nm-hash-utils.h +++ b/shared/nm-utils/nm-hash-utils.h @@ -22,11 +22,11 @@ #ifndef __NM_HASH_UTILS_H__ #define __NM_HASH_UTILS_H__ -#include "siphash24.h" +#include "c-siphash/src/c-siphash.h" #include "nm-macros-internal.h" struct _NMHashState { - struct siphash _state; + CSipHash _state; }; typedef struct _NMHashState NMHashState; @@ -42,7 +42,7 @@ nm_hash_complete (NMHashState *state) nm_assert (state); - h = siphash24_finalize (&state->_state); + h = c_siphash_finalize (&state->_state); /* we don't ever want to return a zero hash. * @@ -57,7 +57,7 @@ nm_hash_update (NMHashState *state, const void *ptr, gsize n) nm_assert (ptr); nm_assert (n > 0); - siphash24_compress (ptr, n, &state->_state); + c_siphash_append (&state->_state, ptr, n); } #define nm_hash_update_val(state, val) \ @@ -168,7 +168,7 @@ nm_hash_update_mem (NMHashState *state, const void *ptr, gsize n) * instead. */ nm_hash_update (state, &n, sizeof (n)); if (n > 0) - siphash24_compress (ptr, n, &state->_state); + c_siphash_append (&state->_state, ptr, n); } static inline void diff --git a/shared/nm-utils/siphash24.c b/shared/nm-utils/siphash24.c deleted file mode 100644 index 8e59afb2c2..0000000000 --- a/shared/nm-utils/siphash24.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - SipHash reference C implementation - - Written in 2012 by - Jean-Philippe Aumasson - Daniel J. Bernstein - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . - - (Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd) - (Refactored by Tom Gundersen to split up in several functions and follow systemd - coding style) -*/ - -#include "nm-default.h" - -#define assert(cond) nm_assert (cond) -#define _fallthrough_ _nm_fallthrough - -#include - -#include "siphash24.h" -#include "unaligned.h" - -static inline uint64_t rotate_left(uint64_t x, uint8_t b) { - assert(b < 64); - - return (x << b) | (x >> (64 - b)); -} - -static inline void sipround(struct siphash *state) { - assert(state); - - state->v0 += state->v1; - state->v1 = rotate_left(state->v1, 13); - state->v1 ^= state->v0; - state->v0 = rotate_left(state->v0, 32); - state->v2 += state->v3; - state->v3 = rotate_left(state->v3, 16); - state->v3 ^= state->v2; - state->v0 += state->v3; - state->v3 = rotate_left(state->v3, 21); - state->v3 ^= state->v0; - state->v2 += state->v1; - state->v1 = rotate_left(state->v1, 17); - state->v1 ^= state->v2; - state->v2 = rotate_left(state->v2, 32); -} - -void siphash24_init(struct siphash *state, const uint8_t k[16]) { - uint64_t k0, k1; - - assert(state); - assert(k); - - k0 = unaligned_read_le64(k); - k1 = unaligned_read_le64(k + 8); - - *state = (struct siphash) { - /* "somepseudorandomlygeneratedbytes" */ - .v0 = 0x736f6d6570736575ULL ^ k0, - .v1 = 0x646f72616e646f6dULL ^ k1, - .v2 = 0x6c7967656e657261ULL ^ k0, - .v3 = 0x7465646279746573ULL ^ k1, - .padding = 0, - .inlen = 0, - }; -} - -void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) { - - const uint8_t *in = _in; - const uint8_t *end = in + inlen; - size_t left = state->inlen & 7; - uint64_t m; - - assert(in); - assert(state); - - /* Update total length */ - state->inlen += inlen; - - /* If padding exists, fill it out */ - if (left > 0) { - for ( ; in < end && left < 8; in ++, left ++) - state->padding |= ((uint64_t) *in) << (left * 8); - - if (in == end && left < 8) - /* We did not have enough input to fill out the padding completely */ - return; - -#ifdef DEBUG - printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0); - printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1); - printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2); - printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3); - printf("(%3zu) compress padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t)state->padding); -#endif - - state->v3 ^= state->padding; - sipround(state); - sipround(state); - state->v0 ^= state->padding; - - state->padding = 0; - } - - end -= (state->inlen % sizeof(uint64_t)); - - for ( ; in < end; in += 8) { - m = unaligned_read_le64(in); -#ifdef DEBUG - printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0); - printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1); - printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2); - printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3); - printf("(%3zu) compress %08x %08x\n", state->inlen, (uint32_t) (m >> 32), (uint32_t) m); -#endif - state->v3 ^= m; - sipround(state); - sipround(state); - state->v0 ^= m; - } - - left = state->inlen & 7; - switch (left) { - case 7: - state->padding |= ((uint64_t) in[6]) << 48; - _fallthrough_; - case 6: - state->padding |= ((uint64_t) in[5]) << 40; - _fallthrough_; - case 5: - state->padding |= ((uint64_t) in[4]) << 32; - _fallthrough_; - case 4: - state->padding |= ((uint64_t) in[3]) << 24; - _fallthrough_; - case 3: - state->padding |= ((uint64_t) in[2]) << 16; - _fallthrough_; - case 2: - state->padding |= ((uint64_t) in[1]) << 8; - _fallthrough_; - case 1: - state->padding |= ((uint64_t) in[0]); - _fallthrough_; - case 0: - break; - } -} - -uint64_t siphash24_finalize(struct siphash *state) { - uint64_t b; - - assert(state); - - b = state->padding | (((uint64_t) state->inlen) << 56); - -#ifdef DEBUG - printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0); - printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1); - printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2); - printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3); - printf("(%3zu) padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t) state->padding); -#endif - - state->v3 ^= b; - sipround(state); - sipround(state); - state->v0 ^= b; - -#ifdef DEBUG - printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0); - printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1); - printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2); - printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3); -#endif - state->v2 ^= 0xff; - - sipround(state); - sipround(state); - sipround(state); - sipround(state); - - return state->v0 ^ state->v1 ^ state->v2 ^ state->v3; -} - -uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]) { - struct siphash state; - - assert(in); - assert(k); - - siphash24_init(&state, k); - siphash24_compress(in, inlen, &state); - - return siphash24_finalize(&state); -} diff --git a/shared/nm-utils/siphash24.h b/shared/nm-utils/siphash24.h deleted file mode 100644 index 54e2420cc6..0000000000 --- a/shared/nm-utils/siphash24.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -struct siphash { - uint64_t v0; - uint64_t v1; - uint64_t v2; - uint64_t v3; - uint64_t padding; - size_t inlen; -}; - -void siphash24_init(struct siphash *state, const uint8_t k[16]); -void siphash24_compress(const void *in, size_t inlen, struct siphash *state); -#define siphash24_compress_byte(byte, state) siphash24_compress((const uint8_t[]) { (byte) }, 1, (state)) - -uint64_t siphash24_finalize(struct siphash *state); - -uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]); diff --git a/src/systemd/sd-adapt/siphash24.h b/src/systemd/sd-adapt/siphash24.h deleted file mode 100644 index ac6e5a1d13..0000000000 --- a/src/systemd/sd-adapt/siphash24.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#include "nm-utils/siphash24.h" diff --git a/src/systemd/src/basic/siphash24.h b/src/systemd/src/basic/siphash24.h new file mode 100644 index 0000000000..77bb9a8c07 --- /dev/null +++ b/src/systemd/src/basic/siphash24.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include +#include + +#if 0 /* NM_IGNORED */ +struct siphash { + uint64_t v0; + uint64_t v1; + uint64_t v2; + uint64_t v3; + uint64_t padding; + size_t inlen; +}; +#else /* NM_IGNORED */ +struct siphash { + CSipHash _csiphash; +}; + +static inline void +siphash24_init (struct siphash *state, const uint8_t k[16]) +{ + c_siphash_init ((CSipHash *) state, k); +} + +static inline void +siphash24_compress (const void *in, size_t inlen, struct siphash *state) +{ + c_siphash_append ((CSipHash *) state, in, inlen); +} + +static inline uint64_t +siphash24_finalize (struct siphash *state) +{ + return c_siphash_finalize ((CSipHash *) state); +} + +static inline uint64_t +siphash24 (const void *in, size_t inlen, const uint8_t k[16]) +{ + return c_siphash_hash (k, in, inlen); +} +#endif /* NM_IGNORED */ + +void siphash24_init(struct siphash *state, const uint8_t k[16]); +void siphash24_compress(const void *in, size_t inlen, struct siphash *state); +#define siphash24_compress_byte(byte, state) siphash24_compress((const uint8_t[]) { (byte) }, 1, (state)) + +uint64_t siphash24_finalize(struct siphash *state); + +uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]); diff --git a/src/tests/meson.build b/src/tests/meson.build index 386ede8782..430ffe43dc 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -33,7 +33,7 @@ cflags = [ exe = executable( test_unit, - [test_unit + '.c'] + shared_siphash, + [test_unit + '.c'], include_directories: src_inc, dependencies: nm_core_dep, c_args: cflags,