iodine 0.1.21 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +3 -2
- data/.travis.yml +23 -2
- data/CHANGELOG.md +9 -2
- data/README.md +232 -179
- data/Rakefile +13 -1
- data/bin/config.ru +63 -0
- data/bin/console +6 -0
- data/bin/echo +42 -32
- data/bin/http-hello +62 -0
- data/bin/http-playground +124 -0
- data/bin/playground +62 -0
- data/bin/poc/Gemfile.lock +23 -0
- data/bin/poc/README.md +37 -0
- data/bin/poc/config.ru +66 -0
- data/bin/poc/gemfile +1 -0
- data/bin/poc/www/index.html +57 -0
- data/bin/raw-rbhttp +35 -0
- data/bin/raw_broadcast +66 -0
- data/bin/test_with_faye +40 -0
- data/bin/ws-broadcast +108 -0
- data/bin/ws-echo +108 -0
- data/exe/iodine +59 -0
- data/ext/iodine/base64.c +264 -0
- data/ext/iodine/base64.h +72 -0
- data/ext/iodine/bscrypt-common.h +109 -0
- data/ext/iodine/bscrypt.h +49 -0
- data/ext/iodine/extconf.rb +41 -0
- data/ext/iodine/hex.c +123 -0
- data/ext/iodine/hex.h +70 -0
- data/ext/iodine/http.c +200 -0
- data/ext/iodine/http.h +128 -0
- data/ext/iodine/http1.c +402 -0
- data/ext/iodine/http1.h +56 -0
- data/ext/iodine/http1_simple_parser.c +473 -0
- data/ext/iodine/http1_simple_parser.h +59 -0
- data/ext/iodine/http_request.h +128 -0
- data/ext/iodine/http_response.c +1606 -0
- data/ext/iodine/http_response.h +393 -0
- data/ext/iodine/http_response_http1.h +374 -0
- data/ext/iodine/iodine_core.c +641 -0
- data/ext/iodine/iodine_core.h +70 -0
- data/ext/iodine/iodine_http.c +615 -0
- data/ext/iodine/iodine_http.h +19 -0
- data/ext/iodine/iodine_websocket.c +430 -0
- data/ext/iodine/iodine_websocket.h +21 -0
- data/ext/iodine/libasync.c +552 -0
- data/ext/iodine/libasync.h +117 -0
- data/ext/iodine/libreact.c +347 -0
- data/ext/iodine/libreact.h +244 -0
- data/ext/iodine/libserver.c +912 -0
- data/ext/iodine/libserver.h +435 -0
- data/ext/iodine/libsock.c +950 -0
- data/ext/iodine/libsock.h +478 -0
- data/ext/iodine/misc.c +181 -0
- data/ext/iodine/misc.h +76 -0
- data/ext/iodine/random.c +193 -0
- data/ext/iodine/random.h +48 -0
- data/ext/iodine/rb-call.c +127 -0
- data/ext/iodine/rb-call.h +60 -0
- data/ext/iodine/rb-libasync.h +79 -0
- data/ext/iodine/rb-rack-io.c +389 -0
- data/ext/iodine/rb-rack-io.h +17 -0
- data/ext/iodine/rb-registry.c +213 -0
- data/ext/iodine/rb-registry.h +33 -0
- data/ext/iodine/sha1.c +359 -0
- data/ext/iodine/sha1.h +85 -0
- data/ext/iodine/sha2.c +825 -0
- data/ext/iodine/sha2.h +138 -0
- data/ext/iodine/siphash.c +136 -0
- data/ext/iodine/siphash.h +15 -0
- data/ext/iodine/spnlock.h +235 -0
- data/ext/iodine/websockets.c +696 -0
- data/ext/iodine/websockets.h +120 -0
- data/ext/iodine/xor-crypt.c +189 -0
- data/ext/iodine/xor-crypt.h +107 -0
- data/iodine.gemspec +25 -18
- data/lib/iodine.rb +57 -58
- data/lib/iodine/http.rb +0 -189
- data/lib/iodine/protocol.rb +36 -245
- data/lib/iodine/version.rb +1 -1
- data/lib/rack/handler/iodine.rb +145 -2
- metadata +115 -37
- data/bin/core_http_test +0 -51
- data/bin/em playground +0 -56
- data/bin/hello_world +0 -75
- data/bin/setup +0 -7
- data/lib/iodine/client.rb +0 -5
- data/lib/iodine/core.rb +0 -102
- data/lib/iodine/core_init.rb +0 -143
- data/lib/iodine/http/hpack.rb +0 -553
- data/lib/iodine/http/http1.rb +0 -251
- data/lib/iodine/http/http2.rb +0 -507
- data/lib/iodine/http/rack_support.rb +0 -108
- data/lib/iodine/http/request.rb +0 -462
- data/lib/iodine/http/response.rb +0 -474
- data/lib/iodine/http/session.rb +0 -143
- data/lib/iodine/http/websocket_client.rb +0 -335
- data/lib/iodine/http/websocket_handler.rb +0 -101
- data/lib/iodine/http/websockets.rb +0 -336
- data/lib/iodine/io.rb +0 -56
- data/lib/iodine/logging.rb +0 -46
- data/lib/iodine/settings.rb +0 -158
- data/lib/iodine/ssl_connector.rb +0 -48
- data/lib/iodine/timers.rb +0 -95
data/ext/iodine/misc.c
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
/*
|
2
|
+
(un)copyright: Boaz segev, 2016
|
3
|
+
License: Public Domain except for any non-public-domain algorithms, which are
|
4
|
+
subject to their own licenses.
|
5
|
+
|
6
|
+
Feel free to copy, use and enjoy in accordance with to the license(s).
|
7
|
+
*/
|
8
|
+
#ifndef _GNU_SOURCE
|
9
|
+
#define _GNU_SOURCE
|
10
|
+
#endif
|
11
|
+
#include "misc.h"
|
12
|
+
/* ***************************************************************************
|
13
|
+
Other helper functions
|
14
|
+
*/
|
15
|
+
|
16
|
+
#ifdef HAS_UNIX_FEATURES
|
17
|
+
#include <fcntl.h>
|
18
|
+
#include <limits.h>
|
19
|
+
#include <errno.h>
|
20
|
+
#include <unistd.h>
|
21
|
+
#include <sys/types.h>
|
22
|
+
#include <sys/stat.h>
|
23
|
+
|
24
|
+
/**
|
25
|
+
Allocates memory and dumps the whole file into the memory allocated.
|
26
|
+
|
27
|
+
Remember to call `free` when done.
|
28
|
+
|
29
|
+
Returns the number of bytes allocated. On error, returns 0 and sets the
|
30
|
+
container pointer to NULL.
|
31
|
+
|
32
|
+
This function has some Unix specific properties that resolve links and user
|
33
|
+
folder referencing.
|
34
|
+
*/
|
35
|
+
fdump_s* bscrypt_fdump(const char* file_path, size_t size_limit) {
|
36
|
+
struct stat f_data;
|
37
|
+
int file = -1;
|
38
|
+
fdump_s* container = NULL;
|
39
|
+
size_t file_path_len;
|
40
|
+
if (file_path == NULL || (file_path_len = strlen(file_path)) == 0 ||
|
41
|
+
file_path_len > PATH_MAX)
|
42
|
+
return NULL;
|
43
|
+
|
44
|
+
char real_public_path[PATH_MAX + 1];
|
45
|
+
real_public_path[PATH_MAX] = 0;
|
46
|
+
if (file_path[0] == '~' && getenv("HOME") && file_path_len <= PATH_MAX) {
|
47
|
+
strcpy(real_public_path, getenv("HOME"));
|
48
|
+
memcpy(real_public_path + strlen(real_public_path), file_path + 1,
|
49
|
+
file_path_len);
|
50
|
+
file_path = real_public_path;
|
51
|
+
}
|
52
|
+
|
53
|
+
if (stat(file_path, &f_data))
|
54
|
+
goto error;
|
55
|
+
if (size_limit == 0 || f_data.st_size < size_limit)
|
56
|
+
size_limit = f_data.st_size;
|
57
|
+
container = malloc(size_limit + sizeof(fdump_s));
|
58
|
+
if (!container)
|
59
|
+
goto error;
|
60
|
+
container->length = size_limit;
|
61
|
+
file = open(file_path, O_RDONLY);
|
62
|
+
if (file < 0)
|
63
|
+
goto error;
|
64
|
+
if (read(file, container->data, size_limit) < size_limit)
|
65
|
+
goto error;
|
66
|
+
close(file);
|
67
|
+
return container;
|
68
|
+
error:
|
69
|
+
if (container)
|
70
|
+
free(container), (container = NULL);
|
71
|
+
if (file >= 0)
|
72
|
+
close(file);
|
73
|
+
return 0;
|
74
|
+
}
|
75
|
+
|
76
|
+
#endif /* HAS_UNIX_FEATURES */
|
77
|
+
|
78
|
+
/**
|
79
|
+
A faster (yet less localized) alternative to `gmtime_r`.
|
80
|
+
|
81
|
+
See the libc `gmtime_r` documentation for details.
|
82
|
+
|
83
|
+
Falls back to `gmtime_r` for dates before epoch.
|
84
|
+
*/
|
85
|
+
struct tm* bscrypt_gmtime(const time_t* timer, struct tm* tmbuf) {
|
86
|
+
// static char* DAYS[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
87
|
+
// static char * Months = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
88
|
+
// "Jul",
|
89
|
+
// "Aug", "Sep", "Oct", "Nov", "Dec"};
|
90
|
+
static uint8_t month_len[] = {
|
91
|
+
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, // nonleap year
|
92
|
+
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 // leap year
|
93
|
+
};
|
94
|
+
if (*timer < 0)
|
95
|
+
return gmtime_r(timer, tmbuf);
|
96
|
+
ssize_t tmp;
|
97
|
+
tmbuf->tm_gmtoff = 0;
|
98
|
+
tmbuf->tm_zone = "UTC";
|
99
|
+
tmbuf->tm_isdst = 0;
|
100
|
+
tmbuf->tm_year = 70; // tm_year == The number of years since 1900
|
101
|
+
tmbuf->tm_mon = 0;
|
102
|
+
// for seconds up to weekdays, we build up, as small values clean up larger
|
103
|
+
// values.
|
104
|
+
tmp = ((ssize_t)*timer);
|
105
|
+
tmbuf->tm_sec = tmp % 60;
|
106
|
+
tmp = tmp / 60;
|
107
|
+
tmbuf->tm_min = tmp % 60;
|
108
|
+
tmp = tmp / 60;
|
109
|
+
tmbuf->tm_hour = tmp % 24;
|
110
|
+
tmp = tmp / 24;
|
111
|
+
// day of epoch was a thursday. Add + 3 so sunday == 0...
|
112
|
+
tmbuf->tm_wday = (tmp + 3) % 7;
|
113
|
+
// tmp == number of days since epoch
|
114
|
+
#define DAYS_PER_400_YEARS ((400 * 365) + 97)
|
115
|
+
while (tmp >= DAYS_PER_400_YEARS) {
|
116
|
+
tmbuf->tm_year += 400;
|
117
|
+
tmp -= DAYS_PER_400_YEARS;
|
118
|
+
}
|
119
|
+
#undef DAYS_PER_400_YEARS
|
120
|
+
#define DAYS_PER_100_YEARS ((100 * 365) + 24)
|
121
|
+
while (tmp >= DAYS_PER_100_YEARS) {
|
122
|
+
tmbuf->tm_year += 100;
|
123
|
+
tmp -= DAYS_PER_100_YEARS;
|
124
|
+
if (((tmbuf->tm_year / 100) & 3) ==
|
125
|
+
0) // leap century divisable by 400 => add leap
|
126
|
+
--tmp;
|
127
|
+
}
|
128
|
+
#undef DAYS_PER_100_YEARS
|
129
|
+
#define DAYS_PER_32_YEARS ((32 * 365) + 8)
|
130
|
+
while (tmp >= DAYS_PER_32_YEARS) {
|
131
|
+
tmbuf->tm_year += 32;
|
132
|
+
tmp -= DAYS_PER_32_YEARS;
|
133
|
+
}
|
134
|
+
#undef DAYS_PER_32_YEARS
|
135
|
+
#define DAYS_PER_8_YEARS ((8 * 365) + 2)
|
136
|
+
while (tmp >= DAYS_PER_8_YEARS) {
|
137
|
+
tmbuf->tm_year += 8;
|
138
|
+
tmp -= DAYS_PER_8_YEARS;
|
139
|
+
}
|
140
|
+
#undef DAYS_PER_8_YEARS
|
141
|
+
#define DAYS_PER_4_YEARS ((4 * 365) + 1)
|
142
|
+
while (tmp >= DAYS_PER_4_YEARS) {
|
143
|
+
tmbuf->tm_year += 4;
|
144
|
+
tmp -= DAYS_PER_4_YEARS;
|
145
|
+
}
|
146
|
+
#undef DAYS_PER_4_YEARS
|
147
|
+
while (tmp >= 365) {
|
148
|
+
tmbuf->tm_year += 1;
|
149
|
+
tmp -= 365;
|
150
|
+
if ((tmbuf->tm_year & 3) == 0) { // leap year
|
151
|
+
if (tmp > 0) {
|
152
|
+
--tmp;
|
153
|
+
continue;
|
154
|
+
} else {
|
155
|
+
tmp += 365;
|
156
|
+
--tmbuf->tm_year;
|
157
|
+
break;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
tmbuf->tm_yday = tmp;
|
162
|
+
if ((tmbuf->tm_year & 3) == 1) {
|
163
|
+
// regular year
|
164
|
+
for (size_t i = 0; i < 12; i++) {
|
165
|
+
if (tmp < month_len[i])
|
166
|
+
break;
|
167
|
+
tmp -= month_len[i];
|
168
|
+
++tmbuf->tm_mon;
|
169
|
+
}
|
170
|
+
} else {
|
171
|
+
// leap year
|
172
|
+
for (size_t i = 12; i < 24; i++) {
|
173
|
+
if (tmp < month_len[i])
|
174
|
+
break;
|
175
|
+
tmp -= month_len[i];
|
176
|
+
++tmbuf->tm_mon;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
tmbuf->tm_mday = tmp;
|
180
|
+
return tmbuf;
|
181
|
+
}
|
data/ext/iodine/misc.h
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
/*
|
2
|
+
(un)copyright: Boaz segev, 2016
|
3
|
+
License: Public Domain except for any non-public-domain algorithms, which are
|
4
|
+
subject to their own licenses.
|
5
|
+
|
6
|
+
Feel free to copy, use and enjoy in accordance with to the license(s).
|
7
|
+
*/
|
8
|
+
#ifndef bscrypt_MISC_H
|
9
|
+
#define bscrypt_MISC_H
|
10
|
+
#include "bscrypt-common.h"
|
11
|
+
#include <time.h>
|
12
|
+
/* *****************************************************************************
|
13
|
+
C++ extern
|
14
|
+
*/
|
15
|
+
#if defined(__cplusplus)
|
16
|
+
extern "C" {
|
17
|
+
#endif
|
18
|
+
|
19
|
+
/* ***************************************************************************
|
20
|
+
Miscellaneous helper functions
|
21
|
+
|
22
|
+
i.e. file content dumping and GMT time alternative to `gmtime_r`.
|
23
|
+
*/
|
24
|
+
|
25
|
+
#ifdef HAS_UNIX_FEATURES
|
26
|
+
|
27
|
+
/**
|
28
|
+
File dump data.
|
29
|
+
|
30
|
+
This struct (or, a pointer to this struct) is returned
|
31
|
+
by the `bscrypt.fdump`
|
32
|
+
function on success.
|
33
|
+
|
34
|
+
To free the pointer returned, simply call `free`.
|
35
|
+
*/
|
36
|
+
typedef struct {
|
37
|
+
size_t length;
|
38
|
+
char data[];
|
39
|
+
} fdump_s;
|
40
|
+
|
41
|
+
/**
|
42
|
+
Allocates memory and dumps the whole file into the
|
43
|
+
memory allocated.
|
44
|
+
Remember
|
45
|
+
to call `free` when done.
|
46
|
+
|
47
|
+
Returns the number of bytes allocated. On error,
|
48
|
+
returns 0 and sets the
|
49
|
+
container pointer to NULL.
|
50
|
+
|
51
|
+
This function has some Unix specific properties that
|
52
|
+
resolve links and user
|
53
|
+
folder referencing.
|
54
|
+
*/
|
55
|
+
fdump_s *bscrypt_fdump(const char *file_path, size_t size_limit);
|
56
|
+
|
57
|
+
#endif /* HAS_UNIX_FEATURES */
|
58
|
+
|
59
|
+
/**
|
60
|
+
A faster (yet less localized) alternative to
|
61
|
+
`gmtime_r`.
|
62
|
+
|
63
|
+
See the libc `gmtime_r` documentation for details.
|
64
|
+
|
65
|
+
Falls back to `gmtime_r` for dates before epoch.
|
66
|
+
*/
|
67
|
+
struct tm *bscrypt_gmtime(const time_t *timer, struct tm *tmbuf);
|
68
|
+
|
69
|
+
/* *****************************************************************************
|
70
|
+
C++ extern finish
|
71
|
+
*/
|
72
|
+
#if defined(__cplusplus)
|
73
|
+
}
|
74
|
+
#endif
|
75
|
+
|
76
|
+
#endif
|
data/ext/iodine/random.c
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
/*
|
2
|
+
(un)copyright: Boaz segev, 2016
|
3
|
+
License: Public Domain except for any non-public-domain algorithms, which are
|
4
|
+
subject to their own licenses.
|
5
|
+
|
6
|
+
Feel free to copy, use and enjoy in accordance with to the license(s).
|
7
|
+
*/
|
8
|
+
#ifndef _GNU_SOURCE
|
9
|
+
#define _GNU_SOURCE
|
10
|
+
#endif
|
11
|
+
#include "random.h"
|
12
|
+
|
13
|
+
#if defined(USE_ALT_RANDOM) || !defined(HAS_UNIX_FEATURES)
|
14
|
+
#include <time.h>
|
15
|
+
#include "sha2.h"
|
16
|
+
uint32_t bscrypt_rand32(void) {
|
17
|
+
bits256_u pseudo = bscrypt_rand256();
|
18
|
+
return pseudo.ints[3];
|
19
|
+
}
|
20
|
+
|
21
|
+
uint64_t bscrypt_rand64(void) {
|
22
|
+
bits256_u pseudo = bscrypt_rand256();
|
23
|
+
return pseudo.words[3];
|
24
|
+
}
|
25
|
+
|
26
|
+
bits128_u bscrypt_rand128(void) {
|
27
|
+
bits256_u pseudo = bscrypt_rand256();
|
28
|
+
bits128_u ret;
|
29
|
+
ret.words[0] = pseudo.words[0];
|
30
|
+
ret.words[1] = pseudo.words[1];
|
31
|
+
return ret;
|
32
|
+
}
|
33
|
+
|
34
|
+
bits256_u bscrypt_rand256(void) {
|
35
|
+
clock_t cpu_state = clock();
|
36
|
+
time_t the_time;
|
37
|
+
time(&the_time);
|
38
|
+
bits256_u pseudo;
|
39
|
+
sha2_s sha2 = bscrypt_sha2_init(SHA_256);
|
40
|
+
bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
|
41
|
+
bscrypt_sha2_write(&sha2, &the_time, sizeof(the_time));
|
42
|
+
bscrypt_sha2_write(&sha2, &cpu_state - 2, 64); /* whatever's on the stack */
|
43
|
+
bscrypt_sha2_result(&sha2);
|
44
|
+
pseudo.words[0] = sha2.digest.i64[0];
|
45
|
+
pseudo.words[1] = sha2.digest.i64[1];
|
46
|
+
pseudo.words[2] = sha2.digest.i64[2];
|
47
|
+
pseudo.words[3] = sha2.digest.i64[3];
|
48
|
+
return pseudo;
|
49
|
+
}
|
50
|
+
|
51
|
+
void bscrypt_rand_bytes(void *target, size_t length) {
|
52
|
+
clock_t cpu_state = clock();
|
53
|
+
time_t the_time;
|
54
|
+
time(&the_time);
|
55
|
+
sha2_s sha2 = bscrypt_sha2_init(SHA_512);
|
56
|
+
bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
|
57
|
+
bscrypt_sha2_write(&sha2, &the_time, sizeof(the_time));
|
58
|
+
bscrypt_sha2_write(&sha2, &cpu_state - 2, 64); /* whatever's on the stack */
|
59
|
+
bscrypt_sha2_result(&sha2);
|
60
|
+
while (length > 64) {
|
61
|
+
memcpy(target, sha2.digest.str, 64);
|
62
|
+
length -= 64;
|
63
|
+
target += 64;
|
64
|
+
bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
|
65
|
+
bscrypt_sha2_result(&sha2);
|
66
|
+
}
|
67
|
+
if (length > 32) {
|
68
|
+
memcpy(target, sha2.digest.str, 32);
|
69
|
+
length -= 32;
|
70
|
+
target += 32;
|
71
|
+
bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
|
72
|
+
bscrypt_sha2_result(&sha2);
|
73
|
+
}
|
74
|
+
if (length > 16) {
|
75
|
+
memcpy(target, sha2.digest.str, 16);
|
76
|
+
length -= 16;
|
77
|
+
target += 16;
|
78
|
+
bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
|
79
|
+
bscrypt_sha2_result(&sha2);
|
80
|
+
}
|
81
|
+
if (length > 8) {
|
82
|
+
memcpy(target, sha2.digest.str, 8);
|
83
|
+
length -= 8;
|
84
|
+
target += 8;
|
85
|
+
bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
|
86
|
+
bscrypt_sha2_result(&sha2);
|
87
|
+
}
|
88
|
+
while (length) {
|
89
|
+
*((uint8_t *)target) = sha2.digest.str[length];
|
90
|
+
++target;
|
91
|
+
--length;
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
#else
|
96
|
+
/* ***************************************************************************
|
97
|
+
Unix Random Engine (use built in machine)
|
98
|
+
*/
|
99
|
+
#include <fcntl.h>
|
100
|
+
#include <errno.h>
|
101
|
+
#include <unistd.h>
|
102
|
+
#include <pthread.h>
|
103
|
+
|
104
|
+
/* ***************************************************************************
|
105
|
+
Machine specific changes
|
106
|
+
*/
|
107
|
+
// #ifdef __linux__
|
108
|
+
// #undef bswap16
|
109
|
+
// #undef bswap32
|
110
|
+
// #undef bswap64
|
111
|
+
// #include <machine/bswap.h>
|
112
|
+
// #endif
|
113
|
+
#ifdef HAVE_X86Intrin
|
114
|
+
// #undef bswap16
|
115
|
+
/*
|
116
|
+
#undef bswap32
|
117
|
+
#define bswap32(i) \
|
118
|
+
{ __asm__("bswap %k0" : "+r"(i) :); }
|
119
|
+
*/
|
120
|
+
#undef bswap64
|
121
|
+
#define bswap64(i) \
|
122
|
+
{ __asm__("bswapq %0" : "+r"(i) :); }
|
123
|
+
|
124
|
+
// shadow sched_yield as _mm_pause for spinwait
|
125
|
+
#define sched_yield() _mm_pause()
|
126
|
+
#endif
|
127
|
+
|
128
|
+
/* ***************************************************************************
|
129
|
+
Random ... (why is this not a system call?)
|
130
|
+
*/
|
131
|
+
|
132
|
+
/* rand generator management */
|
133
|
+
static int _rand_fd_ = -1;
|
134
|
+
static void close_rand_fd(void) {
|
135
|
+
if (_rand_fd_ >= 0)
|
136
|
+
close(_rand_fd_);
|
137
|
+
_rand_fd_ = -1;
|
138
|
+
}
|
139
|
+
static void init_rand_fd(void) {
|
140
|
+
if (_rand_fd_ < 0) {
|
141
|
+
while ((_rand_fd_ = open("/dev/urandom", O_RDONLY)) == -1) {
|
142
|
+
if (errno == ENXIO)
|
143
|
+
perror("bscrypt fatal error, caanot initiate random generator"),
|
144
|
+
exit(-1);
|
145
|
+
sched_yield();
|
146
|
+
}
|
147
|
+
}
|
148
|
+
atexit(close_rand_fd);
|
149
|
+
}
|
150
|
+
/* rand function template */
|
151
|
+
#define MAKE_RAND_FUNC(type, func_name) \
|
152
|
+
type func_name(void) { \
|
153
|
+
if (_rand_fd_ < 0) \
|
154
|
+
init_rand_fd(); \
|
155
|
+
type ret; \
|
156
|
+
while (read(_rand_fd_, &ret, sizeof(type)) < 0) \
|
157
|
+
sched_yield(); \
|
158
|
+
return ret; \
|
159
|
+
}
|
160
|
+
/* rand functions */
|
161
|
+
MAKE_RAND_FUNC(uint32_t, bscrypt_rand32);
|
162
|
+
MAKE_RAND_FUNC(uint64_t, bscrypt_rand64);
|
163
|
+
MAKE_RAND_FUNC(bits128_u, bscrypt_rand128);
|
164
|
+
MAKE_RAND_FUNC(bits256_u, bscrypt_rand256);
|
165
|
+
/* clear template */
|
166
|
+
#undef MAKE_RAND_FUNC
|
167
|
+
|
168
|
+
void bscrypt_rand_bytes(void *target, size_t length) {
|
169
|
+
if (_rand_fd_ < 0)
|
170
|
+
init_rand_fd();
|
171
|
+
while (read(_rand_fd_, target, length) < 0)
|
172
|
+
sched_yield();
|
173
|
+
}
|
174
|
+
#endif /* Unix Random */
|
175
|
+
|
176
|
+
/*******************************************************************************
|
177
|
+
Random
|
178
|
+
*/
|
179
|
+
#if defined(DEBUG) && DEBUG == 1
|
180
|
+
void bscrypt_test_random(void) {
|
181
|
+
clock_t start, end;
|
182
|
+
bscrypt_rand256();
|
183
|
+
start = clock();
|
184
|
+
for (size_t i = 0; i < 100000; i++) {
|
185
|
+
bscrypt_rand256();
|
186
|
+
}
|
187
|
+
end = clock();
|
188
|
+
fprintf(stderr,
|
189
|
+
"+ bscrypt Random generator available\n+ bscrypt 100K X 256bit "
|
190
|
+
"Random %lu CPU clock count\n",
|
191
|
+
end - start);
|
192
|
+
}
|
193
|
+
#endif
|