bcrypt-ruby 2.1.4-x86-mingw32 → 3.0.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
  }