On Tue, 04 Sep 2012 21:41:20 -0700
Doug Barton wrote:

> Can you point out where in the source you're seeing these things?


It's in src/sys/dev/random/randomdev_soft.c:

random_yarrow_write()
random_harvest_internal()
random_kthread()

------------------------------------------------------------------

void
random_yarrow_write(void *buf, int count)
{
        int i;
        u_int chunk;

        /*
         * Break the input up into HARVESTSIZE chunks. The writer has
        too
         * much control here, so "estimate" the entropy as zero.
         */
        for (i = 0; i < count; i += HARVESTSIZE) {
                chunk = HARVESTSIZE;
                if (i + chunk >= count)
                        chunk = (u_int)(count - i);
                random_harvest_internal(get_cyclecount(), (char *)buf +
        i, chunk, 0, 0, RANDOM_WRITE);
        }
}



/* Entropy harvesting routine. This is supposed to be fast; do
 * not do anything slow in here!
 */
static void
random_harvest_internal(u_int64_t somecounter, const void *entropy,
    u_int count, u_int bits, u_int frac, enum esource origin)
{
        struct harvest *event;

        KASSERT(origin == RANDOM_START || origin == RANDOM_WRITE ||
            origin == RANDOM_KEYBOARD || origin == RANDOM_MOUSE ||
            origin == RANDOM_NET || origin == RANDOM_INTERRUPT ||
            origin == RANDOM_PURE,
            ("random_harvest_internal: origin %d invalid\n", origin));

        /* Lockless read to avoid lock operations if fifo is full. */
        if (harvestfifo[origin].count >= RANDOM_FIFO_MAX)
                return;

        mtx_lock_spin(&harvest_mtx);

        /*
         * Don't make the harvest queues too big - help to prevent
        low-grade
         * entropy swamping
         */
        if (harvestfifo[origin].count < RANDOM_FIFO_MAX) {
                event = STAILQ_FIRST(&emptyfifo.head);
                if (event != NULL) {
                        /* Add the harvested data to the fifo */
                        STAILQ_REMOVE_HEAD(&emptyfifo.head, next);
                        harvestfifo[origin].count++;
                        event->somecounter = somecounter;
                        event->size = count;
                        event->bits = bits;
                        event->frac = frac;
                        event->source = origin;

                        /* XXXX Come back and make this dynamic! */
                        count = MIN(count, HARVESTSIZE);
                        memcpy(event->entropy, entropy, count);

                        STAILQ_INSERT_TAIL(&harvestfifo[origin].head,
                            event, next);
                }
        }
        mtx_unlock_spin(&harvest_mtx);
}




static void
random_kthread(void *arg __unused)
{
        STAILQ_HEAD(, harvest) local_queue;
        struct harvest *event = NULL;
        int local_count;
        enum esource source;

        STAILQ_INIT(&local_queue);
        local_count = 0;

        /* Process until told to stop */
        for (; random_kthread_control >= 0;) {

                /* Cycle through all the entropy sources */
                mtx_lock_spin(&harvest_mtx);
                for (source = RANDOM_START; source < ENTROPYSOURCE;
                source++) { /*
                         * Drain entropy source records into a
                thread-local
                         * queue for processing while not holding the
                mutex. */
                        STAILQ_CONCAT(&local_queue,
                &harvestfifo[source].head); local_count +=
                harvestfifo[source].count; harvestfifo[source].count =
                0; }

                /*
                 * Deal with events, if any, dropping the mutex as we
                process
                 * each event.  Then push the events back into the empty
                 * fifo.
                 */
                if (!STAILQ_EMPTY(&local_queue)) {
                        mtx_unlock_spin(&harvest_mtx);
                        STAILQ_FOREACH(event, &local_queue, next)
                                random_process_event(event);
                        mtx_lock_spin(&harvest_mtx);
                        STAILQ_CONCAT(&emptyfifo.head, &local_queue);
                        emptyfifo.count += local_count;
                        local_count = 0;
                }
                mtx_unlock_spin(&harvest_mtx);

                KASSERT(local_count == 0, ("random_kthread: local_count
                %d", local_count));

                /*
                 * If a queue flush was commanded, it has now happened,
                 * and we can mark this by resetting the command.
                 */
                if (random_kthread_control == 1)
                        random_kthread_control = 0;

                /* Work done, so don't belabour the issue */
                pause("-", hz / 10);

        }

        random_set_wakeup_exit(&random_kthread_control);
        /* NOTREACHED */
}
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-security
To unsubscribe, send any mail to "[email protected]"

Reply via email to