Exemplo n.º 1
0
/*
 * Test whether readfd is not set by select when counter value is
 * zero.
 */
static void readfd_not_set_test(int fd)
{
    int ret;
    fd_set readfds;
    struct timeval timeout = { 0, 0 };

    FD_ZERO(&readfds);
    FD_SET(fd, &readfds);

    ret = clear_counter(fd);
    if (ret == -1) {
        tst_resm(TBROK, "error clearing counter");
        return;
    }

    ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
    if (ret == -1) {
        /* EINTR cannot occur, since we don't block. */
        tst_resm(TBROK | TERRNO, "select() failed");
        return;
    }

    if (!FD_ISSET(fd, &readfds))
        tst_resm(TPASS, "fd is not set in readfds");
    else
        tst_resm(TFAIL, "fd is set in readfds");
}
Exemplo n.º 2
0
/*
 * set_counter() - sets the count to specified value
 * @fd: the eventfd
 * @val: the value to be set
 *
 * Clears the counter and sets the counter to @val.
 *
 * RETURNS:
 * 0 on success, -1 on failure
 */
static int set_counter(int fd, uint64_t val)
{
    int ret;

    ret = clear_counter(fd);
    if (ret == -1)
        return -1;

    ret = write(fd, &val, sizeof(val));
    if (ret == -1) {
        tst_resm(TINFO | TERRNO, "error setting counter value");
        return -1;
    }

    return 0;
}
Exemplo n.º 3
0
/*
 * Test whether read returns with error EAGAIN when counter is at 0.
 */
static void read_eagain_test(int fd)
{
    int ret;
    uint64_t val;

    ret = clear_counter(fd);
    if (ret == -1) {
        tst_resm(TBROK, "error clearing counter");
        return;
    }

    ret = read(fd, &val, sizeof(val));
    if (ret == -1) {
        if (errno == EAGAIN)
            tst_resm(TPASS, "read failed with EAGAIN as expected");
        else
            tst_resm(TFAIL | TERRNO, "read failed (wanted EAGAIN)");
    } else
        tst_resm(TFAIL, "read returned with %d", ret);
}
Exemplo n.º 4
0
/*
 * Test wheter write returns with error EINVAL, when the written value
 * is 0xFFFFFFFFFFFFFFFF.
 */
