Exemplo n.º 1
0
static void
bcmrng_get(struct bcm2835rng_softc *sc)
{
    uint32_t status, cnt;
    uint32_t buf[RNG_DATA_MAX]; /* 1k on the stack */

    mutex_spin_enter(&sc->sc_intr_lock);
    while (sc->sc_bytes_wanted) {
        status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS);
        cnt = __SHIFTOUT(status, RNG_STATUS_CNT);
        KASSERT(cnt < RNG_DATA_MAX);
        if (cnt == 0)
            continue;	/* XXX Busy-waiting seems wrong...  */
        bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, RNG_DATA, buf,
                               cnt);

        /*
         * This lock dance is necessary because rnd_add_data
         * may call bcmrng_get_cb which takes the intr lock.
         */
        mutex_spin_exit(&sc->sc_intr_lock);
        mutex_spin_enter(&sc->sc_rnd_lock);
        rnd_add_data(&sc->sc_rndsource, buf, (cnt * 4),
                     (cnt * 4 * NBBY));
        mutex_spin_exit(&sc->sc_rnd_lock);
        mutex_spin_enter(&sc->sc_intr_lock);
        sc->sc_bytes_wanted -= MIN(sc->sc_bytes_wanted, (cnt * 4));
    }
    explicit_memset(buf, 0, sizeof(buf));
    mutex_spin_exit(&sc->sc_intr_lock);
}
Exemplo n.º 2
0
static void
feedrandom(size_t bytes, void *arg)
{
	uint8_t *rnddata;
	size_t dsize;

	rnddata = kmem_intr_alloc(MAXGET, KM_SLEEP);
	if (rumpuser_getrandom(rnddata, MIN(MAXGET, bytes),
	    RUMPUSER_RANDOM_HARD|RUMPUSER_RANDOM_NOWAIT, &dsize) == 0)
		rnd_add_data(&rndsrc, rnddata, dsize, NBBY*dsize);
	kmem_intr_free(rnddata, MAXGET);
}
Exemplo n.º 3
0
static void kprintf_rnd_get(size_t bytes, void *priv)
{
	if (kprnd_added)  {
		KASSERT(kprintf_inited);
		if (mutex_tryenter(&kprintf_mtx)) {
			SHA512_Final(kprnd_accum, &kprnd_sha);
			rnd_add_data(&rnd_printf_source,
				     kprnd_accum, sizeof(kprnd_accum), 0);
			kprnd_added = 0;
			/* This, we must do, since we called _Final. */
			SHA512_Init(&kprnd_sha);
			/* This is optional but seems useful. */
			SHA512_Update(&kprnd_sha, kprnd_accum,
				      sizeof(kprnd_accum));
			mutex_exit(&kprintf_mtx);
		}
	}
}
Exemplo n.º 4
0
static void
ingenic_rng_get(struct ingenic_rng_softc *sc)
{
	uint32_t data;

	mutex_spin_enter(&sc->sc_intr_lock);
	while (sc->sc_bytes_wanted) {
		bus_space_read_region_4(sc->sc_bst, sc->sc_bsh, 0, &data, 1);
#if 0
		device_printf(sc->sc_dev, "random output: %x\n", data);
#endif
		mutex_spin_exit(&sc->sc_intr_lock);
		mutex_spin_enter(&sc->sc_rnd_lock);
		rnd_add_data(&sc->sc_rndsource, &data, sizeof(data),
		    sizeof(data) * NBBY);
		mutex_spin_exit(&sc->sc_rnd_lock);
		mutex_spin_enter(&sc->sc_intr_lock);
		sc->sc_bytes_wanted -= MIN(sc->sc_bytes_wanted, sizeof(data));
	}
	explicit_memset(&data, 0, sizeof(data));
	mutex_spin_exit(&sc->sc_intr_lock);
}
Exemplo n.º 5
0
int
viornd_vq_done(struct virtqueue *vq)
{
	struct virtio_softc *vsc = vq->vq_owner;
	struct viornd_softc *sc = device_private(vsc->sc_child);
	int slot, len;

	mutex_enter(&sc->sc_mutex);

	if (virtio_dequeue(vsc, vq, &slot, &len) != 0) {
		mutex_exit(&sc->sc_mutex);
		return 0;
	}

	sc->sc_active = false;

	bus_dmamap_sync(vsc->sc_dmat, sc->sc_dmamap, 0, VIORND_BUFSIZE,
	    BUS_DMASYNC_POSTREAD);
	if (len > VIORND_BUFSIZE) {
		aprint_error_dev(sc->sc_dev,
				 "inconsistent descriptor length %d > %d\n",
				 len, VIORND_BUFSIZE);
		goto out;
	}

#if VIORND_DEBUG
	aprint_normal("%s: got %d bytes of entropy\n", __func__, len);
#endif
	rnd_add_data(&sc->sc_rndsource, sc->sc_buf, VIORND_BUFSIZE,
		     VIORND_BUFSIZE * NBBY);
out:
	virtio_dequeue_commit(vsc, vq, slot);
	mutex_exit(&sc->sc_mutex);
	
	return 1;
}
Exemplo n.º 6
0
/*
 * Set up the system's time, given a `reasonable' time value.
 */
