summary refs log tree commit diff
path: root/shared/nm-glib-aux/nm-hash-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/nm-glib-aux/nm-hash-utils.c')
-rw-r--r--shared/nm-glib-aux/nm-hash-utils.c358
1 files changed, 174 insertions, 184 deletions
diff --git a/shared/nm-glib-aux/nm-hash-utils.c b/shared/nm-glib-aux/nm-hash-utils.c
index 232c62c0..8a1c87fd 100644
--- a/shared/nm-glib-aux/nm-hash-utils.c
+++ b/shared/nm-glib-aux/nm-hash-utils.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * Copyright (C) 2017 Red Hat, Inc.
  */
@@ -14,283 +14,273 @@
 
 /*****************************************************************************/
 
-#define HASH_KEY_SIZE 16u
-#define HASH_KEY_SIZE_GUINT ((HASH_KEY_SIZE + sizeof (guint) - 1) / sizeof (guint))
+#define HASH_KEY_SIZE       16u
+#define HASH_KEY_SIZE_GUINT ((HASH_KEY_SIZE + sizeof(guint) - 1) / sizeof(guint))
 
-G_STATIC_ASSERT (sizeof (guint) * HASH_KEY_SIZE_GUINT >= HASH_KEY_SIZE);
+G_STATIC_ASSERT(sizeof(guint) * HASH_KEY_SIZE_GUINT >= HASH_KEY_SIZE);
 
 static const guint8 *volatile global_seed = NULL;
 
 static const guint8 *
-_get_hash_key_init (void)
+_get_hash_key_init(void)
 {
-	/* the returned hash is aligned to guin64, hence, it is safe
-	 * to use it as guint* or guint64* pointer. */
-	static union {
-		guint8 v8[HASH_KEY_SIZE];
-		guint _align_as_uint;
-		guint32 _align_as_uint32;
-		guint64 _align_as_uint64;
-	} g_arr;
-	const guint8 *g;
+    /* the returned hash is aligned to guin64, hence, it is safe
+     * to use it as guint* or guint64* pointer. */
+    static union {
+        guint8  v8[HASH_KEY_SIZE];
+        guint   _align_as_uint;
+        guint32 _align_as_uint32;
+        guint64 _align_as_uint64;
+    } g_arr;
+    const guint8 *g;
 
 again:
-	g = g_atomic_pointer_get (&global_seed);
-	if (!G_UNLIKELY (g)) {
-		static gsize g_lock;
-		uint64_t h;
-		union {
-			guint vuint;
-			guint8 v8[HASH_KEY_SIZE];
-			guint8 _extra_entropy[3 * HASH_KEY_SIZE];
-		} t_arr;
-
-		nm_utils_random_bytes (&t_arr, sizeof (t_arr));
-
-		/* We only initialize one random hash key. So we can spend some effort
-		 * of getting this right. For one, we collect more random bytes than
-		 * necessary.
-		 *
-		 * Then, the first guint of the seed should have all the entropy that we could
-		 * obtain in sizeof(t_arr). For that, siphash(t_arr) and xor the first guint
-		 * with hash.
-		 * The first guint is especially interesting for nm_hash_static() below that
-		 * doesn't use siphash itself. */
-		h = c_siphash_hash (t_arr.v8,
-		                    (const guint8 *) &t_arr,
-		                    sizeof (t_arr));
-		if (sizeof (h) > sizeof (guint))
-			t_arr.vuint = t_arr.vuint ^ ((guint) (h & G_MAXUINT)) ^ ((guint) (h >> 32));
-		else
-			t_arr.vuint = t_arr.vuint ^ ((guint) (h & G_MAXUINT));
-
-		if (!g_once_init_enter (&g_lock)) {
-			/* lost a race. The random key is already initialized. */
-			goto again;
-		}
-
-		memcpy (g_arr.v8, t_arr.v8, HASH_KEY_SIZE);
-		g = g_arr.v8;
-		g_atomic_pointer_set (&global_seed, g);
-		g_once_init_leave (&g_lock, 1);
-	}
-
-	nm_assert (g == g_arr.v8);
-	return g;
+    g = g_atomic_pointer_get(&global_seed);
+    if (!G_UNLIKELY(g)) {
+        static gsize g_lock;
+        uint64_t     h;
+        union {
+            guint  vuint;
+            guint8 v8[HASH_KEY_SIZE];
+            guint8 _extra_entropy[3 * HASH_KEY_SIZE];
+        } t_arr;
+
+        nm_utils_random_bytes(&t_arr, sizeof(t_arr));
+
+        /* We only initialize one random hash key. So we can spend some effort
+         * of getting this right. For one, we collect more random bytes than
+         * necessary.
+         *
+         * Then, the first guint of the seed should have all the entropy that we could
+         * obtain in sizeof(t_arr). For that, siphash(t_arr) and xor the first guint
+         * with hash.
+         * The first guint is especially interesting for nm_hash_static() below that
+         * doesn't use siphash itself. */
+        h = c_siphash_hash(t_arr.v8, (const guint8 *) &t_arr, sizeof(t_arr));
+        if (sizeof(h) > sizeof(guint))
+            t_arr.vuint = t_arr.vuint ^ ((guint)(h & G_MAXUINT)) ^ ((guint)(h >> 32));
+        else
+            t_arr.vuint = t_arr.vuint ^ ((guint)(h & G_MAXUINT));
+
+        if (!g_once_init_enter(&g_lock)) {
+            /* lost a race. The random key is already initialized. */
+            goto again;
+        }
+
+        memcpy(g_arr.v8, t_arr.v8, HASH_KEY_SIZE);
+        g = g_arr.v8;
+        g_atomic_pointer_set(&global_seed, g);
+        g_once_init_leave(&g_lock, 1);
+    }
+
+    nm_assert(g == g_arr.v8);
+    return g;
 }
 
