Deleted Added
full compact
crypt-blowfish.c (85358) crypt-blowfish.c (91754)
1/*
2 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
1/*
2 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/secure/lib/libcrypt/crypt-blowfish.c 85358 2001-10-23 10:23:32Z peter $");
32__FBSDID("$FreeBSD: head/secure/lib/libcrypt/crypt-blowfish.c 91754 2002-03-06 17:18:09Z markm $");
33
34/* This password hashing algorithm was designed by David Mazieres
35 * <dm@lcs.mit.edu> and works as follows:
36 *
37 * 1. state := InitState ()
38 * 2. state := ExpandKey (state, salt, password) 3.
39 * REPEAT rounds:
40 * state := ExpandKey (state, 0, salt)

--- 4 unchanged lines hidden (view full) ---

45 * 6. RETURN Concatenate (salt, ctext);
46 *
47 */
48
49/*
50 * FreeBSD implementation by Paul Herman <pherman@frenchfries.net>
51 */
52
33
34/* This password hashing algorithm was designed by David Mazieres
35 * <dm@lcs.mit.edu> and works as follows:
36 *
37 * 1. state := InitState ()
38 * 2. state := ExpandKey (state, salt, password) 3.
39 * REPEAT rounds:
40 * state := ExpandKey (state, 0, salt)

--- 4 unchanged lines hidden (view full) ---

45 * 6. RETURN Concatenate (salt, ctext);
46 *
47 */
48
49/*
50 * FreeBSD implementation by Paul Herman <pherman@frenchfries.net>
51 */
52
53#if 0
54#include <stdio.h>
53#include <stdio.h>
55#endif
56
57#include <stdio.h>
58#include <stdlib.h>
59#include <sys/types.h>
60#include <string.h>
61#include <pwd.h>
62#include "blowfish.h"
54#include <stdlib.h>
55#include <sys/types.h>
56#include <string.h>
57#include <pwd.h>
58#include "blowfish.h"
59#include "crypt.h"
63
64/* This implementation is adaptable to current computing power.
65 * You can have up to 2^31 rounds which should be enough for some
66 * time to come.
67 */
68
69#define BCRYPT_VERSION '2'
70#define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */
71#define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
72#define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */
73
60
61/* This implementation is adaptable to current computing power.
62 * You can have up to 2^31 rounds which should be enough for some
63 * time to come.
64 */
65
66#define BCRYPT_VERSION '2'
67#define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */
68#define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
69#define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */
70
74char *bcrypt_gensalt __P((u_int8_t));
71char *bcrypt_gensalt(u_int8_t);
75
72
76static void encode_salt __P((char *, u_int8_t *, u_int16_t, u_int8_t));
77static void encode_base64 __P((u_int8_t *, u_int8_t *, u_int16_t));
78static void decode_base64 __P((u_int8_t *, u_int16_t, u_int8_t *));
73static void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
74static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t);
75static void decode_base64(u_int8_t *, u_int16_t, const u_int8_t *);
79
80static char encrypted[_PASSWORD_LEN];
81static char gsalt[BCRYPT_MAXSALT * 4 / 3 + 1];
82static char error[] = ":";
83
76
77static char encrypted[_PASSWORD_LEN];
78static char gsalt[BCRYPT_MAXSALT * 4 / 3 + 1];
79static char error[] = ":";
80
84const static u_int8_t Base64Code[] =
81static const u_int8_t Base64Code[] =
85"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
86
82"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
83
87const static u_int8_t index_64[128] =
84static const u_int8_t index_64[128] =
88{
89 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
91 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
92 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
93 255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
94 56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
95 255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
96 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
97 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
98 255, 255, 255, 255, 255, 255, 28, 29, 30,
99 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
100 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
101 51, 52, 53, 255, 255, 255, 255, 255
102};
103#define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
104
85{
86 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
87 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
88 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
89 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90 255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
91 56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
92 255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
93 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
94 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
95 255, 255, 255, 255, 255, 255, 28, 29, 30,
96 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
97 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
98 51, 52, 53, 255, 255, 255, 255, 255
99};
100#define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
101
105#ifdef __STDC__
106static void
102static void
107decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
108#else
109static void
110decode_base64(buffer, len, data)
111 u_int8_t *buffer;
112 u_int16_t len;
113 u_int8_t *data;
114#endif
103decode_base64(u_int8_t *buffer, u_int16_t len, const u_int8_t *data)
115{
116 u_int8_t *bp = buffer;
104{
105 u_int8_t *bp = buffer;
117 u_int8_t *p = data;
106 const u_int8_t *p = data;
118 u_int8_t c1, c2, c3, c4;
119 while (bp < buffer + len) {
120 c1 = CHAR64(*p);
121 c2 = CHAR64(*(p + 1));
122
123 /* Invalid data */
124 if (c1 == 255 || c2 == 255)
125 break;
126
107 u_int8_t c1, c2, c3, c4;
108 while (bp < buffer + len) {
109 c1 = CHAR64(*p);
110 c2 = CHAR64(*(p + 1));
111
112 /* Invalid data */
113 if (c1 == 255 || c2 == 255)
114 break;
115
127 *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
116 *bp++ = (u_int8_t)((c1 << 2) | ((c2 & 0x30) >> 4));
128 if (bp >= buffer + len)
129 break;
130
131 c3 = CHAR64(*(p + 2));
132 if (c3 == 255)
133 break;
134
135 *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);

--- 4 unchanged lines hidden (view full) ---

140 if (c4 == 255)
141 break;
142 *bp++ = ((c3 & 0x03) << 6) | c4;
143
144 p += 4;
145 }
146}
147
117 if (bp >= buffer + len)
118 break;
119
120 c3 = CHAR64(*(p + 2));
121 if (c3 == 255)
122 break;
123
124 *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);

