mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-06 05:06:29 +00:00
random: Add optional continuous repetition test to entropy store based rngs
FIPS-140 requires that all random number generators implement continuous self tests in which each extracted block of data is compared against the last block for repetition. The ansi_cprng implements such a test, but it would be nice if the hw rng's did the same thing. Obviously its not something thats always needed, but it seems like it would be a nice feature to have on occasion. I've written the below patch which allows individual entropy stores to be flagged as desiring a continuous test to be run on them as is extracted. By default this option is off, but is enabled in the event that fips mode is selected during bootup. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Acked-by: Matt Mackall <mpm@selenic.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
b6f34d44cb
commit
5b739ef8a4
@ -25,12 +25,7 @@
|
|||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
#include <linux/rwsem.h>
|
#include <linux/rwsem.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/fips.h>
|
||||||
#ifdef CONFIG_CRYPTO_FIPS
|
|
||||||
extern int fips_enabled;
|
|
||||||
#else
|
|
||||||
#define fips_enabled 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Crypto notification events. */
|
/* Crypto notification events. */
|
||||||
enum {
|
enum {
|
||||||
|
@ -240,6 +240,7 @@
|
|||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/percpu.h>
|
#include <linux/percpu.h>
|
||||||
#include <linux/cryptohash.h>
|
#include <linux/cryptohash.h>
|
||||||
|
#include <linux/fips.h>
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_HARDIRQS
|
#ifdef CONFIG_GENERIC_HARDIRQS
|
||||||
# include <linux/irq.h>
|
# include <linux/irq.h>
|
||||||
@ -413,6 +414,7 @@ struct entropy_store {
|
|||||||
unsigned add_ptr;
|
unsigned add_ptr;
|
||||||
int entropy_count;
|
int entropy_count;
|
||||||
int input_rotate;
|
int input_rotate;
|
||||||
|
__u8 *last_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static __u32 input_pool_data[INPUT_POOL_WORDS];
|
static __u32 input_pool_data[INPUT_POOL_WORDS];
|
||||||
@ -852,12 +854,21 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
|
|||||||
{
|
{
|
||||||
ssize_t ret = 0, i;
|
ssize_t ret = 0, i;
|
||||||
__u8 tmp[EXTRACT_SIZE];
|
__u8 tmp[EXTRACT_SIZE];
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
xfer_secondary_pool(r, nbytes);
|
xfer_secondary_pool(r, nbytes);
|
||||||
nbytes = account(r, nbytes, min, reserved);
|
nbytes = account(r, nbytes, min, reserved);
|
||||||
|
|
||||||
while (nbytes) {
|
while (nbytes) {
|
||||||
extract_buf(r, tmp);
|
extract_buf(r, tmp);
|
||||||
|
|
||||||
|
if (r->last_data) {
|
||||||
|
spin_lock_irqsave(&r->lock, flags);
|
||||||
|
if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
|
||||||
|
panic("Hardware RNG duplicated output!\n");
|
||||||
|
memcpy(r->last_data, tmp, EXTRACT_SIZE);
|
||||||
|
spin_unlock_irqrestore(&r->lock, flags);
|
||||||
|
}
|
||||||
i = min_t(int, nbytes, EXTRACT_SIZE);
|
i = min_t(int, nbytes, EXTRACT_SIZE);
|
||||||
memcpy(buf, tmp, i);
|
memcpy(buf, tmp, i);
|
||||||
nbytes -= i;
|
nbytes -= i;
|
||||||
@ -940,6 +951,9 @@ static void init_std_data(struct entropy_store *r)
|
|||||||
now = ktime_get_real();
|
now = ktime_get_real();
|
||||||
mix_pool_bytes(r, &now, sizeof(now));
|
mix_pool_bytes(r, &now, sizeof(now));
|
||||||
mix_pool_bytes(r, utsname(), sizeof(*(utsname())));
|
mix_pool_bytes(r, utsname(), sizeof(*(utsname())));
|
||||||
|
/* Enable continuous test in fips mode */
|
||||||
|
if (fips_enabled)
|
||||||
|
r->last_data = kmalloc(EXTRACT_SIZE, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rand_initialize(void)
|
static int rand_initialize(void)
|
||||||
|
10
include/linux/fips.h
Normal file
10
include/linux/fips.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _FIPS_H
|
||||||
|
#define _FIPS_H
|
||||||
|
|
||||||
|
#ifdef CONFIG_CRYPTO_FIPS
|
||||||
|
extern int fips_enabled;
|
||||||
|
#else
|
||||||
|
#define fips_enabled 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user