bcrypt 3.1.14-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Written by Solar Designer <solar at openwall.com> in 2000-2011.
3
+ * No copyright is claimed, and the software is hereby placed in the public
4
+ * domain. In case this attempt to disclaim copyright and place the software
5
+ * in the public domain is deemed null and void, then the software is
6
+ * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
7
+ * general public under the following terms:
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted.
11
+ *
12
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
13
+ *
14
+ * See crypt_blowfish.c for more information.
15
+ */
16
+
17
+ #ifndef _CRYPT_BLOWFISH_H
18
+ #define _CRYPT_BLOWFISH_H
19
+
20
+ extern int _crypt_output_magic(const char *setting, char *output, int size);
21
+ extern char *_crypt_blowfish_rn(const char *key, const char *setting,
22
+ char *output, int size);
23
+ extern char *_crypt_gensalt_blowfish_rn(const char *prefix,
24
+ unsigned long count,
25
+ const char *input, int size, char *output, int output_size);
26
+
27
+ #endif
@@ -0,0 +1,124 @@
1
+ /*
2
+ * Written by Solar Designer <solar at openwall.com> in 2000-2011.
3
+ * No copyright is claimed, and the software is hereby placed in the public
4
+ * domain. In case this attempt to disclaim copyright and place the software
5
+ * in the public domain is deemed null and void, then the software is
6
+ * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
7
+ * general public under the following terms:
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted.
11
+ *
12
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
13
+ *
14
+ * See crypt_blowfish.c for more information.
15
+ *
16
+ * This file contains salt generation functions for the traditional and
17
+ * other common crypt(3) algorithms, except for bcrypt which is defined
18
+ * entirely in crypt_blowfish.c.
19
+ */
20
+
21
+ #include <string.h>
22
+
23
+ #include <errno.h>
24
+ #ifndef __set_errno
25
+ #define __set_errno(val) errno = (val)
26
+ #endif
27
+
28
+ /* Just to make sure the prototypes match the actual definitions */
29
+ #include "crypt_gensalt.h"
30
+
31
+ const unsigned char _crypt_itoa64[64 + 1] =
32
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
33
+
34
+ char *_crypt_gensalt_traditional_rn(const char *prefix, unsigned long count,
35
+ const char *input, int size, char *output, int output_size)
36
+ {
37
+ (void) prefix;
38
+
39
+ if (size < 2 || output_size < 2 + 1 || (count && count != 25)) {
40
+ if (output_size > 0) output[0] = '\0';
41
+ __set_errno((output_size < 2 + 1) ? ERANGE : EINVAL);
42
+ return NULL;
43
+ }
44
+
45
+ output[0] = _crypt_itoa64[(unsigned int)input[0] & 0x3f];
46
+ output[1] = _crypt_itoa64[(unsigned int)input[1] & 0x3f];
47
+ output[2] = '\0';
48
+
49
+ return output;
50
+ }
51
+
52
+ char *_crypt_gensalt_extended_rn(const char *prefix, unsigned long count,
53
+ const char *input, int size, char *output, int output_size)
54
+ {
55
+ unsigned long value;
56
+
57
+ (void) prefix;
58
+
59
+ /* Even iteration counts make it easier to detect weak DES keys from a look
60
+ * at the hash, so they should be avoided */
61
+ if (size < 3 || output_size < 1 + 4 + 4 + 1 ||
62
+ (count && (count > 0xffffff || !(count & 1)))) {
63
+ if (output_size > 0) output[0] = '\0';
64
+ __set_errno((output_size < 1 + 4 + 4 + 1) ? ERANGE : EINVAL);
65
+ return NULL;
66
+ }
67
+
68
+ if (!count) count = 725;
69
+
70
+ output[0] = '_';
71
+ output[1] = _crypt_itoa64[count & 0x3f];
72
+ output[2] = _crypt_itoa64[(count >> 6) & 0x3f];
73
+ output[3] = _crypt_itoa64[(count >> 12) & 0x3f];
74
+ output[4] = _crypt_itoa64[(count >> 18) & 0x3f];
75
+ value = (unsigned long)(unsigned char)input[0] |
76
+ ((unsigned long)(unsigned char)input[1] << 8) |
77
+ ((unsigned long)(unsigned char)input[2] << 16);
78
+ output[5] = _crypt_itoa64[value & 0x3f];
79
+ output[6] = _crypt_itoa64[(value >> 6) & 0x3f];
80
+ output[7] = _crypt_itoa64[(value >> 12) & 0x3f];
81
+ output[8] = _crypt_itoa64[(value >> 18) & 0x3f];
82
+ output[9] = '\0';
83
+
84
+ return output;
85
+ }
86
+
87
+ char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count,
88
+ const char *input, int size, char *output, int output_size)
89
+ {
90
+ unsigned long value;
91
+
92
+ (void) prefix;
93
+
94
+ if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000)) {
95
+ if (output_size > 0) output[0] = '\0';
96
+ __set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL);
97
+ return NULL;
98
+ }
99
+
100
+ output[0] = '$';
101
+ output[1] = '1';
102
+ output[2] = '$';
103
+ value = (unsigned long)(unsigned char)input[0] |
104
+ ((unsigned long)(unsigned char)input[1] << 8) |
105
+ ((unsigned long)(unsigned char)input[2] << 16);
106
+ output[3] = _crypt_itoa64[value & 0x3f];
107
+ output[4] = _crypt_itoa64[(value >> 6) & 0x3f];
108
+ output[5] = _crypt_itoa64[(value >> 12) & 0x3f];
109
+ output[6] = _crypt_itoa64[(value >> 18) & 0x3f];
110
+ output[7] = '\0';
111
+
112
+ if (size >= 6 && output_size >= 3 + 4 + 4 + 1) {
113
+ value = (unsigned long)(unsigned char)input[3] |
114
+ ((unsigned long)(unsigned char)input[4] << 8) |
115
+ ((unsigned long)(unsigned char)input[5] << 16);
116
+ output[7] = _crypt_itoa64[value & 0x3f];
117
+ output[8] = _crypt_itoa64[(value >> 6) & 0x3f];
118
+ output[9] = _crypt_itoa64[(value >> 12) & 0x3f];
119
+ output[10] = _crypt_itoa64[(value >> 18) & 0x3f];
120
+ output[11] = '\0';
121
+ }
122
+
123
+ return output;
124
+ }
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Written by Solar Designer <solar at openwall.com> in 2000-2011.
3
+ * No copyright is claimed, and the software is hereby placed in the public
4
+ * domain. In case this attempt to disclaim copyright and place the software
5
+ * in the public domain is deemed null and void, then the software is
6
+ * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
7
+ * general public under the following terms:
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted.
11
+ *
12
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
13
+ *
14
+ * See crypt_blowfish.c for more information.
15
+ */
16
+
17
+ #ifndef _CRYPT_GENSALT_H
18
+ #define _CRYPT_GENSALT_H
19
+
20
+ extern const unsigned char _crypt_itoa64[];
21
+ extern char *_crypt_gensalt_traditional_rn(const char *prefix,
22
+ unsigned long count,
23
+ const char *input, int size, char *output, int output_size);
24
+ extern char *_crypt_gensalt_extended_rn(const char *prefix,
25
+ unsigned long count,
26
+ const char *input, int size, char *output, int output_size);
27
+ extern char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count,
28
+ const char *input, int size, char *output, int output_size);
29
+
30
+ #endif
@@ -0,0 +1,22 @@
1
+ if RUBY_PLATFORM == "java"
2
+ # Don't do anything when run in JRuby; this allows gem installation to pass.
3
+ # We need to write a dummy Makefile so that RubyGems doesn't think compilation
4
+ # failed.
5
+ File.open('Makefile', 'w') do |f|
6
+ f.puts "all:"
7
+ f.puts "\t@true"
8
+ f.puts "install:"
9
+ f.puts "\t@true"
10
+ end
11
+ exit 0
12
+ else
13
+ require "mkmf"
14
+
15
+ # From Openwall's crypt_blowfish Makefile.
16
+ # This is `bcrypt_ext` (our extension) + CRYPT_OBJS from that Makefile.
17
+ $objs = %w(bcrypt_ext.o crypt_blowfish.o x86.o crypt_gensalt.o wrapper.o)
18
+
19
+ $defs << "-D__SKIP_GNU"
20
+ dir_config("bcrypt_ext")
21
+ create_makefile("bcrypt_ext")
22
+ end
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Written by Solar Designer <solar at openwall.com> in 2000-2011.
3
+ * No copyright is claimed, and the software is hereby placed in the public
4
+ * domain. In case this attempt to disclaim copyright and place the software
5
+ * in the public domain is deemed null and void, then the software is
6
+ * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
7
+ * general public under the following terms:
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted.
11
+ *
12
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
13
+ *
14
+ * See crypt_blowfish.c for more information.
15
+ */
16
+
17
+ #ifndef _OW_CRYPT_H
18
+ #define _OW_CRYPT_H
19
+
20
+ #ifndef __GNUC__
21
+ #undef __const
22
+ #define __const const
23
+ #endif
24
+
25
+ #ifndef __SKIP_GNU
26
+ extern char *crypt(__const char *key, __const char *setting);
27
+ extern char *crypt_r(__const char *key, __const char *setting, void *data);
28
+ #endif
29
+
30
+ #ifndef __SKIP_OW
31
+ extern char *crypt_rn(__const char *key, __const char *setting,
32
+ void *data, int size);
33
+ extern char *crypt_ra(__const char *key, __const char *setting,
34
+ void **data, int *size);
35
+ extern char *crypt_gensalt(__const char *prefix, unsigned long count,
36
+ __const char *input, int size);
37
+ extern char *crypt_gensalt_rn(__const char *prefix, unsigned long count,
38
+ __const char *input, int size, char *output, int output_size);
39
+ extern char *crypt_gensalt_ra(__const char *prefix, unsigned long count,
40
+ __const char *input, int size);
41
+ #endif
42
+
43
+ #endif
@@ -0,0 +1,554 @@
1
+ /*
2
+ * Written by Solar Designer <solar at openwall.com> in 2000-2014.
3
+ * No copyright is claimed, and the software is hereby placed in the public
4
+ * domain. In case this attempt to disclaim copyright and place the software
5
+ * in the public domain is deemed null and void, then the software is
6
+ * Copyright (c) 2000-2014 Solar Designer and it is hereby released to the
7
+ * general public under the following terms:
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted.
11
+ *
12
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
13
+ *
14
+ * See crypt_blowfish.c for more information.
15
+ */
16
+
17
+ #include <stdlib.h>
18
+ #include <string.h>
19
+
20
+ /* Redefine strdup to ruby_strdup in case string.h doesn't export it. */
21
+ #include <ruby/util.h>
22
+
23
+ #include <errno.h>
24
+ #ifndef __set_errno
25
+ #define __set_errno(val) errno = (val)
26
+ #endif
27
+
28
+ #ifdef TEST
29
+ #include <stdio.h>
30
+ #include <unistd.h>
31
+ #include <signal.h>
32
+ #include <time.h>
33
+ #include <sys/time.h>
34
+ #include <sys/times.h>
35
+ #ifdef TEST_THREADS
36
+ #include <pthread.h>
37
+ #endif
38
+ #endif
39
+
40
+ #define CRYPT_OUTPUT_SIZE (7 + 22 + 31 + 1)
41
+ #define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1)
42
+
43
+ #if defined(__GLIBC__) && defined(_LIBC)
44
+ #define __SKIP_GNU
45
+ #endif
46
+ #include "ow-crypt.h"
47
+
48
+ #include "crypt_blowfish.h"
49
+ #include "crypt_gensalt.h"
50
+
51
+ #if defined(__GLIBC__) && defined(_LIBC)
52
+ /* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */
53
+ #include "crypt.h"
54
+ extern char *__md5_crypt_r(const char *key, const char *salt,
55
+ char *buffer, int buflen);
56
+ /* crypt-entry.c needs to be patched to define __des_crypt_r rather than
57
+ * __crypt_r, and not define crypt_r and crypt at all */
58
+ extern char *__des_crypt_r(const char *key, const char *salt,
59
+ struct crypt_data *data);
60
+ extern struct crypt_data _ufc_foobar;
61
+ #endif
62
+
63
+ static int _crypt_data_alloc(void **data, int *size, int need)
64
+ {
65
+ void *updated;
66
+
67
+ if (*data && *size >= need) return 0;
68
+
69
+ updated = realloc(*data, need);
70
+
71
+ if (!updated) {
72
+ #ifndef __GLIBC__
73
+ /* realloc(3) on glibc sets errno, so we don't need to bother */
74
+ __set_errno(ENOMEM);
75
+ #endif
76
+ return -1;
77
+ }
78
+
79
+ #if defined(__GLIBC__) && defined(_LIBC)
80
+ if (need >= sizeof(struct crypt_data))
81
+ ((struct crypt_data *)updated)->initialized = 0;
82
+ #endif
83
+
84
+ *data = updated;
85
+ *size = need;
86
+
87
+ return 0;
88
+ }
89
+
90
+ static char *_crypt_retval_magic(char *retval, const char *setting,
91
+ char *output, int size)
92
+ {
93
+ if (retval)
94
+ return retval;
95
+
96
+ if (_crypt_output_magic(setting, output, size))
97
+ return NULL; /* shouldn't happen */
98
+
99
+ return output;
100
+ }
101
+
102
+ #if defined(__GLIBC__) && defined(_LIBC)
103
+ /*
104
+ * Applications may re-use the same instance of struct crypt_data without
105
+ * resetting the initialized field in order to let crypt_r() skip some of
106
+ * its initialization code. Thus, it is important that our multiple hashing
107
+ * algorithms either don't conflict with each other in their use of the
108
+ * data area or reset the initialized field themselves whenever required.
109
+ * Currently, the hashing algorithms simply have no conflicts: the first
110
+ * field of struct crypt_data is the 128-byte large DES key schedule which
111
+ * __des_crypt_r() calculates each time it is called while the two other
112
+ * hashing algorithms use less than 128 bytes of the data area.
113
+ */
114
+
115
+ char *__crypt_rn(__const char *key, __const char *setting,
116
+ void *data, int size)
117
+ {
118
+ if (setting[0] == '$' && setting[1] == '2')
119
+ return _crypt_blowfish_rn(key, setting, (char *)data, size);
120
+ if (setting[0] == '$' && setting[1] == '1')
121
+ return __md5_crypt_r(key, setting, (char *)data, size);
122
+ if (setting[0] == '$' || setting[0] == '_') {
123
+ __set_errno(EINVAL);
124
+ return NULL;
125
+ }
126
+ if (size >= sizeof(struct crypt_data))
127
+ return __des_crypt_r(key, setting, (struct crypt_data *)data);
128
+ __set_errno(ERANGE);
129
+ return NULL;
130
+ }
131
+
132
+ char *__crypt_ra(__const char *key, __const char *setting,
133
+ void **data, int *size)
134
+ {
135
+ if (setting[0] == '$' && setting[1] == '2') {
136
+ if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
137
+ return NULL;
138
+ return _crypt_blowfish_rn(key, setting, (char *)*data, *size);
139
+ }
140
+ if (setting[0] == '$' && setting[1] == '1') {
141
+ if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
142
+ return NULL;
143
+ return __md5_crypt_r(key, setting, (char *)*data, *size);
144
+ }
145
+ if (setting[0] == '$' || setting[0] == '_') {
146
+ __set_errno(EINVAL);
147
+ return NULL;
148
+ }
149
+ if (_crypt_data_alloc(data, size, sizeof(struct crypt_data)))
150
+ return NULL;
151
+ return __des_crypt_r(key, setting, (struct crypt_data *)*data);
152
+ }
153
+
154
+ char *__crypt_r(__const char *key, __const char *setting,
155
+ struct crypt_data *data)
156
+ {
157
+ return _crypt_retval_magic(
158
+ __crypt_rn(key, setting, data, sizeof(*data)),
159
+ setting, (char *)data, sizeof(*data));
160
+ }
161
+
162
+ char *__crypt(__const char *key, __const char *setting)
163
+ {
164
+ return _crypt_retval_magic(
165
+ __crypt_rn(key, setting, &_ufc_foobar, sizeof(_ufc_foobar)),
166
+ setting, (char *)&_ufc_foobar, sizeof(_ufc_foobar));
167
+ }
168
+ #else
169
+ char *crypt_rn(const char *key, const char *setting, void *data, int size)
170
+ {
171
+ return _crypt_blowfish_rn(key, setting, (char *)data, size);
172
+ }
173
+
174
+ char *crypt_ra(const char *key, const char *setting,
175
+ void **data, int *size)
176
+ {
177
+ if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
178
+ return NULL;
179
+ return _crypt_blowfish_rn(key, setting, (char *)*data, *size);
180
+ }
181
+
182
+ char *crypt_r(const char *key, const char *setting, void *data)
183
+ {
184
+ return _crypt_retval_magic(
185
+ crypt_rn(key, setting, data, CRYPT_OUTPUT_SIZE),
186
+ setting, (char *)data, CRYPT_OUTPUT_SIZE);
187
+ }
188
+
189
+ char *crypt(const char *key, const char *setting)
190
+ {
191
+ static char output[CRYPT_OUTPUT_SIZE];
192
+
193
+ return _crypt_retval_magic(
194
+ crypt_rn(key, setting, output, sizeof(output)),
195
+ setting, output, sizeof(output));
196
+ }
197
+
198
+ #define __crypt_gensalt_rn crypt_gensalt_rn
199
+ #define __crypt_gensalt_ra crypt_gensalt_ra
200
+ #define __crypt_gensalt crypt_gensalt
201
+ #endif
202
+
203
+ char *__crypt_gensalt_rn(const char *prefix, unsigned long count,
204
+ const char *input, int size, char *output, int output_size)
205
+ {
206
+ char *(*use)(const char *_prefix, unsigned long _count,
207
+ const char *_input, int _size,
208
+ char *_output, int _output_size);
209
+
210
+ /* This may be supported on some platforms in the future */
211
+ if (!input) {
212
+ __set_errno(EINVAL);
213
+ return NULL;
214
+ }
215
+
216
+ if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2b$", 4) ||
217
+ !strncmp(prefix, "$2y$", 4))
218
+ use = _crypt_gensalt_blowfish_rn;
219
+ else
220
+ if (!strncmp(prefix, "$1$", 3))
221
+ use = _crypt_gensalt_md5_rn;
222
+ else
223
+ if (prefix[0] == '_')
224
+ use = _crypt_gensalt_extended_rn;
225
+ else
226
+ if (!prefix[0] ||
227
+ (prefix[0] && prefix[1] &&
228
+ memchr(_crypt_itoa64, prefix[0], 64) &&
229
+ memchr(_crypt_itoa64, prefix[1], 64)))
230
+ use = _crypt_gensalt_traditional_rn;
231
+ else {
232
+ __set_errno(EINVAL);
233
+ return NULL;
234
+ }
235
+
236
+ return use(prefix, count, input, size, output, output_size);
237
+ }
238
+
239
+ char *__crypt_gensalt_ra(const char *prefix, unsigned long count,
240
+ const char *input, int size)
241
+ {
242
+ char output[CRYPT_GENSALT_OUTPUT_SIZE];
243
+ char *retval;
244
+
245
+ retval = __crypt_gensalt_rn(prefix, count,
246
+ input, size, output, sizeof(output));
247
+
248
+ if (retval) {
249
+ retval = strdup(retval);
250
+ #ifndef __GLIBC__
251
+ /* strdup(3) on glibc sets errno, so we don't need to bother */
252
+ if (!retval)
253
+ __set_errno(ENOMEM);
254
+ #endif
255
+ }
256
+
257
+ return retval;
258
+ }
259
+
260
+ char *__crypt_gensalt(const char *prefix, unsigned long count,
261
+ const char *input, int size)
262
+ {
263
+ static char output[CRYPT_GENSALT_OUTPUT_SIZE];
264
+
265
+ return __crypt_gensalt_rn(prefix, count,
266
+ input, size, output, sizeof(output));
267
+ }
268
+
269
+ #if defined(__GLIBC__) && defined(_LIBC)
270
+ weak_alias(__crypt_rn, crypt_rn)
271
+ weak_alias(__crypt_ra, crypt_ra)
272
+ weak_alias(__crypt_r, crypt_r)
273
+ weak_alias(__crypt, crypt)
274
+ weak_alias(__crypt_gensalt_rn, crypt_gensalt_rn)
275
+ weak_alias(__crypt_gensalt_ra, crypt_gensalt_ra)
276
+ weak_alias(__crypt_gensalt, crypt_gensalt)
277
+ weak_alias(crypt, fcrypt)
278
+ #endif
279
+
280
+ #ifdef TEST
281
+ static const char *tests[][3] = {
282
+ {"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW",
283
+ "U*U"},
284
+ {"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK",
285
+ "U*U*"},
286
+ {"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a",
287
+ "U*U*U"},
288
+ {"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui",
289
+ "0123456789abcdefghijklmnopqrstuvwxyz"
290
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
291
+ "chars after 72 are ignored"},
292
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
293
+ "\xa3"},
294
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
295
+ "\xff\xff\xa3"},
296
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
297
+ "\xff\xff\xa3"},
298
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.nqd1wy.pTMdcvrRWxyiGL2eMz.2a85.",
299
+ "\xff\xff\xa3"},
300
+ {"$2b$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
301
+ "\xff\xff\xa3"},
302
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
303
+ "\xa3"},
304
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
305
+ "\xa3"},
306
+ {"$2b$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
307
+ "\xa3"},
308
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
309
+ "1\xa3" "345"},
310
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
311
+ "\xff\xa3" "345"},
312
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
313
+ "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"},
314
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
315
+ "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"},
316
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.ZC1JEJ8Z4gPfpe1JOr/oyPXTWl9EFd.",
317
+ "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"},
318
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e",
319
+ "\xff\xa3" "345"},
320
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e",
321
+ "\xff\xa3" "345"},
322
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS",
323
+ "\xa3" "ab"},
324
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS",
325
+ "\xa3" "ab"},
326
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS",
327
+ "\xa3" "ab"},
328
+ {"$2x$05$6bNw2HLQYeqHYyBfLMsv/OiwqTymGIGzFsA4hOTWebfehXHNprcAS",
329
+ "\xd1\x91"},
330
+ {"$2x$05$6bNw2HLQYeqHYyBfLMsv/O9LIGgn8OMzuDoHfof8AQimSGfcSWxnS",
331
+ "\xd0\xc1\xd2\xcf\xcc\xd8"},
332
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6",
333
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
334
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
335
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
336
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
337
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
338
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
339
+ "chars after 72 are ignored as usual"},
340
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.R9xrDjiycxMbQE2bp.vgqlYpW5wx2yy",
341
+ "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
342
+ "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
343
+ "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
344
+ "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
345
+ "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
346
+ "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"},
347
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.9tQZzcJfm3uj2NvJ/n5xkhpqLrMpWCe",
348
+ "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
349
+ "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
350
+ "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
351
+ "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
352
+ "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
353
+ "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"},
354
+ {"$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy",
355
+ ""},
356
+ {"*0", "", "$2a$03$CCCCCCCCCCCCCCCCCCCCC."},
357
+ {"*0", "", "$2a$32$CCCCCCCCCCCCCCCCCCCCC."},
358
+ {"*0", "", "$2c$05$CCCCCCCCCCCCCCCCCCCCC."},
359
+ {"*0", "", "$2z$05$CCCCCCCCCCCCCCCCCCCCC."},
360
+ {"*0", "", "$2`$05$CCCCCCCCCCCCCCCCCCCCC."},
361
+ {"*0", "", "$2{$05$CCCCCCCCCCCCCCCCCCCCC."},
362
+ {"*1", "", "*0"},
363
+ {NULL}
364
+ };
365
+
366
+ #define which tests[0]
367
+
368
+ static volatile sig_atomic_t running;
369
+
370
+ static void handle_timer(int signum)
371
+ {
372
+ (void) signum;
373
+ running = 0;
374
+ }
375
+
376
+ static void *run(void *arg)
377
+ {
378
+ unsigned long count = 0;
379
+ int i = 0;
380
+ void *data = NULL;
381
+ int size = 0x12345678;
382
+
383
+ do {
384
+ const char *hash = tests[i][0];
385
+ const char *key = tests[i][1];
386
+ const char *setting = tests[i][2];
387
+
388
+ if (!tests[++i][0])
389
+ i = 0;
390
+
391
+ if (setting && strlen(hash) < 30) /* not for benchmark */
392
+ continue;
393
+
394
+ if (strcmp(crypt_ra(key, hash, &data, &size), hash)) {
395
+ printf("%d: FAILED (crypt_ra/%d/%lu)\n",
396
+ (int)((char *)arg - (char *)0), i, count);
397
+ free(data);
398
+ return NULL;
399
+ }
400
+ count++;
401
+ } while (running);
402
+
403
+ free(data);
404
+ return count + (char *)0;
405
+ }
406
+
407
+ int main(void)
408
+ {
409
+ struct itimerval it;
410
+ struct tms buf;
411
+ clock_t clk_tck, start_real, start_virtual, end_real, end_virtual;
412
+ unsigned long count;
413
+ void *data;
414
+ int size;
415
+ char *setting1, *setting2;
416
+ int i;
417
+ #ifdef TEST_THREADS
418
+ pthread_t t[TEST_THREADS];
419
+ void *t_retval;
420
+ #endif
421
+
422
+ data = NULL;
423
+ size = 0x12345678;
424
+
425
+ for (i = 0; tests[i][0]; i++) {
426
+ const char *hash = tests[i][0];
427
+ const char *key = tests[i][1];
428
+ const char *setting = tests[i][2];
429
+ const char *p;
430
+ int ok = !setting || strlen(hash) >= 30;
431
+ int o_size;
432
+ char s_buf[30], o_buf[61];
433
+ if (!setting) {
434
+ memcpy(s_buf, hash, sizeof(s_buf) - 1);
435
+ s_buf[sizeof(s_buf) - 1] = 0;
436
+ setting = s_buf;
437
+ }
438
+
439
+ __set_errno(0);
440
+ p = crypt(key, setting);
441
+ if ((!ok && !errno) || strcmp(p, hash)) {
442
+ printf("FAILED (crypt/%d)\n", i);
443
+ return 1;
444
+ }
445
+
446
+ if (ok && strcmp(crypt(key, hash), hash)) {
447
+ printf("FAILED (crypt/%d)\n", i);
448
+ return 1;
449
+ }
450
+
451
+ for (o_size = -1; o_size <= (int)sizeof(o_buf); o_size++) {
452
+ int ok_n = ok && o_size == (int)sizeof(o_buf);
453
+ const char *x = "abc";
454
+ strcpy(o_buf, x);
455
+ if (o_size >= 3) {
456
+ x = "*0";
457
+ if (setting[0] == '*' && setting[1] == '0')
458
+ x = "*1";
459
+ }
460
+ __set_errno(0);
461
+ p = crypt_rn(key, setting, o_buf, o_size);
462
+ if ((ok_n && (!p || strcmp(p, hash))) ||
463
+ (!ok_n && (!errno || p || strcmp(o_buf, x)))) {
464
+ printf("FAILED (crypt_rn/%d)\n", i);
465
+ return 1;
466
+ }
467
+ }
468
+
469
+ __set_errno(0);
470
+ p = crypt_ra(key, setting, &data, &size);
471
+ if ((ok && (!p || strcmp(p, hash))) ||
472
+ (!ok && (!errno || p || strcmp((char *)data, hash)))) {
473
+ printf("FAILED (crypt_ra/%d)\n", i);
474
+ return 1;
475
+ }
476
+ }
477
+
478
+ setting1 = crypt_gensalt(which[0], 12, data, size);
479
+ if (!setting1 || strncmp(setting1, "$2a$12$", 7)) {
480
+ puts("FAILED (crypt_gensalt)\n");
481
+ return 1;
482
+ }
483
+
484
+ setting2 = crypt_gensalt_ra(setting1, 12, data, size);
485
+ if (strcmp(setting1, setting2)) {
486
+ puts("FAILED (crypt_gensalt_ra/1)\n");
487
+ return 1;
488
+ }
489
+
490
+ (*(char *)data)++;
491
+ setting1 = crypt_gensalt_ra(setting2, 12, data, size);
492
+ if (!strcmp(setting1, setting2)) {
493
+ puts("FAILED (crypt_gensalt_ra/2)\n");
494
+ return 1;
495
+ }
496
+
497
+ free(setting1);
498
+ free(setting2);
499
+ free(data);
500
+
501
+ #if defined(_SC_CLK_TCK) || !defined(CLK_TCK)
502
+ clk_tck = sysconf(_SC_CLK_TCK);
503
+ #else
504
+ clk_tck = CLK_TCK;
505
+ #endif
506
+
507
+ running = 1;
508
+ signal(SIGALRM, handle_timer);
509
+
510
+ memset(&it, 0, sizeof(it));
511
+ it.it_value.tv_sec = 5;
512
+ setitimer(ITIMER_REAL, &it, NULL);
513
+
514
+ start_real = times(&buf);
515
+ start_virtual = buf.tms_utime + buf.tms_stime;
516
+
517
+ count = (char *)run((char *)0) - (char *)0;
518
+
519
+ end_real = times(&buf);
520
+ end_virtual = buf.tms_utime + buf.tms_stime;
521
+ if (end_virtual == start_virtual) end_virtual++;
522
+
523
+ printf("%.1f c/s real, %.1f c/s virtual\n",
524
+ (float)count * clk_tck / (end_real - start_real),
525
+ (float)count * clk_tck / (end_virtual - start_virtual));
526
+
527
+ #ifdef TEST_THREADS
528
+ running = 1;
529
+ it.it_value.tv_sec = 60;
530
+ setitimer(ITIMER_REAL, &it, NULL);
531
+ start_real = times(&buf);
532
+
533
+ for (i = 0; i < TEST_THREADS; i++)
534
+ if (pthread_create(&t[i], NULL, run, i + (char *)0)) {
535
+ perror("pthread_create");
536
+ return 1;
537
+ }
538
+
539
+ for (i = 0; i < TEST_THREADS; i++) {
540
+ if (pthread_join(t[i], &t_retval)) {
541
+ perror("pthread_join");
542
+ continue;
543
+ }
544
+ if (!t_retval) continue;
545
+ count = (char *)t_retval - (char *)0;
546
+ end_real = times(&buf);
547
+ printf("%d: %.1f c/s real\n", i,
548
+ (float)count * clk_tck / (end_real - start_real));
549
+ }
550
+ #endif
551
+
552
+ return 0;
553
+ }
554
+ #endif