fix undoes errors introduced by https://github.com/openssl/openssl/commit/fc6076ca272...
[openssl.git] / crypto / rand / rand_vms.c
1 /*
2  * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /*
11  * Modified by VMS Software, Inc (2016)
12  *    Eliminate looping through all processes (performance)
13  *    Add additional randomizations using rand() function
14  */
15
16 #include <openssl/rand.h>
17 #include "rand_lcl.h"
18
19 #if defined(OPENSSL_SYS_VMS)
20 # include <descrip.h>
21 # include <jpidef.h>
22 # include <ssdef.h>
23 # include <starlet.h>
24 # include <efndef>
25 # ifdef __DECC
26 #  pragma message disable DOLLARID
27 # endif
28
29 /*
30  * Use 32-bit pointers almost everywhere.  Define the type to which to cast a
31  * pointer passed to an external function.
32  */
33 # if __INITIAL_POINTER_SIZE == 64
34 #  define PTR_T __void_ptr64
35 #  pragma pointer_size save
36 #  pragma pointer_size 32
37 # else                          /* __INITIAL_POINTER_SIZE == 64 */
38 #  define PTR_T void *
39 # endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
40
41 static struct items_data_st {
42     short length, code;         /* length is number of bytes */
43 } items_data[] = {
44     {4, JPI$_BUFIO},
45     {4, JPI$_CPUTIM},
46     {4, JPI$_DIRIO},
47     {4, JPI$_IMAGECOUNT},
48     {8, JPI$_LAST_LOGIN_I},
49     {8, JPI$_LOGINTIM},
50     {4, JPI$_PAGEFLTS},
51     {4, JPI$_PID},
52     {4, JPI$_PPGCNT},
53     {4, JPI$_WSPEAK},
54     {4, JPI$_FINALEXC},
55     {0, 0}                      /* zero terminated */
56 };
57
58 int RAND_poll(void)
59 {
60
61     /* determine the number of items in the JPI array */
62
63     struct items_data_st item_entry;
64     int item_entry_count = sizeof(items_data)/sizeof(item_entry);
65
66     /* Create the JPI itemlist array to hold item_data content */
67
68     struct {
69         short length, code;
70         int *buffer;
71         int *retlen;
72     } item[item_entry_count], *pitem; /* number of entries in items_data */
73
74     struct items_data_st *pitems_data;
75     int data_buffer[(item_entry_count*2)+4]; /* 8 bytes per entry max */
76     int iosb[2];
77     int sys_time[2];
78     int *ptr;
79     int i, j ;
80     int tmp_length   = 0;
81     int total_length = 0;
82
83     pitems_data = items_data;
84     pitem = item;
85
86
87     /* Setup itemlist for GETJPI */
88     while (pitems_data->length) {
89         pitem->length = pitems_data->length;
90         pitem->code   = pitems_data->code;
91         pitem->buffer = &data_buffer[total_length];
92         pitem->retlen = 0;
93         /* total_length is in longwords */
94         total_length += pitems_data->length/4;
95         pitems_data++;
96         pitem ++;
97     }
98     pitem->length = pitem->code = 0;
99
100     /* Fill data_buffer with various info bits from this process */
101     /* and twist that data to seed the SSL random number init    */
102
103     if (sys$getjpiw(EFN$C_ENF, NULL, NULL, item, &iosb, 0, 0) == SS$_NORMAL) {
104         for (i = 0; i < total_length; i++) {
105             sys$gettim((struct _generic_64 *)&sys_time[0]);
106             srand(sys_time[0] * data_buffer[0] * data_buffer[1] + i);
107
108             if (i == (total_length - 1)) { /* for JPI$_FINALEXC */
109                 ptr = &data_buffer[i];
110                 for (j = 0; j < 4; j++) {
111                     data_buffer[i + j] = ptr[j];
112                     /* OK to use rand() just to scramble the seed */
113                     data_buffer[i + j] ^= (sys_time[0] ^ rand());
114                     tmp_length++;
115                 }
116             } else {
117                 /* OK to use rand() just to scramble the seed */
118                 data_buffer[i] ^= (sys_time[0] ^ rand());
119             }
120         }
121
122         total_length += (tmp_length - 1);
123
124         /* size of seed is total_length*4 bytes (64bytes) */
125         RAND_add((PTR_T) data_buffer, total_length*4, total_length * 2);
126     } else {
127         return 0;
128     }
129
130     return 1;
131 }
132
133 #endif