1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* $OpenBSD: bcrypt.c,v 1.16 2002/02/19 19:39:36 millert Exp $ */ 23 24 /* 25 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> 26 * All rights reserved. 27 * 28 * Redistribution and use in source and binary forms, with or without 29 * modification, are permitted provided that the following conditions 30 * are met: 31 * 1. Redistributions of source code must retain the above copyright 32 * notice, this list of conditions and the following disclaimer. 33 * 2. Redistributions in binary form must reproduce the above copyright 34 * notice, this list of conditions and the following disclaimer in the 35 * documentation and/or other materials provided with the distribution. 36 * 3. All advertising materials mentioning features or use of this software 37 * must display the following acknowledgement: 38 * This product includes software developed by Niels Provos. 39 * 4. The name of the author may not be used to endorse or promote products 40 * derived from this software without specific prior written permission. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 52 */ 53 54 /* 55 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 56 * Use is subject to license terms. 57 */ 58 #pragma ident "%Z%%M% %I% %E% SMI" 59 60 /* This password hashing algorithm was designed by David Mazieres 61 * <dm@lcs.mit.edu> and works as follows: 62 * 63 * 1. state := InitState () 64 * 2. state := ExpandKey (state, salt, password) 3. 65 * REPEAT rounds: 66 * state := ExpandKey (state, 0, salt) 67 * state := ExpandKey(state, 0, password) 68 * 4. ctext := "OrpheanBeholderScryDoubt" 69 * 5. REPEAT 64: 70 * ctext := Encrypt_ECB (state, ctext); 71 * 6. RETURN Concatenate (salt, ctext); 72 * 73 */ 74 75 #if 0 76 #include <stdio.h> 77 #endif 78 79 #include <stdio.h> 80 #include <stdlib.h> 81 #include <sys/types.h> 82 #include <string.h> 83 #include <pwd.h> 84 #include <blf.h> 85 86 extern uint32_t arc4random(); 87 88 /* This implementation is adaptable to current computing power. 89 * You can have up to 2^31 rounds which should be enough for some 90 * time to come. 91 */ 92 93 #define BCRYPT_VERSION '2' 94 #define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */ 95 #define BCRYPT_BLOCKS 6 /* Ciphertext blocks */ 96 #define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */ 97 98 char *bcrypt_gensalt(uint8_t); 99 100 static void encode_salt(char *, uint8_t *, uint16_t, uint8_t); 101 static void encode_base64(uint8_t *, uint8_t *, uint16_t); 102 static void decode_base64(uint8_t *, uint16_t, uint8_t *); 103 104 static char encrypted[128]; /* _PASSWORD_LEN in <pwd.h> on OpenBSD */ 105 static char gsalt[BCRYPT_MAXSALT * 4 / 3 + 1]; 106 static char error[] = ":"; 107 108 static uint8_t Base64Code[] = 109 "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 110 111 static uint8_t index_64[128] = 112 { 113 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 114 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 115 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 116 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 117 255, 255, 255, 255, 255, 255, 0, 1, 54, 55, 118 56, 57, 58, 59, 60, 61, 62, 63, 255, 255, 119 255, 255, 255, 255, 255, 2, 3, 4, 5, 6, 120 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 121 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 122 255, 255, 255, 255, 255, 255, 28, 29, 30, 123 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 124 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 125 51, 52, 53, 255, 255, 255, 255, 255 126 }; 127 #define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)]) 128 129 static void 130 decode_base64(uint8_t *buffer, uint16_t len, uint8_t *data) 131 { 132 uint8_t *bp = buffer; 133 uint8_t *p = data; 134 uint8_t c1, c2, c3, c4; 135 while (bp < buffer + len) { 136 c1 = CHAR64(*p); 137 c2 = CHAR64(*(p + 1)); 138 139 /* Invalid data */ 140 if (c1 == 255 || c2 == 255) 141 break; 142 143 *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4); 144 if (bp >= buffer + len) 145 break; 146 147 c3 = CHAR64(*(p + 2)); 148 if (c3 == 255) 149 break; 150 151 *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); 152 if (bp >= buffer + len) 153 break; 154 155 c4 = CHAR64(*(p + 3)); 156 if (c4 == 255) 157 break; 158 *bp++ = ((c3 & 0x03) << 6) | c4; 159 160 p += 4; 161 } 162 } 163 164 static void 165 encode_salt(char *salt, uint8_t *csalt, uint16_t clen, uint8_t logr) 166 { 167 salt[0] = '$'; 168 salt[1] = BCRYPT_VERSION; 169 salt[2] = 'a'; 170 salt[3] = '$'; 171 172 (void) snprintf(salt + 4, 4, "%2.2u$", logr); 173 174 encode_base64((uint8_t *) salt + 7, csalt, clen); 175 } 176 /* Generates a salt for this version of crypt. 177 Since versions may change. Keeping this here 178 seems sensible. 179 */ 180 181 char * 182 bcrypt_gensalt(uint8_t log_rounds) 183 { 184 uint8_t csalt[BCRYPT_MAXSALT]; 185 uint16_t i; 186 uint32_t seed = 0; 187 188 for (i = 0; i < BCRYPT_MAXSALT; i++) { 189 if (i % 4 == 0) 190 seed = arc4random(); 191 csalt[i] = seed & 0xff; 192 seed = seed >> 8; 193 } 194 195 if (log_rounds < 4) 196 log_rounds = 4; 197 198 encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds); 199 return gsalt; 200 } 201 /* We handle $Vers$log2(NumRounds)$salt+passwd$ 202 i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */ 203 204 char * 205 bcrypt(key, salt) 206 const char *key; 207 const char *salt; 208 { 209 blf_ctx state; 210 uint32_t rounds, i, k; 211 uint16_t j; 212 uint8_t key_len, salt_len, logr, minor; 213 uint8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt"; 214 uint8_t csalt[BCRYPT_MAXSALT]; 215 uint32_t cdata[BCRYPT_BLOCKS]; 216 217 /* Discard "$" identifier */ 218 salt++; 219 220 if (*salt > BCRYPT_VERSION) { 221 /* How do I handle errors ? Return ':' */ 222 return error; 223 } 224 225 /* Check for minor versions */ 226 if (salt[1] != '$') { 227 switch (salt[1]) { 228 case 'a': 229 /* 'ab' should not yield the same as 'abab' */ 230 minor = salt[1]; 231 salt++; 232 break; 233 default: 234 return error; 235 } 236 } else 237 minor = 0; 238 239 /* Discard version + "$" identifier */ 240 salt += 2; 241 242 if (salt[2] != '$') 243 /* Out of sync with passwd entry */ 244 return error; 245 246 /* Computer power doesn't increase linear, 2^x should be fine */ 247 if ((rounds = (uint32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS) 248 return error; 249 250 /* Discard num rounds + "$" identifier */ 251 salt += 3; 252 253 if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT) 254 return error; 255 256 /* We dont want the base64 salt but the raw data */ 257 decode_base64(csalt, BCRYPT_MAXSALT, (uint8_t *) salt); 258 salt_len = BCRYPT_MAXSALT; 259 key_len = strlen(key) + (minor >= 'a' ? 1 : 0); 260 261 /* Setting up S-Boxes and Subkeys */ 262 Blowfish_initstate(&state); 263 Blowfish_expandstate(&state, csalt, salt_len, 264 (uint8_t *) key, key_len); 265 for (k = 0; k < rounds; k++) { 266 Blowfish_expand0state(&state, (uint8_t *) key, key_len); 267 Blowfish_expand0state(&state, csalt, salt_len); 268 } 269 270 /* This can be precomputed later */ 271 j = 0; 272 for (i = 0; i < BCRYPT_BLOCKS; i++) 273 cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j); 274 275 /* Now do the encryption */ 276 for (k = 0; k < 64; k++) 277 blf_enc(&state, cdata, BCRYPT_BLOCKS / 2); 278 279 for (i = 0; i < BCRYPT_BLOCKS; i++) { 280 ciphertext[4 * i + 3] = cdata[i] & 0xff; 281 cdata[i] = cdata[i] >> 8; 282 ciphertext[4 * i + 2] = cdata[i] & 0xff; 283 cdata[i] = cdata[i] >> 8; 284 ciphertext[4 * i + 1] = cdata[i] & 0xff; 285 cdata[i] = cdata[i] >> 8; 286 ciphertext[4 * i + 0] = cdata[i] & 0xff; 287 } 288 289 290 i = 0; 291 encrypted[i++] = '$'; 292 encrypted[i++] = BCRYPT_VERSION; 293 if (minor) 294 encrypted[i++] = minor; 295 encrypted[i++] = '$'; 296 297 (void) snprintf(encrypted + i, 4, "%2.2u$", logr); 298 299 encode_base64((uint8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT); 300 encode_base64((uint8_t *) encrypted + strlen(encrypted), ciphertext, 301 4 * BCRYPT_BLOCKS - 1); 302 return encrypted; 303 } 304 305 static void 306 encode_base64(uint8_t *buffer, uint8_t *data, uint16_t len) 307 { 308 uint8_t *bp = buffer; 309 uint8_t *p = data; 310 uint8_t c1, c2; 311 while (p < data + len) { 312 c1 = *p++; 313 *bp++ = Base64Code[(c1 >> 2)]; 314 c1 = (c1 & 0x03) << 4; 315 if (p >= data + len) { 316 *bp++ = Base64Code[c1]; 317 break; 318 } 319 c2 = *p++; 320 c1 |= (c2 >> 4) & 0x0f; 321 *bp++ = Base64Code[c1]; 322 c1 = (c2 & 0x0f) << 2; 323 if (p >= data + len) { 324 *bp++ = Base64Code[c1]; 325 break; 326 } 327 c2 = *p++; 328 c1 |= (c2 >> 6) & 0x03; 329 *bp++ = Base64Code[c1]; 330 *bp++ = Base64Code[c2 & 0x3f]; 331 } 332 *bp = '\0'; 333 } 334 #if 0 335 void 336 main() 337 { 338 char blubber[73]; 339 char salt[100]; 340 char *p; 341 salt[0] = '$'; 342 salt[1] = BCRYPT_VERSION; 343 salt[2] = '$'; 344 345 snprintf(salt + 3, 4, "%2.2u$", 5); 346 347 printf("24 bytes of salt: "); 348 fgets(salt + 6, 94, stdin); 349 salt[99] = 0; 350 printf("72 bytes of password: "); 351 fpurge(stdin); 352 fgets(blubber, 73, stdin); 353 blubber[72] = 0; 354 355 p = crypt(blubber, salt); 356 printf("Passwd entry: %s\n\n", p); 357 358 p = bcrypt_gensalt(5); 359 printf("Generated salt: %s\n", p); 360 p = crypt(blubber, p); 361 printf("Passwd entry: %s\n", p); 362 } 363 #endif 364