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 "suricata.h"
29#include "util-random.h"
30#include "util-debug.h"
31
32#if !(defined(HAVE_WINCRYPT_H) && defined(OS_WIN32))
33#if defined(HAVE_CLOCK_GETTIME)
34
35static long int RandomGetClock(void)
36{
37 struct timespec ts;
38 clock_gettime(CLOCK_REALTIME, &ts);
39
40 // coverity[dont_call : FALSE]
41 srandom((unsigned int)(ts.tv_nsec ^ ts.tv_sec));
42 long int value = random();
43 return value;
44}
45
46#else
47
48static long int RandomGetPosix(void)
49{
50 struct timeval tv;
51 memset(&tv, 0, sizeof(tv));
52 gettimeofday(&tv, NULL);
53
54 // coverity[dont_call : FALSE]
55 srandom(tv.tv_usec ^ tv.tv_sec);
56 long int value = random();
57 return value;
58}
59
60#endif
61#endif /* !(defined(HAVE_WINCRYPT_H) && defined(OS_WIN32)) */
62
63#if defined(HAVE_WINCRYPT_H) && defined(OS_WIN32)
64#include <wincrypt.h>
65
66long int RandomGet(void)
67{
69 return 0;
70
71 HCRYPTPROV p;
72 if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL, 0)) {
73 DWORD err = GetLastError();
74 SCLogDebug("CryptAcquireContext error: %" PRIu32, (uint32_t)err);
75 if (err == (DWORD)NTE_BAD_KEYSET) {
76 /* The key doesn't exist yet, create it */
77 if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL,
78 CRYPT_NEWKEYSET)) {
79
80 SCLogDebug("CryptAcquireContext error: %" PRIu32,
81 (uint32_t)err);
82 return -1;
83 }
84 } else {
85 return -1;
86 }
87 }
88
89 long int value = 0;
90 if (!CryptGenRandom(p, sizeof(value), (BYTE *)&value)) {
91 (void)CryptReleaseContext(p, 0);
92 return -1;
93 }
94
95 (void)CryptReleaseContext(p, 0);
96
97 return value;
98}
99#elif defined(HAVE_GETRANDOM)
100long int RandomGet(void)
101{
103 return 0;
104
105 long int value = 0;
106 ssize_t ret = getrandom(&value, sizeof(value), 0);
107 /* ret should be sizeof(value), but if it is > 0 and < sizeof(value)
108 * it's still better than nothing so we return what we have */
109 if (ret <= 0) {
110 if (ret == -1 && errno == ENOSYS) {
111#if defined(HAVE_CLOCK_GETTIME)
112 return RandomGetClock();
113#else
114 return RandomGetPosix();
115#endif
116 }
117 return -1;
118 }
119 return value;
120}
121#elif defined(HAVE_CLOCK_GETTIME)
122long int RandomGet(void)
123{
125 return 0;
126
127 return RandomGetClock();
128}
129#else
130long int RandomGet(void)
131{
133 return 0;
134
135 return RandomGetPosix();
136}
137#endif
ThreadVars * tv
uint64_t ts
int g_disable_randomness
Definition suricata.c:195
#define SCLogDebug(...)
Definition util-debug.h:275
long int RandomGet(void)