--- 4 unchanged lines hidden (view full) ---

129 if (c4 == 255)
130 break;
131 *bp++ = ((c3 & 0x03) << 6) | c4;
132
133 p += 4;
134 }
135}
136
148#ifdef __STDC__
149static void
150encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
137static void
138encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
151#else
152static void
153encode_salt(salt, csalt, clen, logr)
154 char *salt;
155 u_int8_t *csalt;
156 u_int16_t clen;
157 u_int8_t logr;
158#endif
159{
160 salt[0] = '$';
161 salt[1] = BCRYPT_VERSION;
162 salt[2] = 'a';
163 salt[3] = '$';
164
165 snprintf(salt + 4, 4, "%2.2u$", logr);
166
167 encode_base64((u_int8_t *) salt + 7, csalt, clen);
168}
169/* Generates a salt for this version of crypt.
170 Since versions may change. Keeping this here
171 seems sensible.
172 */
173
139{
140 salt[0] = '$';
141 salt[1] = BCRYPT_VERSION;
142 salt[2] = 'a';
143 salt[3] = '$';
144
145 snprintf(salt + 4, 4, "%2.2u$", logr);
146
147 encode_base64((u_int8_t *) salt + 7, csalt, clen);
148}
149/* Generates a salt for this version of crypt.
150 Since versions may change. Keeping this here
151 seems sensible.
152 */
153
174#ifdef __STDC__
175char *
176bcrypt_gensalt(u_int8_t log_rounds)
154char *
155bcrypt_gensalt(u_int8_t log_rounds)
177#else
178char *
179bcrypt_gensalt(log_rounds)
180 u_int8_t log_rounds;
181#endif
182{
183 u_int8_t csalt[BCRYPT_MAXSALT];
184 u_int16_t i;
185 u_int32_t seed = 0;
186
187 for (i = 0; i < BCRYPT_MAXSALT; i++) {
188 if (i % 4 == 0)
189 seed = arc4random();

--- 6 unchanged lines hidden (view full) ---

196
197 encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds);
198 return gsalt;
199}
200/* We handle $Vers$log2(NumRounds)$salt+passwd$
201 i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
202
203char *
156{
157 u_int8_t csalt[BCRYPT_MAXSALT];
158 u_int16_t i;
159 u_int32_t seed = 0;
160
161 for (i = 0; i < BCRYPT_MAXSALT; i++) {
162 if (i % 4 == 0)
163 seed = arc4random();

--- 6 unchanged lines hidden (view full) ---

170
171 encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds);
172 return gsalt;
173}
174/* We handle $Vers$log2(NumRounds)$salt+passwd$
175 i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
176
177char *
204crypt_blowfish(key, salt)
205 const char *key;
206 const char *salt;
178crypt_blowfish(const char *key, const char *salt)
207{
208 blf_ctx state;
209 u_int32_t rounds, i, k;
210 u_int16_t j;
179{
180 blf_ctx state;
181 u_int32_t rounds, i, k;
182 u_int16_t j;
211 u_int8_t key_len, salt_len, logr, minor;
183 u_int8_t key_len, salt_len, logr, minr;
212 u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
213 u_int8_t csalt[BCRYPT_MAXSALT];
214 u_int32_t cdata[BCRYPT_BLOCKS];
184 u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
185 u_int8_t csalt[BCRYPT_MAXSALT];
186 u_int32_t cdata[BCRYPT_BLOCKS];
215 static char *magic = "$2a$04$";
187 static const char *magic = "$2a$04$";
216
217 /* Defaults */
188
189 /* Defaults */
218 minor = 'a';
190 minr = 'a';
219 logr = 4;
220 rounds = 1 << logr;
221
222 /* If it starts with the magic string, then skip that */
223 if(!strncmp(salt, magic, strlen(magic))) {
224 salt += strlen(magic);
225 }
226 else if (*salt == '$') {

--- 6 unchanged lines hidden (view full) ---

233 return error;
234 }
235
236 /* Check for minor versions */
237 if (salt[1] != '$') {
238 switch (salt[1]) {
239 case 'a':
240 /* 'ab' should not yield the same as 'abab' */
191 logr = 4;
192 rounds = 1 << logr;
193
194 /* If it starts with the magic string, then skip that */
195 if(!strncmp(salt, magic, strlen(magic))) {
196 salt += strlen(magic);
197 }
198 else if (*salt == '$') {

--- 6 unchanged lines hidden (view full) ---

205 return error;
206 }
207
208 /* Check for minor versions */
209 if (salt[1] != '$') {
210 switch (salt[1]) {
211 case 'a':
212 /* 'ab' should not yield the same as 'abab' */
241 minor = salt[1];
213 minr = (u_int8_t)salt[1];
242 salt++;
243 break;
244 default:
245 return error;
246 }
247 } else
214 salt++;
215 break;
216 default:
217 return error;
218 }
219 } else
248 minor = 0;
220 minr = 0;
249
250 /* Discard version + "$" identifier */
251 salt += 2;
252
253 if (salt[2] != '$')
254 /* Out of sync with passwd entry */
255 return error;
256
257 /* Computer power doesnt increase linear, 2^x should be fine */
221
222 /* Discard version + "$" identifier */
223 salt += 2;
224
225 if (salt[2] != '$')
226 /* Out of sync with passwd entry */
227 return error;
228
229 /* Computer power doesnt increase linear, 2^x should be fine */
258 if ((rounds = (u_int32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS)
230 logr = (u_int8_t)atoi(salt);
231 rounds = 1 << logr;
232 if (rounds < BCRYPT_MINROUNDS)
259 return error;
260
261 /* Discard num rounds + "$" identifier */
262 salt += 3;
263 }
264
265
266 /* We dont want the base64 salt but the raw data */
233 return error;
234
235 /* Discard num rounds + "$" identifier */
236 salt += 3;
237 }
238
239
240 /* We dont want the base64 salt but the raw data */
267 decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
241 decode_base64(csalt, BCRYPT_MAXSALT, salt);
268 salt_len = BCRYPT_MAXSALT;
242 salt_len = BCRYPT_MAXSALT;
269 key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
243 key_len = (u_int8_t)(strlen(key) + (minr >= 'a' ? 1 : 0));
270
271 /* Setting up S-Boxes and Subkeys */
272 Blowfish_initstate(&state);
273 Blowfish_expandstate(&state, csalt, salt_len,
244
245 /* Setting up S-Boxes and Subkeys */
246 Blowfish_initstate(&state);
247 Blowfish_expandstate(&state, csalt, salt_len,
274 (u_int8_t *) key, key_len);
248 (const u_int8_t *) key, key_len);
275 for (k = 0; k < rounds; k++) {
249 for (k = 0; k < rounds; k++) {
276 Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
250 Blowfish_expand0state(&state, (const u_int8_t *) key, key_len);
277 Blowfish_expand0state(&state, csalt, salt_len);
278 }
279
280 /* This can be precomputed later */
281 j = 0;
282 for (i = 0; i < BCRYPT_BLOCKS; i++)
283 cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
284

--- 10 unchanged lines hidden (view full) ---

295 cdata[i] = cdata[i] >> 8;
296 ciphertext[4 * i + 0] = cdata[i] & 0xff;
297 }
298
299
300 i = 0;
301 encrypted[i++] = '$';
302 encrypted[i++] = BCRYPT_VERSION;
251 Blowfish_expand0state(&state, csalt, salt_len);
252 }
253
254 /* This can be precomputed later */
255 j = 0;
256 for (i = 0; i < BCRYPT_BLOCKS; i++)
257 cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
258

