bcrypt-ruby 3.1.2.rc1-x64-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,64 @@
1
+ #include <ruby.h>
2
+ #include <ow-crypt.h>
3
+
4
+ static VALUE mBCrypt;
5
+ static VALUE cBCryptEngine;
6
+
7
+ /* Given a logarithmic cost parameter, generates a salt for use with +bc_crypt+.
8
+ */
9
+ static VALUE bc_salt(VALUE self, VALUE prefix, VALUE count, VALUE input) {
10
+ char * salt;
11
+ VALUE str_salt;
12
+
13
+ salt = crypt_gensalt_ra(
14
+ StringValuePtr(prefix),
15
+ NUM2ULONG(count),
16
+ NIL_P(input) ? NULL : StringValuePtr(input),
17
+ NIL_P(input) ? 0 : RSTRING_LEN(input));
18
+
19
+ if(!salt) return Qnil;
20
+
21
+ str_salt = rb_str_new2(salt);
22
+ xfree(salt);
23
+
24
+ return str_salt;
25
+ }
26
+
27
+ /* Given a secret and a salt, generates a salted hash (which you can then store safely).
28
+ */
29
+ static VALUE bc_crypt(VALUE self, VALUE key, VALUE setting) {
30
+ char * value;
31
+ void * data;
32
+ int size;
33
+ VALUE out;
34
+
35
+ data = NULL;
36
+ size = 0xDEADBEEF;
37
+
38
+ if(NIL_P(key) || NIL_P(setting)) return Qnil;
39
+
40
+ value = crypt_ra(
41
+ NIL_P(key) ? NULL : StringValuePtr(key),
42
+ NIL_P(setting) ? NULL : StringValuePtr(setting),
43
+ &data,
44
+ &size);
45
+
46
+ if(!value) return Qnil;
47
+
48
+ out = rb_str_new(data, size - 1);
49
+
50
+ xfree(data);
51
+
52
+ return out;
53
+ }
54
+
55
+ /* Create the BCrypt and BCrypt::Engine modules, and populate them with methods. */
56
+ void Init_bcrypt_ext(){
57
+ mBCrypt = rb_define_module("BCrypt");
58
+ cBCryptEngine = rb_define_class_under(mBCrypt, "Engine", rb_cObject);
59
+
60
+ rb_define_singleton_method(cBCryptEngine, "__bc_salt", bc_salt, 3);
61
+ rb_define_singleton_method(cBCryptEngine, "__bc_crypt", bc_crypt, 2);
62
+ }
63
+
64
+ /* vim: set noet sws=4 sw=4: */
data/ext/mri/crypt.c ADDED
@@ -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
+ }
data/ext/mri/crypt.h ADDED
@@ -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
@@ -0,0 +1,786 @@
1
+ /*
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.
5
+ *
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.
9
+ *
10
+ * There's absolutely no warranty.
11
+ *
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).
32
+ */
33
+
34
+ #include <string.h>
35
+
36
+ #include <errno.h>
37
+ #ifndef __set_errno
38
+ #define __set_errno(val) errno = (val)
39
+ #endif
40
+
41
+ #undef __CONST
42
+ #ifdef __GNUC__
43
+ #define __CONST __const
44
+ #else
45
+ #define __CONST
46
+ #endif
47
+
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
54
+
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
62
+
63
+ typedef unsigned int BF_word;
64
+ typedef signed int BF_word_signed;
65
+
66
+ /* Number of Blowfish rounds, this is also hardcoded into a few places */
67
+ #define BF_N 16
68
+
69
+ typedef BF_word BF_key[BF_N + 2];
70
+
71
+ typedef struct {
72
+ BF_word S[4][0x100];
73
+ BF_key P;
74
+ } BF_ctx;
75
+
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
+ {
90
+ {
91
+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
92
+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
93
+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
94
+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
95
+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
96
+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
97
+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
98
+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
99
+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
100
+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
101
+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
102
+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
103
+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
104
+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
105
+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
106
+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
107
+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
108
+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
109
+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
110
+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
111
+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
112
+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
113
+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
114
+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
115
+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
116
+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
117
+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
118
+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
119
+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
120
+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
121
+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
122
+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
123
+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
124
+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
125
+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
126
+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
127
+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
128
+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
129
+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
130
+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
131
+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
132
+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
133
+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
134
+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
135
+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
136
+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
137
+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
138
+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
139
+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
140
+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
141
+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
142
+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
143
+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
144
+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
145
+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
146
+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
147
+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
148
+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
149
+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
150
+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
151
+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
152
+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
153
+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
154
+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
155
+ }, {
156
+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
157
+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
158
+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
159
+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
160
+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
161
+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
162
+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
163
+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
164
+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
165
+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
166
+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
167
+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
168
+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
169
+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
170
+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
171
+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
172
+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
173
+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
174
+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
175
+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
176
+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
177
+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
178
+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
179
+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
180
+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
181
+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
182
+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
183
+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
184
+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
185
+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
186
+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
187
+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
188
+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
189
+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
190
+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
191
+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
192
+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
193
+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
194
+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
195
+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
196
+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
197
+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
198
+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
199
+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
200
+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
201
+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
202
+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
203
+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
204
+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
205
+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
206
+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
207
+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
208
+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
209
+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
210
+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
211
+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
212
+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
213
+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
214
+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
215
+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
216
+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
217
+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
218
+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
219
+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
220
+ }, {
221
+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
222
+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
223
+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
224
+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
225
+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
226
+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
227
+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
228
+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
229
+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
230
+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
231
+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
232
+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
233
+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
234
+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
235
+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
236
+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
237
+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
238
+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
239
+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
240
+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
241
+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
242
+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
243
+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
244
+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
245
+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
246
+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
247
+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
248
+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
249
+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
250
+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
251
+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
252
+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
253
+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
254
+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
255
+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
256
+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
257
+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
258
+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
259
+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
260
+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
261
+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
262
+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
263
+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
264
+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
265
+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
266
+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
267
+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
268
+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
269
+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
270
+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
271
+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
272
+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
273
+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
274
+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
275
+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
276
+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
277
+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
278
+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
279
+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
280
+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
281
+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
282
+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
283
+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
284
+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
285
+ }, {
286
+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
287
+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
288
+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
289
+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
290
+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
291
+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
292
+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
293
+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
294
+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
295
+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
296
+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
297
+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
298
+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
299
+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
300
+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
301
+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
302
+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
303
+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
304
+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
305
+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
306
+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
307
+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
308
+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
309
+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
310
+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
311
+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
312
+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
313
+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
314
+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
315
+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
316
+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
317
+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
318
+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
319
+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
320
+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
321
+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
322
+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
323
+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
324
+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
325
+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
326
+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
327
+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
328
+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
329
+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
330
+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
331
+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
332
+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
333
+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
334
+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
335
+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
336
+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
337
+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
338
+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
339
+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
340
+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
341
+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
342
+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
343
+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
344
+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
345
+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
346
+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
347
+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
348
+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
349
+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
350
+ }
351
+ }, {
352
+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
353
+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
354
+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
355
+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
356
+ 0x9216d5d9, 0x8979fb1b
357
+ }
358
+ };
359
+
360
+ static unsigned char BF_itoa64[64 + 1] =
361
+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
362
+
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
+ };
371
+
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
+ }
379
+
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
+ }
388
+
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;
411
+ }
412
+
413
+ static void BF_encode(char *dst, __CONST BF_word *src, int size)
414
+ {
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
+ }
428
+
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
+ }
437
+
438
+ c2 = *sptr++;
439
+ c1 |= c2 >> 6;
440
+ *dptr++ = BF_itoa64[c1];
441
+ *dptr++ = BF_itoa64[c2 & 0x3f];
442
+ } while (sptr < end);
443
+ }
444
+
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
+ }
458
+
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++;
559
+ }
560
+
561
+ expanded[i] = tmp;
562
+ initial[i] = BF_init_state.P[i] ^ tmp;
563
+ }
564
+ }
565
+
566
+ static char *BF_crypt(__CONST char *key, __CONST char *setting,
567
+ char *output, int size,
568
+ BF_word min)
569
+ {
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;
587
+ }
588
+
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
+ }
600
+
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;
606
+ }
607
+ BF_swap(data.binary.salt, 4);
608
+
609
+ BF_set_key(key, data.expanded_key, data.ctx.P, setting[2] == 'x');
610
+
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;
620
+ }
621
+
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
+ }
698
+
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];
702
+
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';
708
+
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
715
+
716
+ return output;
717
+ }
718
+
719
+ char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
720
+ char *output, int size)
721
+ {
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
760
+ }
761
+
762
+ char *_crypt_gensalt_blowfish_rn(unsigned long count,
763
+ __CONST char *input, int size, char *output, int output_size)
764
+ {
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;
770
+ }
771
+
772
+ if (!count) count = 5;
773
+
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] = '$';
781
+
782
+ BF_encode(&output[7], (BF_word *)input, 16);
783
+ output[7 + 22] = '\0';
784
+
785
+ return output;
786
+ }