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