aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2018-04-11 16:32:17 -0400
committerTheodore Ts'o <tytso@mit.edu>2018-04-14 11:59:31 -0400
commitd848e5f8e1ebdb227d045db55fe4f825e82965fa (patch)
tree7661e5f63b463d3fb22da99aef52bf1e00d814f4
parent0bb29a849a6433b72e249eea7695477b02056e94 (diff)
random: add new ioctl RNDRESEEDCRNG
Add a new ioctl which forces the the crng to be reseeded. Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@kernel.org
-rw-r--r--drivers/char/random.c13
-rw-r--r--include/uapi/linux/random.h3
2 files changed, 15 insertions, 1 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 898233f594b4..3cd3aae24d6d 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -429,6 +429,7 @@ struct crng_state primary_crng = {
429static int crng_init = 0; 429static int crng_init = 0;
430#define crng_ready() (likely(crng_init > 1)) 430#define crng_ready() (likely(crng_init > 1))
431static int crng_init_cnt = 0; 431static int crng_init_cnt = 0;
432static unsigned long crng_global_init_time = 0;
432#define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) 433#define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
433static void _extract_crng(struct crng_state *crng, 434static void _extract_crng(struct crng_state *crng,
434 __u32 out[CHACHA20_BLOCK_WORDS]); 435 __u32 out[CHACHA20_BLOCK_WORDS]);
@@ -933,7 +934,8 @@ static void _extract_crng(struct crng_state *crng,
933 unsigned long v, flags; 934 unsigned long v, flags;
934 935
935 if (crng_ready() && 936 if (crng_ready() &&
936 time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) 937 (time_after(crng_global_init_time, crng->init_time) ||
938 time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)))
937 crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); 939 crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL);
938 spin_lock_irqsave(&crng->lock, flags); 940 spin_lock_irqsave(&crng->lock, flags);
939 if (arch_get_random_long(&v)) 941 if (arch_get_random_long(&v))
@@ -1757,6 +1759,7 @@ static int rand_initialize(void)
1757 init_std_data(&input_pool); 1759 init_std_data(&input_pool);
1758 init_std_data(&blocking_pool); 1760 init_std_data(&blocking_pool);
1759 crng_initialize(&primary_crng); 1761 crng_initialize(&primary_crng);
1762 crng_global_init_time = jiffies;
1760 return 0; 1763 return 0;
1761} 1764}
1762early_initcall(rand_initialize); 1765early_initcall(rand_initialize);
@@ -1930,6 +1933,14 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
1930 input_pool.entropy_count = 0; 1933 input_pool.entropy_count = 0;
1931 blocking_pool.entropy_count = 0; 1934 blocking_pool.entropy_count = 0;
1932 return 0; 1935 return 0;
1936 case RNDRESEEDCRNG:
1937 if (!capable(CAP_SYS_ADMIN))
1938 return -EPERM;
1939 if (crng_init < 2)
1940 return -ENODATA;
1941 crng_reseed(&primary_crng, NULL);
1942 crng_global_init_time = jiffies - 1;
1943 return 0;
1933 default: 1944 default:
1934 return -EINVAL; 1945 return -EINVAL;
1935 } 1946 }
diff --git a/include/uapi/linux/random.h b/include/uapi/linux/random.h
index c34f4490d025..26ee91300e3e 100644
--- a/include/uapi/linux/random.h
+++ b/include/uapi/linux/random.h
@@ -35,6 +35,9 @@
35/* Clear the entropy pool and associated counters. (Superuser only.) */ 35/* Clear the entropy pool and associated counters. (Superuser only.) */
36#define RNDCLEARPOOL _IO( 'R', 0x06 ) 36#define RNDCLEARPOOL _IO( 'R', 0x06 )
37 37
38/* Reseed CRNG. (Superuser only.) */
39#define RNDRESEEDCRNG _IO( 'R', 0x07 )
40
38struct rand_pool_info { 41struct rand_pool_info {
39 int entropy_count; 42 int entropy_count;
40 int buf_size; 43 int buf_size;