“fips_run_rng_test” is legacy code, recommend to disable 'FIPS 140-2' test if to use 'rngd-tools’. -Miaoqing -----Original Message----- From: Oleksij Rempel [mailto:linux@xxxxxxxxxxxxxxxx] Sent: Sunday, July 26, 2015 3:41 PM To: Pan, Miaoqing; linville@xxxxxxxxxxxxx Cc: linux-wireless@xxxxxxxxxxxxxxx; ath9k-devel Subject: Re: [PATCH 2/2] ath9k: export HW random number generator Hi all, i did rngtest on top of this patch. The results are incredibly bad, right now it is more a pattern generator not random number generator. Is it possible to fix it? /home/lex# cat /dev/hwrng | rngtest -c 1000 rngtest 5 Copyright (c) 2004 by Henrique de Moraes Holschuh This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. rngtest: starting FIPS tests... rngtest: bits received from input: 20000032 rngtest: FIPS 140-2 successes: 0 rngtest: FIPS 140-2 failures: 1000 rngtest: FIPS 140-2(2001-10-10) Monobit: 27 rngtest: FIPS 140-2(2001-10-10) Poker: 1000 rngtest: FIPS 140-2(2001-10-10) Runs: 1000 rngtest: FIPS 140-2(2001-10-10) Long run: 2 rngtest: FIPS 140-2(2001-10-10) Continuous run: 0 rngtest: input channel speed: (min=1.879; avg=871.897; max=19531250.000)Kibits/s rngtest: FIPS tests speed: (min=19.443; avg=48.374; max=70.123)Mibits/s rngtest: Program run time: 23423736 microseconds Am 15.07.2015 um 09:54 schrieb miaoqing@xxxxxxxxxxxxxxxx: > From: Miaoqing Pan <miaoqing@xxxxxxxxxxxxxxxx> > > We measured the FFT-based entropy in 3 ways, Shannon entropy, > collision entropy, and directly measured min-entropy. Just to be > conservative, we recommend the estimated min-Entropy to be > 10 bits per 16-bit value. > > Analysis was done by Jacobson,David(djacobso@xxxxxxxxxxxxxxxx). > > Signed-off-by: Miaoqing Pan <miaoqing@xxxxxxxxxxxxxxxx> > --- > drivers/net/wireless/ath/ath9k/Kconfig | 7 +++ > drivers/net/wireless/ath/ath9k/Makefile | 1 + > drivers/net/wireless/ath/ath9k/ath9k.h | 23 ++++++++++ > drivers/net/wireless/ath/ath9k/main.c | 4 ++ > drivers/net/wireless/ath/ath9k/rng.c | 75 +++++++++++++++++++++++++++++++++ > 5 files changed, 110 insertions(+) > create mode 100644 drivers/net/wireless/ath/ath9k/rng.c > > diff --git a/drivers/net/wireless/ath/ath9k/Kconfig > b/drivers/net/wireless/ath/ath9k/Kconfig > index fee0cad..bde62ec9 100644 > --- a/drivers/net/wireless/ath/ath9k/Kconfig > +++ b/drivers/net/wireless/ath/ath9k/Kconfig > @@ -176,3 +176,10 @@ config ATH9K_HTC_DEBUGFS > depends on ATH9K_HTC && DEBUG_FS > ---help--- > Say Y, if you need access to ath9k_htc's statistics. > + > +config ATH9K_HWRNG > + bool "Random number generator support" > + depends on ATH9K && (HW_RANDOM = y || HW_RANDOM = ATH9K) > + default y > + ---help--- > + Provides a hardware random number generator to the kernel. > diff --git a/drivers/net/wireless/ath/ath9k/Makefile > b/drivers/net/wireless/ath/ath9k/Makefile > index ecda613..76f9dc3 100644 > --- a/drivers/net/wireless/ath/ath9k/Makefile > +++ b/drivers/net/wireless/ath/ath9k/Makefile > @@ -15,6 +15,7 @@ ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o > ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o > ath9k-$(CONFIG_ATH9K_TX99) += tx99.o > ath9k-$(CONFIG_ATH9K_WOW) += wow.o > +ath9k-$(CONFIG_ATH9K_HWRNG) += rng.o > > ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o > > diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h > b/drivers/net/wireless/ath/ath9k/ath9k.h > index a7a81b3..45596e5 100644 > --- a/drivers/net/wireless/ath/ath9k/ath9k.h > +++ b/drivers/net/wireless/ath/ath9k/ath9k.h > @@ -23,6 +23,7 @@ > #include <linux/leds.h> > #include <linux/completion.h> > #include <linux/time.h> > +#include <linux/hw_random.h> > > #include "common.h" > #include "debug.h" > @@ -1041,6 +1042,12 @@ struct ath_softc { > u32 wow_intr_before_sleep; > bool force_wow; > #endif > + > +#ifdef CONFIG_ATH9K_HWRNG > + struct hwrng rng; > + bool rng_initialized; > + u32 rng_last; > +#endif > }; > > /********/ > @@ -1063,6 +1070,22 @@ static inline int ath9k_tx99_send(struct > ath_softc *sc, } #endif /* CONFIG_ATH9K_TX99 */ > > +/***************************/ > +/* Random Number Generator */ > +/***************************/ > +#ifdef CONFIG_ATH9K_HWRNG > +void ath9k_rng_register(struct ath_softc *sc); void > +ath9k_rng_unregister(struct ath_softc *sc); #else static inline void > +ath9k_rng_register(struct ath_softc *sc) { } > + > +static inline void ath9k_rng_unregister(struct ath_softc *sc) { } > +#endif > + > static inline void ath_read_cachesize(struct ath_common *common, int > *csz) { > common->bus_ops->read_cachesize(common, csz); diff --git > a/drivers/net/wireless/ath/ath9k/main.c > b/drivers/net/wireless/ath/ath9k/main.c > index cfd45cb..5916ab2 100644 > --- a/drivers/net/wireless/ath/ath9k/main.c > +++ b/drivers/net/wireless/ath/ath9k/main.c > @@ -739,6 +739,8 @@ static int ath9k_start(struct ieee80211_hw *hw) > > ath9k_ps_restore(sc); > > + ath9k_rng_register(sc); > + > return 0; > } > > @@ -828,6 +830,8 @@ static void ath9k_stop(struct ieee80211_hw *hw) > > ath9k_deinit_channel_context(sc); > > + ath9k_rng_unregister(sc); > + > mutex_lock(&sc->mutex); > > ath_cancel_work(sc); > diff --git a/drivers/net/wireless/ath/ath9k/rng.c > b/drivers/net/wireless/ath/ath9k/rng.c > new file mode 100644 > index 0000000..d8fa7a5 > --- /dev/null > +++ b/drivers/net/wireless/ath/ath9k/rng.c > @@ -0,0 +1,75 @@ > +/* > + * Copyright (c) 2015 Qualcomm Atheros, Inc. > + * > + * Permission to use, copy, modify, and/or distribute this software > +for any > + * purpose with or without fee is hereby granted, provided that the > +above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL > +WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE > +LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY > +DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN > +AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING > +OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include "ath9k.h" > +#include "hw.h" > +#include "ar9003_phy.h" > + > +static int ath9k_rng_data_read(struct hwrng *rng, u32 *data) { > + u32 v1, v2; > + struct ath_softc *sc = (struct ath_softc *)rng->priv; > + struct ath_hw *ah = sc->sc_ah; > + > + ath9k_ps_wakeup(sc); > + > + REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 5); > + REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); > + REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, > +AR_PHY_TEST_CTL_RX_OBS_SEL, 0); > + > + v1 = REG_READ(ah, AR_PHY_TST_ADC); > + v2 = REG_READ(ah, AR_PHY_TST_ADC); > + > + ath9k_ps_restore(sc); > + > + /* wait for data ready */ > + if (v1 && v2 && sc->rng_last != v1 && v1 != v2) { > + *data = (v1 & 0xffff) | (v2 << 16); > + sc->rng_last = v2; > + > + return sizeof(u32); > + } > + > + sc->rng_last = v2; > + > + return 0; > +} > + > +void ath9k_rng_register(struct ath_softc *sc) { > + struct ath_hw *ah = sc->sc_ah; > + > + if (WARN_ON(sc->rng_initialized)) > + return; > + > + if (!AR_SREV_9300_20_OR_LATER(ah)) > + return; > + > + sc->rng.name = "ath9k"; > + sc->rng.data_read = ath9k_rng_data_read; > + sc->rng.priv = (unsigned long)sc; > + > + if (!hwrng_register(&sc->rng)) > + sc->rng_initialized = true; > +} > + > +void ath9k_rng_unregister(struct ath_softc *sc) { > + if (sc->rng_initialized) { > + hwrng_unregister(&sc->rng); > + sc->rng_initialized = false; > + } > +} > -- Regards, Oleksij ��.n��������+%������w��{.n�����{���zW����ܨ}���Ơz�j:+v�����w����ޙ��&�)ߡ�a����z�ޗ���ݢj��w�f