-#define _get_hash_key() \
-	({ \
-		const guint8 *_g; \
-		\
-		_g = g_atomic_pointer_get (&global_seed); \
-		if (G_UNLIKELY (!_g)) \
-			_g = _get_hash_key_init (); \
-		_g; \
-	})
+#define _get_hash_key()                          \
+    ({                                           \
+        const guint8 *_g;                        \
+                                                 \
+        _g = g_atomic_pointer_get(&global_seed); \
+        if (G_UNLIKELY(!_g))                     \
+            _g = _get_hash_key_init();           \
+        _g;                                      \
+    })
 
 guint
-nm_hash_static (guint static_seed)
+nm_hash_static(guint static_seed)
 {
-	/* Note that we only xor the static_seed with the first guint of the key.
-	 *
-	 * We don't use siphash, which would mix the bits better with _get_hash_key().
-	 * Note that nm_hash_static() isn't used to hash the static_seed. Instead, it
-	 * is used to get a unique hash value in a static context. That means, every
-	 * caller is responsible to choose a static_seed that is sufficiently
-	 * distinct from all other callers. In other words, static_seed should be a
-	 * unique constant with good entropy.
-	 *
-	 * Note that _get_hash_key_init() already xored the first guint of the
-	 * key with the siphash of the entire static key. That means, even if
-	 * we got bad randomness for the first guint, the first guint is also
-	 * mixed with the randomness of the entire random key.
-	 *
-	 * Also, ensure that we don't return zero (like for nm_hash_complete()).
-	 */
-	return    ((*((const guint *) _get_hash_key ())) ^ static_seed)
-	       ?: 3679500967u;
+    /* Note that we only xor the static_seed with the first guint of the key.
+     *
+     * We don't use siphash, which would mix the bits better with _get_hash_key().
+     * Note that nm_hash_static() isn't used to hash the static_seed. Instead, it
+     * is used to get a unique hash value in a static context. That means, every
+     * caller is responsible to choose a static_seed that is sufficiently
+     * distinct from all other callers. In other words, static_seed should be a
+     * unique constant with good entropy.
+     *
+     * Note that _get_hash_key_init() already xored the first guint of the
+     * key with the siphash of the entire static key. That means, even if
+     * we got bad randomness for the first guint, the first guint is also
+     * mixed with the randomness of the entire random key.
+     *
+     * Also, ensure that we don't return zero (like for nm_hash_complete()).
+     */
+    return ((*((const guint *) _get_hash_key())) ^ static_seed) ?: 3679500967u;
 }
 
 void
