suricata
util-random.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2017 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Functions for getting a random value based on
24  * SEI CERT C Coding Standard MSC30-C
25  */
26 
27 #include "suricata-common.h"
28 #include "util-random.h"
29 
30 
31 #if !(defined(HAVE_WINCRYPT_H) && defined(OS_WIN32))
32 #if defined(HAVE_CLOCK_GETTIME)
33 
34 static long int RandomGetClock(void)
35 {
36  struct timespec ts;
37  clock_gettime(CLOCK_REALTIME, &ts);
38 
39  // coverity[dont_call : FALSE]
40  srandom(ts.tv_nsec ^ ts.tv_sec);
41  long int value = random();
42  return value;
43 }
44 
45 #else
46 
47 static long int RandomGetPosix(void)
48 {
49  struct timeval tv;
50  memset(&tv, 0, sizeof(tv));
51  gettimeofday(&tv, NULL);
52 
53  // coverity[dont_call : FALSE]
54  srandom(tv.tv_usec ^ tv.tv_sec);
55  long int value = random();
56  return value;
57 }
58 
59 #endif
60 #endif /* !(defined(HAVE_WINCRYPT_H) && defined(OS_WIN32)) */
61 
62 #if defined(HAVE_WINCRYPT_H) && defined(OS_WIN32)
63 #include <wincrypt.h>
64 
65 long int RandomGet(void)
66 {
68  return 0;
69 
70  HCRYPTPROV p;
71  if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL, 0)) {
72  DWORD err = GetLastError();
73  SCLogDebug("CryptAcquireContext error: %" PRIu32, (uint32_t)err);
74  if (err == (DWORD)NTE_BAD_KEYSET) {
75  /* The key doesn't exist yet, create it */
76  if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL,
77  CRYPT_NEWKEYSET)) {
78 
79  SCLogDebug("CryptAcquireContext error: %" PRIu32,
80  (uint32_t)err);
81  return -1;
82  }
83  } else {
84  return -1;
85  }
86  }
87 
88  long int value = 0;
89  if (!CryptGenRandom(p, sizeof(value), (BYTE *)&value)) {
90  (void)CryptReleaseContext(p, 0);
91  return -1;
92  }
93 
94  (void)CryptReleaseContext(p, 0);
95 
96  return value;
97 }
98 #elif defined(HAVE_GETRANDOM)
99 long int RandomGet(void)
100 {
102  return 0;
103 
104  long int value = 0;
105  int ret = getrandom(&value, sizeof(value), 0);
106  /* ret should be sizeof(value), but if it is > 0 and < sizeof(value)
107  * it's still better than nothing so we return what we have */
108  if (ret <= 0) {
109  if (ret == -1 && errno == ENOSYS) {
110 #if defined(HAVE_CLOCK_GETTIME)
111  return RandomGetClock();
112 #else
113  return RandomGetPosix();
114 #endif
115  }
116  return -1;
117  }
118  return value;
119 }
120 #elif defined(HAVE_CLOCK_GETTIME)
121 long int RandomGet(void)
122 {
124  return 0;
125 
126  return RandomGetClock();
127 }
128 #else
129 long int RandomGet(void)
130 {
132  return 0;
133 
134  return RandomGetPosix();
135 }
136 #endif
#define SCLogDebug(...)
Definition: util-debug.h:335
long int RandomGet(void)
Definition: util-random.c:129
int g_disable_randomness
Definition: suricata.c:230
uint64_t ts