bcrypt 3.1.12 → 3.1.13

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
@@ -1,5 +1,16 @@
1
1
  /*
2
- * Written by Solar Designer and placed in the public domain.
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
+ *
3
14
  * See crypt_blowfish.c for more information.
4
15
  *
5
16
  * This file contains salt generation functions for the traditional and
@@ -14,19 +25,17 @@
14
25
  #define __set_errno(val) errno = (val)
15
26
  #endif
16
27
 
17
- #undef __CONST
18
- #ifdef __GNUC__
19
- #define __CONST __const
20
- #else
21
- #define __CONST
22
- #endif
28
+ /* Just to make sure the prototypes match the actual definitions */
29
+ #include "crypt_gensalt.h"
23
30
 
24
31
  unsigned char _crypt_itoa64[64 + 1] =
25
32
  "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
26
33
 
27
- char *_crypt_gensalt_traditional_rn(unsigned long count,
28
- __CONST char *input, int size, char *output, int output_size)
34
+ char *_crypt_gensalt_traditional_rn(const char *prefix, unsigned long count,
35
+ const char *input, int size, char *output, int output_size)
29
36
  {
37
+ (void) prefix;
38
+
30
39
  if (size < 2 || output_size < 2 + 1 || (count && count != 25)) {
31
40
  if (output_size > 0) output[0] = '\0';
32
41
  __set_errno((output_size < 2 + 1) ? ERANGE : EINVAL);
@@ -40,11 +49,13 @@ char *_crypt_gensalt_traditional_rn(unsigned long count,
40
49
  return output;
41
50
  }
42
51
 
43
- char *_crypt_gensalt_extended_rn(unsigned long count,
44
- __CONST char *input, int size, char *output, int output_size)
52
+ char *_crypt_gensalt_extended_rn(const char *prefix, unsigned long count,
53
+ const char *input, int size, char *output, int output_size)
45
54
  {
46
55
  unsigned long value;
47
56
 
57
+ (void) prefix;
58
+
48
59
  /* Even iteration counts make it easier to detect weak DES keys from a look
49
60
  * at the hash, so they should be avoided */
50
61
  if (size < 3 || output_size < 1 + 4 + 4 + 1 ||
@@ -73,11 +84,13 @@ char *_crypt_gensalt_extended_rn(unsigned long count,
73
84
  return output;
74
85
  }
75
86
 
76
- char *_crypt_gensalt_md5_rn(unsigned long count,
77
- __CONST char *input, int size, char *output, int output_size)
87
+ char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count,
88
+ const char *input, int size, char *output, int output_size)
78
89
  {
79
90
  unsigned long value;
80
91
 
92
+ (void) prefix;
93
+
81
94
  if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000)) {
82
95
  if (output_size > 0) output[0] = '\0';
83
96
  __set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL);
@@ -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 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
@@ -11,6 +11,12 @@ if RUBY_PLATFORM == "java"
11
11
  exit 0
12
12
  else
13
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"
14
20
  dir_config("bcrypt_ext")
15
21
  create_makefile("bcrypt_ext")
16
22
  end
@@ -1,35 +1,43 @@
1
1
  /*
2
- * Written by Solar Designer and placed in the public domain.
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
+ *
3
14
  * See crypt_blowfish.c for more information.
4
15
  */
5
16
 
6
17
  #ifndef _OW_CRYPT_H
7
18
  #define _OW_CRYPT_H
8
19
 
9
- #undef __CONST
10
- #if defined __GNUC__
11
- #define __CONST __const
12
- #elif defined _MSC_VER
13
- #define __CONST const
14
- #else
20
+ #ifndef __GNUC__
21
+ #undef __const
22
+ #define __const const
15
23
  #endif
16
24
 
17
25
  #ifndef __SKIP_GNU
18
- extern char *crypt(__CONST char *key, __CONST char *setting);
19
- extern char *crypt_r(__CONST char *key, __CONST char *setting, void *data);
26
+ extern char *crypt(__const char *key, __const char *setting);
27
+ extern char *crypt_r(__const char *key, __const char *setting, void *data);
20
28
  #endif
21
29
 
22
30
  #ifndef __SKIP_OW
23
- extern char *crypt_rn(__CONST char *key, __CONST char *setting,
31
+ extern char *crypt_rn(__const char *key, __const char *setting,
24
32
  void *data, int size);
25
- extern char *crypt_ra(__CONST char *key, __CONST char *setting,
33
+ extern char *crypt_ra(__const char *key, __const char *setting,
26
34
  void **data, int *size);
27
- extern char *crypt_gensalt(__CONST char *prefix, unsigned long count,
28
- __CONST char *input, int size);
29
- extern char *crypt_gensalt_rn(__CONST char *prefix, unsigned long count,
30
- __CONST char *input, int size, char *output, int output_size);
31
- extern char *crypt_gensalt_ra(__CONST char *prefix, unsigned long count,
32
- __CONST char *input, 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);
33
41
  #endif
34
42
 
35
43
  #endif
@@ -1,5 +1,16 @@
1
1
  /*
2
- * Written by Solar Designer and placed in the public domain.
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
+ *
3
14
  * See crypt_blowfish.c for more information.
4
15
  */
5
16
 
@@ -23,13 +34,6 @@
23
34
  #endif
24
35
  #endif
25
36
 
26
- #include <ruby.h>
27
- #ifdef HAVE_RUBY_UTIL_H
28
- #include <ruby/util.h>
29
- #else
30
- #include <util.h>
31
- #endif
32
-
33
37
  #define CRYPT_OUTPUT_SIZE (7 + 22 + 31 + 1)
34
38
  #define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1)
35
39
 
@@ -38,18 +42,8 @@
38
42
  #endif
39
43
  #include "ow-crypt.h"
40
44
 
41
- extern char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
42
- char *output, int size);
43
- extern char *_crypt_gensalt_blowfish_rn(unsigned long count,
44
- __CONST char *input, int size, char *output, int output_size);
45
-
46
- extern unsigned char _crypt_itoa64[];
47
- extern char *_crypt_gensalt_traditional_rn(unsigned long count,
48
- __CONST char *input, int size, char *output, int output_size);
49
- extern char *_crypt_gensalt_extended_rn(unsigned long count,
50
- __CONST char *input, int size, char *output, int output_size);
51
- extern char *_crypt_gensalt_md5_rn(unsigned long count,
52
- __CONST char *input, int size, char *output, int output_size);
45
+ #include "crypt_blowfish.h"
46
+ #include "crypt_gensalt.h"
53
47
 
54
48
  #if defined(__GLIBC__) && defined(_LIBC)
55
49
  /* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */
@@ -90,17 +84,14 @@ static int _crypt_data_alloc(void **data, int *size, int need)
90
84
  return 0;
91
85
  }
92
86
 
93
- static char *_crypt_retval_magic(char *retval, __CONST char *setting,
94
- char *output)
87
+ static char *_crypt_retval_magic(char *retval, const char *setting,
88
+ char *output, int size)
95
89
  {
96
- if (retval) return retval;
90
+ if (retval)
91
+ return retval;
97
92
 
98
- output[0] = '*';
99
- output[1] = '0';
100
- output[2] = '\0';
101
-
102
- if (setting[0] == '*' && setting[1] == '0')
103
- output[1] = '1';
93
+ if (_crypt_output_magic(setting, output, size))
94
+ return NULL; /* shouldn't happen */
104
95
 
105
96
  return output;
106
97
  }
@@ -162,22 +153,22 @@ char *__crypt_r(__const char *key, __const char *setting,
162
153
  {
163
154
  return _crypt_retval_magic(
164
155
  __crypt_rn(key, setting, data, sizeof(*data)),
165
- setting, (char *)data);
156
+ setting, (char *)data, sizeof(*data));
166
157
  }
167
158
 
168
159
  char *__crypt(__const char *key, __const char *setting)
169
160
  {
170
161
  return _crypt_retval_magic(
171
162
  __crypt_rn(key, setting, &_ufc_foobar, sizeof(_ufc_foobar)),
172
- setting, (char *)&_ufc_foobar);
163
+ setting, (char *)&_ufc_foobar, sizeof(_ufc_foobar));
173
164
  }
174
165
  #else
175
- char *crypt_rn(__CONST char *key, __CONST char *setting, void *data, int size)
166
+ char *crypt_rn(const char *key, const char *setting, void *data, int size)
176
167
  {
177
168
  return _crypt_blowfish_rn(key, setting, (char *)data, size);
178
169
  }
179
170
 
180
- char *crypt_ra(__CONST char *key, __CONST char *setting,
171
+ char *crypt_ra(const char *key, const char *setting,
181
172
  void **data, int *size)
182
173
  {
183
174
  if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
@@ -185,11 +176,20 @@ char *crypt_ra(__CONST char *key, __CONST char *setting,
185
176
  return _crypt_blowfish_rn(key, setting, (char *)*data, *size);
186
177
  }
187
178
 
188
- char *crypt_r(__CONST char *key, __CONST char *setting, void *data)
179
+ char *crypt_r(const char *key, const char *setting, void *data)
189
180
  {
190
181
  return _crypt_retval_magic(
191
182
  crypt_rn(key, setting, data, CRYPT_OUTPUT_SIZE),
192
- setting, (char *)data);
183
+ setting, (char *)data, CRYPT_OUTPUT_SIZE);
184
+ }
185
+
186
+ char *crypt(const char *key, const char *setting)
187
+ {
188
+ static char output[CRYPT_OUTPUT_SIZE];
189
+
190
+ return _crypt_retval_magic(
191
+ crypt_rn(key, setting, output, sizeof(output)),
192
+ setting, output, sizeof(output));
193
193
  }
194
194
 
195
195
  #define __crypt_gensalt_rn crypt_gensalt_rn
@@ -197,11 +197,12 @@ char *crypt_r(__CONST char *key, __CONST char *setting, void *data)
197
197
  #define __crypt_gensalt crypt_gensalt
198
198
  #endif
199
199
 
200
- char *__crypt_gensalt_rn(__CONST char *prefix, unsigned long count,
201
- __CONST char *input, int size, char *output, int output_size)
200
+ char *__crypt_gensalt_rn(const char *prefix, unsigned long count,
201
+ const char *input, int size, char *output, int output_size)
202
202
  {
203
- char *(*use)(unsigned long count,
204
- __CONST char *input, int size, char *output, int output_size);
203
+ char *(*use)(const char *_prefix, unsigned long _count,
204
+ const char *_input, int _size,
205
+ char *_output, int _output_size);
205
206
 
206
207
  /* This may be supported on some platforms in the future */
207
208
  if (!input) {
@@ -209,7 +210,8 @@ char *__crypt_gensalt_rn(__CONST char *prefix, unsigned long count,
209
210
  return NULL;
210
211
  }
211
212
 
212
- if (!strncmp(prefix, "$2a$", 4))
213
+ if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2b$", 4) ||
214
+ !strncmp(prefix, "$2y$", 4))
213
215
  use = _crypt_gensalt_blowfish_rn;
214
216
  else
215
217
  if (!strncmp(prefix, "$1$", 3))
@@ -228,11 +230,11 @@ char *__crypt_gensalt_rn(__CONST char *prefix, unsigned long count,
228
230
  return NULL;
229
231
  }
230
232
 
231
- return use(count, input, size, output, output_size);
233
+ return use(prefix, count, input, size, output, output_size);
232
234
  }
233
235
 
234
- char *__crypt_gensalt_ra(__CONST char *prefix, unsigned long count,
235
- __CONST char *input, int size)
236
+ char *__crypt_gensalt_ra(const char *prefix, unsigned long count,
237
+ const char *input, int size)
236
238
  {
237
239
  char output[CRYPT_GENSALT_OUTPUT_SIZE];
238
240
  char *retval;
@@ -241,7 +243,7 @@ char *__crypt_gensalt_ra(__CONST char *prefix, unsigned long count,
241
243
  input, size, output, sizeof(output));
242
244
 
243
245
  if (retval) {
244
- retval = ruby_strdup(retval);
246
+ retval = strdup(retval);
245
247
  #ifndef __GLIBC__
246
248
  /* strdup(3) on glibc sets errno, so we don't need to bother */
247
249
  if (!retval)
@@ -252,11 +254,298 @@ char *__crypt_gensalt_ra(__CONST char *prefix, unsigned long count,
252
254
  return retval;
253
255
  }
254
256
 
255
- char *__crypt_gensalt(__CONST char *prefix, unsigned long count,
256
- __CONST char *input, int size)
257
+ char *__crypt_gensalt(const char *prefix, unsigned long count,
258
+ const char *input, int size)
257
259
  {
258
260
  static char output[CRYPT_GENSALT_OUTPUT_SIZE];
259
261
 
260
262
  return __crypt_gensalt_rn(prefix, count,
261
263
  input, size, output, sizeof(output));
262
264
  }
265
+
266
+ #if defined(__GLIBC__) && defined(_LIBC)
267
+ weak_alias(__crypt_rn, crypt_rn)
268
+ weak_alias(__crypt_ra, crypt_ra)
269
+ weak_alias(__crypt_r, crypt_r)
270
+ weak_alias(__crypt, crypt)
271
+ weak_alias(__crypt_gensalt_rn, crypt_gensalt_rn)
272
+ weak_alias(__crypt_gensalt_ra, crypt_gensalt_ra)
273
+ weak_alias(__crypt_gensalt, crypt_gensalt)
274
+ weak_alias(crypt, fcrypt)
275
+ #endif
276
+
277
+ #ifdef TEST
278
+ static const char *tests[][3] = {
279
+ {"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW",
280
+ "U*U"},
281
+ {"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK",
282
+ "U*U*"},
283
+ {"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a",
284
+ "U*U*U"},
285
+ {"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui",
286
+ "0123456789abcdefghijklmnopqrstuvwxyz"
287
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
288
+ "chars after 72 are ignored"},
289
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
290
+ "\xa3"},
291
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
292
+ "\xff\xff\xa3"},
293
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
294
+ "\xff\xff\xa3"},
295
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.nqd1wy.pTMdcvrRWxyiGL2eMz.2a85.",
296
+ "\xff\xff\xa3"},
297
+ {"$2b$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
298
+ "\xff\xff\xa3"},
299
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
300
+ "\xa3"},
301
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
302
+ "\xa3"},
303
+ {"$2b$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
304
+ "\xa3"},
305
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
306
+ "1\xa3" "345"},
307
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
308
+ "\xff\xa3" "345"},
309
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
310
+ "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"},
311
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
312
+ "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"},
313
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.ZC1JEJ8Z4gPfpe1JOr/oyPXTWl9EFd.",
314
+ "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"},
315
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e",
316
+ "\xff\xa3" "345"},
317
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e",
318
+ "\xff\xa3" "345"},
319
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS",
320
+ "\xa3" "ab"},
321
+ {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS",
322
+ "\xa3" "ab"},
323
+ {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS",
324
+ "\xa3" "ab"},
325
+ {"$2x$05$6bNw2HLQYeqHYyBfLMsv/OiwqTymGIGzFsA4hOTWebfehXHNprcAS",
326
+ "\xd1\x91"},
327
+ {"$2x$05$6bNw2HLQYeqHYyBfLMsv/O9LIGgn8OMzuDoHfof8AQimSGfcSWxnS",
328
+ "\xd0\xc1\xd2\xcf\xcc\xd8"},
329
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6",
330
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
331
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
332
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
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
+ "chars after 72 are ignored as usual"},
337
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.R9xrDjiycxMbQE2bp.vgqlYpW5wx2yy",
338
+ "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
339
+ "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
340
+ "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
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
+ {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.9tQZzcJfm3uj2NvJ/n5xkhpqLrMpWCe",
345
+ "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
346
+ "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
347
+ "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
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
+ {"$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy",
352
+ ""},
353
+ {"*0", "", "$2a$03$CCCCCCCCCCCCCCCCCCCCC."},
354
+ {"*0", "", "$2a$32$CCCCCCCCCCCCCCCCCCCCC."},
355
+ {"*0", "", "$2c$05$CCCCCCCCCCCCCCCCCCCCC."},
356
+ {"*0", "", "$2z$05$CCCCCCCCCCCCCCCCCCCCC."},
357
+ {"*0", "", "$2`$05$CCCCCCCCCCCCCCCCCCCCC."},
358
+ {"*0", "", "$2{$05$CCCCCCCCCCCCCCCCCCCCC."},
359
+ {"*1", "", "*0"},
360
+ {NULL}
361
+ };
362
+
363
+ #define which tests[0]
364
+
365
+ static volatile sig_atomic_t running;
366
+
367
+ static void handle_timer(int signum)
368
+ {
369
+ (void) signum;
370
+ running = 0;
371
+ }
372
+
373
+ static void *run(void *arg)
374
+ {
375
+ unsigned long count = 0;
376
+ int i = 0;
377
+ void *data = NULL;
378
+ int size = 0x12345678;
379
+
380
+ do {
381
+ const char *hash = tests[i][0];
382
+ const char *key = tests[i][1];
383
+ const char *setting = tests[i][2];
384
+
385
+ if (!tests[++i][0])
386
+ i = 0;
387
+
388
+ if (setting && strlen(hash) < 30) /* not for benchmark */
389
+ continue;
390
+
391
+ if (strcmp(crypt_ra(key, hash, &data, &size), hash)) {
392
+ printf("%d: FAILED (crypt_ra/%d/%lu)\n",
393
+ (int)((char *)arg - (char *)0), i, count);
394
+ free(data);
395
+ return NULL;
396
+ }
397
+ count++;
398
+ } while (running);
399
+
400
+ free(data);
401
+ return count + (char *)0;
402
+ }
403
+
404
+ int main(void)
405
+ {
406
+ struct itimerval it;
407
+ struct tms buf;
408
+ clock_t clk_tck, start_real, start_virtual, end_real, end_virtual;
409
+ unsigned long count;
410
+ void *data;
411
+ int size;
412
+ char *setting1, *setting2;
413
+ int i;
414
+ #ifdef TEST_THREADS
415
+ pthread_t t[TEST_THREADS];
416
+ void *t_retval;
417
+ #endif
418
+
419
+ data = NULL;
420
+ size = 0x12345678;
421
+
422
+ for (i = 0; tests[i][0]; i++) {
423
+ const char *hash = tests[i][0];
424
+ const char *key = tests[i][1];
425
+ const char *setting = tests[i][2];
426
+ const char *p;
427
+ int ok = !setting || strlen(hash) >= 30;
428
+ int o_size;
429
+ char s_buf[30], o_buf[61];
430
+ if (!setting) {
431
+ memcpy(s_buf, hash, sizeof(s_buf) - 1);
432
+ s_buf[sizeof(s_buf) - 1] = 0;
433
+ setting = s_buf;
434
+ }
435
+
436
+ __set_errno(0);
437
+ p = crypt(key, setting);
438
+ if ((!ok && !errno) || strcmp(p, hash)) {
439
+ printf("FAILED (crypt/%d)\n", i);
440
+ return 1;
441
+ }
442
+
443
+ if (ok && strcmp(crypt(key, hash), hash)) {
444
+ printf("FAILED (crypt/%d)\n", i);
445
+ return 1;
446
+ }
447
+
448
+ for (o_size = -1; o_size <= (int)sizeof(o_buf); o_size++) {
449
+ int ok_n = ok && o_size == (int)sizeof(o_buf);
450
+ const char *x = "abc";
451
+ strcpy(o_buf, x);
452
+ if (o_size >= 3) {
453
+ x = "*0";
454
+ if (setting[0] == '*' && setting[1] == '0')
455
+ x = "*1";
456
+ }
457
+ __set_errno(0);
458
+ p = crypt_rn(key, setting, o_buf, o_size);
459
+ if ((ok_n && (!p || strcmp(p, hash))) ||
460
+ (!ok_n && (!errno || p || strcmp(o_buf, x)))) {
461
+ printf("FAILED (crypt_rn/%d)\n", i);
462
+ return 1;
463
+ }
464
+ }
465
+
466
+ __set_errno(0);
467
+ p = crypt_ra(key, setting, &data, &size);
468
+ if ((ok && (!p || strcmp(p, hash))) ||
469
+ (!ok && (!errno || p || strcmp((char *)data, hash)))) {
470
+ printf("FAILED (crypt_ra/%d)\n", i);
471
+ return 1;
472
+ }
473
+ }
474
+
475
+ setting1 = crypt_gensalt(which[0], 12, data, size);
476
+ if (!setting1 || strncmp(setting1, "$2a$12$", 7)) {
477
+ puts("FAILED (crypt_gensalt)\n");
478
+ return 1;
479
+ }
480
+
481
+ setting2 = crypt_gensalt_ra(setting1, 12, data, size);
482
+ if (strcmp(setting1, setting2)) {
483
+ puts("FAILED (crypt_gensalt_ra/1)\n");
484
+ return 1;
485
+ }
486
+
487
+ (*(char *)data)++;
488
+ setting1 = crypt_gensalt_ra(setting2, 12, data, size);
489
+ if (!strcmp(setting1, setting2)) {
490
+ puts("FAILED (crypt_gensalt_ra/2)\n");
491
+ return 1;
492
+ }
493
+
494
+ free(setting1);
495
+ free(setting2);
496
+ free(data);
497
+
498
+ #if defined(_SC_CLK_TCK) || !defined(CLK_TCK)
499
+ clk_tck = sysconf(_SC_CLK_TCK);
500
+ #else
501
+ clk_tck = CLK_TCK;
502
+ #endif
503
+
504
+ running = 1;
505
+ signal(SIGALRM, handle_timer);
506
+
507
+ memset(&it, 0, sizeof(it));
508
+ it.it_value.tv_sec = 5;
509
+ setitimer(ITIMER_REAL, &it, NULL);
510
+
511
+ start_real = times(&buf);
512
+ start_virtual = buf.tms_utime + buf.tms_stime;
513
+
514
+ count = (char *)run((char *)0) - (char *)0;
515
+
516
+ end_real = times(&buf);
517
+ end_virtual = buf.tms_utime + buf.tms_stime;
518
+ if (end_virtual == start_virtual) end_virtual++;
519
+
520
+ printf("%.1f c/s real, %.1f c/s virtual\n",
521
+ (float)count * clk_tck / (end_real - start_real),
522
+ (float)count * clk_tck / (end_virtual - start_virtual));
523
+
524
+ #ifdef TEST_THREADS
525
+ running = 1;
526
+ it.it_value.tv_sec = 60;
527
+ setitimer(ITIMER_REAL, &it, NULL);
528
+ start_real = times(&buf);
529
+
530
+ for (i = 0; i < TEST_THREADS; i++)
531
+ if (pthread_create(&t[i], NULL, run, i + (char *)0)) {
532
+ perror("pthread_create");
533
+ return 1;
534
+ }
535
+
536
+ for (i = 0; i < TEST_THREADS; i++) {
537
+ if (pthread_join(t[i], &t_retval)) {
538
+ perror("pthread_join");
539
+ continue;
540
+ }
541
+ if (!t_retval) continue;
542
+ count = (char *)t_retval - (char *)0;
543
+ end_real = times(&buf);
544
+ printf("%d: %.1f c/s real\n", i,
545
+ (float)count * clk_tck / (end_real - start_real));
546
+ }
547
+ #endif
548
+
549
+ return 0;
550
+ }
551
+ #endif