-nm_hash_siphash42_init (CSipHash *h, guint static_seed)
+nm_hash_siphash42_init(CSipHash *h, guint static_seed)
 {
-	const guint8 *g;
-	union {
-		guint64 _align_as_uint64;
-		guint arr[HASH_KEY_SIZE_GUINT];
-	} seed;
-
-	nm_assert (h);
-
-	g = _get_hash_key ();
-	memcpy (&seed, g, HASH_KEY_SIZE);
-	seed.arr[0] ^= static_seed;
-	c_siphash_init (h, (const guint8 *) &seed);
+    const guint8 *g;
+    union {
+        guint64 _align_as_uint64;
+        guint   arr[HASH_KEY_SIZE_GUINT];
+    } seed;
+
+    nm_assert(h);
+
+    g = _get_hash_key();
+    memcpy(&seed, g, HASH_KEY_SIZE);
+    seed.arr[0] ^= static_seed;
+    c_siphash_init(h, (const guint8 *) &seed);
 }
 
 guint
-nm_hash_str (const char *str)
+nm_hash_str(const char *str)
 {
-	NMHashState h;
+    NMHashState h;
 
-	if (!str)
-		return nm_hash_static (1867854211u);
-	nm_hash_init (&h, 1867854211u);
-	nm_hash_update_str (&h, str);
-	return nm_hash_complete (&h);
+    if (!str)
+        return nm_hash_static(1867854211u);
+    nm_hash_init(&h, 1867854211u);
+    nm_hash_update_str(&h, str);
+    return nm_hash_complete(&h);
 }
 
 guint
-nm_str_hash (gconstpointer str)
+nm_str_hash(gconstpointer str)
 {
-	return nm_hash_str (str);
+    return nm_hash_str(str);
 }
 
 guint
-nm_hash_ptr (gconstpointer ptr)
+nm_hash_ptr(gconstpointer ptr)
 {
-	NMHashState h;
+    NMHashState h;
 
-	if (!ptr)
-		return nm_hash_static (2907677551u);
-	nm_hash_init (&h, 2907677551u);
-	nm_hash_update (&h, &ptr, sizeof (ptr));
-	return nm_hash_complete (&h);
+    if (!ptr)
+        return nm_hash_static(2907677551u);
+    nm_hash_init(&h, 2907677551u);
+    nm_hash_update(&h, &ptr, sizeof(ptr));
+    return nm_hash_complete(&h);
 }
 
 guint
-nm_direct_hash (gconstpointer ptr)
+nm_direct_hash(gconstpointer ptr)
 {
-	return nm_hash_ptr (ptr);
+    return nm_hash_ptr(ptr);
 }
 
 /*****************************************************************************/
 
 guint
-nm_pstr_hash (gconstpointer p)
+nm_pstr_hash(gconstpointer p)
 {
-	const char *const*s = p;
+    const char *const *s = p;
 
-	if (!s)
-		return nm_hash_static (101061439u);
-	return nm_hash_str (*s);
+    if (!s)
+        return nm_hash_static(101061439u);
+    return nm_hash_str(*s);
 }
 
 gboolean
-nm_pstr_equal (gconstpointer a, gconstpointer b)
+nm_pstr_equal(gconstpointer a, gconstpointer b)
 {
-	const char *const*s1 = a;
-	const char *const*s2 = b;
+    const char *const *s1 = a;
+    const char *const *s2 = b;
 
-	return    (s1 == s2)
-	       || (   s1
-	           && s2
-	           && nm_streq0 (*s1, *s2));
+    return (s1 == s2) || (s1 && s2 && nm_streq0(*s1, *s2));
 }
 
 guint
-nm_pint_hash (gconstpointer p)
+nm_pint_hash(gconstpointer p)
 {
-	const int *s = p;
+    const int *s = p;
 
-	if (!s)
-		return nm_hash_static (298377461u);
-	return nm_hash_val (1208815757u, *s);
+    if (!s)
+        return nm_hash_static(298377461u);
+    return nm_hash_val(1208815757u, *s);
 }
 
 gboolean
-nm_pint_equals (gconstpointer a, gconstpointer b)
+nm_pint_equals(gconstpointer a, gconstpointer b)
 {
-	const int *s1 = a;
-	const int *s2 = a;
+    const int *s1 = a;
+    const int *s2 = a;
 
-	return    s1 == s2
-	       || (s1 && s2 && *s1 == *s2);
+    return s1 == s2 || (s1 && s2 && *s1 == *s2);
 }
 
 guint
