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