bcrypt-ruby 2.1.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,57 @@
1
+ #include <ruby.h>
2
+ #include <ow-crypt.h>
3
+
4
+ VALUE mCrypt;
5
+
6
+ static VALUE crypt_salt(VALUE self, VALUE prefix, VALUE count, VALUE input)
7
+ {
8
+ char * salt;
9
+ VALUE str_salt;
10
+
11
+ salt = crypt_gensalt_ra(
12
+ StringValuePtr(prefix),
13
+ NUM2ULONG(count),
14
+ NIL_P(input) ? NULL : StringValuePtr(input),
15
+ NIL_P(input) ? 0 : RSTRING_LEN(input));
16
+
17
+ if(!salt) return Qnil;
18
+
19
+ str_salt = rb_str_new2(salt);
20
+ free(salt);
21
+
22
+ return str_salt;
23
+ }
24
+
25
+ static VALUE ra(VALUE self, VALUE key, VALUE setting)
26
+ {
27
+ char * value;
28
+ void * data;
29
+ int size;
30
+ VALUE out;
31
+
32
+ data = NULL;
33
+ size = 0xDEADBEEF;
34
+
35
+ if(NIL_P(key) || NIL_P(setting)) return Qnil;
36
+
37
+ value = crypt_ra(
38
+ NIL_P(key) ? NULL : StringValuePtr(key),
39
+ NIL_P(setting) ? NULL : StringValuePtr(setting),
40
+ &data,
41
+ &size);
42
+
43
+ if(!value) return Qnil;
44
+
45
+ out = rb_str_new(data, size - 1);
46
+
47
+ free(data);
48
+
49
+ return out;
50
+ }
51
+
52
+ void Init_crypt()
53
+ {
54
+ mCrypt = rb_define_module("Crypt");
55
+ rb_define_singleton_method(mCrypt, "salt", crypt_salt, 3);
56
+ rb_define_singleton_method(mCrypt, "crypt", ra, 2);
57
+ }
@@ -0,0 +1,13 @@
1
+ /*
2
+ * Written by Solar Designer and placed in the public domain.
3
+ * See crypt_blowfish.c for more information.
4
+ */
5
+
6
+ #include <gnu-crypt.h>
7
+
8
+ #if defined(_OW_SOURCE) || defined(__USE_OW)
9
+ #define __SKIP_GNU
10
+ #undef __SKIP_OW
11
+ #include <ow-crypt.h>
12
+ #undef __SKIP_GNU
13
+ #endif
@@ -1,119 +1,92 @@
1
- /* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
2
1
  /*
3
- * Blowfish block cipher for OpenBSD
4
- * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5
- * All rights reserved.
2
+ * This code comes from John the Ripper password cracker, with reentrant
3
+ * and crypt(3) interfaces added, but optimizations specific to password
4
+ * cracking removed.
6
5
  *
7
- * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
6
+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
7
+ * placed in the public domain. Quick self-test added in 2011 and also
8
+ * placed in the public domain.
8
9
  *
9
- * Redistribution and use in source and binary forms, with or without
10
- * modification, are permitted provided that the following conditions
11
- * are met:
12
- * 1. Redistributions of source code must retain the above copyright
13
- * notice, this list of conditions and the following disclaimer.
14
- * 2. Redistributions in binary form must reproduce the above copyright
15
- * notice, this list of conditions and the following disclaimer in the
16
- * documentation and/or other materials provided with the distribution.
17
- * 3. All advertising materials mentioning features or use of this software
18
- * must display the following acknowledgement:
19
- * This product includes software developed by Niels Provos.
20
- * 4. The name of the author may not be used to endorse or promote products
21
- * derived from this software without specific prior written permission.
10
+ * There's absolutely no warranty.
22
11
  *
23
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12
+ * It is my intent that you should be able to use this on your system,
13
+ * as a part of a software package, or anywhere else to improve security,
14
+ * ensure compatibility, or for any other purpose. I would appreciate
15
+ * it if you give credit where it is due and keep your modifications in
16
+ * the public domain as well, but I don't require that in order to let
17
+ * you place this code and any modifications you make under a license
18
+ * of your choice.
19
+ *
20
+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
21
+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
22
+ * ideas. The password hashing algorithm was designed by David Mazieres
23
+ * <dm at lcs.mit.edu>.
24
+ *
25
+ * There's a paper on the algorithm that explains its design decisions:
26
+ *
27
+ * http://www.usenix.org/events/usenix99/provos.html
28
+ *
29
+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
30
+ * Blowfish library (I can't be sure if I would think of something if I
31
+ * hadn't seen his code).
33
32
  */
