Home | History | Annotate | Line # | Download | only in libcrypt
bcrypt.c revision 1.4
      1  1.4  christos /*	$NetBSD: bcrypt.c,v 1.4 2005/01/11 22:39:21 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.4  christos __RCSID("$NetBSD: bcrypt.c,v 1.4 2005/01/11 22:39:21 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.1    itojun const static u_int8_t index_64[128] =
     90  1.1    itojun {
     91  1.1    itojun 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     92  1.1    itojun 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     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, 0, 1, 54, 55,
     96  1.1    itojun 	56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
     97  1.1    itojun 	255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
     98  1.1    itojun 	7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
     99  1.1    itojun 	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
    100  1.1    itojun 	255, 255, 255, 255, 255, 255, 28, 29, 30,
    101  1.1    itojun 	31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    102  1.1    itojun 	41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
    103  1.1    itojun 	51, 52, 53, 255, 255, 255, 255, 255
    104  1.1    itojun };
    105  1.1    itojun #define CHAR64(c)  ( (c) > 127 ? 255 : index_64[(c)])
    106  1.1    itojun 
    107  1.1    itojun static void
    108  1.1    itojun decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
    109  1.1    itojun {
    110  1.1    itojun 	u_int8_t *bp = buffer;
    111  1.1    itojun 	u_int8_t *p = data;
    112  1.1    itojun 	u_int8_t c1, c2, c3, c4;
    113  1.1    itojun 	while (bp < buffer + len) {
    114  1.1    itojun 		c1 = CHAR64(*p);
    115  1.1    itojun 		c2 = CHAR64(*(p + 1));
    116  1.1    itojun 
    117  1.1    itojun 		/* Invalid data */
    118  1.1    itojun 		if (c1 == 255 || c2 == 255)
    119  1.1    itojun 			break;
    120  1.1    itojun 
    121  1.1    itojun 		*bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
    122  1.1    itojun 		if (bp >= buffer + len)
    123  1.1    itojun 			break;
    124  1.1    itojun 
    125  1.1    itojun 		c3 = CHAR64(*(p + 2));
    126  1.1    itojun 		if (c3 == 255)
    127  1.1    itojun 			break;
    128  1.1    itojun 
    129  1.1    itojun 		*bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
    130  1.1    itojun 		if (bp >= buffer + len)
    131  1.1    itojun 			break;
    132  1.1    itojun 
    133  1.1    itojun 		c4 = CHAR64(*(p + 3));
    134  1.1    itojun 		if (c4 == 255)
    135  1.1    itojun 			break;
    136  1.1    itojun 		*bp++ = ((c3 & 0x03) << 6) | c4;
    137  1.1    itojun 
    138  1.1    itojun 		p += 4;
    139  1.1    itojun 	}
    140  1.1    itojun }
    141  1.1    itojun 
    142  1.1    itojun static void
    143  1.1    itojun encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
    144  1.1    itojun {
    145  1.1    itojun 	salt[0] = '$';
    146  1.1    itojun 	salt[1] = BCRYPT_VERSION;
    147  1.1    itojun 	salt[2] = 'a';
    148  1.1    itojun 	salt[3] = '$';
    149  1.1    itojun 
    150  1.1    itojun 	snprintf(salt + 4, 4, "%2.2u$", logr);
    151  1.1    itojun 
    152  1.1    itojun 	encode_base64((u_int8_t *) salt + 7, csalt, clen);
    153  1.1    itojun }
    154  1.1    itojun 
    155  1.4  christos int
    156  1.4  christos __gensalt_blowfish(char *salt, size_t saltlen, size_t nrounds)
    157  1.1    itojun {
    158  1.4  christos 	size_t i;
    159  1.4  christos 	u_int32_t seed = 0;
    160  1.1    itojun 	u_int8_t csalt[BCRYPT_MAXSALT];
    161  1.4  christos 
    162  1.4  christos 	if (saltlen < BCRYPT_MAXSALTLEN) {
    163  1.4  christos 		errno = ENOSPC;
    164  1.4  christos 		return -1;
    165  1.4  christos 	}
    166  1.4  christos 
    167  1.4  christos 	if (nrounds > 255) {
    168  1.4  christos 		errno = EINVAL;
    169  1.4  christos 		return -1;
    170  1.4  christos 	}
    171  1.4  christos 
    172  1.4  christos 	if (nrounds < 4)
    173  1.4  christos 		nrounds = 4;
    174  1.1    itojun 
    175  1.1    itojun 	for (i = 0; i < BCRYPT_MAXSALT; i++) {
    176  1.1    itojun 		if (i % 4 == 0)
    177  1.1    itojun 			seed = arc4random();
    178  1.1    itojun 		csalt[i] = seed & 0xff;
    179  1.1    itojun 		seed = seed >> 8;
    180  1.1    itojun 	}
    181  1.4  christos 	encode_salt(salt, csalt, BCRYPT_MAXSALT, nrounds);
    182  1.4  christos 	return 0;
    183  1.4  christos }
    184  1.1    itojun 
    185  1.4  christos /* Generates a salt for this version of crypt.
    186  1.4  christos    Since versions may change. Keeping this here
    187  1.4  christos    seems sensible.
    188  1.4  christos    XXX: compat.
    189  1.4  christos  */
    190  1.4  christos char *
    191  1.4  christos bcrypt_gensalt(u_int8_t log_rounds)
    192  1.4  christos {
    193  1.4  christos 	static char gsalt[BCRYPT_MAXSALTLEN];
    194  1.4  christos 	if (__gensalt_blowfish(gsalt, sizeof(gsalt), log_rounds) == -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