static void write_einval2_test(int fd)
{
    int ret;
    uint64_t val;

    ret = clear_counter(fd);
    if (ret == -1) {
        tst_resm(TBROK, "error clearing counter");
        return;
    }

    val = 0xffffffffffffffffLL;
    ret = write(fd, &val, sizeof(val));
    if (ret == -1) {
        if (errno == EINVAL)
            tst_resm(TPASS, "write failed with EINVAL as expected");
        else
            tst_resm(TFAIL | TERRNO,
                     "write failed (wanted EINVAL)");
    } else {
        tst_resm(TFAIL, "write returned with %d", ret);
    }
}
Exemplo n.º 5
0
static void
reseed(u_int fastslow)
{
	/* Interrupt-context stack is a limited resource; make large
	 * structures static.
	 */
	static uint8_t v[TIMEBIN][KEYSIZE];	/* v[i] */
	static struct randomdev_hash context;
	uint8_t hash[KEYSIZE];			/* h' */
	uint8_t temp[KEYSIZE];
	u_int i;
	enum esource j;

#if 0
	printf("Yarrow: %s reseed\n", fastslow == FAST ? "fast" : "slow");
#endif

	/* The reseed task must not be jumped on */
	mtx_lock(&random_reseed_mtx);

	/* 1. Hash the accumulated entropy into v[0] */

	randomdev_hash_init(&context);
	/* Feed the slow pool hash in if slow */
	if (fastslow == SLOW)
		randomdev_hash_iterate(&context,
			&random_state.pool[SLOW].hash,
			sizeof(struct randomdev_hash));
	randomdev_hash_iterate(&context,
		&random_state.pool[FAST].hash, sizeof(struct randomdev_hash));
	randomdev_hash_finish(&context, v[0]);

	/* 2. Compute hash values for all v. _Supposed_ to be computationally
	 *    intensive.
	 */

	if (random_state.bins > TIMEBIN)
		random_state.bins = TIMEBIN;
	for (i = 1; i < random_state.bins; i++) {
		randomdev_hash_init(&context);
		/* v[i] #= h(v[i - 1]) */
		randomdev_hash_iterate(&context, v[i - 1], KEYSIZE);
		/* v[i] #= h(v[0]) */
		randomdev_hash_iterate(&context, v[0], KEYSIZE);
		/* v[i] #= h(i) */
		randomdev_hash_iterate(&context, &i, sizeof(u_int));
		/* Return the hashval */
		randomdev_hash_finish(&context, v[i]);
	}

	/* 3. Compute a new key; h' is the identity function here;
	 *    it is not being ignored!
	 */

	randomdev_hash_init(&context);
	randomdev_hash_iterate(&context, &random_state.key, KEYSIZE);
	for (i = 1; i < random_state.bins; i++)
		randomdev_hash_iterate(&context, &v[i], KEYSIZE);
	randomdev_hash_finish(&context, temp);
	randomdev_encrypt_init(&random_state.key, temp);

	/* 4. Recompute the counter */

	clear_counter();
	randomdev_encrypt(&random_state.key, random_state.counter.byte, temp, BLOCKSIZE);
	memcpy(random_state.counter.byte, temp, BLOCKSIZE);

	/* 5. Reset entropy estimate accumulators to zero */

	for (i = 0; i <= fastslow; i++)
		for (j = RANDOM_START; j < ENTROPYSOURCE; j++)
			random_state.pool[i].source[j].bits = 0;

	/* 6. Wipe memory of intermediate values */

	memset((void *)v, 0, sizeof(v));
	memset((void *)temp, 0, sizeof(temp));
	memset((void *)hash, 0, sizeof(hash));

	/* 7. Dump to seed file */
	/* XXX Not done here yet */

	/* Unblock the device if it was blocked due to being unseeded */
	randomdev_unblock();

	/* Release the reseed mutex */
	mtx_unlock(&random_reseed_mtx);
}
Exemplo n.º 6
0
void
random_yarrow_init_alg(void)
{
	int i;
#ifndef __OSV__
	struct sysctl_oid *random_yarrow_o;

	/* Yarrow parameters. Do not adjust these unless you have
	 * have a very good clue about what they do!
	 */
	random_yarrow_o = SYSCTL_ADD_NODE(clist,
		SYSCTL_STATIC_CHILDREN(_kern_random),
		OID_AUTO, "yarrow", CTLFLAG_RW, 0,
		"Yarrow Parameters");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"gengateinterval", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.gengateinterval, 10,
		random_check_uint_gengateinterval, "I",
		"Generation gate interval");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"bins", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.bins, 10,
		random_check_uint_bins, "I",
		"Execution time tuner");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"fastthresh", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.pool[0].thresh, (3*(BLOCKSIZE*8))/4,
		random_check_uint_fastthresh, "I",
		"Fast reseed threshold");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"slowthresh", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.pool[1].thresh, (BLOCKSIZE*8),
		random_check_uint_slowthresh, "I",
		"Slow reseed threshold");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"slowoverthresh", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.slowoverthresh, 2,
		random_check_uint_slowoverthresh, "I",
		"Slow over-threshold reseed");
#endif
	random_state.gengateinterval = 10;
	random_state.bins = 10;
	random_state.pool[0].thresh = (3*(BLOCKSIZE*8))/4;
	random_state.pool[1].thresh = (BLOCKSIZE*8);
	random_state.slowoverthresh = 2;
	random_state.which = FAST;

	/* Initialise the fast and slow entropy pools */
	for (i = 0; i < 2; i++)
		randomdev_hash_init(&random_state.pool[i].hash);

	/* Clear the counter */
	clear_counter();

	/* Set up a lock for the reseed process */
	mtx_init(&random_reseed_mtx, "Yarrow reseed", NULL, MTX_DEF);
}