From: Richard Levitte Date: Wed, 3 Aug 2016 19:45:06 +0000 (+0200) Subject: VSI submission: make the VMS version of RAND_poll() faster and more secure X-Git-Tag: OpenSSL_1_1_0~292 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=5fc2c6896d5050735c7d99dc80275c72fc58c49c VSI submission: make the VMS version of RAND_poll() faster and more secure Reviewed-by: Rich Salz --- diff --git a/crypto/rand/rand_vms.c b/crypto/rand/rand_vms.c index ae6f17d91f..9c462dd374 100644 --- a/crypto/rand/rand_vms.c +++ b/crypto/rand/rand_vms.c @@ -7,15 +7,21 @@ * https://www.openssl.org/source/license.html */ +/* + * Modified by VMS Software, Inc (2016) + * Eliminate looping through all processes (performance) + * Add additional randomizations using rand() function + */ + #include #include "rand_lcl.h" #if defined(OPENSSL_SYS_VMS) - # include # include # include # include +# include # ifdef __DECC # pragma message disable DOLLARID # endif @@ -33,76 +39,94 @@ # endif /* __INITIAL_POINTER_SIZE == 64 [else] */ static struct items_data_st { - short length, code; /* length is amount of bytes */ + short length, code; /* length is number of bytes */ } items_data[] = { - { - 4, JPI$_BUFIO - }, - { - 4, JPI$_CPUTIM - }, - { - 4, JPI$_DIRIO - }, - { - 8, JPI$_LOGINTIM - }, - { - 4, JPI$_PAGEFLTS - }, - { - 4, JPI$_PID - }, - { - 4, JPI$_WSSIZE - }, - { - 0, 0 - } + {4, JPI$_BUFIO}, + {4, JPI$_CPUTIM}, + {4, JPI$_DIRIO}, + {4, JPI$_IMAGECOUNT}, + {8, JPI$_LAST_LOGIN_I}, + {8, JPI$_LOGINTIM}, + {4, JPI$_PAGEFLTS}, + {4, JPI$_PID}, + {4, JPI$_PPGCNT}, + {4, JPI$_WSPEAK}, + {4, JPI$_FINALEXC}, + {0, 0} /* zero terminated */ }; int RAND_poll(void) { - long pid, iosb[2]; - int status = 0; + + /* determine the number of items in the JPI array */ + + struct items_data_st item_entry; + int item_entry_count = sizeof(items_data)/sizeof(item_entry); + + /* Create the JPI itemlist array to hold item_data content */ + struct { short length, code; - long *buffer; + int *buffer; int *retlen; - } item[32], *pitem; - unsigned char data_buffer[256]; - short total_length = 0; + } item[item_entry_count], *pitem; /* number of entries in items_data */ + struct items_data_st *pitems_data; + int data_buffer[(item_entry_count*2)+4]; /* 8 bytes per entry max */ + int iosb[2]; + int sys_time[2]; + int *ptr; + int i, j ; + int tmp_length = 0; + int total_length = 0; pitems_data = items_data; pitem = item; - /* Setup */ - while (pitems_data->length && (total_length + pitems_data->length <= 256)) { + + /* Setup itemlist for GETJPI */ + while (pitems_data->length) { pitem->length = pitems_data->length; - pitem->code = pitems_data->code; - pitem->buffer = (long *)&data_buffer[total_length]; + pitem->code = pitems_data->code; + pitem->buffer = &data_buffer[total_length]; pitem->retlen = 0; - total_length += pitems_data->length; + /* total_length is in longwords */ + total_length += pitems_data->length/4; pitems_data++; pitem ++; } pitem->length = pitem->code = 0; - /* - * Scan through all the processes in the system and add entropy with - * results from the processes that were possible to look at. - * However, view the information as only half trustable. - */ - pid = -1; /* search context */ - while ((status = sys$getjpiw(0, &pid, 0, item, iosb, 0, 0)) - != SS$_NOMOREPROC) { - if (status == SS$_NORMAL) { - RAND_add((PTR_T) data_buffer, total_length, total_length / 2); + /* Fill data_buffer with various info bits from this process */ + /* and twist that data to seed the SSL random number init */ + + if (sys$getjpiw(EFN$C_ENF, NULL, NULL, item, &iosb, 0, 0) == SS$_NORMAL) { + for (i = 0; i < total_length; i++) { + sys$gettim((struct _generic_64 *)&sys_time[0]); + srand(sys_time[0] * data_buffer[0] * data_buffer[1] + i); + + if (i == (total_length - 1)) { /* for JPI$_FINALEXC */ + ptr = &data_buffer[i]; + for (j = 0; j < 4; j++) { + data_buffer[i + j] = ptr[j]; + /* OK to use rand() just to scramble the seed */ + data_buffer[i + j] ^= (sys_time[0] ^ rand()); + tmp_length++; + } + } else { + /* OK to use rand() just to scramble the seed */ + data_buffer[i] ^= (sys_time[0] ^ rand()); + } } + + total_length += (tmp_length - 1); + + /* size of seed is total_length*4 bytes (64bytes) */ + RAND_add((PTR_T) data_buffer, total_length*4, total_length * 2); + } else { + return 0; } - sys$gettim(iosb); - RAND_add((PTR_T) iosb, sizeof(iosb), sizeof(iosb) / 2); + return 1; }