-nm_pdirect_hash (gconstpointer p)
+nm_pdirect_hash(gconstpointer p)
 {
-	const void *const*s = p;
+    const void *const *s = p;
 
-	if (!s)
-		return nm_hash_static (1852748873u);
-	return nm_direct_hash (*s);
+    if (!s)
+        return nm_hash_static(1852748873u);
+    return nm_direct_hash(*s);
 }
 
 gboolean
-nm_pdirect_equal (gconstpointer a, gconstpointer b)
+nm_pdirect_equal(gconstpointer a, gconstpointer b)
 {
-	const void *const*s1 = a;
-	const void *const*s2 = b;
+    const void *const *s1 = a;
+    const void *const *s2 = b;
 
-	return    (s1 == s2)
-	       || (   s1
-	           && s2
-	           && *s1 == *s2);
+    return (s1 == s2) || (s1 && s2 && *s1 == *s2);
 }
 
 guint
-nm_ppdirect_hash (gconstpointer p)
+nm_ppdirect_hash(gconstpointer p)
 {
-	const void *const*const*s = p;
+    const void *const *const *s = p;
 
-	if (!s)
-		return nm_hash_static (396534869u);
-	if (!*s)
-		return nm_hash_static (1476102263u);
-	return nm_direct_hash (**s);
+    if (!s)
+        return nm_hash_static(396534869u);
+    if (!*s)
+        return nm_hash_static(1476102263u);
+    return nm_direct_hash(**s);
 }
 
 gboolean
-nm_ppdirect_equal (gconstpointer a, gconstpointer b)
+nm_ppdirect_equal(gconstpointer a, gconstpointer b)
 {
-	const void *const*const*s1 = a;
-	const void *const*const*s2 = b;
+    const void *const *const *s1 = a;
+    const void *const *const *s2 = b;
 
-	if (s1 == s2)
-		return TRUE;
-	if (!s1 || !s2)
-		return FALSE;
+    if (s1 == s2)
+        return TRUE;
+    if (!s1 || !s2)
+        return FALSE;
 
-	if (*s1 == *s2)
-		return TRUE;
-	if (!*s1 || !*s2)
-		return FALSE;
+    if (*s1 == *s2)
+        return TRUE;
+    if (!*s1 || !*s2)
+        return FALSE;
 
-	return **s1 == **s2;
+    return **s1 == **s2;
 }
 
 /*****************************************************************************/
 
 guint
-nm_gbytes_hash (gconstpointer p)
+nm_gbytes_hash(gconstpointer p)
 {
-	GBytes *ptr = (GBytes *) p;
-	gconstpointer arr;
-	gsize len;
+    GBytes *      ptr = (GBytes *) p;
+    gconstpointer arr;
+    gsize         len;
 
-	arr = g_bytes_get_data (ptr, &len);
-	return nm_hash_mem (792701303u, arr, len);
+    arr = g_bytes_get_data(ptr, &len);
+    return nm_hash_mem(792701303u, arr, len);
 }
 
 guint
-nm_pgbytes_hash (gconstpointer p)
+nm_pgbytes_hash(gconstpointer p)
 {
-	GBytes *const*ptr = p;
-	gconstpointer arr;
-	gsize len;
+    GBytes *const *ptr = p;
+    gconstpointer  arr;
+    gsize          len;
 
-	arr = g_bytes_get_data (*ptr, &len);
-	return nm_hash_mem (1470631313u, arr, len);
+    arr = g_bytes_get_data(*ptr, &len);
+    return nm_hash_mem(1470631313u, arr, len);
 }
 
 gboolean
-nm_pgbytes_equal (gconstpointer a, gconstpointer b)
+nm_pgbytes_equal(gconstpointer a, gconstpointer b)
 {
-	GBytes *const*ptr_a = a;
-	GBytes *const*ptr_b = b;
+    GBytes *const *ptr_a = a;
+    GBytes *const *ptr_b = b;
 
-	return g_bytes_equal (*ptr_a, *ptr_b);
+    return g_bytes_equal(*ptr_a, *ptr_b);
 }