34
33
 
35
- /*
36
- * This code is derived from section 14.3 and the given source
37
- * in section V of Applied Cryptography, second edition.
38
- * Blowfish is an unpatented fast block cipher designed by
39
- * Bruce Schneier.
40
- */
34
+ #include <string.h>
41
35
 
42
- #include "blf.h"
36
+ #include <errno.h>
37
+ #ifndef __set_errno
38
+ #define __set_errno(val) errno = (val)
39
+ #endif
43
40
 
44
- #undef inline
41
+ #undef __CONST
45
42
  #ifdef __GNUC__
46
- #define inline __inline
47
- #else /* !__GNUC__ */
48
- #define inline
49
- #endif /* !__GNUC__ */
43
+ #define __CONST __const
44
+ #else
45
+ #define __CONST
46
+ #endif
50
47
 
51
- /* Function for Feistel Networks */
48
+ /*
49
+ * Please keep this enabled. We really don't want incompatible hashes to be
50
+ * produced. The performance cost of this quick self-test is around 0.6% at
51
+ * the "$2a$08" setting.
52
+ */
53
+ #define BF_SELF_TEST
52
54
 
53
- #define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \
54
- + (s)[0x100 + (((x)>>16)&0xFF)]) \
55
- ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
56
- + (s)[0x300 + ( (x) &0xFF)])
55
+ #if defined(__x86_64__) || defined(__alpha__) || defined(__hppa__)
56
+ #define BF_ASM 0
57
+ #define BF_SCALE 1
58
+ #else
59
+ #define BF_ASM 0
60
+ #define BF_SCALE 0
61
+ #endif
57
62
 
58
- #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
63
+ typedef unsigned int BF_word;
64
+ typedef signed int BF_word_signed;
59
65
 
60
- void
61
- Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
62
- {
63
- uint32_t Xl;
64
- uint32_t Xr;
65
- uint32_t *s = c->S[0];
66
- uint32_t *p = c->P;
67
-
68
- Xl = *xl;
69
- Xr = *xr;
70
-
71
- Xl ^= p[0];
72
- BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
73
- BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
74
- BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
75
- BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
76
- BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
77
- BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
78
- BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
79
- BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
80
-
81
- *xl = Xr ^ p[17];
82
- *xr = Xl;
83
- }
66
+ /* Number of Blowfish rounds, this is also hardcoded into a few places */
67
+ #define BF_N 16
84
68
 
85
- void
86
- Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
87
- {
88
- uint32_t Xl;
89
- uint32_t Xr;
90
- uint32_t *s = c->S[0];
91
- uint32_t *p = c->P;
92
-
93
- Xl = *xl;
94
- Xr = *xr;
95
-
96
- Xl ^= p[17];
97
- BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
98
- BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
99
- BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
100
- BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
101
- BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
102
- BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
103
- BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
104
- BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
105
-
106
- *xl = Xr ^ p[0];
107
- *xr = Xl;
108
- }
69
+ typedef BF_word BF_key[BF_N + 2];
109
70
 
