Add a new ioctl which forces the the crng to be reseeded.
Unified · Split
| @@ -429,6 +429,7 @@ struct crng_state primary_crng = { · 428 unmodified lines | |||
| 429 | static int crng_init = 0; | 429 | static int crng_init = 0; |
| 430 | #define crng_ready() (likely(crng_init > 1)) | 430 | #define crng_ready() (likely(crng_init > 1)) |
| 431 | static int crng_init_cnt = 0; | 431 | static int crng_init_cnt = 0; |
| 432 | static 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) |
| 433 | static void _extract_crng(struct crng_state *crng, | 434 | static 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, · 498 unmodified lines | |||
| 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) · 817 unmodified lines | |||
| 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 | } |
| 1762 | early_initcall(rand_initialize); | 1765 | early_initcall(rand_initialize); |
| @@ -1930,6 +1933,14 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) · 167 unmodified lines | |||
| 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 | } |
| @@ -35,6 +35,9 @@ · 34 unmodified lines | |||
| 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 | |||
| 38 | struct rand_pool_info { | 41 | struct rand_pool_info { |
| 39 | int entropy_count; | 42 | int entropy_count; |
| 40 | int buf_size; | 43 | int buf_size; |