143e30386SXin LI /* $OpenBSD: bcrypt.c,v 1.29 2014/02/24 19:45:43 tedu Exp $ */ 243e30386SXin LI 35c129616SMark Murray /* 45c129616SMark Murray * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> 55c129616SMark Murray * All rights reserved. 65c129616SMark Murray * 75c129616SMark Murray * Redistribution and use in source and binary forms, with or without 85c129616SMark Murray * modification, are permitted provided that the following conditions 95c129616SMark Murray * are met: 105c129616SMark Murray * 1. Redistributions of source code must retain the above copyright 115c129616SMark Murray * notice, this list of conditions and the following disclaimer. 125c129616SMark Murray * 2. Redistributions in binary form must reproduce the above copyright 135c129616SMark Murray * notice, this list of conditions and the following disclaimer in the 145c129616SMark Murray * documentation and/or other materials provided with the distribution. 155c129616SMark Murray * 3. All advertising materials mentioning features or use of this software 165c129616SMark Murray * must display the following acknowledgement: 175c129616SMark Murray * This product includes software developed by Niels Provos. 185c129616SMark Murray * 4. The name of the author may not be used to endorse or promote products 195c129616SMark Murray * derived from this software without specific prior written permission. 205c129616SMark Murray * 215c129616SMark Murray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 225c129616SMark Murray * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 235c129616SMark Murray * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 245c129616SMark Murray * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 255c129616SMark Murray * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 265c129616SMark Murray * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 275c129616SMark Murray * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 285c129616SMark Murray * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 295c129616SMark Murray * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 305c129616SMark Murray * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 315c129616SMark Murray */ 325c129616SMark Murray 3368344a95SPeter Wemm #include <sys/cdefs.h> 3468344a95SPeter Wemm __FBSDID("$FreeBSD$"); 3568344a95SPeter Wemm 365c129616SMark Murray /* This password hashing algorithm was designed by David Mazieres 375c129616SMark Murray * <dm@lcs.mit.edu> and works as follows: 385c129616SMark Murray * 395c129616SMark Murray * 1. state := InitState () 4043e30386SXin LI * 2. state := ExpandKey (state, salt, password) 4143e30386SXin LI * 3. REPEAT rounds: 425c129616SMark Murray * state := ExpandKey (state, 0, password) 4343e30386SXin LI * state := ExpandKey (state, 0, salt) 445c129616SMark Murray * 4. ctext := "OrpheanBeholderScryDoubt" 455c129616SMark Murray * 5. REPEAT 64: 465c129616SMark Murray * ctext := Encrypt_ECB (state, ctext); 475c129616SMark Murray * 6. RETURN Concatenate (salt, ctext); 485c129616SMark Murray * 495c129616SMark Murray */ 505c129616SMark Murray 515c129616SMark Murray /* 525c129616SMark Murray * FreeBSD implementation by Paul Herman <pherman@frenchfries.net> 5343e30386SXin LI * and updated by Xin Li <delphij@FreeBSD.org> 545c129616SMark Murray */ 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" 62f2ac424aSMark Murray #include "crypt.h" 635c129616SMark Murray 645c129616SMark Murray /* This implementation is adaptable to current computing power. 655c129616SMark Murray * You can have up to 2^31 rounds which should be enough for some 665c129616SMark Murray * time to come. 675c129616SMark Murray */ 685c129616SMark Murray 695c129616SMark Murray #define BCRYPT_VERSION '2' 705c129616SMark Murray #define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */ 715c129616SMark Murray #define BCRYPT_BLOCKS 6 /* Ciphertext blocks */ 7243e30386SXin LI #define BCRYPT_MINLOGROUNDS 4 /* we have log2(rounds) in salt */ 7343e30386SXin LI 745c129616SMark Murray 75f2ac424aSMark Murray static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t); 76f2ac424aSMark Murray static void decode_base64(u_int8_t *, u_int16_t, const u_int8_t *); 775c129616SMark Murray 7843e30386SXin LI const static u_int8_t Base64Code[] = 795c129616SMark Murray "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 805c129616SMark Murray 8143e30386SXin LI const static u_int8_t index_64[128] = { 825c129616SMark Murray 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 835c129616SMark Murray 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 845c129616SMark Murray 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 855c129616SMark Murray 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 865c129616SMark Murray 255, 255, 255, 255, 255, 255, 0, 1, 54, 55, 875c129616SMark Murray 56, 57, 58, 59, 60, 61, 62, 63, 255, 255, 885c129616SMark Murray 255, 255, 255, 255, 255, 2, 3, 4, 5, 6, 895c129616SMark Murray 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 905c129616SMark Murray 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 915c129616SMark Murray 255, 255, 255, 255, 255, 255, 28, 29, 30, 925c129616SMark Murray 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 935c129616SMark Murray 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 945c129616SMark Murray 51, 52, 53, 255, 255, 255, 255, 255 955c129616SMark Murray }; 965c129616SMark Murray #define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)]) 975c129616SMark Murray 985c129616SMark Murray static void 99f2ac424aSMark Murray decode_base64(u_int8_t *buffer, u_int16_t len, const u_int8_t *data) 1005c129616SMark Murray { 1015c129616SMark Murray u_int8_t *bp = buffer; 102f2ac424aSMark Murray const u_int8_t *p = data; 1035c129616SMark Murray u_int8_t c1, c2, c3, c4; 1045c129616SMark Murray while (bp < buffer + len) { 1055c129616SMark Murray c1 = CHAR64(*p); 1065c129616SMark Murray c2 = CHAR64(*(p + 1)); 1075c129616SMark Murray 1085c129616SMark Murray /* Invalid data */ 1095c129616SMark Murray if (c1 == 255 || c2 == 255) 1105c129616SMark Murray break; 1115c129616SMark Murray 11243e30386SXin LI *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4); 1135c129616SMark Murray if (bp >= buffer + len) 1145c129616SMark Murray break; 1155c129616SMark Murray 1165c129616SMark Murray c3 = CHAR64(*(p + 2)); 1175c129616SMark Murray if (c3 == 255) 1185c129616SMark Murray break; 1195c129616SMark Murray 1205c129616SMark Murray *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); 1215c129616SMark Murray if (bp >= buffer + len) 1225c129616SMark Murray break; 1235c129616SMark Murray 1245c129616SMark Murray c4 = CHAR64(*(p + 3)); 1255c129616SMark Murray if (c4 == 255) 1265c129616SMark Murray break; 1275c129616SMark Murray *bp++ = ((c3 & 0x03) << 6) | c4; 1285c129616SMark Murray 1295c129616SMark Murray p += 4; 1305c129616SMark Murray } 1315c129616SMark Murray } 1325c129616SMark Murray 1335c129616SMark Murray /* We handle $Vers$log2(NumRounds)$salt+passwd$ 1345c129616SMark Murray i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */ 1355c129616SMark Murray 136*5f521d7bSEd Schouten int 137*5f521d7bSEd Schouten crypt_blowfish(const char *key, const char *salt, char *buffer) 1385c129616SMark Murray { 1395c129616SMark Murray blf_ctx state; 1405c129616SMark Murray u_int32_t rounds, i, k; 1415c129616SMark Murray u_int16_t j; 14243e30386SXin LI size_t key_len; 14343e30386SXin LI u_int8_t salt_len, logr, minr; 1445c129616SMark Murray u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt"; 1455c129616SMark Murray u_int8_t csalt[BCRYPT_MAXSALT]; 1465c129616SMark Murray u_int32_t cdata[BCRYPT_BLOCKS]; 14743e30386SXin LI char arounds[3]; 1485c129616SMark Murray 1495c129616SMark Murray /* Defaults */ 150185e05eeSXin LI minr = 'b'; 15143e30386SXin LI logr = BCRYPT_MINLOGROUNDS; 15243e30386SXin LI rounds = 1U << logr; 1535c129616SMark Murray 15443e30386SXin LI if (*salt == '$') { 1555c129616SMark Murray /* Discard "$" identifier */ 1565c129616SMark Murray salt++; 1575c129616SMark Murray 158*5f521d7bSEd Schouten if (*salt > BCRYPT_VERSION) 159*5f521d7bSEd Schouten return (-1); 1605c129616SMark Murray 1615c129616SMark Murray /* Check for minor versions */ 1625c129616SMark Murray if (salt[1] != '$') { 1635c129616SMark Murray switch (salt[1]) { 16443e30386SXin LI case 'a': /* 'ab' should not yield the same as 'abab' */ 16543e30386SXin LI case 'b': /* cap input length at 72 bytes */ 166a3b20e50SAllan Jude case 'y': /* same as 'b', for compatibility 167a3b20e50SAllan Jude * with openwall crypt_blowfish 168a3b20e50SAllan Jude */ 16943e30386SXin LI minr = salt[1]; 1705c129616SMark Murray salt++; 1715c129616SMark Murray break; 1725c129616SMark Murray default: 173*5f521d7bSEd Schouten return (-1); 1745c129616SMark Murray } 1755c129616SMark Murray } else 176f2ac424aSMark Murray minr = 0; 1775c129616SMark Murray 1785c129616SMark Murray /* Discard version + "$" identifier */ 1795c129616SMark Murray salt += 2; 1805c129616SMark Murray 1815c129616SMark Murray if (salt[2] != '$') 1825c129616SMark Murray /* Out of sync with passwd entry */ 183*5f521d7bSEd Schouten return (-1); 1845c129616SMark Murray 18543e30386SXin LI memcpy(arounds, salt, sizeof(arounds)); 18643e30386SXin LI if (arounds[sizeof(arounds) - 1] != '$') 187*5f521d7bSEd Schouten return (-1); 18843e30386SXin LI arounds[sizeof(arounds) - 1] = 0; 18943e30386SXin LI logr = strtonum(arounds, BCRYPT_MINLOGROUNDS, 31, NULL); 19043e30386SXin LI if (logr == 0) 191*5f521d7bSEd Schouten return (-1); 19243e30386SXin LI /* Computer power doesn't increase linearly, 2^x should be fine */ 19343e30386SXin LI rounds = 1U << logr; 1945c129616SMark Murray 1955c129616SMark Murray /* Discard num rounds + "$" identifier */ 1965c129616SMark Murray salt += 3; 1975c129616SMark Murray } 1985c129616SMark Murray 19943e30386SXin LI if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT) 200*5f521d7bSEd Schouten return (-1); 2015c129616SMark Murray 2025c129616SMark Murray /* We dont want the base64 salt but the raw data */ 203c8fa8e25SMark Murray decode_base64(csalt, BCRYPT_MAXSALT, (const u_int8_t *) salt); 2045c129616SMark Murray salt_len = BCRYPT_MAXSALT; 20543e30386SXin LI if (minr <= 'a') 206f2ac424aSMark Murray key_len = (u_int8_t)(strlen(key) + (minr >= 'a' ? 1 : 0)); 20743e30386SXin LI else { 20843e30386SXin LI /* strlen() returns a size_t, but the function calls 20943e30386SXin LI * below result in implicit casts to a narrower integer 21043e30386SXin LI * type, so cap key_len at the actual maximum supported 21143e30386SXin LI * length here to avoid integer wraparound */ 21243e30386SXin LI key_len = strlen(key); 21343e30386SXin LI if (key_len > 72) 21443e30386SXin LI key_len = 72; 21543e30386SXin LI key_len++; /* include the NUL */ 21643e30386SXin LI } 2175c129616SMark Murray 2185c129616SMark Murray /* Setting up S-Boxes and Subkeys */ 2195c129616SMark Murray Blowfish_initstate(&state); 2205c129616SMark Murray Blowfish_expandstate(&state, csalt, salt_len, 221f2ac424aSMark Murray (const u_int8_t *) key, key_len); 2225c129616SMark Murray for (k = 0; k < rounds; k++) { 223f2ac424aSMark Murray Blowfish_expand0state(&state, (const u_int8_t *) key, key_len); 2245c129616SMark Murray Blowfish_expand0state(&state, csalt, salt_len); 2255c129616SMark Murray } 2265c129616SMark Murray 2275c129616SMark Murray /* This can be precomputed later */ 2285c129616SMark Murray j = 0; 2295c129616SMark Murray for (i = 0; i < BCRYPT_BLOCKS; i++) 2305c129616SMark Murray cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j); 2315c129616SMark Murray 2325c129616SMark Murray /* Now do the encryption */ 2335c129616SMark Murray for (k = 0; k < 64; k++) 2345c129616SMark Murray blf_enc(&state, cdata, BCRYPT_BLOCKS / 2); 2355c129616SMark Murray 2365c129616SMark Murray for (i = 0; i < BCRYPT_BLOCKS; i++) { 2375c129616SMark Murray ciphertext[4 * i + 3] = cdata[i] & 0xff; 2385c129616SMark Murray cdata[i] = cdata[i] >> 8; 2395c129616SMark Murray ciphertext[4 * i + 2] = cdata[i] & 0xff; 2405c129616SMark Murray cdata[i] = cdata[i] >> 8; 2415c129616SMark Murray ciphertext[4 * i + 1] = cdata[i] & 0xff; 2425c129616SMark Murray cdata[i] = cdata[i] >> 8; 2435c129616SMark Murray ciphertext[4 * i + 0] = cdata[i] & 0xff; 2445c129616SMark Murray } 2455c129616SMark Murray 2465c129616SMark Murray 247*5f521d7bSEd Schouten *buffer++ = '$'; 248*5f521d7bSEd Schouten *buffer++ = BCRYPT_VERSION; 249f2ac424aSMark Murray if (minr) 250*5f521d7bSEd Schouten *buffer++ = minr; 251*5f521d7bSEd Schouten *buffer++ = '$'; 2525c129616SMark Murray 253*5f521d7bSEd Schouten snprintf(buffer, 4, "%2.2u$", logr); 254*5f521d7bSEd Schouten buffer += 3; 2555c129616SMark Murray 256*5f521d7bSEd Schouten encode_base64((u_int8_t *)buffer, csalt, BCRYPT_MAXSALT); 257*5f521d7bSEd Schouten buffer += strlen(buffer); 258*5f521d7bSEd Schouten encode_base64((u_int8_t *)buffer, ciphertext, 4 * BCRYPT_BLOCKS - 1); 25943e30386SXin LI memset(&state, 0, sizeof(state)); 26043e30386SXin LI memset(ciphertext, 0, sizeof(ciphertext)); 26143e30386SXin LI memset(csalt, 0, sizeof(csalt)); 26243e30386SXin LI memset(cdata, 0, sizeof(cdata)); 263*5f521d7bSEd Schouten return (0); 2645c129616SMark Murray } 2655c129616SMark Murray 2665c129616SMark Murray static void 2675c129616SMark Murray encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len) 2685c129616SMark Murray { 2695c129616SMark Murray u_int8_t *bp = buffer; 2705c129616SMark Murray u_int8_t *p = data; 2715c129616SMark Murray u_int8_t c1, c2; 2725c129616SMark Murray while (p < data + len) { 2735c129616SMark Murray c1 = *p++; 2745c129616SMark Murray *bp++ = Base64Code[(c1 >> 2)]; 2755c129616SMark Murray c1 = (c1 & 0x03) << 4; 2765c129616SMark Murray if (p >= data + len) { 2775c129616SMark Murray *bp++ = Base64Code[c1]; 2785c129616SMark Murray break; 2795c129616SMark Murray } 2805c129616SMark Murray c2 = *p++; 2815c129616SMark Murray c1 |= (c2 >> 4) & 0x0f; 2825c129616SMark Murray *bp++ = Base64Code[c1]; 2835c129616SMark Murray c1 = (c2 & 0x0f) << 2; 2845c129616SMark Murray if (p >= data + len) { 2855c129616SMark Murray *bp++ = Base64Code[c1]; 2865c129616SMark Murray break; 2875c129616SMark Murray } 2885c129616SMark Murray c2 = *p++; 2895c129616SMark Murray c1 |= (c2 >> 6) & 0x03; 2905c129616SMark Murray *bp++ = Base64Code[c1]; 2915c129616SMark Murray *bp++ = Base64Code[c2 & 0x3f]; 2925c129616SMark Murray } 2935c129616SMark Murray *bp = '\0'; 2945c129616SMark Murray } 2955c129616SMark Murray #if 0 2965c129616SMark Murray void 2975c129616SMark Murray main() 2985c129616SMark Murray { 2995c129616SMark Murray char blubber[73]; 3005c129616SMark Murray char salt[100]; 3015c129616SMark Murray char *p; 3025c129616SMark Murray salt[0] = '$'; 3035c129616SMark Murray salt[1] = BCRYPT_VERSION; 3045c129616SMark Murray salt[2] = '$'; 3055c129616SMark Murray 3065c129616SMark Murray snprintf(salt + 3, 4, "%2.2u$", 5); 3075c129616SMark Murray 3085c129616SMark Murray printf("24 bytes of salt: "); 30943e30386SXin LI fgets(salt + 6, sizeof(salt) - 6, stdin); 3105c129616SMark Murray salt[99] = 0; 3115c129616SMark Murray printf("72 bytes of password: "); 3125c129616SMark Murray fpurge(stdin); 31343e30386SXin LI fgets(blubber, sizeof(blubber), stdin); 3145c129616SMark Murray blubber[72] = 0; 3155c129616SMark Murray 3165c129616SMark Murray p = crypt(blubber, salt); 3175c129616SMark Murray printf("Passwd entry: %s\n\n", p); 3185c129616SMark Murray 3195c129616SMark Murray p = bcrypt_gensalt(5); 3205c129616SMark Murray printf("Generated salt: %s\n", p); 3215c129616SMark Murray p = crypt(blubber, p); 3225c129616SMark Murray printf("Passwd entry: %s\n", p); 3235c129616SMark Murray } 3245c129616SMark Murray #endif 325