static void uart_pps_process(struct uart_softc *sc, int ser_sig) { sbintime_t now; int is_assert, pps_sig; /* Which signal is configured as PPS? Early out if none. */ switch(sc->sc_pps_mode & UART_PPS_SIGNAL_MASK) { case UART_PPS_CTS: pps_sig = SER_CTS; break; case UART_PPS_DCD: pps_sig = SER_DCD; break; default: return; } /* Early out if there is no change in the signal configured as PPS. */ if ((ser_sig & SER_DELTA(pps_sig)) == 0) return; /* * In narrow-pulse mode we need to synthesize both capture and clear * events from a single "delta occurred" indication from the uart * hardware because the pulse width is too narrow to reliably detect * both edges. However, when the pulse width is close to our interrupt * processing latency we might intermittantly catch both edges. To * guard against generating spurious events when that happens, we use a * separate timer to ensure at least half a second elapses before we * generate another event. */ pps_capture(&sc->sc_pps); if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE) { now = getsbinuptime(); if (now > sc->sc_pps_captime + 500 * SBT_1MS) { sc->sc_pps_captime = now; pps_event(&sc->sc_pps, PPS_CAPTUREASSERT); pps_event(&sc->sc_pps, PPS_CAPTURECLEAR); } } else { is_assert = ser_sig & pps_sig; if (sc->sc_pps_mode & UART_PPS_INVERT_PULSE) is_assert = !is_assert; pps_event(&sc->sc_pps, is_assert ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); } }
/* The argument buf points to a whole number of blocks. */ void random_fortuna_read(uint8_t *buf, u_int bytecount) { #ifdef _KERNEL sbintime_t thistime; #endif struct randomdev_hash context; uint8_t s[NPOOLS*KEYSIZE], temp[KEYSIZE]; int i; u_int seedlength; /* We must be locked for all this as plenty of state gets messed with */ mtx_lock(&random_reseed_mtx); /* if buf == NULL and bytecount == 0 then this is the pre-read. */ /* if buf == NULL and bytecount != 0 then this is the post-read; ignore. */ if (buf == NULL) { if (bytecount == 0) { if (fortuna_state.pool[0].length >= fortuna_state.minpoolsize #ifdef _KERNEL /* F&S - Use 'getsbinuptime()' to prevent reseed-spamming. */ && ((thistime = getsbinuptime()) - fortuna_state.lasttime > hz/10) #endif ) { #ifdef _KERNEL fortuna_state.lasttime = thistime; #endif seedlength = 0U; /* F&S - ReseedCNT = ReseedCNT + 1 */ fortuna_state.reseedcount++; /* s = \epsilon by default */ for (i = 0; i < NPOOLS; i++) { /* F&S - if Divides(ReseedCnt, 2^i) ... */ if ((fortuna_state.reseedcount % (1 << i)) == 0U) { seedlength += KEYSIZE; /* F&S - temp = (P_i) */ randomdev_hash_finish(&fortuna_state.pool[i].hash, temp); /* F&S - P_i = \epsilon */ randomdev_hash_init(&fortuna_state.pool[i].hash); fortuna_state.pool[i].length = 0U; /* F&S - s = s|H(temp) */ randomdev_hash_init(&context); randomdev_hash_iterate(&context, temp, KEYSIZE); randomdev_hash_finish(&context, s + i*KEYSIZE); } else break; } #ifdef RANDOM_DEBUG printf("random: active reseed: reseedcount [%d] ", fortuna_state.reseedcount); for (i = 0; i < NPOOLS; i++) printf(" %d", fortuna_state.pool[i].length); printf("\n"); #endif /* F&S */ reseed(s, seedlength); /* Clean up */ memset(s, 0, seedlength); seedlength = 0U; memset(temp, 0, sizeof(temp)); memset(&context, 0, sizeof(context)); } } } /* if buf != NULL do a regular read. */ else random_fortuna_genrandom(buf, bytecount); mtx_unlock(&random_reseed_mtx); }