Exemple #1
0
/*
 * update pools
 */
static void
add_entropy(FState *st, const uint8 *data, unsigned len)
{
	unsigned	pos;
	uint8		hash[BLOCK];
	MD_CTX		md;

	/* hash given data */
	md_init(&md);
	md_update(&md, data, len);
	md_result(&md, hash);

	/*
	 * Make sure the pool 0 is initialized, then update randomly.
	 */
	if (st->reseed_count == 0)
		pos = 0;
	else
		pos = get_rand_pool(st);
	md_update(&st->pool[pos], hash, BLOCK);

	if (pos == 0)
		st->pool0_bytes += len;

	px_memset(hash, 0, BLOCK);
	px_memset(&md, 0, sizeof(md));
}
Exemple #2
0
static void
hmac_free(PX_HMAC *h)
{
	unsigned	bs;

	bs = px_md_block_size(h->md);
	px_md_free(h->md);

	px_memset(h->p.ipad, 0, bs);
	px_memset(h->p.opad, 0, bs);
	px_free(h->p.ipad);
	px_free(h->p.opad);
	px_free(h);
}
Exemple #3
0
static void
hmac_init(PX_HMAC *h, const uint8 *key, unsigned klen)
{
	unsigned	bs,
				i;
	uint8	   *keybuf;
	PX_MD	   *md = h->md;

	bs = px_md_block_size(md);
	keybuf = px_alloc(bs);
	memset(keybuf, 0, bs);

	if (klen > bs)
	{
		px_md_update(md, key, klen);
		px_md_finish(md, keybuf);
		px_md_reset(md);
	}
	else
		memcpy(keybuf, key, klen);

	for (i = 0; i < bs; i++)
	{
		h->p.ipad[i] = keybuf[i] ^ HMAC_IPAD;
		h->p.opad[i] = keybuf[i] ^ HMAC_OPAD;
	}

	px_memset(keybuf, 0, bs);
	px_free(keybuf);

	px_md_update(md, h->p.ipad, bs);
}
Exemple #4
0
/*
 * The time between reseed must be at least RESEED_INTERVAL
 * microseconds.
 */
