xref: /freebsd/secure/lib/libcrypt/crypt-blowfish.c (revision 5c1296168babf97c51ff030872cddb7f9857474f)
15c129616SMark Murray /*
25c129616SMark Murray  * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
35c129616SMark Murray  * All rights reserved.
45c129616SMark Murray  *
55c129616SMark Murray  * Redistribution and use in source and binary forms, with or without
65c129616SMark Murray  * modification, are permitted provided that the following conditions
75c129616SMark Murray  * are met:
85c129616SMark Murray  * 1. Redistributions of source code must retain the above copyright
95c129616SMark Murray  *    notice, this list of conditions and the following disclaimer.
105c129616SMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
115c129616SMark Murray  *    notice, this list of conditions and the following disclaimer in the
125c129616SMark Murray  *    documentation and/or other materials provided with the distribution.
135c129616SMark Murray  * 3. All advertising materials mentioning features or use of this software
145c129616SMark Murray  *    must display the following acknowledgement:
155c129616SMark Murray  *      This product includes software developed by Niels Provos.
165c129616SMark Murray  * 4. The name of the author may not be used to endorse or promote products
175c129616SMark Murray  *    derived from this software without specific prior written permission.
185c129616SMark Murray  *
195c129616SMark Murray  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
205c129616SMark Murray  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
215c129616SMark Murray  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
225c129616SMark Murray  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
235c129616SMark Murray  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
245c129616SMark Murray  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c129616SMark Murray  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c129616SMark Murray  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c129616SMark Murray  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
285c129616SMark Murray  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c129616SMark Murray  *
305c129616SMark Murray  * $FreeBSD$
315c129616SMark Murray  */
325c129616SMark Murray 
335c129616SMark Murray /* This password hashing algorithm was designed by David Mazieres
345c129616SMark Murray  * <dm@lcs.mit.edu> and works as follows:
355c129616SMark Murray  *
365c129616SMark Murray  * 1. state := InitState ()
375c129616SMark Murray  * 2. state := ExpandKey (state, salt, password) 3.
385c129616SMark Murray  * REPEAT rounds:
395c129616SMark Murray  *	state := ExpandKey (state, 0, salt)
405c129616SMark Murray  *      state := ExpandKey(state, 0, password)
415c129616SMark Murray  * 4. ctext := "OrpheanBeholderScryDoubt"
425c129616SMark Murray  * 5. REPEAT 64:
435c129616SMark Murray  * 	ctext := Encrypt_ECB (state, ctext);
445c129616SMark Murray  * 6. RETURN Concatenate (salt, ctext);
455c129616SMark Murray  *
465c129616SMark Murray  */
475c129616SMark Murray 
485c129616SMark Murray /*
495c129616SMark Murray  * FreeBSD implementation by Paul Herman <pherman@frenchfries.net>
505c129616SMark Murray  */
515c129616SMark Murray 
525c129616SMark Murray #if 0
535c129616SMark Murray #include <stdio.h>
545c129616SMark Murray #endif
555c129616SMark Murray 
565c129616SMark Murray #include <stdio.h>
575c129616SMark Murray #include <stdlib.h>
585c129616SMark Murray #include <sys/types.h>
595c129616SMark Murray #include <string.h>
605c129616SMark Murray #include <pwd.h>
615c129616SMark Murray #include "blowfish.h"
625c129616SMark Murray 
635c129616SMark Murray /* This implementation is adaptable to current computing power.
645c129616SMark Murray  * You can have up to 2^31 rounds which should be enough for some
655c129616SMark Murray  * time to come.
665c129616SMark Murray  */
675c129616SMark Murray 
685c129616SMark Murray #define BCRYPT_VERSION '2'
695c129616SMark Murray #define BCRYPT_MAXSALT 16	/* Precomputation is just so nice */
705c129616SMark Murray #define BCRYPT_BLOCKS 6		/* Ciphertext blocks */
715c129616SMark Murray #define BCRYPT_MINROUNDS 16	/* we have log2(rounds) in salt */
725c129616SMark Murray 
735c129616SMark Murray char   *bcrypt_gensalt __P((u_int8_t));
745c129616SMark Murray 
755c129616SMark Murray static void encode_salt __P((char *, u_int8_t *, u_int16_t, u_int8_t));
765c129616SMark Murray static void encode_base64 __P((u_int8_t *, u_int8_t *, u_int16_t));
775c129616SMark Murray static void decode_base64 __P((u_int8_t *, u_int16_t, u_int8_t *));
785c129616SMark Murray 
795c129616SMark Murray static char    encrypted[_PASSWORD_LEN];
805c129616SMark Murray static char    gsalt[BCRYPT_MAXSALT * 4 / 3 + 1];
815c129616SMark Murray static char    error[] = ":";
825c129616SMark Murray 
835c129616SMark Murray const static u_int8_t Base64Code[] =
845c129616SMark Murray "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
855c129616SMark Murray 
865c129616SMark Murray const static u_int8_t index_64[128] =
875c129616SMark Murray {
885c129616SMark Murray 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
895c129616SMark Murray 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
905c129616SMark Murray 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
915c129616SMark Murray 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
925c129616SMark Murray 	255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
935c129616SMark Murray 	56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
945c129616SMark Murray 	255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
955c129616SMark Murray 	7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
965c129616SMark Murray 	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
975c129616SMark Murray 	255, 255, 255, 255, 255, 255, 28, 29, 30,
985c129616SMark Murray 	31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
995c129616SMark Murray 	41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
1005c129616SMark Murray 	51, 52, 53, 255, 255, 255, 255, 255
1015c129616SMark Murray };
1025c129616SMark Murray #define CHAR64(c)  ( (c) > 127 ? 255 : index_64[(c)])
1035c129616SMark Murray 
1045c129616SMark Murray #ifdef __STDC__
1055c129616SMark Murray static void
1065c129616SMark Murray decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
1075c129616SMark Murray #else
1085c129616SMark Murray static void
1095c129616SMark Murray decode_base64(buffer, len, data)
1105c129616SMark Murray 	u_int8_t *buffer;
1115c129616SMark Murray 	u_int16_t len;
1125c129616SMark Murray 	u_int8_t *data;
1135c129616SMark Murray #endif
1145c129616SMark Murray {
1155c129616SMark Murray 	u_int8_t *bp = buffer;
1165c129616SMark Murray 	u_int8_t *p = data;
1175c129616SMark Murray 	u_int8_t c1, c2, c3, c4;
1185c129616SMark Murray 	while (bp < buffer + len) {
1195c129616SMark Murray 		c1 = CHAR64(*p);
1205c129616SMark Murray 		c2 = CHAR64(*(p + 1));
1215c129616SMark Murray 
1225c129616SMark Murray 		/* Invalid data */
1235c129616SMark Murray 		if (c1 == 255 || c2 == 255)
1245c129616SMark Murray 			break;
1255c129616SMark Murray 
1265c129616SMark Murray 		*bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1275c129616SMark Murray 		if (bp >= buffer + len)
1285c129616SMark Murray 			break;
1295c129616SMark Murray 
1305c129616SMark Murray 		c3 = CHAR64(*(p + 2));
1315c129616SMark Murray 		if (c3 == 255)
1325c129616SMark Murray 			break;
1335c129616SMark Murray 
1345c129616SMark Murray 		*bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
1355c129616SMark Murray 		if (bp >= buffer + len)
1365c129616SMark Murray 			break;
1375c129616SMark Murray 
1385c129616SMark Murray 		c4 = CHAR64(*(p + 3));
1395c129616SMark Murray 		if (c4 == 255)
1405c129616SMark Murray 			break;
1415c129616SMark Murray 		*bp++ = ((c3 & 0x03) << 6) | c4;
1425c129616SMark Murray 
1435c129616SMark Murray 		p += 4;
1445c129616SMark Murray 	}
1455c129616SMark Murray }
1465c129616SMark Murray 
1475c129616SMark Murray #ifdef __STDC__
1485c129616SMark Murray static void
1495c129616SMark Murray encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
1505c129616SMark Murray #else
1515c129616SMark Murray static void
1525c129616SMark Murray encode_salt(salt, csalt, clen, logr)
1535c129616SMark Murray 	char   *salt;
1545c129616SMark Murray 	u_int8_t *csalt;
1555c129616SMark Murray 	u_int16_t clen;
1565c129616SMark Murray 	u_int8_t logr;
1575c129616SMark Murray #endif
1585c129616SMark Murray {
1595c129616SMark Murray 	salt[0] = '$';
1605c129616SMark Murray 	salt[1] = BCRYPT_VERSION;
1615c129616SMark Murray 	salt[2] = 'a';
1625c129616SMark Murray 	salt[3] = '$';
1635c129616SMark Murray 
1645c129616SMark Murray 	snprintf(salt + 4, 4, "%2.2u$", logr);
1655c129616SMark Murray 
1665c129616SMark Murray 	encode_base64((u_int8_t *) salt + 7, csalt, clen);
1675c129616SMark Murray }
1685c129616SMark Murray /* Generates a salt for this version of crypt.
1695c129616SMark Murray    Since versions may change. Keeping this here
1705c129616SMark Murray    seems sensible.
1715c129616SMark Murray  */
1725c129616SMark Murray 
1735c129616SMark Murray #ifdef __STDC__
1745c129616SMark Murray char *
1755c129616SMark Murray bcrypt_gensalt(u_int8_t log_rounds)
1765c129616SMark Murray #else
1775c129616SMark Murray char *
1785c129616SMark Murray bcrypt_gensalt(log_rounds)
1795c129616SMark Murray 	u_int8_t log_rounds;
1805c129616SMark Murray #endif
1815c129616SMark Murray {
1825c129616SMark Murray 	u_int8_t csalt[BCRYPT_MAXSALT];
1835c129616SMark Murray 	u_int16_t i;
1845c129616SMark Murray 	u_int32_t seed = 0;
1855c129616SMark Murray 
1865c129616SMark Murray 	for (i = 0; i < BCRYPT_MAXSALT; i++) {
1875c129616SMark Murray 		if (i % 4 == 0)
1885c129616SMark Murray 			seed = arc4random();
1895c129616SMark Murray 		csalt[i] = seed & 0xff;
1905c129616SMark Murray 		seed = seed >> 8;
1915c129616SMark Murray 	}
1925c129616SMark Murray 
1935c129616SMark Murray 	if (log_rounds < 4)
1945c129616SMark Murray 		log_rounds = 4;
1955c129616SMark Murray 
1965c129616SMark Murray 	encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds);
1975c129616SMark Murray 	return gsalt;
1985c129616SMark Murray }
1995c129616SMark Murray /* We handle $Vers$log2(NumRounds)$salt+passwd$
2005c129616SMark Murray    i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
2015c129616SMark Murray 
2025c129616SMark Murray char   *
2035c129616SMark Murray crypt_blowfish(key, salt)
2045c129616SMark Murray 	const char   *key;
2055c129616SMark Murray 	const char   *salt;
2065c129616SMark Murray {
2075c129616SMark Murray 	blf_ctx state;
2085c129616SMark Murray 	u_int32_t rounds, i, k;
2095c129616SMark Murray 	u_int16_t j;
2105c129616SMark Murray 	u_int8_t key_len, salt_len, logr, minor;
2115c129616SMark Murray 	u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
2125c129616SMark Murray 	u_int8_t csalt[BCRYPT_MAXSALT];
2135c129616SMark Murray 	u_int32_t cdata[BCRYPT_BLOCKS];
2145c129616SMark Murray 	static char     *magic = "$2a$04$";
2155c129616SMark Murray 
2165c129616SMark Murray 		/* Defaults */
2175c129616SMark Murray 	minor = 'a';
2185c129616SMark Murray 	logr = 4;
2195c129616SMark Murray 	rounds = 1 << logr;
2205c129616SMark Murray 
2215c129616SMark Murray         /* If it starts with the magic string, then skip that */
2225c129616SMark Murray 	if(!strncmp(salt, magic, strlen(magic))) {
2235c129616SMark Murray 		salt += strlen(magic);
2245c129616SMark Murray 	}
2255c129616SMark Murray 	else if (*salt == '$') {
2265c129616SMark Murray 
2275c129616SMark Murray 		/* Discard "$" identifier */
2285c129616SMark Murray 		salt++;
2295c129616SMark Murray 
2305c129616SMark Murray 		if (*salt > BCRYPT_VERSION) {
2315c129616SMark Murray 			/* How do I handle errors ? Return ':' */
2325c129616SMark Murray 			return error;
2335c129616SMark Murray 		}
2345c129616SMark Murray 
2355c129616SMark Murray 		/* Check for minor versions */
2365c129616SMark Murray 		if (salt[1] != '$') {
2375c129616SMark Murray 			 switch (salt[1]) {
2385c129616SMark Murray 			 case 'a':
2395c129616SMark Murray 				 /* 'ab' should not yield the same as 'abab' */
2405c129616SMark Murray 				 minor = salt[1];
2415c129616SMark Murray 				 salt++;
2425c129616SMark Murray 				 break;
2435c129616SMark Murray 			 default:
2445c129616SMark Murray 				 return error;
2455c129616SMark Murray 			 }
2465c129616SMark Murray 		} else
2475c129616SMark Murray 			 minor = 0;
2485c129616SMark Murray 
2495c129616SMark Murray 		/* Discard version + "$" identifier */
2505c129616SMark Murray 		salt += 2;
2515c129616SMark Murray 
2525c129616SMark Murray 		if (salt[2] != '$')
2535c129616SMark Murray 			/* Out of sync with passwd entry */
2545c129616SMark Murray 			return error;
2555c129616SMark Murray 
2565c129616SMark Murray 		/* Computer power doesnt increase linear, 2^x should be fine */
2575c129616SMark Murray 		if ((rounds = (u_int32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS)
2585c129616SMark Murray 			return error;
2595c129616SMark Murray 
2605c129616SMark Murray 		/* Discard num rounds + "$" identifier */
2615c129616SMark Murray 		salt += 3;
2625c129616SMark Murray 	}
2635c129616SMark Murray 
2645c129616SMark Murray 
2655c129616SMark Murray 	/* We dont want the base64 salt but the raw data */
2665c129616SMark Murray 	decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
2675c129616SMark Murray 	salt_len = BCRYPT_MAXSALT;
2685c129616SMark Murray 	key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
2695c129616SMark Murray 
2705c129616SMark Murray 	/* Setting up S-Boxes and Subkeys */
2715c129616SMark Murray 	Blowfish_initstate(&state);
2725c129616SMark Murray 	Blowfish_expandstate(&state, csalt, salt_len,
2735c129616SMark Murray 	    (u_int8_t *) key, key_len);
2745c129616SMark Murray 	for (k = 0; k < rounds; k++) {
2755c129616SMark Murray 		Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
2765c129616SMark Murray 		Blowfish_expand0state(&state, csalt, salt_len);
2775c129616SMark Murray 	}
2785c129616SMark Murray 
2795c129616SMark Murray 	/* This can be precomputed later */
2805c129616SMark Murray 	j = 0;
2815c129616SMark Murray 	for (i = 0; i < BCRYPT_BLOCKS; i++)
2825c129616SMark Murray 		cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
2835c129616SMark Murray 
2845c129616SMark Murray 	/* Now do the encryption */
2855c129616SMark Murray 	for (k = 0; k < 64; k++)
2865c129616SMark Murray 		blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
2875c129616SMark Murray 
2885c129616SMark Murray 	for (i = 0; i < BCRYPT_BLOCKS; i++) {
2895c129616SMark Murray 		ciphertext[4 * i + 3] = cdata[i] & 0xff;
2905c129616SMark Murray 		cdata[i] = cdata[i] >> 8;
2915c129616SMark Murray 		ciphertext[4 * i + 2] = cdata[i] & 0xff;
2925c129616SMark Murray 		cdata[i] = cdata[i] >> 8;
2935c129616SMark Murray 		ciphertext[4 * i + 1] = cdata[i] & 0xff;
2945c129616SMark Murray 		cdata[i] = cdata[i] >> 8;
2955c129616SMark Murray 		ciphertext[4 * i + 0] = cdata[i] & 0xff;
2965c129616SMark Murray 	}
2975c129616SMark Murray 
2985c129616SMark Murray 
2995c129616SMark Murray 	i = 0;
3005c129616SMark Murray 	encrypted[i++] = '$';
3015c129616SMark Murray 	encrypted[i++] = BCRYPT_VERSION;
3025c129616SMark Murray 	if (minor)
3035c129616SMark Murray 		encrypted[i++] = minor;
3045c129616SMark Murray 	encrypted[i++] = '$';
3055c129616SMark Murray 
3065c129616SMark Murray 	snprintf(encrypted + i, 4, "%2.2u$", logr);
3075c129616SMark Murray 
3085c129616SMark Murray 	encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
3095c129616SMark Murray 	encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
3105c129616SMark Murray 	    4 * BCRYPT_BLOCKS - 1);
3115c129616SMark Murray 	return encrypted;
3125c129616SMark Murray }
3135c129616SMark Murray 
3145c129616SMark Murray #ifdef __STDC__
3155c129616SMark Murray static void
3165c129616SMark Murray encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
3175c129616SMark Murray #else
3185c129616SMark Murray static void
3195c129616SMark Murray encode_base64(buffer, data, len)
3205c129616SMark Murray 	u_int8_t *buffer;
3215c129616SMark Murray 	u_int8_t *data;
3225c129616SMark Murray 	u_int16_t len;
3235c129616SMark Murray #endif
3245c129616SMark Murray {
3255c129616SMark Murray 	u_int8_t *bp = buffer;
3265c129616SMark Murray 	u_int8_t *p = data;
3275c129616SMark Murray 	u_int8_t c1, c2;
3285c129616SMark Murray 	while (p < data + len) {
3295c129616SMark Murray 		c1 = *p++;
3305c129616SMark Murray 		*bp++ = Base64Code[(c1 >> 2)];
3315c129616SMark Murray 		c1 = (c1 & 0x03) << 4;
3325c129616SMark Murray 		if (p >= data + len) {
3335c129616SMark Murray 			*bp++ = Base64Code[c1];
3345c129616SMark Murray 			break;
3355c129616SMark Murray 		}
3365c129616SMark Murray 		c2 = *p++;
3375c129616SMark Murray 		c1 |= (c2 >> 4) & 0x0f;
3385c129616SMark Murray 		*bp++ = Base64Code[c1];
3395c129616SMark Murray 		c1 = (c2 & 0x0f) << 2;
3405c129616SMark Murray 		if (p >= data + len) {
3415c129616SMark Murray 			*bp++ = Base64Code[c1];
3425c129616SMark Murray 			break;
3435c129616SMark Murray 		}
3445c129616SMark Murray 		c2 = *p++;
3455c129616SMark Murray 		c1 |= (c2 >> 6) & 0x03;
3465c129616SMark Murray 		*bp++ = Base64Code[c1];
3475c129616SMark Murray 		*bp++ = Base64Code[c2 & 0x3f];
3485c129616SMark Murray 	}
3495c129616SMark Murray 	*bp = '\0';
3505c129616SMark Murray }
3515c129616SMark Murray #if 0
3525c129616SMark Murray void
3535c129616SMark Murray main()
3545c129616SMark Murray {
3555c129616SMark Murray 	char    blubber[73];
3565c129616SMark Murray 	char    salt[100];
3575c129616SMark Murray 	char   *p;
3585c129616SMark Murray 	salt[0] = '$';
3595c129616SMark Murray 	salt[1] = BCRYPT_VERSION;
3605c129616SMark Murray 	salt[2] = '$';
3615c129616SMark Murray 
3625c129616SMark Murray 	snprintf(salt + 3, 4, "%2.2u$", 5);
3635c129616SMark Murray 
3645c129616SMark Murray 	printf("24 bytes of salt: ");
3655c129616SMark Murray 	fgets(salt + 6, 94, stdin);
3665c129616SMark Murray 	salt[99] = 0;
3675c129616SMark Murray 	printf("72 bytes of password: ");
3685c129616SMark Murray 	fpurge(stdin);
3695c129616SMark Murray 	fgets(blubber, 73, stdin);
3705c129616SMark Murray 	blubber[72] = 0;
3715c129616SMark Murray 
3725c129616SMark Murray 	p = crypt(blubber, salt);
3735c129616SMark Murray 	printf("Passwd entry: %s\n\n", p);
3745c129616SMark Murray 
3755c129616SMark Murray 	p = bcrypt_gensalt(5);
3765c129616SMark Murray 	printf("Generated salt: %s\n", p);
3775c129616SMark Murray 	p = crypt(blubber, p);
3785c129616SMark Murray 	printf("Passwd entry: %s\n", p);
3795c129616SMark Murray }
3805c129616SMark Murray #endif
381