Move csrand() to a new file csrand.c
A set of APIs similar to arc4random(3) is complex enough to deserve its own file. Cc: "Jason A. Donenfeld" <Jason@zx2c4.com> Cc: Cristian Rodríguez <crrodriguez@opensuse.org> Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org> Cc: Björn Esser <besser82@fedoraproject.org> Cc: Yann Droneaud <ydroneaud@opteya.com> Cc: Joseph Myers <joseph@codesourcery.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
This commit is contained in:
		
				
					committed by
					
						
						Serge Hallyn
					
				
			
			
				
	
			
			
			
						parent
						
							986ef4e69c
						
					
				
				
					commit
					be1f4f7972
				
			
							
								
								
									
										61
									
								
								libmisc/csrand.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								libmisc/csrand.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#ident "$Id$"
 | 
			
		||||
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#if HAVE_SYS_RANDOM_H
 | 
			
		||||
#include <sys/random.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "bit.h"
 | 
			
		||||
#include "prototypes.h"
 | 
			
		||||
#include "shadowlog.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return a uniformly-distributed CS random u_long value.
 | 
			
		||||
 */
 | 
			
		||||
unsigned long
 | 
			
		||||
csrand(void)
 | 
			
		||||
{
 | 
			
		||||
	FILE           *fp;
 | 
			
		||||
	unsigned long  r;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_GETENTROPY
 | 
			
		||||
	/* getentropy may exist but lack kernel support.  */
 | 
			
		||||
	if (getentropy(&r, sizeof(r)) == 0)
 | 
			
		||||
		return r;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_GETRANDOM
 | 
			
		||||
	/* Likewise getrandom.  */
 | 
			
		||||
	if (getrandom(&r, sizeof(r), 0) == sizeof(r))
 | 
			
		||||
		return r;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_ARC4RANDOM_BUF
 | 
			
		||||
	/* arc4random_buf can never fail.  */
 | 
			
		||||
	arc4random_buf(&r, sizeof(r));
 | 
			
		||||
	return r;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Use /dev/urandom as a last resort.  */
 | 
			
		||||
	fp = fopen("/dev/urandom", "r");
 | 
			
		||||
	if (NULL == fp) {
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (fread(&r, sizeof(r), 1, fp) != 1) {
 | 
			
		||||
		fclose(fp);
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
	return r;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
	fprintf(log_get_logfd(), _("Unable to obtain random bytes.\n"));
 | 
			
		||||
	exit(1);
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user