110
- void
111
- Blowfish_initstate(blf_ctx *c)
112
- {
113
- /* P-box and S-box tables initialized with digits of Pi */
71
+ typedef struct {
72
+ BF_word S[4][0x100];
73
+ BF_key P;
74
+ } BF_ctx;
114
75
 
115
- static const blf_ctx initstate =
116
- { {
76
+ /*
77
+ * Magic IV for 64 Blowfish encryptions that we do at the end.
78
+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
79
+ */
80
+ static BF_word BF_magic_w[6] = {
81
+ 0x4F727068, 0x65616E42, 0x65686F6C,
82
+ 0x64657253, 0x63727944, 0x6F756274
83
+ };
84
+
85
+ /*
86
+ * P-box and S-box tables initialized with digits of Pi.
87
+ */
88
+ static BF_ctx BF_init_state = {
89
+ {
117
90
  {
118
91
  0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
119
92
  0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
@@ -178,8 +151,8 @@ Blowfish_initstate(blf_ctx *c)
178
151
  0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
179
152
  0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
180
153
  0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
181
- 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
182
- {
154
+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
155
+ }, {
183
156
  0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
184
157
  0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
185
158
  0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
@@ -243,8 +216,8 @@ Blowfish_initstate(blf_ctx *c)
243
216
  0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
244
217
  0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
245
218
  0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
246
- 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
247
- {
219
+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
220
+ }, {
248
221
  0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
249
222
  0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
250
223
  0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
@@ -308,8 +281,8 @@ Blowfish_initstate(blf_ctx *c)
308
281
  0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
309
282
  0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
310
283
  0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
311
- 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
312
- {
284
+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
285
+ }, {
313
286
  0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
314
287
  0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
315
288
  0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
@@ -373,263 +346,441 @@ Blowfish_initstate(blf_ctx *c)
373
346
  0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
374
347
  0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
375
348
  0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
376
- 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
377
- },
378
- {
349
+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
350
+ }
351
+ }, {
379
352
  0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
380
353
  0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
381
354
  0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
382
355
  0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
383
356
  0x9216d5d9, 0x8979fb1b
384
- } };
357
+ }
358
+ };
385
359
 
386
- *c = initstate;
387
- }
360
+ static unsigned char BF_itoa64[64 + 1] =
361
+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
388
362
 
389
- uint32_t
390
- Blowfish_stream2word(const uint8_t *data, uint16_t databytes,
391
- uint16_t *current)
392
- {
393
- uint8_t i;
394
- uint16_t j;
395
- uint32_t temp;
363
+ static unsigned char BF_atoi64[0x60] = {
364
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
365
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
366
+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
367
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
368
+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
369
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
370
+ };
396
371
 
397
- temp = 0x00000000;
398
- j = *current;
372
+ /*
373
+ * This may be optimized out if built with function inlining and no BF_ASM.
374
+ */
375
+ static void clean(void *data, int size)
376
+ {
377
+ memset(data, 0, size);
378
+ }
399
379
 
400
- for (i = 0; i < 4; i++, j++) {
401
- if (j >= databytes)
402
- j = 0;
403
- temp = (temp << 8) | data[j];
404
- }
380
+ #define BF_safe_atoi64(dst, src) \
381
+ { \
382
+ tmp = (unsigned char)(src); \
383
+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
384
+ tmp = BF_atoi64[tmp]; \
385
+ if (tmp > 63) return -1; \
386
+ (dst) = tmp; \
387
+ }
405
388
 
406
- *current = j;
407
- return temp;
389
+ static int BF_decode(BF_word *dst, __CONST char *src, int size)
390
+ {
391
+ unsigned char *dptr = (unsigned char *)dst;
392
+ unsigned char *end = dptr + size;
393
+ unsigned char *sptr = (unsigned char *)src;
394
+ unsigned int tmp, c1, c2, c3, c4;
395
+
396
+ do {
397
+ BF_safe_atoi64(c1, *sptr++);
398
+ BF_safe_atoi64(c2, *sptr++);
399
+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
400
+ if (dptr >= end) break;
401
+
402
+ BF_safe_atoi64(c3, *sptr++);
403
+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
404
+ if (dptr >= end) break;
405
+
406
+ BF_safe_atoi64(c4, *sptr++);
407
+ *dptr++ = ((c3 & 0x03) << 6) | c4;
408
+ } while (dptr < end);
409
+
410
+ return 0;
408
411
  }
409
412
 
410
- void
411
- Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
413
+ static void BF_encode(char *dst, __CONST BF_word *src, int size)
412
414
  {
413
- uint16_t i;
414
- uint16_t j;
415
- uint16_t k;
416
- uint32_t temp;
417
- uint32_t datal;
418
- uint32_t datar;
419
-
420
- j = 0;
421
- for (i = 0; i < BLF_N + 2; i++) {
422
- /* Extract 4 int8 to 1 int32 from keystream */
423
- temp = Blowfish_stream2word(key, keybytes, &j);
424
- c->P[i] = c->P[i] ^ temp;
425
- }
415
+ unsigned char *sptr = (unsigned char *)src;
416
+ unsigned char *end = sptr + size;
417
+ unsigned char *dptr = (unsigned char *)dst;
418
+ unsigned int c1, c2;
419
+
420
+ do {
421
+ c1 = *sptr++;
422
+ *dptr++ = BF_itoa64[c1 >> 2];
423
+ c1 = (c1 & 0x03) << 4;
424
+ if (sptr >= end) {
425
+ *dptr++ = BF_itoa64[c1];
426
+ break;
427
+ }
426
428
 
427
- j = 0;
428
- datal = 0x00000000;
429
- datar = 0x00000000;
430
- for (i = 0; i < BLF_N + 2; i += 2) {
431
- Blowfish_encipher(c, &datal, &datar);
429
+ c2 = *sptr++;
430
+ c1 |= c2 >> 4;
431
+ *dptr++ = BF_itoa64[c1];
432
+ c1 = (c2 & 0x0f) << 2;
433
+ if (sptr >= end) {
434
+ *dptr++ = BF_itoa64[c1];
435
+ break;
436
+ }
432
437
 
433
- c->P[i] = datal;
434
- c->P[i + 1] = datar;
435
- }
438
+ c2 = *sptr++;
439
+ c1 |= c2 >> 6;
440
+ *dptr++ = BF_itoa64[c1];
441
+ *dptr++ = BF_itoa64[c2 & 0x3f];
442
+ } while (sptr < end);
443
+ }
436
444
 
437
- for (i = 0; i < 4; i++) {
438
- for (k = 0; k < 256; k += 2) {
439
- Blowfish_encipher(c, &datal, &datar);
445
+ static void BF_swap(BF_word *x, int count)
446
+ {
447
+ static int endianness_check = 1;
448
+ char *is_little_endian = (char *)&endianness_check;
449
+ BF_word tmp;
450
+
451
+ if (*is_little_endian)
452
+ do {
453
+ tmp = *x;
454
+ tmp = (tmp << 16) | (tmp >> 16);
455
+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
456
+ } while (--count);
457
+ }
440
458
 
441
- c->S[i][k] = datal;
442
- c->S[i][k + 1] = datar;
459
+ #if BF_SCALE
460
+ /* Architectures which can shift addresses left by 2 bits with no extra cost */
461
+ #define BF_ROUND(L, R, N) \
462
+ tmp1 = L & 0xFF; \
463
+ tmp2 = L >> 8; \
464
+ tmp2 &= 0xFF; \
465
+ tmp3 = L >> 16; \
466
+ tmp3 &= 0xFF; \
467
+ tmp4 = L >> 24; \
468
+ tmp1 = data.ctx.S[3][tmp1]; \
469
+ tmp2 = data.ctx.S[2][tmp2]; \
470
+ tmp3 = data.ctx.S[1][tmp3]; \
471
+ tmp3 += data.ctx.S[0][tmp4]; \
472
+ tmp3 ^= tmp2; \
473
+ R ^= data.ctx.P[N + 1]; \
474
+ tmp3 += tmp1; \
475
+ R ^= tmp3;
476
+ #else
477
+ /* Architectures with no complicated addressing modes supported */
478
+ #define BF_INDEX(S, i) \
479
+ (*((BF_word *)(((unsigned char *)S) + (i))))
480
+ #define BF_ROUND(L, R, N) \
481
+ tmp1 = L & 0xFF; \
482
+ tmp1 <<= 2; \
483
+ tmp2 = L >> 6; \
484
+ tmp2 &= 0x3FC; \
485
+ tmp3 = L >> 14; \
486
+ tmp3 &= 0x3FC; \
487
+ tmp4 = L >> 22; \
488
+ tmp4 &= 0x3FC; \
489
+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
490
+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
491
+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
492
+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
493
+ tmp3 ^= tmp2; \
494
+ R ^= data.ctx.P[N + 1]; \
495
+ tmp3 += tmp1; \
496
+ R ^= tmp3;
497
+ #endif
498
+
499
+ /*
500
+ * Encrypt one block, BF_N is hardcoded here.
501
+ */
502
+ #define BF_ENCRYPT \
503
+ L ^= data.ctx.P[0]; \
504
+ BF_ROUND(L, R, 0); \
505
+ BF_ROUND(R, L, 1); \
506
+ BF_ROUND(L, R, 2); \
507
+ BF_ROUND(R, L, 3); \
508
+ BF_ROUND(L, R, 4); \
509
+ BF_ROUND(R, L, 5); \
510
+ BF_ROUND(L, R, 6); \
511
+ BF_ROUND(R, L, 7); \
512
+ BF_ROUND(L, R, 8); \
513
+ BF_ROUND(R, L, 9); \
514
+ BF_ROUND(L, R, 10); \
515
+ BF_ROUND(R, L, 11); \
516
+ BF_ROUND(L, R, 12); \
517
+ BF_ROUND(R, L, 13); \
518
+ BF_ROUND(L, R, 14); \
519
+ BF_ROUND(R, L, 15); \
520
+ tmp4 = R; \
521
+ R = L; \
522
+ L = tmp4 ^ data.ctx.P[BF_N + 1];
523
+
524
+ #define BF_body() \
525
+ L = R = 0; \
526
+ ptr = data.ctx.P; \
527
+ do { \
528
+ ptr += 2; \
529
+ BF_ENCRYPT; \
530
+ *(ptr - 2) = L; \
531
+ *(ptr - 1) = R; \
532
+ } while (ptr < &data.ctx.P[BF_N + 2]); \
533
+ \
534
+ ptr = data.ctx.S[0]; \
535
+ do { \
536
+ ptr += 2; \
537
+ BF_ENCRYPT; \
538
+ *(ptr - 2) = L; \
539
+ *(ptr - 1) = R; \
540
+ } while (ptr < &data.ctx.S[3][0xFF]);
541
+
542
+ static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial,
543
+ int sign_extension_bug)
544
+ {
545
+ __CONST char *ptr = key;
546
+ int i, j;
547
+ BF_word tmp;
548
+
549
+ for (i = 0; i < BF_N + 2; i++) {
550
+ tmp = 0;
551
+ for (j = 0; j < 4; j++) {
552
+ tmp <<= 8;
553
+ if (sign_extension_bug)
554
+ tmp |= (BF_word_signed)(signed char)*ptr;
555
+ else
556
+ tmp |= (unsigned char)*ptr;
557
+
558
+ if (!*ptr) ptr = key; else ptr++;
443
559
  }
560
+
561
+ expanded[i] = tmp;
562
+ initial[i] = BF_init_state.P[i] ^ tmp;
444
563
  }
445
564
  }
446
565
 
447
-
448
- void
449
- Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
450
- const uint8_t *key, uint16_t keybytes)
566
+ static char *BF_crypt(__CONST char *key, __CONST char *setting,
567
+ char *output, int size,
568
+ BF_word min)
451
569
  {
452
- uint16_t i;
453
- uint16_t j;
454
- uint16_t k;
455
- uint32_t temp;
456
- uint32_t datal;
457
- uint32_t datar;
458
-
459
- j = 0;
460
- for (i = 0; i < BLF_N + 2; i++) {
461
- /* Extract 4 int8 to 1 int32 from keystream */
462
- temp = Blowfish_stream2word(key, keybytes, &j);
463
- c->P[i] = c->P[i] ^ temp;
570
+ struct {
571
+ BF_ctx ctx;
572
+ BF_key expanded_key;
573
+ union {
574
+ BF_word salt[4];
575
+ BF_word output[6];
576
+ } binary;
577
+ } data;
578
+ BF_word L, R;
579
+ BF_word tmp1, tmp2, tmp3, tmp4;
580
+ BF_word *ptr;
581
+ BF_word count;
582
+ int i;
583
+
584
+ if (size < 7 + 22 + 31 + 1) {
585
+ __set_errno(ERANGE);
586
+ return NULL;
464
587
  }
465
588
 
466
- j = 0;
467
- datal = 0x00000000;
468
- datar = 0x00000000;
469
- for (i = 0; i < BLF_N + 2; i += 2) {
470
- datal ^= Blowfish_stream2word(data, databytes, &j);
471
- datar ^= Blowfish_stream2word(data, databytes, &j);
472
- Blowfish_encipher(c, &datal, &datar);
589
+ if (setting[0] != '$' ||
590
+ setting[1] != '2' ||
591
+ (setting[2] != 'a' && setting[2] != 'x') ||
592
+ setting[3] != '$' ||
593
+ setting[4] < '0' || setting[4] > '3' ||
594
+ setting[5] < '0' || setting[5] > '9' ||
595
+ (setting[4] == '3' && setting[5] > '1') ||
596
+ setting[6] != '$') {
597
+ __set_errno(EINVAL);
598
+ return NULL;
599
+ }
473
600
 
474
- c->P[i] = datal;
475
- c->P[i + 1] = datar;
601
+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
602
+ if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) {
603
+ clean(data.binary.salt, sizeof(data.binary.salt));
604
+ __set_errno(EINVAL);
605
+ return NULL;
476
606
  }
607
+ BF_swap(data.binary.salt, 4);
477
608
 
478
- for (i = 0; i < 4; i++) {
479
- for (k = 0; k < 256; k += 2) {
480
- datal ^= Blowfish_stream2word(data, databytes, &j);
481
- datar ^= Blowfish_stream2word(data, databytes, &j);
482
- Blowfish_encipher(c, &datal, &datar);
609
+ BF_set_key(key, data.expanded_key, data.ctx.P, setting[2] == 'x');
483
610
 
484
- c->S[i][k] = datal;
485
- c->S[i][k + 1] = datar;
486
- }
611
+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
612
+
613
+ L = R = 0;
614
+ for (i = 0; i < BF_N + 2; i += 2) {
615
+ L ^= data.binary.salt[i & 2];
616
+ R ^= data.binary.salt[(i & 2) + 1];
617
+ BF_ENCRYPT;
618
+ data.ctx.P[i] = L;
619
+ data.ctx.P[i + 1] = R;
487
620
  }
488
621
 
489
- }
622
+ ptr = data.ctx.S[0];
623
+ do {
624
+ ptr += 4;
625
+ L ^= data.binary.salt[(BF_N + 2) & 3];
626
+ R ^= data.binary.salt[(BF_N + 3) & 3];
627
+ BF_ENCRYPT;
628
+ *(ptr - 4) = L;
629
+ *(ptr - 3) = R;
630
+
631
+ L ^= data.binary.salt[(BF_N + 4) & 3];
632
+ R ^= data.binary.salt[(BF_N + 5) & 3];
633
+ BF_ENCRYPT;
634
+ *(ptr - 2) = L;
635
+ *(ptr - 1) = R;
636
+ } while (ptr < &data.ctx.S[3][0xFF]);
637
+
638
+ do {
639
+ data.ctx.P[0] ^= data.expanded_key[0];
640
+ data.ctx.P[1] ^= data.expanded_key[1];
641
+ data.ctx.P[2] ^= data.expanded_key[2];
642
+ data.ctx.P[3] ^= data.expanded_key[3];
643
+ data.ctx.P[4] ^= data.expanded_key[4];
644
+ data.ctx.P[5] ^= data.expanded_key[5];
645
+ data.ctx.P[6] ^= data.expanded_key[6];
646
+ data.ctx.P[7] ^= data.expanded_key[7];
647
+ data.ctx.P[8] ^= data.expanded_key[8];
648
+ data.ctx.P[9] ^= data.expanded_key[9];
649
+ data.ctx.P[10] ^= data.expanded_key[10];
650
+ data.ctx.P[11] ^= data.expanded_key[11];
651
+ data.ctx.P[12] ^= data.expanded_key[12];
652
+ data.ctx.P[13] ^= data.expanded_key[13];
653
+ data.ctx.P[14] ^= data.expanded_key[14];
654
+ data.ctx.P[15] ^= data.expanded_key[15];
655
+ data.ctx.P[16] ^= data.expanded_key[16];
656
+ data.ctx.P[17] ^= data.expanded_key[17];
657
+
658
+ BF_body();
659
+
660
+ tmp1 = data.binary.salt[0];
661
+ tmp2 = data.binary.salt[1];
662
+ tmp3 = data.binary.salt[2];
663
+ tmp4 = data.binary.salt[3];
664
+ data.ctx.P[0] ^= tmp1;
665
+ data.ctx.P[1] ^= tmp2;
666
+ data.ctx.P[2] ^= tmp3;
667
+ data.ctx.P[3] ^= tmp4;
668
+ data.ctx.P[4] ^= tmp1;
669
+ data.ctx.P[5] ^= tmp2;
670
+ data.ctx.P[6] ^= tmp3;
671
+ data.ctx.P[7] ^= tmp4;
672
+ data.ctx.P[8] ^= tmp1;
673
+ data.ctx.P[9] ^= tmp2;
674
+ data.ctx.P[10] ^= tmp3;
675
+ data.ctx.P[11] ^= tmp4;
676
+ data.ctx.P[12] ^= tmp1;
677
+ data.ctx.P[13] ^= tmp2;
678
+ data.ctx.P[14] ^= tmp3;
679
+ data.ctx.P[15] ^= tmp4;
680
+ data.ctx.P[16] ^= tmp1;
681
+ data.ctx.P[17] ^= tmp2;
682
+
683
+ BF_body();
684
+ } while (--count);
685
+
686
+ for (i = 0; i < 6; i += 2) {
687
+ L = BF_magic_w[i];
688
+ R = BF_magic_w[i + 1];
689
+
690
+ count = 64;
691
+ do {
692
+ BF_ENCRYPT;
693
+ } while (--count);
694
+
695
+ data.binary.output[i] = L;
696
+ data.binary.output[i + 1] = R;
697
+ }
490
698
 
491
- void
492
- blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
493
- {
494
- /* Initialize S-boxes and subkeys with Pi */
495
- Blowfish_initstate(c);
699
+ memcpy(output, setting, 7 + 22 - 1);
700
+ output[7 + 22 - 1] = BF_itoa64[(int)
701
+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
496
702
 
497
- /* Transform S-boxes and subkeys with key */
498
- Blowfish_expand0state(c, k, len);
499
- }
703
+ /* This has to be bug-compatible with the original implementation, so
704
+ * only encode 23 of the 24 bytes. :-) */
705
+ BF_swap(data.binary.output, 6);
706
+ BF_encode(&output[7 + 22], data.binary.output, 23);
707
+ output[7 + 22 + 31] = '\0';
500
708
 
501
- void
502
- blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
503
- {
504
- uint32_t *d;
505
- uint16_t i;
709
+ #ifndef BF_SELF_TEST
710
+ /* Overwrite the most obvious sensitive data we have on the stack. Note
711
+ * that this does not guarantee there's no sensitive data left on the
712
+ * stack and/or in registers; I'm not aware of portable code that does. */
713
+ clean(&data, sizeof(data));
714
+ #endif
506
715
 
507
- d = data;
508
- for (i = 0; i < blocks; i++) {
509
- Blowfish_encipher(c, d, d + 1);
510
- d += 2;
511
- }
716
+ return output;
512
717
  }
513
718
 
514
- void
515
- blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
719
+ char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
720
+ char *output, int size)
516
721
  {
517
- uint32_t *d;
518
- uint16_t i;
519
-
520
- d = data;
521
- for (i = 0; i < blocks; i++) {
522
- Blowfish_decipher(c, d, d + 1);
523
- d += 2;
524
- }
722
+ #ifdef BF_SELF_TEST
723
+ __CONST char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
724
+ __CONST char *test_2a =
725
+ "$2a$00$abcdefghijklmnopqrstuui1D709vfamulimlGcq0qq3UvuUasvEa"
726
+ "\0"
727
+ "canary";
728
+ __CONST char *test_2x =
729
+ "$2x$00$abcdefghijklmnopqrstuuVUrPmXD6q/nVSSp7pNDhCR9071IfIRe"
730
+ "\0"
731
+ "canary";
732
+ __CONST char *test_hash, *p;
733
+ int ok;
734
+ char buf[7 + 22 + 31 + 1 + 6 + 1];
735
+
736
+ output = BF_crypt(key, setting, output, size, 16);
737
+
738
+ /* Do a quick self-test. This also happens to overwrite BF_crypt()'s data. */
739
+ test_hash = (setting[2] == 'x') ? test_2x : test_2a;
740
+ memcpy(buf, test_hash, sizeof(buf));
741
+ memset(buf, -1, sizeof(buf) - (6 + 1)); /* keep "canary" only */
742
+ p = BF_crypt(test_key, test_hash, buf, sizeof(buf) - 6, 1);
743
+
744
+ ok = (p == buf && !memcmp(p, test_hash, sizeof(buf)));
745
+
746
+ /* This could reveal what hash type we were using last. Unfortunately, we
747
+ * can't reliably clean the test_hash pointer. */
748
+ clean(&buf, sizeof(buf));
749
+
750
+ if (ok)
751
+ return output;
752
+
753
+ /* Should not happen */
754
+ __set_errno(EINVAL); /* pretend we don't support this hash type */
755
+ return NULL;
756
+ #else
757
+ #warning Self-test is disabled, please enable
758
+ return BF_crypt(key, setting, output, size, 16);
759
+ #endif
525
760
  }
526
761
 
527
- void
528
- blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
762
+ char *_crypt_gensalt_blowfish_rn(unsigned long count,
763
+ __CONST char *input, int size, char *output, int output_size)
529
764
  {
530
- uint32_t l, r;
531
- uint32_t i;
532
-
533
- for (i = 0; i < len; i += 8) {
534
- l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
535
- r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
536
- Blowfish_encipher(c, &l, &r);
537
- data[0] = l >> 24 & 0xff;
538
- data[1] = l >> 16 & 0xff;
539
- data[2] = l >> 8 & 0xff;
540
- data[3] = l & 0xff;
541
- data[4] = r >> 24 & 0xff;
542
- data[5] = r >> 16 & 0xff;
543
- data[6] = r >> 8 & 0xff;
544
- data[7] = r & 0xff;
545
- data += 8;
765
+ if (size < 16 || output_size < 7 + 22 + 1 ||
766
+ (count && (count < 4 || count > 31))) {
767
+ if (output_size > 0) output[0] = '\0';
768
+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
769
+ return NULL;
546
770
  }
547
- }
548
771
 
549
- void
550
- blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
551
- {
552
- uint32_t l, r;
553
- uint32_t i;
554
-
555
- for (i = 0; i < len; i += 8) {
556
- l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
557
- r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
558
- Blowfish_decipher(c, &l, &r);
559
- data[0] = l >> 24 & 0xff;
560
- data[1] = l >> 16 & 0xff;
561
- data[2] = l >> 8 & 0xff;
562
- data[3] = l & 0xff;
563
- data[4] = r >> 24 & 0xff;
564
- data[5] = r >> 16 & 0xff;
565
- data[6] = r >> 8 & 0xff;
566
- data[7] = r & 0xff;
567
- data += 8;
568
- }
569
- }
772
+ if (!count) count = 5;
570
773
 
571
- void
572
- blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
573
- {
574
- uint32_t l, r;
575
- uint32_t i, j;
576
-
577
- for (i = 0; i < len; i += 8) {
578
- for (j = 0; j < 8; j++)
579
- data[j] ^= iv[j];
580
- l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
581
- r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
582
- Blowfish_encipher(c, &l, &r);
583
- data[0] = l >> 24 & 0xff;
584
- data[1] = l >> 16 & 0xff;
585
- data[2] = l >> 8 & 0xff;
586
- data[3] = l & 0xff;
587
- data[4] = r >> 24 & 0xff;
588
- data[5] = r >> 16 & 0xff;
589
- data[6] = r >> 8 & 0xff;
590
- data[7] = r & 0xff;
591
- iv = data;
592
- data += 8;
593
- }
594
- }
774
+ output[0] = '$';
775
+ output[1] = '2';
776
+ output[2] = 'a';
777
+ output[3] = '$';
778
+ output[4] = '0' + count / 10;
779
+ output[5] = '0' + count % 10;
780
+ output[6] = '$';
595
781
 
596
- void
597
- blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
598
- {
599
- uint32_t l, r;
600
- uint8_t *iv;
601
- uint32_t i, j;
602
-
603
- iv = data + len - 16;
604
- data = data + len - 8;
605
- for (i = len - 8; i >= 8; i -= 8) {
606
- l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
607
- r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
608
- Blowfish_decipher(c, &l, &r);
609
- data[0] = l >> 24 & 0xff;
610
- data[1] = l >> 16 & 0xff;
611
- data[2] = l >> 8 & 0xff;
612
- data[3] = l & 0xff;
613
- data[4] = r >> 24 & 0xff;
614
- data[5] = r >> 16 & 0xff;
615
- data[6] = r >> 8 & 0xff;
616
- data[7] = r & 0xff;
617
- for (j = 0; j < 8; j++)
618
- data[j] ^= iv[j];
619
- iv -= 8;
620
- data -= 8;
621
- }
622
- l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
623
- r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
624
- Blowfish_decipher(c, &l, &r);
625
- data[0] = l >> 24 & 0xff;
626
- data[1] = l >> 16 & 0xff;
627
- data[2] = l >> 8 & 0xff;
628
- data[3] = l & 0xff;
629
- data[4] = r >> 24 & 0xff;
630
- data[5] = r >> 16 & 0xff;
631
- data[6] = r >> 8 & 0xff;
632
- data[7] = r & 0xff;
633
- for (j = 0; j < 8; j++)
634
- data[j] ^= iva[j];
782
+ BF_encode(&output[7], (BF_word *)input, 16);
783
+ output[7 + 22] = '\0';
784
+
785
+ return output;
635
786
  }