static int
enough_time_passed(FState *st)
{
	int			ok;
	struct timeval tv;
	struct timeval *last = &st->last_reseed_time;

	gettimeofday(&tv, NULL);

	/* check how much time has passed */
	ok = 0;
	if (tv.tv_sec > last->tv_sec + 1)
		ok = 1;
	else if (tv.tv_sec == last->tv_sec + 1)
	{
		if (1000000 + tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
			ok = 1;
	}
	else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
		ok = 1;

	/* reseed will happen, update last_reseed_time */
	if (ok)
		memcpy(last, &tv, sizeof(tv));

	px_memset(&tv, 0, sizeof(tv));

	return ok;
}
Exemple #5
0
void
pgp_cfb_free(PGP_CFB *ctx)
{
	px_cipher_free(ctx->ciph);
	px_memset(ctx, 0, sizeof(*ctx));
	px_free(ctx);
}
Exemple #6
0
static void
combo_free(PX_Combo *cx)
{
	if (cx->cipher)
		px_cipher_free(cx->cipher);
	px_memset(cx, 0, sizeof(*cx));
	px_free(cx);
}
Exemple #7
0
static void
int_md5_free(PX_MD *h)
{
	MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;

	px_memset(ctx, 0, sizeof(*ctx));
	px_free(ctx);
	px_free(h);
}
Exemple #8
0
int
pgp_free(PGP_Context *ctx)
{
	if (ctx->pub_key)
		pgp_key_free(ctx->pub_key);
	px_memset(ctx, 0, sizeof *ctx);
	px_free(ctx);
	return 0;
}
Exemple #9
0
static void
md_result(MD_CTX * ctx, uint8 *dst)
{
	SHA256_CTX	tmp;

	memcpy(&tmp, ctx, sizeof(*ctx));
	SHA256_Final(dst, &tmp);
	px_memset(&tmp, 0, sizeof(tmp));
}
Exemple #10
0
static void
int_sha224_free(PX_MD *h)
{
	SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;

	px_memset(ctx, 0, sizeof(*ctx));
	px_free(ctx);
	px_free(h);
}
Exemple #11
0
static void
gen_ossl_free(PX_Cipher *c)
{
	ossldata   *od = (ossldata *) c->ptr;

	EVP_CIPHER_CTX_cleanup(&od->evp_ctx);
	px_memset(od, 0, sizeof(*od));
	px_free(od);
	px_free(c);
}
Exemple #12
0
/*
 * generate new key from all the pools
 */
static void
reseed(FState *st)
{
	unsigned	k;
	unsigned	n;
	MD_CTX		key_md;
	uint8		buf[BLOCK];

	/* set pool as empty */
	st->pool0_bytes = 0;

	/*
	 * Both #0 and #1 reseed would use only pool 0. Just skip #0 then.
	 */
	n = ++st->reseed_count;

	/*
	 * The goal: use k-th pool only 1/(2^k) of the time.
	 */
	md_init(&key_md);
	for (k = 0; k < NUM_POOLS; k++)
	{
		md_result(&st->pool[k], buf);
		md_update(&key_md, buf, BLOCK);

		if (n & 1 || !n)
			break;
		n >>= 1;
	}

	/* add old key into mix too */
	md_update(&key_md, st->key, BLOCK);

	/* now we have new key */
	md_result(&key_md, st->key);

	/* use new key */
	ciph_init(&st->ciph, st->key, BLOCK);

	px_memset(&key_md, 0, sizeof(key_md));
	px_memset(buf, 0, BLOCK);
}
Exemple #13
0
static void
intctx_free(PX_Cipher *c)
{
	struct int_ctx *cx = (struct int_ctx *) c->ptr;

	if (cx)
	{
		px_memset(cx, 0, sizeof *cx);
		px_free(cx);
	}
	px_free(c);
}
/*
 * Mix a block of data into RNG.
 */
static void
add_block_entropy(PX_MD *md, text *data)
{
	uint8		sha1[20];

	px_md_reset(md);
	px_md_update(md, (uint8 *) VARDATA(data), VARSIZE(data) - VARHDRSZ);
	px_md_finish(md, sha1);

	px_add_entropy(sha1, 20);

	px_memset(sha1, 0, 20);
}
Exemple #15
0
static void
system_reseed(void)
{
	uint8		buf[1024];
	int			n;
	time_t		t;
	int			skip = 1;

	t = time(NULL);

	if (seed_time == 0)
		skip = 0;
	else if ((t - seed_time) < SYSTEM_RESEED_MIN)
		skip = 1;
	else if ((t - seed_time) > SYSTEM_RESEED_MAX)
		skip = 0;
	else if (check_time == 0 ||
			 (t - check_time) > SYSTEM_RESEED_CHECK_TIME)
	{
		check_time = t;

		/* roll dice */
		px_get_random_bytes(buf, 1);
		skip = buf[0] >= SYSTEM_RESEED_CHANCE;
	}
	/* clear 1 byte */
	px_memset(buf, 0, sizeof(buf));

	if (skip)
		return;

	n = px_acquire_system_randomness(buf);
	if (n > 0)
		fortuna_add_entropy(buf, n);

	seed_time = t;
	px_memset(buf, 0, sizeof(buf));
}
Exemple #16
0
static int
calc_s2k_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
{
	unsigned	md_rlen;
	uint8		buf[PGP_MAX_DIGEST];
	unsigned	preload = 0;
	uint8	   *dst;
	unsigned	remain;

	md_rlen = px_md_result_size(md);

	dst = s2k->key;
	remain = s2k->key_len;
	while (remain > 0)
	{
		px_md_reset(md);

		if (preload > 0)
		{
			memset(buf, 0, preload);
			px_md_update(md, buf, preload);
		}
		preload++;

		px_md_update(md, s2k->salt, PGP_S2K_SALT);
		px_md_update(md, key, key_len);
		px_md_finish(md, buf);

		if (remain > md_rlen)
		{
			memcpy(dst, buf, md_rlen);
			remain -= md_rlen;
			dst += md_rlen;
		}
		else
		{
			memcpy(dst, buf, remain);
			remain = 0;
		}
	}
	px_memset(buf, 0, sizeof(buf));
	return 0;
}
Exemple #17
0
static void
hmac_finish(PX_HMAC *h, uint8 *dst)
{
	PX_MD	   *md = h->md;
	unsigned	bs,
				hlen;
	uint8	   *buf;

	bs = px_md_block_size(md);
	hlen = px_md_result_size(md);

	buf = px_alloc(hlen);

	px_md_finish(md, buf);

	px_md_reset(md);
	px_md_update(md, h->p.opad, bs);
	px_md_update(md, buf, hlen);
	px_md_finish(md, dst);

	px_memset(buf, 0, hlen);
	px_free(buf);
}
/*
 * Mix user data into RNG.  It is for user own interests to have
 * RNG state shuffled.
 */
static void
add_entropy(text *data1, text *data2, text *data3)
{
	PX_MD	   *md;
	uint8		rnd[3];

	if (!data1 && !data2 && !data3)
		return;

	if (px_get_random_bytes(rnd, 3) < 0)
		return;

	if (px_find_digest("sha1", &md) < 0)
		return;

	/*
	 * Try to make the feeding unpredictable.
	 *
	 * Prefer data over keys, as it's rather likely that key is same in
	 * several calls.
	 */

	/* chance: 7/8 */
	if (data1 && rnd[0] >= 32)
		add_block_entropy(md, data1);

	/* chance: 5/8 */
	if (data2 && rnd[1] >= 160)
		add_block_entropy(md, data2);

	/* chance: 5/8 */
	if (data3 && rnd[2] >= 160)
		add_block_entropy(md, data3);

	px_md_free(md);
	px_memset(rnd, 0, sizeof(rnd));
}
Exemple #19
0
/*
 * Hide public constants. (counter, pools > 0)
 *
 * This can also be viewed as spreading the startup
 * entropy over all of the components.
 */
static void
startup_tricks(FState *st)
{
	int			i;
	uint8		buf[BLOCK];

	/* Use next block as counter. */
	encrypt_counter(st, st->counter);

	/* Now shuffle pools, excluding #0 */
	for (i = 1; i < NUM_POOLS; i++)
	{
		encrypt_counter(st, buf);
		encrypt_counter(st, buf + CIPH_BLOCK);
		md_update(&st->pool[i], buf, BLOCK);
	}
	px_memset(buf, 0, BLOCK);

	/* Hide the key. */
	rekey(st);

	/* This can be done only once. */
	st->tricks_done = 1;
}
Exemple #20
0
int
px_gen_salt(const char *salt_type, char *buf, int rounds)
{
	int			res;
	struct generator *g;
	char	   *p;
	char		rbuf[16];

	for (g = gen_list; g->name; g++)
		if (pg_strcasecmp(g->name, salt_type) == 0)
			break;

	if (g->name == NULL)
		return PXE_UNKNOWN_SALT_ALGO;

	if (g->def_rounds)
	{
		if (rounds == 0)
			rounds = g->def_rounds;

		if (rounds < g->min_rounds || rounds > g->max_rounds)
			return PXE_BAD_SALT_ROUNDS;
	}

	res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
	if (res < 0)
		return res;

	p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
	px_memset(rbuf, 0, sizeof(rbuf));

	if (p == NULL)
		return PXE_BAD_SALT_ROUNDS;

	return strlen(p);
}
static void
clear_and_pfree(text *p)
{
	px_memset(p, 0, VARSIZE(p));
	pfree(p);
}
Exemple #22
0
static int
calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
					 unsigned key_len)
{
	unsigned	md_rlen;
	uint8		buf[PGP_MAX_DIGEST];
	uint8	   *dst;
	unsigned	preload = 0;
	unsigned	remain,
				c,
				curcnt,
				count;

	count = s2k_decode_count(s2k->iter);

	md_rlen = px_md_result_size(md);

	remain = s2k->key_len;
	dst = s2k->key;
	while (remain > 0)
	{
		px_md_reset(md);

		if (preload)
		{
			memset(buf, 0, preload);
			px_md_update(md, buf, preload);
		}
		preload++;

		px_md_update(md, s2k->salt, PGP_S2K_SALT);
		px_md_update(md, key, key_len);
		curcnt = PGP_S2K_SALT + key_len;

		while (curcnt < count)
		{
			if (curcnt + PGP_S2K_SALT < count)
				c = PGP_S2K_SALT;
			else
				c = count - curcnt;
			px_md_update(md, s2k->salt, c);
			curcnt += c;

			if (curcnt + key_len < count)
				c = key_len;
			else if (curcnt < count)
				c = count - curcnt;
			else
				break;
			px_md_update(md, key, c);
			curcnt += c;
		}
		px_md_finish(md, buf);

		if (remain > md_rlen)
		{
			memcpy(dst, buf, md_rlen);
			remain -= md_rlen;
			dst += md_rlen;
		}
		else
		{
			memcpy(dst, buf, remain);
			remain = 0;
		}
	}
	px_memset(buf, 0, sizeof(buf));
	return 0;
}