Example #1
0
/**
 * Hash key.
 *
 * This is the trapping function we're installing for our hash set, which will
 * dereference the pointer field of the user's key within the value and hash it.
 */
static uint
hikset_key_hash(const void *value, void *data)
{
	hikset_t *hik = data;
	const void * const *key = value;

	hikset_check(hik);

	return NULL == hik->ihash ?
		binary_hash(*key, hik->uik.keysize) :
		(*hik->ihash)(*key);
}
Example #2
0
/**
 * Hashing of host_addr_t.
 */
unsigned
host_addr_hash(host_addr_t ha)
{
	switch (ha.net) {
	case NET_TYPE_IPV6:
		{
			host_addr_t ha_ipv4;

			if (!host_addr_convert(ha, &ha_ipv4, NET_TYPE_IPV4))
				return binary_hash(&ha.addr.ipv6[0], sizeof ha.addr.ipv6);
			ha = ha_ipv4;
		}
		/* FALL THROUGH */
	case NET_TYPE_IPV4:
		return ha.net ^ integer_hash(host_addr_ipv4(ha));
	case NET_TYPE_LOCAL:
	case NET_TYPE_NONE:
		return ha.net;
	}
	g_assert_not_reached();
	return (unsigned) -1;
}
Example #3
0
/**
 * Create a security token from host address and port using specified key.
 *
 * Optionally, extra contextual data may be given (i.e. the token is not
 * only based on the address and port) to make the token more unique to
 * a specific context.
 *
 * @param stg		the security token generator
 * @param n			key index to use
 * @param tok		where security token is written
 * @param addr		address of the host for which we're generating a token
 * @param port		port of the host for which we're generating a token
 * @param data		optional contextual data
 * @param len		length of contextual data
 */
static void
sectoken_generate_n(sectoken_gen_t *stg, size_t n,
	sectoken_t *tok, host_addr_t addr, uint16 port,
	const void *data, size_t len)
{
	char block[8];
	char enc[8];
	char *p = block;

	sectoken_gen_check(stg);
	g_assert(tok != NULL);
	g_assert(size_is_non_negative(n));
	g_assert(n < stg->keycnt);
	g_assert((NULL != data) == (len != 0));

	switch (host_addr_net(addr)) {
	case NET_TYPE_IPV4:
		p = poke_be32(p, host_addr_ipv4(addr));
		break;
	case NET_TYPE_IPV6:
		{
			uint val;

			val = binary_hash(host_addr_ipv6(&addr), 16);
			p = poke_be32(p, val);
		}
		break;
	case NET_TYPE_LOCAL:
	case NET_TYPE_NONE:
		g_error("unexpected address for security token generation: %s",
			host_addr_to_string(addr));
	}

	p = poke_be16(p, port);
	p = poke_be16(p, 0);		/* Filler */

	g_assert(p == &block[8]);

	STATIC_ASSERT(sizeof(tok->v) == sizeof(uint32));
	STATIC_ASSERT(sizeof(block) == sizeof(enc));

	tea_encrypt(&stg->keys[n], enc, block, sizeof block);

	/*
	 * If they gave contextual data, encrypt them by block of 8 bytes,
	 * filling the last partial block with zeroes if needed.
	 */

	if (data != NULL) {
		const void *q = data;
		size_t remain = len;
		char denc[8];

		STATIC_ASSERT(sizeof(denc) == sizeof(enc));

		while (remain != 0) {
			size_t fill = MIN(remain, 8U);
			unsigned i;

			if (fill != 8U)
				ZERO(&block);

			memcpy(block, q, fill);
			remain -= fill;
			q = const_ptr_add_offset(q, fill);

			/*
			 * Encrypt block of contextual data (possibly filled with trailing
			 * zeroes) and merge back the result into the main encryption
			 * output with XOR.
			 */

			tea_encrypt(&stg->keys[n], denc, block, sizeof block);

			for (i = 0; i < sizeof denc; i++)
				enc[i] ^= denc[i];
		}
	}

	poke_be32(tok->v, tea_squeeze(enc, sizeof enc));
}
Example #4
0
/**
 * Hash a KUID.
 */
unsigned
kuid_hash(const void *key)
{
	return binary_hash(key, KUID_RAW_SIZE);
}