bcrypt.c revision 1.6 1 1.6 christos /* $NetBSD: bcrypt.c,v 1.6 2005/01/12 03:32:52 christos Exp $ */
2 1.1 itojun /* $OpenBSD: bcrypt.c,v 1.16 2002/02/19 19:39:36 millert Exp $ */
3 1.1 itojun
4 1.1 itojun /*
5 1.1 itojun * Copyright 1997 Niels Provos <provos (at) physnet.uni-hamburg.de>
6 1.1 itojun * All rights reserved.
7 1.1 itojun *
8 1.1 itojun * Redistribution and use in source and binary forms, with or without
9 1.1 itojun * modification, are permitted provided that the following conditions
10 1.1 itojun * are met:
11 1.1 itojun * 1. Redistributions of source code must retain the above copyright
12 1.1 itojun * notice, this list of conditions and the following disclaimer.
13 1.1 itojun * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 itojun * notice, this list of conditions and the following disclaimer in the
15 1.1 itojun * documentation and/or other materials provided with the distribution.
16 1.1 itojun * 3. All advertising materials mentioning features or use of this software
17 1.1 itojun * must display the following acknowledgement:
18 1.1 itojun * This product includes software developed by Niels Provos.
19 1.1 itojun * 4. The name of the author may not be used to endorse or promote products
20 1.1 itojun * derived from this software without specific prior written permission.
21 1.1 itojun *
22 1.1 itojun * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 1.1 itojun * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 1.1 itojun * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 1.1 itojun * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 1.1 itojun * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 1.1 itojun * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 1.1 itojun * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 1.1 itojun * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 1.1 itojun * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 1.1 itojun * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.1 itojun */
33 1.1 itojun
34 1.1 itojun /* This password hashing algorithm was designed by David Mazieres
35 1.1 itojun * <dm (at) lcs.mit.edu> and works as follows:
36 1.1 itojun *
37 1.1 itojun * 1. state := InitState ()
38 1.1 itojun * 2. state := ExpandKey (state, salt, password) 3.
39 1.1 itojun * REPEAT rounds:
40 1.1 itojun * state := ExpandKey (state, 0, salt)
41 1.1 itojun * state := ExpandKey(state, 0, password)
42 1.1 itojun * 4. ctext := "OrpheanBeholderScryDoubt"
43 1.1 itojun * 5. REPEAT 64:
44 1.1 itojun * ctext := Encrypt_ECB (state, ctext);
45 1.1 itojun * 6. RETURN Concatenate (salt, ctext);
46 1.1 itojun *
47 1.1 itojun */
48 1.3 jdolecek #include <sys/cdefs.h>
49 1.6 christos __RCSID("$NetBSD: bcrypt.c,v 1.6 2005/01/12 03:32:52 christos Exp $");
50 1.1 itojun
51 1.1 itojun #include <stdio.h>
52 1.1 itojun #include <stdlib.h>
53 1.1 itojun #include <sys/types.h>
54 1.1 itojun #include <string.h>
55 1.1 itojun #include <pwd.h>
56 1.4 christos #include <errno.h>
57 1.1 itojun
58 1.4 christos #include "crypt.h"
59 1.2 thorpej #include "blowfish.c"
60 1.1 itojun
61 1.1 itojun /* This implementation is adaptable to current computing power.
62 1.1 itojun * You can have up to 2^31 rounds which should be enough for some
63 1.1 itojun * time to come.
64 1.1 itojun */
65 1.1 itojun
66 1.1 itojun #define BCRYPT_VERSION '2'
67 1.1 itojun #define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */
68 1.4 christos #define BCRYPT_MAXSALTLEN (BCRYPT_MAXSALT * 4 / 3 + 1)
69 1.1 itojun #define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
70 1.1 itojun #define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */
71 1.1 itojun
72 1.1 itojun static void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
73 1.1 itojun static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t);
74 1.1 itojun static void decode_base64(u_int8_t *, u_int16_t, u_int8_t *);
75 1.1 itojun
76 1.1 itojun char *__bcrypt(const char *, const char *); /* XXX */
77 1.1 itojun
78 1.1 itojun static char encrypted[_PASSWORD_LEN];
79 1.1 itojun static char error[] = ":";
80 1.1 itojun
81 1.1 itojun const static u_int8_t Base64Code[] =
82 1.1 itojun "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
83 1.1 itojun
84 1.5 christos char *bcrypt_gensalt(u_int8_t);
85 1.5 christos
86 1.1 itojun const static u_int8_t index_64[128] =
87 1.1 itojun {
88 1.1 itojun 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
89 1.1 itojun 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90 1.1 itojun 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
91 1.1 itojun 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
92 1.1 itojun 255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
93 1.1 itojun 56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
94 1.1 itojun 255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
95 1.1 itojun 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
96 1.1 itojun 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
97 1.1 itojun 255, 255, 255, 255, 255, 255, 28, 29, 30,
98 1.1 itojun 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
99 1.1 itojun 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
100 1.1 itojun 51, 52, 53, 255, 255, 255, 255, 255
101 1.1 itojun };
102 1.1 itojun #define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
103 1.1 itojun
104 1.1 itojun static void
105 1.1 itojun decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
106 1.1 itojun {
107 1.1 itojun u_int8_t *bp = buffer;
108 1.1 itojun u_int8_t *p = data;
109 1.1 itojun u_int8_t c1, c2, c3, c4;
110 1.1 itojun while (bp < buffer + len) {
111 1.1 itojun c1 = CHAR64(*p);
112 1.1 itojun c2 = CHAR64(*(p + 1));
113 1.1 itojun
114 1.1 itojun /* Invalid data */
115 1.1 itojun if (c1 == 255 || c2 == 255)
116 1.1 itojun break;
117 1.1 itojun
118 1.1 itojun *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
119 1.1 itojun if (bp >= buffer + len)
120 1.1 itojun break;
121 1.1 itojun
122 1.1 itojun c3 = CHAR64(*(p + 2));
123 1.1 itojun if (c3 == 255)
124 1.1 itojun break;
125 1.1 itojun
126 1.1 itojun *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
127 1.1 itojun if (bp >= buffer + len)
128 1.1 itojun break;
129 1.1 itojun
130 1.1 itojun c4 = CHAR64(*(p + 3));
131 1.1 itojun if (c4 == 255)
132 1.1 itojun break;
133 1.1 itojun *bp++ = ((c3 & 0x03) << 6) | c4;
134 1.1 itojun
135 1.1 itojun p += 4;
136 1.1 itojun }
137 1.1 itojun }
138 1.1 itojun
139 1.1 itojun static void
140 1.1 itojun encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
141 1.1 itojun {
142 1.1 itojun salt[0] = '$';
143 1.1 itojun salt[1] = BCRYPT_VERSION;
144 1.1 itojun salt[2] = 'a';
145 1.1 itojun salt[3] = '$';
146 1.1 itojun
147 1.1 itojun snprintf(salt + 4, 4, "%2.2u$", logr);
148 1.1 itojun
149 1.1 itojun encode_base64((u_int8_t *) salt + 7, csalt, clen);
150 1.1 itojun }
151 1.1 itojun
152 1.4 christos int
153 1.6 christos __gensalt_blowfish(char *salt, size_t saltlen, const char *option)
154 1.1 itojun {
155 1.4 christos size_t i;
156 1.4 christos u_int32_t seed = 0;
157 1.1 itojun u_int8_t csalt[BCRYPT_MAXSALT];
158 1.4 christos
159 1.4 christos if (saltlen < BCRYPT_MAXSALTLEN) {
160 1.4 christos errno = ENOSPC;
161 1.4 christos return -1;
162 1.4 christos }
163 1.4 christos
164 1.4 christos if (nrounds > 255) {
165 1.4 christos errno = EINVAL;
166 1.4 christos return -1;
167 1.4 christos }
168 1.4 christos
169 1.4 christos if (nrounds < 4)
170 1.4 christos nrounds = 4;
171 1.1 itojun
172 1.1 itojun for (i = 0; i < BCRYPT_MAXSALT; i++) {
173 1.1 itojun if (i % 4 == 0)
174 1.1 itojun seed = arc4random();
175 1.1 itojun csalt[i] = seed & 0xff;
176 1.1 itojun seed = seed >> 8;
177 1.1 itojun }
178 1.4 christos encode_salt(salt, csalt, BCRYPT_MAXSALT, nrounds);
179 1.4 christos return 0;
180 1.4 christos }
181 1.1 itojun
182 1.4 christos /* Generates a salt for this version of crypt.
183 1.4 christos Since versions may change. Keeping this here
184 1.4 christos seems sensible.
185 1.4 christos XXX: compat.
186 1.4 christos */
187 1.4 christos char *
188 1.4 christos bcrypt_gensalt(u_int8_t log_rounds)
189 1.4 christos {
190 1.4 christos static char gsalt[BCRYPT_MAXSALTLEN];
191 1.6 christos char num[10];
192 1.6 christos
193 1.6 christos (void)snprintf(num, sizeof(num), "%d", log_rounds);
194 1.6 christos if (__gensalt_blowfish(gsalt, sizeof(gsalt), num) == -1)
195 1.4 christos return NULL;
196 1.1 itojun return gsalt;
197 1.1 itojun }
198 1.1 itojun
199 1.1 itojun /* We handle $Vers$log2(NumRounds)$salt+passwd$
200 1.1 itojun i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
201 1.1 itojun
202 1.1 itojun char *
203 1.1 itojun __bcrypt(key, salt)
204 1.1 itojun const char *key;
205 1.1 itojun const char *salt;
206 1.1 itojun {
207 1.1 itojun blf_ctx state;
208 1.1 itojun u_int32_t rounds, i, k;
209 1.1 itojun u_int16_t j;
210 1.1 itojun u_int8_t key_len, salt_len, logr, minor;
211 1.1 itojun u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
212 1.1 itojun u_int8_t csalt[BCRYPT_MAXSALT];
213 1.1 itojun u_int32_t cdata[BCRYPT_BLOCKS];
214 1.1 itojun
215 1.1 itojun /* Discard "$" identifier */
216 1.1 itojun salt++;
217 1.1 itojun
218 1.1 itojun if (*salt > BCRYPT_VERSION) {
219 1.1 itojun /* How do I handle errors ? Return ':' */
220 1.1 itojun return error;
221 1.1 itojun }
222 1.1 itojun
223 1.1 itojun /* Check for minor versions */
224 1.1 itojun if (salt[1] != '$') {
225 1.1 itojun switch (salt[1]) {
226 1.1 itojun case 'a':
227 1.1 itojun /* 'ab' should not yield the same as 'abab' */
228 1.1 itojun minor = salt[1];
229 1.1 itojun salt++;
230 1.1 itojun break;
231 1.1 itojun default:
232 1.1 itojun return error;
233 1.1 itojun }
234 1.1 itojun } else
235 1.1 itojun minor = 0;
236 1.1 itojun
237 1.1 itojun /* Discard version + "$" identifier */
238 1.1 itojun salt += 2;
239 1.1 itojun
240 1.1 itojun if (salt[2] != '$')
241 1.1 itojun /* Out of sync with passwd entry */
242 1.1 itojun return error;
243 1.1 itojun
244 1.1 itojun /* Computer power doesn't increase linear, 2^x should be fine */
245 1.1 itojun if ((rounds = (u_int32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS)
246 1.1 itojun return error;
247 1.1 itojun
248 1.1 itojun /* Discard num rounds + "$" identifier */
249 1.1 itojun salt += 3;
250 1.1 itojun
251 1.1 itojun if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
252 1.1 itojun return error;
253 1.1 itojun
254 1.1 itojun /* We dont want the base64 salt but the raw data */
255 1.1 itojun decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
256 1.1 itojun salt_len = BCRYPT_MAXSALT;
257 1.1 itojun key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
258 1.1 itojun
259 1.1 itojun /* Setting up S-Boxes and Subkeys */
260 1.1 itojun Blowfish_initstate(&state);
261 1.1 itojun Blowfish_expandstate(&state, csalt, salt_len,
262 1.1 itojun (u_int8_t *) key, key_len);
263 1.1 itojun for (k = 0; k < rounds; k++) {
264 1.1 itojun Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
265 1.1 itojun Blowfish_expand0state(&state, csalt, salt_len);
266 1.1 itojun }
267 1.1 itojun
268 1.1 itojun /* This can be precomputed later */
269 1.1 itojun j = 0;
270 1.1 itojun for (i = 0; i < BCRYPT_BLOCKS; i++)
271 1.1 itojun cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
272 1.1 itojun
273 1.1 itojun /* Now do the encryption */
274 1.1 itojun for (k = 0; k < 64; k++)
275 1.1 itojun blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
276 1.1 itojun
277 1.1 itojun for (i = 0; i < BCRYPT_BLOCKS; i++) {
278 1.1 itojun ciphertext[4 * i + 3] = cdata[i] & 0xff;
279 1.1 itojun cdata[i] = cdata[i] >> 8;
280 1.1 itojun ciphertext[4 * i + 2] = cdata[i] & 0xff;
281 1.1 itojun cdata[i] = cdata[i] >> 8;
282 1.1 itojun ciphertext[4 * i + 1] = cdata[i] & 0xff;
283 1.1 itojun cdata[i] = cdata[i] >> 8;
284 1.1 itojun ciphertext[4 * i + 0] = cdata[i] & 0xff;
285 1.1 itojun }
286 1.1 itojun
287 1.1 itojun
288 1.1 itojun i = 0;
289 1.1 itojun encrypted[i++] = '$';
290 1.1 itojun encrypted[i++] = BCRYPT_VERSION;
291 1.1 itojun if (minor)
292 1.1 itojun encrypted[i++] = minor;
293 1.1 itojun encrypted[i++] = '$';
294 1.1 itojun
295 1.1 itojun snprintf(encrypted + i, 4, "%2.2u$", logr);
296 1.1 itojun
297 1.1 itojun encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
298 1.1 itojun encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
299 1.1 itojun 4 * BCRYPT_BLOCKS - 1);
300 1.1 itojun return encrypted;
301 1.1 itojun }
302 1.1 itojun
303 1.1 itojun static void
304 1.1 itojun encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
305 1.1 itojun {
306 1.1 itojun u_int8_t *bp = buffer;
307 1.1 itojun u_int8_t *p = data;
308 1.1 itojun u_int8_t c1, c2;
309 1.1 itojun while (p < data + len) {
310 1.1 itojun c1 = *p++;
311 1.1 itojun *bp++ = Base64Code[(c1 >> 2)];
312 1.1 itojun c1 = (c1 & 0x03) << 4;
313 1.1 itojun if (p >= data + len) {
314 1.1 itojun *bp++ = Base64Code[c1];
315 1.1 itojun break;
316 1.1 itojun }
317 1.1 itojun c2 = *p++;
318 1.1 itojun c1 |= (c2 >> 4) & 0x0f;
319 1.1 itojun *bp++ = Base64Code[c1];
320 1.1 itojun c1 = (c2 & 0x0f) << 2;
321 1.1 itojun if (p >= data + len) {
322 1.1 itojun *bp++ = Base64Code[c1];
323 1.1 itojun break;
324 1.1 itojun }
325 1.1 itojun c2 = *p++;
326 1.1 itojun c1 |= (c2 >> 6) & 0x03;
327 1.1 itojun *bp++ = Base64Code[c1];
328 1.1 itojun *bp++ = Base64Code[c2 & 0x3f];
329 1.1 itojun }
330 1.1 itojun *bp = '\0';
331 1.1 itojun }
332 1.1 itojun #if 0
333 1.1 itojun void
334 1.1 itojun main()
335 1.1 itojun {
336 1.1 itojun char blubber[73];
337 1.1 itojun char salt[100];
338 1.1 itojun char *p;
339 1.1 itojun salt[0] = '$';
340 1.1 itojun salt[1] = BCRYPT_VERSION;
341 1.1 itojun salt[2] = '$';
342 1.1 itojun
343 1.1 itojun snprintf(salt + 3, 4, "%2.2u$", 5);
344 1.1 itojun
345 1.1 itojun printf("24 bytes of salt: ");
346 1.1 itojun fgets(salt + 6, 94, stdin);
347 1.1 itojun salt[99] = 0;
348 1.1 itojun printf("72 bytes of password: ");
349 1.1 itojun fpurge(stdin);
350 1.1 itojun fgets(blubber, 73, stdin);
351 1.1 itojun blubber[72] = 0;
352 1.1 itojun
353 1.1 itojun p = crypt(blubber, salt);
354 1.1 itojun printf("Passwd entry: %s\n\n", p);
355 1.1 itojun
356 1.1 itojun p = bcrypt_gensalt(5);
357 1.1 itojun printf("Generated salt: %s\n", p);
358 1.1 itojun p = crypt(blubber, p);
359 1.1 itojun printf("Passwd entry: %s\n", p);
360 1.1 itojun }
361 1.1 itojun #endif
362