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