--- 10 unchanged lines hidden (view full) ---

269 cdata[i] = cdata[i] >> 8;
270 ciphertext[4 * i + 0] = cdata[i] & 0xff;
271 }
272
273
274 i = 0;
275 encrypted[i++] = '$';
276 encrypted[i++] = BCRYPT_VERSION;
303 if (minor)
304 encrypted[i++] = minor;
277 if (minr)
278 encrypted[i++] = (int8_t)minr;
305 encrypted[i++] = '$';
306
307 snprintf(encrypted + i, 4, "%2.2u$", logr);
308
309 encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
310 encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
311 4 * BCRYPT_BLOCKS - 1);
312 return encrypted;
313}
314
279 encrypted[i++] = '$';
280
281 snprintf(encrypted + i, 4, "%2.2u$", logr);
282
283 encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
284 encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
285 4 * BCRYPT_BLOCKS - 1);
286 return encrypted;
287}
288
315#ifdef __STDC__
316static void
317encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
289static void
290encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
318#else
319static void
320encode_base64(buffer, data, len)
321 u_int8_t *buffer;
322 u_int8_t *data;
323 u_int16_t len;
324#endif
325{
326 u_int8_t *bp = buffer;
327 u_int8_t *p = data;
328 u_int8_t c1, c2;
329 while (p < data + len) {
330 c1 = *p++;
331 *bp++ = Base64Code[(c1 >> 2)];
332 c1 = (c1 & 0x03) << 4;

--- 11 unchanged lines hidden (view full) ---

344 }
345 c2 = *p++;
346 c1 |= (c2 >> 6) & 0x03;
347 *bp++ = Base64Code[c1];
348 *bp++ = Base64Code[c2 & 0x3f];
349 }
350 *bp = '\0';
351}
291{
292 u_int8_t *bp = buffer;
293 u_int8_t *p = data;
294 u_int8_t c1, c2;
295 while (p < data + len) {
296 c1 = *p++;
297 *bp++ = Base64Code[(c1 >> 2)];
298 c1 = (c1 & 0x03) << 4;

--- 11 unchanged lines hidden (view full) ---

310 }
311 c2 = *p++;
312 c1 |= (c2 >> 6) & 0x03;
313 *bp++ = Base64Code[c1];
314 *bp++ = Base64Code[c2 & 0x3f];
315 }
316 *bp = '\0';
317}
318
352#if 0
353void
354main()
355{
356 char blubber[73];
357 char salt[100];
358 char *p;
359 salt[0] = '$';

--- 22 unchanged lines hidden ---
319#if 0
320void
321main()
322{
323 char blubber[73];
324 char salt[100];
325 char *p;
326 salt[0] = '$';

--- 22 unchanged lines hidden ---