void
inittodr(time_t base)
{
	bool badbase = false;
	bool waszero = (base == 0);
	bool goodtime = false;
	bool badrtc = false;
	int s;
	struct timespec ts;
	struct timeval tv;

	rnd_add_data(NULL, &base, sizeof(base), 0);

	if (base < 5 * SECS_PER_COMMON_YEAR) {
		struct clock_ymdhms basedate;

		/*
		 * If base is 0, assume filesystem time is just unknown
		 * instead of preposterous. Don't bark.
		 */
		if (base != 0)
			printf("WARNING: preposterous time in file system\n");
		/* not going to use it anyway, if the chip is readable */
		basedate.dt_year = 2010;
		basedate.dt_mon = 1;
		basedate.dt_day = 1;
		basedate.dt_hour = 12;
		basedate.dt_min = 0;
		basedate.dt_sec = 0;
		base = clock_ymdhms_to_secs(&basedate);
		badbase = true;
	}

	/*
	 * Some ports need to be supplied base in order to fabricate a time_t.
	 */
	if (todr_handle)
		todr_handle->base_time = base;

	if ((todr_handle == NULL) ||
	    (todr_gettime(todr_handle, &tv) != 0) ||
	    (tv.tv_sec < (25 * SECS_PER_COMMON_YEAR))) {

		if (todr_handle != NULL)
			printf("WARNING: preposterous TOD clock time\n");
		else
			printf("WARNING: no TOD clock present\n");
		badrtc = true;
	} else {
		time_t deltat = tv.tv_sec - base;

		if (deltat < 0)
			deltat = -deltat;

		if (!badbase && deltat >= 2 * SECS_PER_DAY) {
			
			if (tv.tv_sec < base) {
				/*
				 * The clock should never go backwards
				 * relative to filesystem time.  If it
				 * does by more than the threshold,
				 * believe the filesystem.
				 */
				printf("WARNING: clock lost %" PRId64 " days\n",
				    deltat / SECS_PER_DAY);
				badrtc = true;
			} else {
				aprint_verbose("WARNING: clock gained %" PRId64
				    " days\n", deltat / SECS_PER_DAY);
				goodtime = true;
			}
		} else {
			goodtime = true;
		}

		rnd_add_data(NULL, &tv, sizeof(tv), 0);
	}

	/* if the rtc time is bad, use the filesystem time */
	if (badrtc) {
		if (badbase) {
			printf("WARNING: using default initial time\n");
		} else {
			printf("WARNING: using filesystem time\n");
		}
		tv.tv_sec = base;
		tv.tv_usec = 0;
	}

	timeset = true;

	ts.tv_sec = tv.tv_sec;
	ts.tv_nsec = tv.tv_usec * 1000;
	s = splclock();
	tc_setclock(&ts);
	splx(s);

	if (waszero || goodtime)
		return;

	printf("WARNING: CHECK AND RESET THE DATE!\n");
}