xref: /openbsd-src/lib/libc/crypt/bcrypt.c (revision 1a0ab62094e3228bee25c13db900b0ec294222ab)
1 /*	$OpenBSD: bcrypt.c,v 1.45 2014/07/20 04:22:34 guenther Exp $	*/
2 
3 /*
4  * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
5  * Copyright (c) 1997 Niels Provos <provos@umich.edu>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 /* This password hashing algorithm was designed by David Mazieres
20  * <dm@lcs.mit.edu> and works as follows:
21  *
22  * 1. state := InitState ()
23  * 2. state := ExpandKey (state, salt, password)
24  * 3. REPEAT rounds:
25  *      state := ExpandKey (state, 0, password)
26  *	state := ExpandKey (state, 0, salt)
27  * 4. ctext := "OrpheanBeholderScryDoubt"
28  * 5. REPEAT 64:
29  * 	ctext := Encrypt_ECB (state, ctext);
30  * 6. RETURN Concatenate (salt, ctext);
31  *
32  */
33 
34 #include <sys/types.h>
35 #include <blf.h>
36 #include <ctype.h>
37 #include <pwd.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 
42 /* This implementation is adaptable to current computing power.
43  * You can have up to 2^31 rounds which should be enough for some
44  * time to come.
45  */
46 
47 #define BCRYPT_VERSION '2'
48 #define BCRYPT_MAXSALT 16	/* Precomputation is just so nice */
49 #define BCRYPT_BLOCKS 6		/* Ciphertext blocks */
50 #define BCRYPT_MINLOGROUNDS 4	/* we have log2(rounds) in salt */
51 
52 #define	BCRYPT_SALTSPACE	(7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1)
53 
54 char   *bcrypt_gensalt(u_int8_t);
55 
56 static int encode_base64(char *, const u_int8_t *, size_t);
57 static int decode_base64(u_int8_t *, size_t, const char *);
58 
59 /*
60  * Generates a salt for this version of crypt.
61  */
62 static int
63 bcrypt_initsalt(int log_rounds, uint8_t *salt, size_t saltbuflen)
64 {
65 	uint8_t csalt[BCRYPT_MAXSALT];
66 
67 	if (saltbuflen < BCRYPT_SALTSPACE)
68 		return -1;
69 
70 	arc4random_buf(csalt, sizeof(csalt));
71 
72 	if (log_rounds < 4)
73 		log_rounds = 4;
74 	else if (log_rounds > 31)
75 		log_rounds = 31;
76 
77 	snprintf(salt, saltbuflen, "$2b$%2.2u$", log_rounds);
78 	encode_base64(salt + 7, csalt, sizeof(csalt));
79 
80 	return 0;
81 }
82 
83 /*
84  * the core bcrypt function
85  */
86 static int
87 bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
88     size_t encryptedlen)
89 {
90 	blf_ctx state;
91 	u_int32_t rounds, i, k;
92 	u_int16_t j;
93 	size_t key_len;
94 	u_int8_t salt_len, logr, minor;
95 	u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
96 	u_int8_t csalt[BCRYPT_MAXSALT];
97 	u_int32_t cdata[BCRYPT_BLOCKS];
98 
99 	/* Check and discard "$" identifier */
100 	if (salt[0] != '$')
101 		return -1;
102 	salt += 1;
103 
104 	if (salt[0] != BCRYPT_VERSION)
105 		return -1;
106 
107 	/* Check for minor versions */
108 	switch ((minor = salt[1])) {
109 	case 'a':
110 		key_len = (u_int8_t)(strlen(key) + 1);
111 		break;
112 	case 'b':
113 		/* strlen() returns a size_t, but the function calls
114 		 * below result in implicit casts to a narrower integer
115 		 * type, so cap key_len at the actual maximum supported
116 		 * length here to avoid integer wraparound */
117 		key_len = strlen(key);
118 		if (key_len > 72)
119 			key_len = 72;
120 		key_len++; /* include the NUL */
121 		break;
122 	default:
123 		 return -1;
124 	}
125 	if (salt[2] != '$')
126 		return -1;
127 	/* Discard version + "$" identifier */
128 	salt += 3;
129 
130 	/* Check and parse num rounds */
131 	if (!isdigit((unsigned char)salt[0]) ||
132 	    !isdigit((unsigned char)salt[1]) || salt[2] != '$')
133 		return -1;
134 	logr = atoi(salt);
135 	if (logr < BCRYPT_MINLOGROUNDS || logr > 31)
136 		return -1;
137 	/* Computer power doesn't increase linearly, 2^x should be fine */
138 	rounds = 1U << logr;
139 
140 	/* Discard num rounds + "$" identifier */
141 	salt += 3;
142 
143 	if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
144 		return -1;
145 
146 	/* We dont want the base64 salt but the raw data */
147 	if (decode_base64(csalt, BCRYPT_MAXSALT, salt))
148 		return -1;
149 	salt_len = BCRYPT_MAXSALT;
150 
151 	/* Setting up S-Boxes and Subkeys */
152 	Blowfish_initstate(&state);
153 	Blowfish_expandstate(&state, csalt, salt_len,
154 	    (u_int8_t *) key, key_len);
155 	for (k = 0; k < rounds; k++) {
156 		Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
157 		Blowfish_expand0state(&state, csalt, salt_len);
158 	}
159 
160 	/* This can be precomputed later */
161 	j = 0;
162 	for (i = 0; i < BCRYPT_BLOCKS; i++)
163 		cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
164 
165 	/* Now do the encryption */
166 	for (k = 0; k < 64; k++)
167 		blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
168 
169 	for (i = 0; i < BCRYPT_BLOCKS; i++) {
170 		ciphertext[4 * i + 3] = cdata[i] & 0xff;
171 		cdata[i] = cdata[i] >> 8;
172 		ciphertext[4 * i + 2] = cdata[i] & 0xff;
173 		cdata[i] = cdata[i] >> 8;
174 		ciphertext[4 * i + 1] = cdata[i] & 0xff;
175 		cdata[i] = cdata[i] >> 8;
176 		ciphertext[4 * i + 0] = cdata[i] & 0xff;
177 	}
178 
179 
180 	i = 0;
181 	encrypted[i++] = '$';
182 	encrypted[i++] = BCRYPT_VERSION;
183 	encrypted[i++] = minor;
184 	encrypted[i++] = '$';
185 
186 	snprintf(encrypted + i, 4, "%2.2u$", logr);
187 
188 	encode_base64(encrypted + i + 3, csalt, BCRYPT_MAXSALT);
189 	encode_base64(encrypted + strlen(encrypted), ciphertext,
190 	    4 * BCRYPT_BLOCKS - 1);
191 	explicit_bzero(&state, sizeof(state));
192 	explicit_bzero(ciphertext, sizeof(ciphertext));
193 	explicit_bzero(csalt, sizeof(csalt));
194 	explicit_bzero(cdata, sizeof(cdata));
195 	return 0;
196 }
197 
198 /*
199  * user friendly functions
200  */
201 int
202 bcrypt_newhash(const char *pass, int log_rounds, char *hash, size_t hashlen)
203 {
204 	char salt[BCRYPT_SALTSPACE];
205 
206 	if (bcrypt_initsalt(log_rounds, salt, sizeof(salt)) != 0)
207 		return -1;
208 
209 	if (bcrypt_hashpass(pass, salt, hash, hashlen) != 0)
210 		return -1;
211 
212 	explicit_bzero(salt, sizeof(salt));
213 	return 0;
214 }
215 
216 int
217 bcrypt_checkpass(const char *pass, const char *goodhash)
218 {
219 	char hash[_PASSWORD_LEN];
220 
221 	if (bcrypt_hashpass(pass, goodhash, hash, sizeof(hash)) != 0)
222 		return -1;
223 	if (strlen(hash) != strlen(goodhash) ||
224 	    timingsafe_bcmp(hash, goodhash, strlen(goodhash)) != 0)
225 		return -1;
226 
227 	explicit_bzero(hash, sizeof(hash));
228 	return 0;
229 }
230 
231 /*
232  * internal utilities
233  */
234 static const u_int8_t Base64Code[] =
235 "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
236 
237 static const u_int8_t index_64[128] = {
238 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
239 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
240 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
241 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
242 	255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
243 	56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
244 	255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
245 	7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
246 	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
247 	255, 255, 255, 255, 255, 255, 28, 29, 30,
248 	31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
249 	41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
250 	51, 52, 53, 255, 255, 255, 255, 255
251 };
252 #define CHAR64(c)  ( (c) > 127 ? 255 : index_64[(c)])
253 
254 /*
255  * read buflen (after decoding) bytes of data from b64data
256  */
257 static int
258 decode_base64(u_int8_t *buffer, size_t len, const char *b64data)
259 {
260 	u_int8_t *bp = buffer;
261 	const u_int8_t *p = b64data;
262 	u_int8_t c1, c2, c3, c4;
263 
264 	while (bp < buffer + len) {
265 		c1 = CHAR64(*p);
266 		/* Invalid data */
267 		if (c1 == 255)
268 			return -1;
269 
270 		c2 = CHAR64(*(p + 1));
271 		if (c2 == 255)
272 			return -1;
273 
274 		*bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
275 		if (bp >= buffer + len)
276 			break;
277 
278 		c3 = CHAR64(*(p + 2));
279 		if (c3 == 255)
280 			return -1;
281 
282 		*bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
283 		if (bp >= buffer + len)
284 			break;
285 
286 		c4 = CHAR64(*(p + 3));
287 		if (c4 == 255)
288 			return -1;
289 		*bp++ = ((c3 & 0x03) << 6) | c4;
290 
291 		p += 4;
292 	}
293 	return 0;
294 }
295 
296 /*
297  * Turn len bytes of data into base64 encoded data.
298  * This works without = padding.
299  */
300 static int
301 encode_base64(char *b64buffer, const u_int8_t *data, size_t len)
302 {
303 	u_int8_t *bp = b64buffer;
304 	const u_int8_t *p = data;
305 	u_int8_t c1, c2;
306 
307 	while (p < data + len) {
308 		c1 = *p++;
309 		*bp++ = Base64Code[(c1 >> 2)];
310 		c1 = (c1 & 0x03) << 4;
311 		if (p >= data + len) {
312 			*bp++ = Base64Code[c1];
313 			break;
314 		}
315 		c2 = *p++;
316 		c1 |= (c2 >> 4) & 0x0f;
317 		*bp++ = Base64Code[c1];
318 		c1 = (c2 & 0x0f) << 2;
319 		if (p >= data + len) {
320 			*bp++ = Base64Code[c1];
321 			break;
322 		}
323 		c2 = *p++;
324 		c1 |= (c2 >> 6) & 0x03;
325 		*bp++ = Base64Code[c1];
326 		*bp++ = Base64Code[c2 & 0x3f];
327 	}
328 	*bp = '\0';
329 	return 0;
330 }
331 
332 /*
333  * classic interface
334  */
335 char *
336 bcrypt_gensalt(u_int8_t log_rounds)
337 {
338 	static char    gsalt[BCRYPT_SALTSPACE];
339 
340 	bcrypt_initsalt(log_rounds, gsalt, sizeof(gsalt));
341 
342 	return gsalt;
343 }
344 
345 char *
346 bcrypt(const char *pass, const char *salt)
347 {
348 	static char    gencrypted[_PASSWORD_LEN];
349 	static char    gerror[2];
350 
351 	/* How do I handle errors ? Return ':' */
352 	strlcpy(gerror, ":", sizeof(gerror));
353 	if (bcrypt_hashpass(pass, salt, gencrypted, sizeof(gencrypted)) != 0)
354 		return gerror;
355 
356 	return gencrypted;
357 }
358 
359