Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+15 -1
+12 -1
drivers/char/random.c
··· 429 429 static int crng_init = 0; 430 430 #define crng_ready() (likely(crng_init > 1)) 431 431 static int crng_init_cnt = 0; 432 + static unsigned long crng_global_init_time = 0; 432 433 #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) 433 434 static void _extract_crng(struct crng_state *crng, 434 435 __u32 out[CHACHA20_BLOCK_WORDS]); ··· 934 933 unsigned long v, flags; 935 934 936 935 if (crng_ready() && 937 - time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) 936 + (time_after(crng_global_init_time, crng->init_time) || 937 + time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))) 938 938 crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); 939 939 spin_lock_irqsave(&crng->lock, flags); 940 940 if (arch_get_random_long(&v)) ··· 1759 1757 init_std_data(&input_pool); 1760 1758 init_std_data(&blocking_pool); 1761 1759 crng_initialize(&primary_crng); 1760 + crng_global_init_time = jiffies; 1762 1761 return 0; 1763 1762 } 1764 1763 early_initcall(rand_initialize); ··· 1932 1929 return -EPERM; 1933 1930 input_pool.entropy_count = 0; 1934 1931 blocking_pool.entropy_count = 0; 1932 + return 0; 1933 + case RNDRESEEDCRNG: 1934 + if (!capable(CAP_SYS_ADMIN)) 1935 + return -EPERM; 1936 + if (crng_init < 2) 1937 + return -ENODATA; 1938 + crng_reseed(&primary_crng, NULL); 1939 + crng_global_init_time = jiffies - 1; 1935 1940 return 0; 1936 1941 default: 1937 1942 return -EINVAL;
+3
include/uapi/linux/random.h
··· 35 35 /* Clear the entropy pool and associated counters. (Superuser only.) */ 36 36 #define RNDCLEARPOOL _IO( 'R', 0x06 ) 37 37 38 + /* Reseed CRNG. (Superuser only.) */ 39 + #define RNDRESEEDCRNG _IO( 'R', 0x07 ) 40 + 38 41 struct rand_pool_info { 39 42 int entropy_count; 40 43 int buf_size;