Home | History | Annotate | Line # | Download | only in libcrypt
bcrypt.c revision 1.5
      1  1.5  christos /*	$NetBSD: bcrypt.c,v 1.5 2005/01/11 23:02:16 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.1    itojun 
     49  1.1    itojun #if 0
     50  1.1    itojun #include <stdio.h>
     51  1.1    itojun #endif
     52  1.3  jdolecek 
     53  1.3  jdolecek #include <sys/cdefs.h>
     54  1.5  christos __RCSID("$NetBSD: bcrypt.c,v 1.5 2005/01/11 23:02:16 christos Exp $");
     55  1.1    itojun 
     56  1.1    itojun #include <stdio.h>
     57  1.1    itojun #include <stdlib.h>
     58  1.1    itojun #include <sys/types.h>
     59  1.1    itojun #include <string.h>
     60  1.1    itojun #include <pwd.h>
     61  1.4  christos #include <errno.h>
     62  1.1    itojun 
     63  1.4  christos #include "crypt.h"
     64  1.2   thorpej #include "blowfish.c"
     65  1.1    itojun 
     66  1.1    itojun /* This implementation is adaptable to current computing power.
     67  1.1    itojun  * You can have up to 2^31 rounds which should be enough for some
     68  1.1    itojun  * time to come.
     69  1.1    itojun  */
     70  1.1    itojun 
     71  1.1    itojun #define BCRYPT_VERSION '2'
     72  1.1    itojun #define BCRYPT_MAXSALT 16	/* Precomputation is just so nice */
     73  1.4  christos #define BCRYPT_MAXSALTLEN 	(BCRYPT_MAXSALT * 4 / 3 + 1)
     74  1.1    itojun #define BCRYPT_BLOCKS 6		/* Ciphertext blocks */
     75  1.1    itojun #define BCRYPT_MINROUNDS 16	/* we have log2(rounds) in salt */
     76  1.1    itojun 
     77  1.1    itojun static void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
     78  1.1    itojun static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t);
     79  1.1    itojun static void decode_base64(u_int8_t *, u_int16_t, u_int8_t *);
     80  1.1    itojun 
     81  1.1    itojun char *__bcrypt(const char *, const char *);	/* XXX */
     82  1.1    itojun 
     83  1.1    itojun static char    encrypted[_PASSWORD_LEN];
     84  1.1    itojun static char    error[] = ":";
     85  1.1    itojun 
     86  1.1    itojun const static u_int8_t Base64Code[] =
     87  1.1    itojun "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
     88  1.1    itojun 
     89  1.5  christos char *bcrypt_gensalt(u_int8_t);
     90  1.5  christos 
     91  1.1    itojun const static u_int8_t index_64[128] =
     92  1.1    itojun {
     93  1.1    itojun 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     94  1.1    itojun 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     95  1.1    itojun 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     96  1.1    itojun 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     97  1.1    itojun 	255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
     98  1.1    itojun 	56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
     99  1.1    itojun 	255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
    100  1.1    itojun 	7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    101  1.1    itojun 	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
    102  1.1    itojun 	255, 255, 255, 255, 255, 255, 28, 29, 30,
    103  1.1    itojun 	31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    104  1.1    itojun 	41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
    105  1.1    itojun 	51, 52, 53, 255, 255, 255, 255, 255
    106  1.1    itojun };
    107  1.1    itojun #define CHAR64(c)  ( (c) > 127 ? 255 : index_64[(c)])
    108  1.1    itojun 
    109  1.1    itojun static void
    110  1.1    itojun decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
    111  1.1    itojun {
    112  1.1    itojun 	u_int8_t *bp = buffer;
    113  1.1    itojun 	u_int8_t *p = data;
    114  1.1    itojun 	u_int8_t c1, c2, c3, c4;
    115  1.1    itojun 	while (bp < buffer + len) {
    116  1.1    itojun 		c1 = CHAR64(*p);
    117  1.1    itojun 		c2 = CHAR64(*(p + 1));
    118  1.1    itojun 
    119  1.1    itojun 		/* Invalid data */
    120  1.1    itojun 		if (c1 == 255 || c2 == 255)
    121  1.1    itojun 			break;
    122  1.1    itojun 
    123  1.1    itojun 		*bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
    124  1.1    itojun 		if (bp >= buffer + len)
    125  1.1    itojun 			break;
    126  1.1    itojun 
    127  1.1    itojun 		c3 = CHAR64(*(p + 2));
    128  1.1    itojun 		if (c3 == 255)
    129  1.1    itojun 			break;
    130  1.1    itojun 
    131  1.1    itojun 		*bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
    132  1.1    itojun 		if (bp >= buffer + len)
    133  1.1    itojun 			break;
    134  1.1    itojun 
    135  1.1    itojun 		c4 = CHAR64(*(p + 3));
    136  1.1    itojun 		if (c4 == 255)
    137  1.1    itojun 			break;
    138  1.1    itojun 		*bp++ = ((c3 & 0x03) << 6) | c4;
    139  1.1    itojun 
    140  1.1    itojun 		p += 4;
    141  1.1    itojun 	}
    142  1.1    itojun }
    143  1.1    itojun 
    144  1.1    itojun static void
    145  1.1    itojun encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
    146  1.1    itojun {
    147  1.1    itojun 	salt[0] = '$';
    148  1.1    itojun 	salt[1] = BCRYPT_VERSION;
    149  1.1    itojun 	salt[2] = 'a';
    150  1.1    itojun 	salt[3] = '$';
    151  1.1    itojun 
    152  1.1    itojun 	snprintf(salt + 4, 4, "%2.2u$", logr);
    153  1.1    itojun 
    154  1.1    itojun 	encode_base64((u_int8_t *) salt + 7, csalt, clen);
    155  1.1    itojun }
    156  1.1    itojun 
    157  1.4  christos int
    158  1.4  christos __gensalt_blowfish(char *salt, size_t saltlen, size_t nrounds)
    159  1.1    itojun {
    160  1.4  christos 	size_t i;
    161  1.4  christos 	u_int32_t seed = 0;
    162  1.1    itojun 	u_int8_t csalt[BCRYPT_MAXSALT];
    163  1.4  christos 
    164  1.4  christos 	if (saltlen < BCRYPT_MAXSALTLEN) {
    165  1.4  christos 		errno = ENOSPC;
    166  1.4  christos 		return -1;
    167  1.4  christos 	}
    168  1.4  christos 
    169  1.4  christos 	if (nrounds > 255) {
    170  1.4  christos 		errno = EINVAL;
    171  1.4  christos 		return -1;
    172  1.4  christos 	}
    173  1.4  christos 
    174  1.4  christos 	if (nrounds < 4)
    175  1.4  christos 		nrounds = 4;
    176  1.1    itojun 
    177  1.1    itojun 	for (i = 0; i < BCRYPT_MAXSALT; i++) {
    178  1.1    itojun 		if (i % 4 == 0)
    179  1.1    itojun 			seed = arc4random();
    180  1.1    itojun 		csalt[i] = seed & 0xff;
    181  1.1    itojun 		seed = seed >> 8;
    182  1.1    itojun 	}
    183  1.4  christos 	encode_salt(salt, csalt, BCRYPT_MAXSALT, nrounds);
    184  1.4  christos 	return 0;
    185  1.4  christos }
    186  1.1    itojun 
    187  1.4  christos /* Generates a salt for this version of crypt.
    188  1.4  christos    Since versions may change. Keeping this here
    189  1.4  christos    seems sensible.
    190  1.4  christos    XXX: compat.
    191  1.4  christos  */
    192  1.4  christos char *
    193  1.4  christos bcrypt_gensalt(u_int8_t log_rounds)
    194  1.4  christos {
    195  1.4  christos 	static char gsalt[BCRYPT_MAXSALTLEN];
    196  1.4  christos 	if (__gensalt_blowfish(gsalt, sizeof(gsalt), log_rounds) == -1)
    197  1.4  christos 		return NULL;
    198  1.1    itojun 	return gsalt;
    199  1.1    itojun }
    200  1.1    itojun 
    201  1.1    itojun /* We handle $Vers$log2(NumRounds)$salt+passwd$
    202  1.1    itojun    i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
    203  1.1    itojun 
    204  1.1    itojun char   *
    205  1.1    itojun __bcrypt(key, salt)
    206  1.1    itojun 	const char   *key;
    207  1.1    itojun 	const char   *salt;
    208  1.1    itojun {
    209  1.1    itojun 	blf_ctx state;
    210  1.1    itojun 	u_int32_t rounds, i, k;
    211  1.1    itojun 	u_int16_t j;
    212  1.1    itojun 	u_int8_t key_len, salt_len, logr, minor;
    213  1.1    itojun 	u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
    214  1.1    itojun 	u_int8_t csalt[BCRYPT_MAXSALT];
    215  1.1    itojun 	u_int32_t cdata[BCRYPT_BLOCKS];
    216  1.1    itojun 
    217  1.1    itojun 	/* Discard "$" identifier */
    218  1.1    itojun 	salt++;
    219  1.1    itojun 
    220  1.1    itojun 	if (*salt > BCRYPT_VERSION) {
    221  1.1    itojun 		/* How do I handle errors ? Return ':' */
    222  1.1    itojun 		return error;
    223  1.1    itojun 	}
    224  1.1    itojun 
    225  1.1    itojun 	/* Check for minor versions */
    226  1.1    itojun 	if (salt[1] != '$') {
    227  1.1    itojun 		 switch (salt[1]) {
    228  1.1    itojun 		 case 'a':
    229  1.1    itojun 			 /* 'ab' should not yield the same as 'abab' */
    230  1.1    itojun 			 minor = salt[1];
    231  1.1    itojun 			 salt++;
    232  1.1    itojun 			 break;
    233  1.1    itojun 		 default:
    234  1.1    itojun 			 return error;
    235  1.1    itojun 		 }
    236  1.1    itojun 	} else
    237  1.1    itojun 		 minor = 0;
    238  1.1    itojun 
    239  1.1    itojun 	/* Discard version + "$" identifier */
    240  1.1    itojun 	salt += 2;
    241  1.1    itojun 
    242  1.1    itojun 	if (salt[2] != '$')
    243  1.1    itojun 		/* Out of sync with passwd entry */
    244  1.1    itojun 		return error;
    245  1.1    itojun 
    246  1.1    itojun 	/* Computer power doesn't increase linear, 2^x should be fine */
    247  1.1    itojun 	if ((rounds = (u_int32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS)
    248  1.1    itojun 		return error;
    249  1.1    itojun 
    250  1.1    itojun 	/* Discard num rounds + "$" identifier */
    251  1.1    itojun 	salt += 3;
    252  1.1    itojun 
    253  1.1    itojun 	if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
    254  1.1    itojun 		return error;
    255  1.1    itojun 
    256  1.1    itojun 	/* We dont want the base64 salt but the raw data */
    257  1.1    itojun 	decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
    258  1.1    itojun 	salt_len = BCRYPT_MAXSALT;
    259  1.1    itojun 	key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
    260  1.1    itojun 
    261  1.1    itojun 	/* Setting up S-Boxes and Subkeys */
    262  1.1    itojun 	Blowfish_initstate(&state);
    263  1.1    itojun 	Blowfish_expandstate(&state, csalt, salt_len,
    264  1.1    itojun 	    (u_int8_t *) key, key_len);
    265  1.1    itojun 	for (k = 0; k < rounds; k++) {
    266  1.1    itojun 		Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
    267  1.1    itojun 		Blowfish_expand0state(&state, csalt, salt_len);
    268  1.1    itojun 	}
    269  1.1    itojun 
    270  1.1    itojun 	/* This can be precomputed later */
    271  1.1    itojun 	j = 0;
    272  1.1    itojun 	for (i = 0; i < BCRYPT_BLOCKS; i++)
    273  1.1    itojun 		cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
    274  1.1    itojun 
    275  1.1    itojun 	/* Now do the encryption */
    276  1.1    itojun 	for (k = 0; k < 64; k++)
    277  1.1    itojun 		blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
    278  1.1    itojun 
    279  1.1    itojun 	for (i = 0; i < BCRYPT_BLOCKS; i++) {
    280  1.1    itojun 		ciphertext[4 * i + 3] = cdata[i] & 0xff;
    281  1.1    itojun 		cdata[i] = cdata[i] >> 8;
    282  1.1    itojun 		ciphertext[4 * i + 2] = cdata[i] & 0xff;
    283  1.1    itojun 		cdata[i] = cdata[i] >> 8;
    284  1.1    itojun 		ciphertext[4 * i + 1] = cdata[i] & 0xff;
    285  1.1    itojun 		cdata[i] = cdata[i] >> 8;
    286  1.1    itojun 		ciphertext[4 * i + 0] = cdata[i] & 0xff;
    287  1.1    itojun 	}
    288  1.1    itojun 
    289  1.1    itojun 
    290  1.1    itojun 	i = 0;
    291  1.1    itojun 	encrypted[i++] = '$';
    292  1.1    itojun 	encrypted[i++] = BCRYPT_VERSION;
    293  1.1    itojun 	if (minor)
    294  1.1    itojun 		encrypted[i++] = minor;
    295  1.1    itojun 	encrypted[i++] = '$';
    296  1.1    itojun 
    297  1.1    itojun 	snprintf(encrypted + i, 4, "%2.2u$", logr);
    298  1.1    itojun 
    299  1.1    itojun 	encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
    300  1.1    itojun 	encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
    301  1.1    itojun 	    4 * BCRYPT_BLOCKS - 1);
    302  1.1    itojun 	return encrypted;
    303  1.1    itojun }
    304  1.1    itojun 
    305  1.1    itojun static void
    306  1.1    itojun encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
    307  1.1    itojun {
    308  1.1    itojun 	u_int8_t *bp = buffer;
    309  1.1    itojun 	u_int8_t *p = data;
    310  1.1    itojun 	u_int8_t c1, c2;
    311  1.1    itojun 	while (p < data + len) {
    312  1.1    itojun 		c1 = *p++;
    313  1.1    itojun 		*bp++ = Base64Code[(c1 >> 2)];
    314  1.1    itojun 		c1 = (c1 & 0x03) << 4;
    315  1.1    itojun 		if (p >= data + len) {
    316  1.1    itojun 			*bp++ = Base64Code[c1];
    317  1.1    itojun 			break;
    318  1.1    itojun 		}
    319  1.1    itojun 		c2 = *p++;
    320  1.1    itojun 		c1 |= (c2 >> 4) & 0x0f;
    321  1.1    itojun 		*bp++ = Base64Code[c1];
    322  1.1    itojun 		c1 = (c2 & 0x0f) << 2;
    323  1.1    itojun 		if (p >= data + len) {
    324  1.1    itojun 			*bp++ = Base64Code[c1];
    325  1.1    itojun 			break;
    326  1.1    itojun 		}
    327  1.1    itojun 		c2 = *p++;
    328  1.1    itojun 		c1 |= (c2 >> 6) & 0x03;
    329  1.1    itojun 		*bp++ = Base64Code[c1];
    330  1.1    itojun 		*bp++ = Base64Code[c2 & 0x3f];
    331  1.1    itojun 	}
    332  1.1    itojun 	*bp = '\0';
    333  1.1    itojun }
    334  1.1    itojun #if 0
    335  1.1    itojun void
    336  1.1    itojun main()
    337  1.1    itojun {
    338  1.1    itojun 	char    blubber[73];
    339  1.1    itojun 	char    salt[100];
    340  1.1    itojun 	char   *p;
    341  1.1    itojun 	salt[0] = '$';
    342  1.1    itojun 	salt[1] = BCRYPT_VERSION;
    343  1.1    itojun 	salt[2] = '$';
    344  1.1    itojun 
    345  1.1    itojun 	snprintf(salt + 3, 4, "%2.2u$", 5);
    346  1.1    itojun 
    347  1.1    itojun 	printf("24 bytes of salt: ");
    348  1.1    itojun 	fgets(salt + 6, 94, stdin);
    349  1.1    itojun 	salt[99] = 0;
    350  1.1    itojun 	printf("72 bytes of password: ");
    351  1.1    itojun 	fpurge(stdin);
    352  1.1    itojun 	fgets(blubber, 73, stdin);
    353  1.1    itojun 	blubber[72] = 0;
    354  1.1    itojun 
    355  1.1    itojun 	p = crypt(blubber, salt);
    356  1.1    itojun 	printf("Passwd entry: %s\n\n", p);
    357  1.1    itojun 
    358  1.1    itojun 	p = bcrypt_gensalt(5);
    359  1.1    itojun 	printf("Generated salt: %s\n", p);
    360  1.1    itojun 	p = crypt(blubber, p);
    361  1.1    itojun 	printf("Passwd entry: %s\n", p);
    362  1.1    itojun }
    363  1.1    itojun #endif
    364