all: merge branch 'th/nm-hash-seed'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1783
This commit is contained in:
Thomas Haller
2023-11-14 19:12:27 +01:00
5 changed files with 113 additions and 70 deletions

View File

@@ -3191,7 +3191,11 @@ ensure_hotspot_frequency(NMDeviceWifi *self, NMSettingWireless *s_wifi, NMWifiAP
GBytes *ssid; GBytes *ssid;
gsize ssid_len; gsize ssid_len;
const guint8 *ssid_data; const guint8 *ssid_data;
const guint8 random_seed[16] = {0x9a,
/* Calculate a stable "random" number based on the SSID. */
ssid = nm_setting_wireless_get_ssid(s_wifi);
ssid_data = g_bytes_get_data(ssid, &ssid_len);
rnd = c_siphash_hash(NM_HASH_SEED_16(0x9a,
0xdc, 0xdc,
0x86, 0x86,
0x9a, 0x9a,
@@ -3206,12 +3210,9 @@ ensure_hotspot_frequency(NMDeviceWifi *self, NMSettingWireless *s_wifi, NMWifiAP
0x9f, 0x9f,
0xa8, 0xa8,
0x09, 0x09,
0x2b}; 0x2b),
ssid_data,
/* Calculate a stable "random" number based on the SSID. */ ssid_len);
ssid = nm_setting_wireless_get_ssid(s_wifi);
ssid_data = g_bytes_get_data(ssid, &ssid_len);
rnd = c_siphash_hash(random_seed, ssid_data, ssid_len);
} }
if (nm_streq0(band, "a")) { if (nm_streq0(band, "a")) {

View File

@@ -2711,7 +2711,7 @@ _host_id_read_timestamp(gboolean use_secret_key_file,
#define EPOCH_TWO_YEARS (G_GINT64_CONSTANT(2 * 365 * 24 * 3600) * NM_UTILS_NSEC_PER_SEC) #define EPOCH_TWO_YEARS (G_GINT64_CONSTANT(2 * 365 * 24 * 3600) * NM_UTILS_NSEC_PER_SEC)
v = nm_hash_siphash42(1156657133u, host_id, host_id_len); v = c_siphash_hash(NM_HASH_SEED_16_U64(1156657133u), host_id, host_id_len);
now = time(NULL); now = time(NULL);
*out_timestamp_ns = *out_timestamp_ns =
@@ -3820,7 +3820,7 @@ nm_utils_dhcp_client_id_mac(int arp_type, const guint8 *hwaddr, gsize hwaddr_len
} }
#define HASH_KEY \ #define HASH_KEY \
((const guint8[16]){0x80, \ NM_HASH_SEED_16(0x80, \
0x11, \ 0x11, \
0x8c, \ 0x8c, \
0xc2, \ 0xc2, \
@@ -3835,7 +3835,7 @@ nm_utils_dhcp_client_id_mac(int arp_type, const guint8 *hwaddr, gsize hwaddr_len
0x36, \ 0x36, \
0x39, \ 0x39, \
0x14, \ 0x14, \
0x09}) 0x09)
/** /**
* nm_utils_create_dhcp_iaid: * nm_utils_create_dhcp_iaid:

View File

@@ -391,7 +391,7 @@ _ipv4ll_addrgen(NML3IPv4LL *self, gboolean generate_new_addr)
/* MAC_HASH_KEY is the same as used by systemd. */ /* MAC_HASH_KEY is the same as used by systemd. */
#define MAC_HASH_KEY \ #define MAC_HASH_KEY \
((const guint8[16]){0xdf, \ NM_HASH_SEED_16(0xdf, \
0x04, \ 0x04, \
0x22, \ 0x22, \
0x98, \ 0x98, \
@@ -406,7 +406,7 @@ _ipv4ll_addrgen(NML3IPv4LL *self, gboolean generate_new_addr)
0x9c, \ 0x9c, \
0x70, \ 0x70, \
0xe2, \ 0xe2, \
0xf2}) 0xf2)
if (self->mac_set && (!self->seed_set || !nm_ether_addr_equal(&self->mac, &self->seed_mac))) { if (self->mac_set && (!self->seed_set || !nm_ether_addr_equal(&self->mac, &self->seed_mac))) {
/* systemd's ipv4ll library by default only hashes the MAC address (as we do here). /* systemd's ipv4ll library by default only hashes the MAC address (as we do here).
@@ -466,7 +466,7 @@ _ipv4ll_addrgen(NML3IPv4LL *self, gboolean generate_new_addr)
gen_addr: gen_addr:
#define PICK_HASH_KEY \ #define PICK_HASH_KEY \
((const guint8[16]){0x15, \ NM_HASH_SEED_16(0x15, \
0xac, \ 0xac, \
0x82, \ 0x82, \
0xa6, \ 0xa6, \
@@ -481,7 +481,7 @@ gen_addr:
0x69, \ 0x69, \
0x02, \ 0x02, \
0x94, \ 0x94, \
0x0b}) 0x0b)
h = c_siphash_hash(PICK_HASH_KEY, (const guint8 *) &self->seed, sizeof(self->seed)); h = c_siphash_hash(PICK_HASH_KEY, (const guint8 *) &self->seed, sizeof(self->seed));

View File

@@ -557,6 +557,21 @@ test_nm_hash(void)
#endif #endif
NM_STATIC_ASSERT_EXPR_VOID(NM_HASH_COMBINE_BOOLS(int, 1, 0, 1) == 5); NM_STATIC_ASSERT_EXPR_VOID(NM_HASH_COMBINE_BOOLS(int, 1, 0, 1) == 5);
g_assert_cmpmem(NM_HASH_SEED_16(55, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
16,
((guint8[16]){55, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}),
16);
g_assert_cmpmem(NM_HASH_SEED_16_U64(1), 16, ((guint8[16]){0, 0, 0, 0, 0, 0, 0, 1, 0}), 16);
g_assert_cmpmem(NM_HASH_SEED_16_U64(0x1234567890ABCDEFu),
16,
((guint8[16]){0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0}),
16);
g_assert_cmpint(c_siphash_hash(NM_HASH_SEED_16_U64(0x780E21E45489CC6Fu), (guint8 *) "foo", 3),
==,
0XA5A41E5C1B4153BFu);
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -14,6 +14,30 @@
#define NM_HASH_SEED_16(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af) \ #define NM_HASH_SEED_16(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af) \
((const guint8[16]){a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af}) ((const guint8[16]){a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af})
struct _nm_packed _nm_hash_seed_16_u64_data {
guint64 s1;
guint64 s2;
};
G_STATIC_ASSERT(sizeof(struct _nm_hash_seed_16_u64_data) == 16);
G_STATIC_ASSERT(sizeof(struct _nm_hash_seed_16_u64_data) == sizeof(guint64) * 2);
/* c_siphash_init() has a seed of 16 bytes (NM_HASH_SEED_16()). That is
* cumbersome to use, because we usually just hardcode an arbitrarily chosen,
* fixed number.
*
* This macro takes a u64 (in host-endianness) and returns a 16 byte seed
* buffer. The number will be big endian encoded, to be architecture
* independent. */
#define NM_HASH_SEED_16_U64(u64) \
((const guint8 *) ((gpointer) \
& ((struct _nm_hash_seed_16_u64_data){ \
.s1 = htobe64((u64)), \
.s2 = 0, \
})))
/*****************************************************************************/
void nm_hash_siphash42_init(CSipHash *h, guint static_seed); void nm_hash_siphash42_init(CSipHash *h, guint static_seed);
/* Siphash24 of binary buffer @arr and @len, using the randomized seed from /* Siphash24 of binary buffer @arr and @len, using the randomized seed from
@@ -22,7 +46,7 @@ void nm_hash_siphash42_init(CSipHash *h, guint static_seed);
* Note, that this is guaranteed to use siphash42 under the hood (contrary to * Note, that this is guaranteed to use siphash42 under the hood (contrary to
* all other NMHash API, which leave this undefined). That matters at the point, * all other NMHash API, which leave this undefined). That matters at the point,
* where the caller needs to be sure that a reasonably strong hashing algorithm * where the caller needs to be sure that a reasonably strong hashing algorithm
* is used. (Yes, NMHash is all about siphash24, but otherwise that is not promised * is used. (Yes, NMHash is all about siphash42, but otherwise that is not promised
* anywhere). * anywhere).
* *
* Another difference is, that this returns guint64 (not guint like other NMHash functions). * Another difference is, that this returns guint64 (not guint like other NMHash functions).
@@ -32,6 +56,9 @@ void nm_hash_siphash42_init(CSipHash *h, guint static_seed);
* Then, why not use c_siphash_hash() directly? Because this also uses the randomized, * Then, why not use c_siphash_hash() directly? Because this also uses the randomized,
* per-run hash-seed like nm_hash_init(). So, you get siphash24 with a random * per-run hash-seed like nm_hash_init(). So, you get siphash24 with a random
* seed (which is cached for the current run of the program). * seed (which is cached for the current run of the program).
*
* WARNING: the static_seed gets randomized like with nm_hash*(). If you want a reproducible
* siphash42, use instead `c_siphash_hash(NM_HASH_SEED_16_U64(number), ptr, len)`.
*/ */
static inline guint64 static inline guint64
nm_hash_siphash42(guint static_seed, const void *ptr, gsize n) nm_hash_siphash42(guint static_seed, const void *ptr, gsize n)