bool RSSIData_from_bytes(RSSIData *msg, const char *buf, uint32_t *seq_out) { size_t offset = sizeof(msg->magic) + sizeof(msg->siphash); memmove((void *)msg, (void *)buf, sizeof(*msg)); *seq_out = msg->seq; return (siphash24(((char *)msg) + offset, sizeof(*msg) - offset, "scary spooky skeletons") == msg->siphash); }
void hashtable_del(struct hashtable *const hashtable, const void *const key) { const uint64_t hash = siphash24(key, hashtable->key_len, hashtable->key); struct hashlist *entry; for(entry = hashtable->table[hash & hashtable->mask]; entry != NULL; entry = entry->next) { if(memcmp(key, entry->key, hashtable->key_len) == 0) { if(entry->prev == NULL) { hashtable->table[hash & hashtable->mask] = entry->next; } else { entry->prev->next = entry->next; } if(entry->next != NULL) { entry->next->prev = entry->prev; } break; } } }
void RSSIData_to_bytes(RSSIData *msg, char *buf, uint32_t seq) { size_t offset = sizeof(msg->magic) + sizeof(msg->siphash); msg->seq = seq; msg->siphash = siphash24(((char *)msg) + offset, sizeof(*msg) - offset, "scary spooky skeletons"); memmove((void *)buf, (void *)msg, sizeof(*msg)); }
static uint64_t hash64( const char *buf, size_t len ) { /* http://www.random.org/cgi-bin/randbyte?nbytes=16&format=h */ char key[16] = { 0xf5, 0x7c, 0x53, 0x74, 0x92, 0x23, 0x39, 0x7c, 0xcd, 0xe9, 0x05, 0xfb, 0xc0, 0xf1, 0x3a, 0xc6 }; return siphash24( buf, len, key ); }
void WiFlyStringWireFormat_to_bytes(WiFlyStringWireFormat *msg, char *buf, uint32_t seq) { size_t offset = sizeof(msg->magic) + sizeof(msg->siphash); msg->seq = seq; msg->siphash = siphash24(((char *)msg) + offset, sizeof(*msg) - offset, "scary spooky skeletons"); memmove((void *)buf, (void *)msg, sizeof(*msg)); }
unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) { const DnsServer *s = p; uint64_t u; siphash24((uint8_t*) &u, &s->address, FAMILY_ADDRESS_SIZE(s->family), hash_key); u = u * hash_key[0] + u + s->family; return u; }
int hsearch_r(ENTRY item, ACTION action, ENTRY** retval, struct hsearch_data* htab) { uint64_t hv=siphash24(htab->key,(const unsigned char*)item.key,strlen(item.key)); struct bucket** b=&htab->table[hv%htab->size]; while (*b) { if ((*b)->hv==hv && !strcmp((*b)->e.key,item.key)) { /* found */ if (retval) *retval=&(*b)->e; return 1; } b=(&(*b)->next); } if (action==FIND) { errno=ESRCH; return 0; } /* if we get this far, we are supposed to add the key */ if (htab -> size < primes[nprimes-1] && htab->filled+1 > htab->size) { /* attempt to resize */ unsigned int i; struct bucket** n; for (i=0; i<nprimes; ++i) if (htab->size < primes[i]) break; i=primes[i]; n=calloc(i,sizeof(struct bucket*)); /* If the allocation failed, we can just limp on. * Performance will be reduced but we'll live. */ if (n) { unsigned int j; for (j=0; j<htab->size; ++j) { struct bucket* B=htab->table[j]; while (B) { struct bucket* c=B; B=B->next; unsigned int m=c->hv % i; c->next=n[m]; n[m]=c; } } free(htab->table); htab->table=n; htab->size=i; b=&htab->table[hv%htab->size]; while (*b) b=(&(*b)->next); } } *b=malloc(sizeof(struct bucket)); if (!*b) return 0; ++htab->filled; (*b)->next=0; (*b)->e=item; (*b)->hv=hv; if (retval) *retval=&(*b)->e; return 1; }
uint64_t siphash24_secure(const void *data, size_t len) { static bool initialized; static uint64_t k0, k1; if (!initialized) { k0 = ((uint64_t)csrandom() << 32) | csrandom(); k1 = ((uint64_t)csrandom() << 32) | csrandom(); initialized = true; } return siphash24(data, len, k0, k1); }
void hash(int key_type, char *msg, int msg_len, u64 *res){ char *ptr; if(key_type == KEY_NAME){ ptr = "key for name\x00\x00\x00\x00"; } else if(key_type == KEY_SERIAL){ ptr = "key for serial\x00\x00"; } else{ assert(0); } siphash24((uint8_t*)ptr, msg, msg_len, (uint8_t*)res); }
int main(void) { uint64_t k0 = 0x0706050403020100ull; uint64_t k1 = 0x0f0e0d0c0b0a0908ull; uint8_t msg[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e}; uint64_t s = siphash24(k0, k1, msg, sizeof(msg)); printf("SipHash-2-4 test: 0x%016llx (expected 0x%016llx)\n", s, 0xa129ca6149be45e5ull); return 0; }
static unsigned long catalog_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) { const CatalogItem *i = p; uint64_t u; size_t l, sz; void *v; l = strlen(i->language); sz = sizeof(i->id) + l; v = alloca(sz); memcpy(mempcpy(v, &i->id, sizeof(i->id)), i->language, l); siphash24((uint8_t*) &u, v, sz, hash_key); return (unsigned long) u; }
void * hashtable_get(const struct hashtable *const hashtable, const void *const key) { const uint64_t hash = siphash24(key, hashtable->key_len, hashtable->key); struct hashlist *entry; for(entry = hashtable->table[hash & hashtable->mask]; entry != NULL; entry = entry->next) { if(memcmp(key, entry->key, hashtable->key_len) == 0) { break; } } return entry; }
int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) { int r; assert_return(ll, -EINVAL); if (!ll->random_data) { uint64_t seed; /* If no random data is set, generate some from the MAC */ seed = siphash24(&addr->ether_addr_octet, ETH_ALEN, HASH_KEY.bytes); assert_cc(sizeof(unsigned) <= 8); r = sd_ipv4ll_set_address_seed(ll, (unsigned) htole64(seed)); if (r < 0) return r; } return sd_ipv4acd_set_mac(ll->acd, addr); }
int main() { int i; char key[16] = {0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf}; char plaintext[64]; for (i=0; i<64; i++) plaintext[i] = i; int j; uint64_t t0, t1; t0 = gettime_ns(); for (j=0; j<REPEATS; j++){ for (i=0; i<64; i++) { assert(siphash24(plaintext, i, key) == vectors[i]); } } t1 = gettime_ns(); printf("%i tests passed in %.3fms, %.0fns per test\n", REPEATS*64, (t1-t0)/1000000., (t1-t0)/(REPEATS*64.)); return 0; }
/* This is temporary. I've added this because I don't want to 'fix' the hash api when it's going to be removed soon. */ static void apache_add_unique_hash_entry(const char *sipkey, lily_hash_val *hash_val, lily_value *pair_key, lily_value *pair_value) { lily_hash_elem *elem = lily_malloc(sizeof(lily_hash_elem)); uint64_t key_siphash = siphash24(pair_key->value.string->string, pair_key->value.string->size, sipkey); elem->key_siphash = key_siphash; elem->elem_key = pair_key; elem->elem_value = pair_value; if (hash_val->elem_chain) hash_val->elem_chain->prev = elem; elem->prev = NULL; elem->next = hash_val->elem_chain; hash_val->elem_chain = elem; hash_val->num_elems++; }
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) { sd_id128_t machine_id; int r; assert(duid); assert(len); r = sd_id128_get_machine(&machine_id); if (r < 0) return r; duid->type = htobe16(DHCP6_DUID_EN); duid->en.pen = htobe32(SYSTEMD_PEN); *len = sizeof(duid->type) + sizeof(duid->en); /* a bit of snake-oil perhaps, but no need to expose the machine-id directly */ siphash24(duid->en.id, &machine_id, sizeof(machine_id), HASH_KEY.bytes); return 0; }
static int do_test(const uint8_t *in, size_t len, const uint8_t *key) { struct siphash state = {}; uint64_t out = 0; unsigned i, j; out = siphash24(in, len, key); assert_se(out == 0xa129ca6149be45e5); /* verify the internal state as given in the above paper */ siphash24_init(&state, key); assert_se(state.v0 == 0x7469686173716475); assert_se(state.v1 == 0x6b617f6d656e6665); assert_se(state.v2 == 0x6b7f62616d677361); assert_se(state.v3 == 0x7b6b696e727e6c7b); siphash24_compress(in, len, &state); assert_se(state.v0 == 0x4a017198de0a59e0); assert_se(state.v1 == 0x0d52f6f62a4f59a4); assert_se(state.v2 == 0x634cb3577b01fd3d); assert_se(state.v3 == 0xa5224d6f55c7d9c8); out = siphash24_finalize(&state); assert_se(out == 0xa129ca6149be45e5); assert_se(state.v0 == 0xf6bcd53893fecff1); assert_se(state.v1 == 0x54b9964c7ea0d937); assert_se(state.v2 == 0x1b38329c099bb55a); assert_se(state.v3 == 0x1814bb89ad7be679); /* verify that decomposing the input in three chunks gives the same result */ for (i = 0; i < len; i++) { for (j = i; j < len; j++) { siphash24_init(&state, key); siphash24_compress(in, i, &state); siphash24_compress(&in[i], j - i, &state); siphash24_compress(&in[j], len - j, &state); out = siphash24_finalize(&state); assert_se(out == 0xa129ca6149be45e5); } } return 0; }
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) { sd_id128_t machine_id; uint64_t hash; int r; assert(duid); assert(len); r = sd_id128_get_machine(&machine_id); if (r < 0) return r; unaligned_write_be16(&duid->type, DUID_TYPE_EN); unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN); *len = sizeof(duid->type) + sizeof(duid->en); /* a bit of snake-oil perhaps, but no need to expose the machine-id directly; duid->en.id might not be aligned, so we need to copy */ hash = htole64(siphash24(&machine_id, sizeof(machine_id), HASH_KEY.bytes)); memcpy(duid->en.id, &hash, sizeof(duid->en.id)); return 0; }
void hashtable_add(struct hashtable *const hashtable, const void *const key, void *const elem) { const uint64_t hash = siphash24(key, hashtable->key_len, hashtable->key); struct hashlist *entry; entry = hashtable->table[hash & hashtable->mask]; if(entry == NULL) { hashtable->table[hash & hashtable->mask] = elem; ((struct hashlist *) elem)->prev = NULL; } else { while(entry->next != NULL) { entry = entry->next; } entry->next = elem; ((struct hashlist *) elem)->prev = entry; } ((struct hashlist *) elem)->next = NULL; }
/** * InternalObjectIndexHash * * Given an object, this function will calculate a hash to speed-up * lookup. */ uint64_t ctr_internal_index_hash(ctr_object* key) { ctr_object* stringKey = ctr_internal_cast2string(key); return siphash24(stringKey->value.svalue->value, stringKey->value.svalue->vlen, CtrHashKey); }
int sd_ipv4ll_start (sd_ipv4ll *ll) { int r; assert_return(ll, -EINVAL); assert_return(ll->event, -EINVAL); assert_return(ll->index > 0, -EINVAL); assert_return(IN_SET(ll->state, IPV4LL_STATE_INIT, IPV4LL_STATE_STOPPED), -EBUSY); ll->state = IPV4LL_STATE_INIT; r = arp_network_bind_raw_socket(ll->index, &ll->link); if (r < 0) goto out; ll->fd = r; ll->conflict = 0; ll->defend_window = 0; ll->claimed_address = 0; if (!ll->random_data) { uint8_t seed[8]; /* Fallback to mac */ siphash24(seed, &ll->mac_addr.ether_addr_octet, ETH_ALEN, HASH_KEY.bytes); r = sd_ipv4ll_set_address_seed(ll, seed); if (r < 0) goto out; } if (ll->address == 0) { r = ipv4ll_pick_address(ll, &ll->address); if (r < 0) goto out; } ipv4ll_set_state (ll, IPV4LL_STATE_INIT, 1); r = sd_event_add_io(ll->event, &ll->receive_message, ll->fd, EPOLLIN, ipv4ll_receive_message, ll); if (r < 0) goto out; r = sd_event_source_set_priority(ll->receive_message, ll->event_priority); if (r < 0) goto out; r = sd_event_source_set_description(ll->receive_message, "ipv4ll-receive-message"); if (r < 0) goto out; r = sd_event_add_time(ll->event, &ll->timer, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()), 0, ipv4ll_timer, ll); if (r < 0) goto out; r = sd_event_source_set_priority(ll->timer, ll->event_priority); if (r < 0) goto out; r = sd_event_source_set_description(ll->timer, "ipv4ll-timer"); out: if (r < 0) ipv4ll_stop(ll, IPV4LL_EVENT_STOP); return 0; }
uint64_t siphash24g(const void *src, unsigned long src_sz) { tor_assert(the_siphash_key_is_set); return siphash24(src, src_sz, &the_siphash_key); }
static int pick_uid(char **suggested_paths, const char *name, uid_t *ret_uid) { /* Find a suitable free UID. We use the following strategy to find a suitable UID: * * 1. Initially, we try to read the UID of a number of specified paths. If any of these UIDs works, we use * them. We use in order to increase the chance of UID reuse, if StateDirectory=, CacheDirectory= or * LogsDirectory= are used, as reusing the UID these directories are owned by saves us from having to * recursively chown() them to new users. * * 2. If that didn't yield a currently unused UID, we hash the user name, and try to use that. This should be * pretty good, as the use ris by default derived from the unit name, and hence the same service and same * user should usually get the same UID as long as our hashing doesn't clash. * * 3. Finally, if that didn't work, we randomly pick UIDs, until we find one that is empty. * * Since the dynamic UID space is relatively small we'll stop trying after 100 iterations, giving up. */ enum { PHASE_SUGGESTED, /* the first phase, reusing directory ownership UIDs */ PHASE_HASHED, /* the second phase, deriving a UID from the username by hashing */ PHASE_RANDOM, /* the last phase, randomly picking UIDs */ } phase = PHASE_SUGGESTED; static const uint8_t hash_key[] = { 0x37, 0x53, 0x7e, 0x31, 0xcf, 0xce, 0x48, 0xf5, 0x8a, 0xbb, 0x39, 0x57, 0x8d, 0xd9, 0xec, 0x59 }; unsigned n_tries = 100, current_suggested = 0; int r; (void) mkdir("/run/systemd/dynamic-uid", 0755); for (;;) { char lock_path[STRLEN("/run/systemd/dynamic-uid/") + DECIMAL_STR_MAX(uid_t) + 1]; _cleanup_close_ int lock_fd = -1; uid_t candidate; ssize_t l; if (--n_tries <= 0) /* Give up retrying eventually */ return -EBUSY; switch (phase) { case PHASE_SUGGESTED: { struct stat st; if (!suggested_paths || !suggested_paths[current_suggested]) { /* We reached the end of the suggested paths list, let's try by hashing the name */ phase = PHASE_HASHED; continue; } if (stat(suggested_paths[current_suggested++], &st) < 0) continue; /* We can't read the UID of this path, but that doesn't matter, just try the next */ candidate = st.st_uid; break; } case PHASE_HASHED: /* A static user by this name does not exist yet. Let's find a free ID then, and use that. We * start with a UID generated as hash from the user name. */ candidate = UID_CLAMP_INTO_RANGE(siphash24(name, strlen(name), hash_key)); /* If this one fails, we should proceed with random tries */ phase = PHASE_RANDOM; break; case PHASE_RANDOM: /* Pick another random UID, and see if that works for us. */ random_bytes(&candidate, sizeof(candidate)); candidate = UID_CLAMP_INTO_RANGE(candidate); break; default: assert_not_reached("unknown phase"); } /* Make sure whatever we picked here actually is in the right range */ if (!uid_is_dynamic(candidate)) continue; xsprintf(lock_path, "/run/systemd/dynamic-uid/" UID_FMT, candidate); for (;;) { struct stat st; lock_fd = open(lock_path, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600); if (lock_fd < 0) return -errno; r = flock(lock_fd, LOCK_EX|LOCK_NB); /* Try to get a BSD file lock on the UID lock file */ if (r < 0) { if (IN_SET(errno, EBUSY, EAGAIN)) goto next; /* already in use */ return -errno; } if (fstat(lock_fd, &st) < 0) return -errno; if (st.st_nlink > 0) break; /* Oh, bummer, we got the lock, but the file was unlinked between the time we opened it and * got the lock. Close it, and try again. */ lock_fd = safe_close(lock_fd); } /* Some superficial check whether this UID/GID might already be taken by some static user */ if (getpwuid(candidate) || getgrgid((gid_t) candidate) || search_ipc(candidate, (gid_t) candidate) != 0) { (void) unlink(lock_path); continue; } /* Let's store the user name in the lock file, so that we can use it for looking up the username for a UID */ l = pwritev(lock_fd, (struct iovec[2]) { IOVEC_INIT_STRING(name), IOVEC_INIT((char[1]) { '\n' }, 1), }, 2, 0);