Commit ad89bf78 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

PR: 2563

Submitted by: Paul Green <Paul.Green@stratus.com>
Reviewed by: steve

Improved PRNG seeding for VOS.
parent e75440d2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -255,6 +255,9 @@
  
 Changes between 1.0.0f and 1.0.1  [xx XXX xxxx]

  *) Improved PRNG seeding for VOS.
     [Paul Green <Paul.Green@stratus.com>]

  *) Extensive assembler packs updates, most notably:

	- x86[_64]:     AES-NI, PCLMULQDQ, RDRAND support;
+2 −2
Original line number Diff line number Diff line
@@ -200,8 +200,8 @@ my %table=(
"cc",		"cc:-O::(unknown)::::::",

####VOS Configurations
"vos-gcc","gcc:-O3 -Wall -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",
"debug-vos-gcc","gcc:-O0 -g -Wall -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",
"vos-gcc","gcc:-O3 -Wall -DOPENSSL_SYSNAME_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",
"debug-vos-gcc","gcc:-O0 -g -Wall -DOPENSSL_SYSNAME_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",

#### Solaris x86 with GNU C setups
# -DOPENSSL_NO_INLINE_ASM switches off inline assembler. We have to do it
+74 −34
Original line number Diff line number Diff line
@@ -133,47 +133,87 @@
# define FD_SETSIZE (8*sizeof(fd_set))
#endif

#ifdef __VOS__
#if defined(OPENSSL_SYS_VOS)

/* The following algorithm repeatedly samples the real-time clock
   (RTC) to generate a sequence of unpredictable data.  The algorithm
   relies upon the uneven execution speed of the code (due to factors
   such as cache misses, interrupts, bus activity, and scheduling) and
   upon the rather large relative difference between the speed of the
   clock and the rate at which it can be read.

   If this code is ported to an environment where execution speed is
   more constant or where the RTC ticks at a much slower rate, or the
   clock can be read with fewer instructions, it is likely that the
   results would be far more predictable.

   As a precaution, we generate 4 times the minimum required amount of
   seed data.  */

int RAND_poll(void)
{
	unsigned char buf[ENTROPY_NEEDED];
	short int code;
	gid_t curr_gid;
	pid_t curr_pid;
	uid_t curr_uid;
	static int first=1;
	int i;
	long rnd = 0;
	int i, k;
	struct timespec ts;
	unsigned seed;

/* The VOS random() function starts from a static seed so its
   initial value is predictable.  If random() returns the
   initial value, reseed it with dynamic data.  The VOS
   real-time clock has a granularity of 1 nsec so it should be
   reasonably difficult to predict its exact value.  Do not
   gratuitously reseed the PRNG because other code in this
   process or thread may be using it.  */

	if (first) {
		first = 0;
		rnd = random ();
		if (rnd == 1804289383) {
			clock_gettime (CLOCK_REALTIME, &ts);
	unsigned char v;

#ifdef OPENSSL_SYS_VOS_HPPA
	long duration;
	extern void s$sleep (long *_duration, short int *_code);
#else
#ifdef OPENSSL_SYS_VOS_IA32
	long long duration;
	extern void s$sleep2 (long long *_duration, short int *_code);
#else
#error "Unsupported Platform."
#endif /* OPENSSL_SYS_VOS_IA32 */
#endif /* OPENSSL_SYS_VOS_HPPA */

	/* Seed with the gid, pid, and uid, to ensure *some*
	   variation between different processes.  */

	curr_gid = getgid();
	RAND_add (&curr_gid, sizeof curr_gid, 1);
	curr_gid = 0;

	curr_pid = getpid();
	RAND_add (&curr_pid, sizeof curr_pid, 1);
	curr_pid = 0;

	curr_uid = getuid();
			seed = ts.tv_sec ^ ts.tv_nsec ^ curr_pid ^ curr_uid;
			srandom (seed);
		}
	}
	RAND_add (&curr_uid, sizeof curr_uid, 1);
	curr_uid = 0;

	for (i = 0; i < sizeof(buf); i++) {
		if (i % 4 == 0)
			rnd = random();
		buf[i] = rnd;
		rnd >>= 8;
	}
	RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
	memset(buf, 0, sizeof(buf));
	for (i=0; i<(ENTROPY_NEEDED*4); i++)
	{
		/* burn some cpu; hope for interrupts, cache
		   collisions, bus interference, etc.  */
		for (k=0; k<99; k++)
			ts.tv_nsec = random ();

#ifdef OPENSSL_SYS_VOS_HPPA
		/* sleep for 1/1024 of a second (976 us).  */
		duration = 1;
		s$sleep (&duration, &code);
#else
#ifdef OPENSSL_SYS_VOS_IA32
		/* sleep for 1/65536 of a second (15 us).  */
		duration = 1;
		s$sleep2 (&duration, &code);
#endif /* OPENSSL_SYS_VOS_IA32 */
#endif /* OPENSSL_SYS_VOS_HPPA */

		/* get wall clock time.  */
		clock_gettime (CLOCK_REALTIME, &ts);

		/* take 8 bits */
		v = (unsigned char) (ts.tv_nsec % 256);
		RAND_add (&v, sizeof v, 1);
		v = 0;
	}
	return 1;
}
#elif defined __OpenBSD__
+7 −1
Original line number Diff line number Diff line
@@ -193,8 +193,14 @@ extern "C" {
#endif

/* --------------------------------- VOS ----------------------------------- */
#ifdef OPENSSL_SYSNAME_VOS
#if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS)
# define OPENSSL_SYS_VOS
#ifdef __HPPA__
# define OPENSSL_SYS_VOS_HPPA
#endif
#ifdef __IA32__
# define OPENSSL_SYS_VOS_IA32
#endif
#endif

/* ------------------------------- VxWorks --------------------------------- */