OpenVAS Scanner  22.7.9
genrand.c
Go to the documentation of this file.
1 /* SPDX-FileCopyrightText: 2023 Greenbone AG
2  * SPDX-FileCopyrightText: 2001 Jeremy Allison
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later
5  */
6 
13 /*
14  Modified for OpenVAS by Preeti Subramanian <spreeti@secpod.com>
15  MODIFICATION: This file has only those functions that cater to the
16  requirements of OpenVAS, remaining functions are removed
17  * BOOL is changed to bool
18  * sys_open is changed to open
19  * sys_getpid is changed to getpid
20  * In do_reseed function, adding secret file contents of smb
21  passwd file not required(removed) and add in the root
22  encrypted password note required(removed)
23 */
24 #include "byteorder.h"
25 #include "md4.h"
26 #include "proto.h"
27 #include "smb.h"
28 
29 #include <pwd.h>
30 #include <time.h>
31 #include <unistd.h>
32 #ifndef HAVE_UCBINCLUDE
33 #include <fcntl.h>
34 #else
35 /* Solaris */
36 #include "/usr/ucbinclude/fcntl.h"
37 #endif
38 
39 #ifndef uint32
40 #define uint32 uint32_t
41 #endif
42 
43 typedef unsigned int bool;
44 #define False 0
45 #define True 1
46 
47 static unsigned char smb_arc4_state[258];
48 static uint32 counter;
49 
55 /* zero a structure */
56 #define ZERO_STRUCT(x) memset ((char *) &(x), 0, sizeof (x))
57 
58 static bool done_reseed_ntlmssp = False;
59 static void (*reseed_callback_ntlmssp) (int *newseed);
60 
61 /****************************************************************
62  Copy any user given reseed data.
63 *****************************************************************/
64 
65 static void
66 get_rand_reseed_data_ntlmssp (int *reseed_data)
67 {
69  {
70  reseed_callback_ntlmssp (reseed_data);
71  }
72  else
73  {
74  *reseed_data = 0;
75  }
76 }
77 
78 /****************************************************************
79  Get a 16 byte hash from the contents of a file.
80  Note that the hash is not initialised.
81 *****************************************************************/
82 
83 static void
84 do_filehash_ntlmssp (const char *fname, unsigned char *the_hash)
85 {
86  unsigned char buf[1011]; /* deliberate weird size */
87  unsigned char tmp_md4[16];
88  int fd, n;
89 
90  fd = open (fname, O_RDONLY, 0);
91  if (fd == -1)
92  return;
93 
94  while ((n = read (fd, (char *) buf, sizeof (buf))) > 0)
95  {
96  mdfour_ntlmssp (tmp_md4, buf, n);
97  for (n = 0; n < 16; n++)
98  the_hash[n] ^= tmp_md4[n];
99  }
100  close (fd);
101 }
102 
103 /**************************************************************
104  Try and get a good random number seed. Try a number of
105  different factors. Firstly, try /dev/urandom - use if exists.
106 
107  We use /dev/urandom as a read of /dev/random can block if
108  the entropy pool dries up. This leads clients to timeout
109  or be very slow on connect.
110 
111  If we can't use /dev/urandom then seed the stream random generator
112  above...
113 **************************************************************/
114 
115 static int
116 do_reseed_ntlmssp (bool use_fd, int fd)
117 {
118  unsigned char seed_inbuf[40];
119  uint32 v1, v2;
120  struct timeval tval;
121  pid_t mypid;
122  int reseed_data = 0;
123 
124  if (use_fd)
125  {
126  if (fd != -1)
127  return fd;
128  fd = open ("/dev/urandom", O_RDONLY, 0);
129  if (fd >= 0)
130  return fd;
131  }
132 
133  /* Add in some secret file contents */
134  memset (seed_inbuf, '\0', sizeof (seed_inbuf));
135  do_filehash_ntlmssp ("/etc/shadow", &seed_inbuf[0]);
136  /*
137  * Add the counter, time of day, and pid.
138  */
139 
140  GetTimeOfDay_ntlmssp (&tval);
141  mypid = getpid ();
142  v1 = (counter++) + mypid + (uint32) tval.tv_sec;
143  v2 = (counter++) * mypid + (uint32) tval.tv_usec;
144 
145  SIVAL (seed_inbuf, 32, v1 ^ IVAL (seed_inbuf, 32));
146  SIVAL (seed_inbuf, 36, v2 ^ IVAL (seed_inbuf, 36));
147 
148  /*
149  * Add any user-given reseed data.
150  */
151 
152  get_rand_reseed_data_ntlmssp (&reseed_data);
153  if (reseed_data)
154  {
155  size_t i;
156  for (i = 0; i < sizeof (seed_inbuf); i++)
157  seed_inbuf[i] ^= ((char *) (&reseed_data))[i % sizeof (reseed_data)];
158  }
159 
160  smb_arc4_init_ntlmssp (smb_arc4_state, seed_inbuf, sizeof (seed_inbuf));
161 
162  return -1;
163 }
164 
165 /*******************************************************************
166  Interface to the (hopefully) good crypto random number generator.
167 ********************************************************************/
168 
169 void
170 generate_random_buffer_ntlmssp (unsigned char *out, int len)
171 {
172  static int urand_fd = -1;
173  unsigned char md4_buf[64];
174  unsigned char tmp_buf[16];
175  unsigned char *p;
176 
177  if (!done_reseed_ntlmssp)
178  {
179  urand_fd = do_reseed_ntlmssp (True, urand_fd);
181  }
182 
183  if (urand_fd != -1 && len > 0)
184  {
185  if (read (urand_fd, out, len) == len)
186  return; /* len bytes of random data read from urandom. */
187 
188  /* Read of urand error, drop back to non urand method. */
189  close (urand_fd);
190  urand_fd = -1;
191  do_reseed_ntlmssp (False, -1);
193  }
194 
195  /*
196  * Generate random numbers in chunks of 64 bytes,
197  * then md4 them & copy to the output buffer.
198  * This way the raw state of the stream is never externally
199  * seen.
200  */
201 
202  p = out;
203  while (len > 0)
204  {
205  int copy_len = len > 16 ? 16 : len;
206 
207  bzero (md4_buf, sizeof (md4_buf));
208  smb_arc4_crypt_ntlmssp (smb_arc4_state, md4_buf, sizeof (md4_buf));
209  mdfour_ntlmssp (tmp_buf, md4_buf, sizeof (md4_buf));
210  memcpy (p, tmp_buf, copy_len);
211  p += copy_len;
212  len -= copy_len;
213  }
214 }
mdfour_ntlmssp
void mdfour_ntlmssp(unsigned char *out, const unsigned char *in, int n)
Definition: md4.c:165
do_reseed_ntlmssp
static int do_reseed_ntlmssp(bool use_fd, int fd)
Definition: genrand.c:116
byteorder.h
Unix SMB/CIFS implementation. SMB Byte handling.
True
#define True
Definition: genrand.c:45
get_rand_reseed_data_ntlmssp
static void get_rand_reseed_data_ntlmssp(int *reseed_data)
Definition: genrand.c:66
SIVAL
#define SIVAL(buf, pos, val)
Definition: byteorder.h:117
smb_arc4_crypt_ntlmssp
void smb_arc4_crypt_ntlmssp(unsigned char arc4_state_inout[258], unsigned char *data, size_t len)
Definition: arc4.c:47
smb_arc4_state
static unsigned char smb_arc4_state[258]
Definition: genrand.c:47
smb.h
Unix SMB/CIFS implementation.
generate_random_buffer_ntlmssp
void generate_random_buffer_ntlmssp(unsigned char *out, int len)
Definition: genrand.c:170
proto.h
done_reseed_ntlmssp
static bool done_reseed_ntlmssp
Definition: genrand.c:58
smb_arc4_init_ntlmssp
void smb_arc4_init_ntlmssp(unsigned char arc4_state_out[258], const unsigned char *key, size_t keylen)
Definition: arc4.c:16
counter
static uint32 counter
Definition: genrand.c:48
len
uint8_t len
Definition: nasl_packet_forgery.c:1
do_filehash_ntlmssp
static void do_filehash_ntlmssp(const char *fname, unsigned char *the_hash)
Definition: genrand.c:84
timeval
static struct timeval timeval(unsigned long val)
Definition: nasl_builtin_synscan.c:94
reseed_callback_ntlmssp
static void(* reseed_callback_ntlmssp)(int *newseed)
Definition: genrand.c:59
False
#define False
Definition: genrand.c:44
md4.h
Unix SMB/CIFS implementation.
uint32
#define uint32
Definition: genrand.c:40
IVAL
#define IVAL(buf, pos)
Definition: byteorder.h:108
GetTimeOfDay_ntlmssp
void GetTimeOfDay_ntlmssp(struct timeval *tval)
Definition: time.c:90
bool
unsigned int bool
Definition: genrand.c:43