forked from mirrors/linux
		
	hwrng: core - start hwrng kthread also for untrusted sources
Start the hwrng kthread even if the hwrng source has a quality setting of zero. Then, every crng reseed interval, one batch of data from this zero-quality hwrng source will be mixed into the CRNG pool. This patch is based on the assumption that data from a hwrng source will not actively harm the CRNG state. Instead, many hwrng sources (such as TPM devices), even though they are assigend a quality level of zero, actually provide some entropy, which is good enough to mix into the CRNG pool every once in a while. Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
		
							parent
							
								
									4edff849f7
								
							
						
					
					
						commit
						b006c439d5
					
				
					 1 changed files with 10 additions and 26 deletions
				
			
		|  | @ -52,7 +52,7 @@ MODULE_PARM_DESC(default_quality, | |||
| 
 | ||||
| static void drop_current_rng(void); | ||||
| static int hwrng_init(struct hwrng *rng); | ||||
| static void hwrng_manage_rngd(struct hwrng *rng); | ||||
| static int hwrng_fillfn(void *unused); | ||||
| 
 | ||||
| static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size, | ||||
| 			       int wait); | ||||
|  | @ -96,6 +96,15 @@ static int set_current_rng(struct hwrng *rng) | |||
| 	drop_current_rng(); | ||||
| 	current_rng = rng; | ||||
| 
 | ||||
| 	/* if necessary, start hwrng thread */ | ||||
| 	if (!hwrng_fill) { | ||||
| 		hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng"); | ||||
| 		if (IS_ERR(hwrng_fill)) { | ||||
| 			pr_err("hwrng_fill thread creation failed\n"); | ||||
| 			hwrng_fill = NULL; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -167,8 +176,6 @@ static int hwrng_init(struct hwrng *rng) | |||
| 		rng->quality = 1024; | ||||
| 	current_quality = rng->quality; /* obsolete */ | ||||
| 
 | ||||
| 	hwrng_manage_rngd(rng); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -454,10 +461,6 @@ static ssize_t rng_quality_store(struct device *dev, | |||
| 	/* the best available RNG may have changed */ | ||||
| 	ret = enable_best_rng(); | ||||
| 
 | ||||
| 	/* start/stop rngd if necessary */ | ||||
| 	if (current_rng) | ||||
| 		hwrng_manage_rngd(current_rng); | ||||
| 
 | ||||
| out: | ||||
| 	mutex_unlock(&rng_mutex); | ||||
| 	return ret ? ret : len; | ||||
|  | @ -513,9 +516,6 @@ static int hwrng_fillfn(void *unused) | |||
| 
 | ||||
| 		put_rng(rng); | ||||
| 
 | ||||
| 		if (!quality) | ||||
| 			break; | ||||
| 
 | ||||
| 		if (rc <= 0) | ||||
| 			continue; | ||||
| 
 | ||||
|  | @ -534,22 +534,6 @@ static int hwrng_fillfn(void *unused) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void hwrng_manage_rngd(struct hwrng *rng) | ||||
| { | ||||
| 	if (WARN_ON(!mutex_is_locked(&rng_mutex))) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (rng->quality == 0 && hwrng_fill) | ||||
| 		kthread_stop(hwrng_fill); | ||||
| 	if (rng->quality > 0 && !hwrng_fill) { | ||||
| 		hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng"); | ||||
| 		if (IS_ERR(hwrng_fill)) { | ||||
| 			pr_err("hwrng_fill thread creation failed\n"); | ||||
| 			hwrng_fill = NULL; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int hwrng_register(struct hwrng *rng) | ||||
| { | ||||
| 	int err = -EINVAL; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Dominik Brodowski
						Dominik Brodowski