--- blowfish.c | 515 ++++++++++++++++++++++++++++++++++++++++++++++++++++- blowfish.h | 5 + 2 files changed, 518 insertions(+), 2 deletions(-)
diff --git a/blowfish.c b/blowfish.c index 52040f13..d0b45117 100644 --- a/blowfish.c +++ b/blowfish.c @@ -45,7 +45,12 @@ (from Nettle's blowfish.h), dropping the libgcrypt wrapper functions, fixing #include's, remove support for non-16 rounds (there are no test vectors), adding FOR_BLOCK iterations, and - running indent on the code. */ + running indent on the code. + + The lower half of this file includes code for the computation + of bcrypt hashes, which was added at a later date. + + */
#if HAVE_CONFIG_H #include "config.h" @@ -397,7 +402,7 @@ blowfish_set_key (struct blowfish_ctx *ctx, ctx->p[i] = datal; ctx->p[i + 1] = datar; } - + for (j = 0; j < 4; j++) for (i = 0; i < 256; i += 2) { @@ -428,3 +433,509 @@ blowfish128_set_key(struct blowfish_ctx *ctx, const uint8_t *key) { return blowfish_set_key (ctx, BLOWFISH128_KEY_SIZE, key); } + +/* + * The crypt_blowfish homepage is: + * + * http://www.openwall.com/crypt/ + * + * This code comes from John the Ripper password cracker, with reentrant + * and crypt(3) interfaces added, but optimizations specific to password + * cracking removed. + * + * Written by Solar Designer <solar at openwall.com> in 1998-2015. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 1998-2015 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * It is my intent that you should be able to use this on your system, + * as part of a software package, or anywhere else to improve security, + * ensure compatibility, or for any other purpose. I would appreciate + * it if you give credit where it is due and keep your modifications in + * the public domain as well, but I don't require that in order to let + * you place this code and any modifications you make under a license + * of your choice. + * + * This implementation is fully compatible with OpenBSD's bcrypt.c for prefix + * "$2b$", originally by Niels Provos <provos at citi.umich.edu>, and it uses + * some of his ideas. The password hashing algorithm was designed by David + * Mazieres <dm at lcs.mit.edu>. For information on the level of + * compatibility for bcrypt hash prefixes other than "$2b$", please refer to + * the comments in BF_set_key() below and to the included crypt(3) man page. + * + * There's a paper on the algorithm that explains its design decisions: + * + * http://www.usenix.org/events/usenix99/provos.html + */ + +#include <string.h> + +#include <errno.h> +#ifndef __set_errno +#define __set_errno(val) errno = (val) +#endif + +typedef uint32_t BF_key[_BLOWFISH_ROUNDS + 2]; + +/* + * Magic IV for 64 Blowfish encryptions that we do at the end. + * The string is "OrpheanBeholderScryDoubt" on big-endian. + */ +static uint32_t BF_magic_w[6] = { + 0x4F727068, 0x65616E42, 0x65686F6C, + 0x64657253, 0x63727944, 0x6F756274 +}; + +static unsigned char BF_itoa64[64 + 1] = + "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +static unsigned char BF_atoi64[0x60] = { + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, + 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, + 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 +}; + +#define BF_safe_atoi64(dst, src) \ +{ \ + tmp = (unsigned char)(src); \ + if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ + tmp = BF_atoi64[tmp]; \ + if (tmp > 63) return -1; \ + (dst) = tmp; \ +} + +static int BF_decode(uint32_t *dst, const char *src, int size) +{ + unsigned char *dptr = (unsigned char *)dst; + unsigned char *end = dptr + size; + const unsigned char *sptr = (const unsigned char *)src; + unsigned int tmp, c1, c2, c3, c4; + + do { + BF_safe_atoi64(c1, *sptr++); + BF_safe_atoi64(c2, *sptr++); + *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); + if (dptr >= end) break; + + BF_safe_atoi64(c3, *sptr++); + *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); + if (dptr >= end) break; + + BF_safe_atoi64(c4, *sptr++); + *dptr++ = ((c3 & 0x03) << 6) | c4; + } while (dptr < end); + + if (end - dptr == size) + return -1; + + *dptr = 0; + + return 0; +} + +static void BF_encode(char *dst, const uint32_t *src, int size) +{ + const unsigned char *sptr = (const unsigned char *)src; + const unsigned char *end = sptr + size; + unsigned char *dptr = (unsigned char *)dst; + unsigned int c1, c2; + + do { + c1 = *sptr++; + *dptr++ = BF_itoa64[c1 >> 2]; + c1 = (c1 & 0x03) << 4; + if (sptr >= end) { + *dptr++ = BF_itoa64[c1]; + break; + } + + c2 = *sptr++; + c1 |= c2 >> 4; + *dptr++ = BF_itoa64[c1]; + c1 = (c2 & 0x0f) << 2; + if (sptr >= end) { + *dptr++ = BF_itoa64[c1]; + break; + } + + c2 = *sptr++; + c1 |= c2 >> 6; + *dptr++ = BF_itoa64[c1]; + *dptr++ = BF_itoa64[c2 & 0x3f]; + } while (sptr < end); +} + +static void BF_swap(uint32_t *x, int count) +{ + static int endianness_check = 1; + char *is_little_endian = (char *)&endianness_check; + uint32_t tmp; + + if (*is_little_endian) + do { + tmp = *x; + tmp = (tmp << 16) | (tmp >> 16); + *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); + } while (--count); +} + +static void BF_set_key(const char *key, BF_key expanded, BF_key initial, + unsigned char flags) +{ + const char *ptr = key; + unsigned int bug, i, j; + uint32_t safety, sign, diff, tmp[2]; + +/* + * There was a sign extension bug in older revisions of this function. While + * we would have liked to simply fix the bug and move on, we have to provide + * a backwards compatibility feature (essentially the bug) for some systems and + * a safety measure for some others. The latter is needed because for certain + * multiple inputs to the buggy algorithm there exist easily found inputs to + * the correct algorithm that produce the same hash. Thus, we optionally + * deviate from the correct algorithm just enough to avoid such collisions. + * While the bug itself affected the majority of passwords containing + * characters with the 8th bit set (although only a percentage of those in a + * collision-producing way), the anti-collision safety measure affects + * only a subset of passwords containing the '\xff' character (not even all of + * those passwords, just some of them). This character is not found in valid + * UTF-8 sequences and is rarely used in popular 8-bit character encodings. + * Thus, the safety measure is unlikely to cause much annoyance, and is a + * reasonable tradeoff to use when authenticating against existing hashes that + * are not reliably known to have been computed with the correct algorithm. + * + * We use an approach that tries to minimize side-channel leaks of password + * information - that is, we mostly use fixed-cost bitwise operations instead + * of branches or table lookups. (One conditional branch based on password + * length remains. It is not part of the bug aftermath, though, and is + * difficult and possibly unreasonable to avoid given the use of C strings by + * the caller, which results in similar timing leaks anyway.) + * + * For actual implementation, we set an array index in the variable "bug" + * (0 means no bug, 1 means sign extension bug emulation) and a flag in the + * variable "safety" (bit 16 is set when the safety measure is requested). + * Valid combinations of settings are: + * + * Prefix "$2a$": bug = 0, safety = 0x10000 + * Prefix "$2b$": bug = 0, safety = 0 + * Prefix "$2x$": bug = 1, safety = 0 + * Prefix "$2y$": bug = 0, safety = 0 + */ + bug = (unsigned int)flags & 1; + safety = ((uint32_t)flags & 2) << 15; + + sign = diff = 0; + + for (i = 0; i < _BLOWFISH_ROUNDS + 2; i++) { + tmp[0] = tmp[1] = 0; + for (j = 0; j < 4; j++) { + tmp[0] <<= 8; + tmp[0] |= (unsigned char)*ptr; /* correct */ + tmp[1] <<= 8; + tmp[1] |= (signed char)*ptr; /* bug */ +/* + * Sign extension in the first char has no effect - nothing to overwrite yet, + * and those extra 24 bits will be fully shifted out of the 32-bit word. For + * chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign + * extension in tmp[1] occurs. Once this flag is set, it remains set. + */ + if (j) + sign |= tmp[1] & 0x80; + if (!*ptr) + ptr = key; + else + ptr++; + } + diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */ + + expanded[i] = tmp[bug]; + initial[i] = initial_ctx.p[i] ^ tmp[bug]; + } + +/* + * At this point, "diff" is zero iff the correct and buggy algorithms produced + * exactly the same result. If so and if "sign" is non-zero, which indicates + * that there was a non-benign sign extension, this means that we have a + * collision between the correctly computed hash for this password and a set of + * passwords that could be supplied to the buggy algorithm. Our safety measure + * is meant to protect from such many-buggy to one-correct collisions, by + * deviating from the correct algorithm in such cases. Let's check for this. + */ + diff |= diff >> 16; /* still zero iff exact match */ + diff &= 0xffff; /* ditto */ + diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */ + sign <<= 9; /* move the non-benign sign extension flag to bit 16 */ + sign &= ~diff & safety; /* action needed? */ + +/* + * If we have determined that we need to deviate from the correct algorithm, + * flip bit 16 in initial expanded key. (The choice of 16 is arbitrary, but + * let's stick to it now. It came out of the approach we used above, and it's + * not any worse than any other choice we could make.) + * + * It is crucial that we don't do the same to the expanded key used in the main + * Eksblowfish loop. By doing it to only one of these two, we deviate from a + * state that could be directly specified by a password to the buggy algorithm + * (and to the fully correct one as well, but that's a side-effect). + */ + initial[0] ^= sign; +} + +static const unsigned char flags_by_subtype[26] = + {2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0}; + +static char *BF_crypt(const char *key, const char *settings, + char *output, int size, + uint32_t min) +{ + struct { + struct blowfish_ctx ctx; + BF_key expanded_key; + union { + uint32_t salt[4]; + uint32_t output[6]; + } binary; + } data; + uint32_t L, R; + uint32_t tmp1, tmp2, tmp3, tmp4; + uint32_t *ptr; + uint32_t count; + int i; + + if (size < 7 + 22 + 31 + 1) { + __set_errno(ERANGE); + return NULL; + } + + if (settings[0] != '$' || + settings[1] != '2' || + settings[2] < 'a' || settings[2] > 'z' || + !flags_by_subtype[(unsigned int)(unsigned char)settings[2] - 'a'] || + settings[3] != '$' || + settings[4] < '0' || settings[4] > '3' || + settings[5] < '0' || settings[5] > '9' || + (settings[4] == '3' && settings[5] > '1') || + settings[6] != '$') { + __set_errno(EINVAL); + return NULL; + } + + count = (uint32_t)1 << ((settings[4] - '0') * 10 + (settings[5] - '0')); + if (count < min || BF_decode(data.binary.salt, &settings[7], 16)) { + __set_errno(EINVAL); + return NULL; + } + BF_swap(data.binary.salt, 4); + + BF_set_key(key, data.expanded_key, data.ctx.p, + flags_by_subtype[(unsigned int)(unsigned char)settings[2] - 'a']); + + memcpy(data.ctx.s, initial_ctx.s, sizeof(data.ctx.s)); + + L = R = 0; + for (i = 0; i < _BLOWFISH_ROUNDS + 2; i += 2) { + L ^= data.binary.salt[i & 2]; + R ^= data.binary.salt[(i & 2) + 1]; + encrypt(&data.ctx, &L, &R); + data.ctx.p[i] = L; + data.ctx.p[i + 1] = R; + } + + ptr = data.ctx.s[0]; + do { + ptr += 4; + L ^= data.binary.salt[(_BLOWFISH_ROUNDS + 2) & 3]; + R ^= data.binary.salt[(_BLOWFISH_ROUNDS + 3) & 3]; + encrypt(&data.ctx, &L, &R); + *(ptr - 4) = L; + *(ptr - 3) = R; + + L ^= data.binary.salt[(_BLOWFISH_ROUNDS + 4) & 3]; + R ^= data.binary.salt[(_BLOWFISH_ROUNDS + 5) & 3]; + encrypt(&data.ctx, &L, &R); + *(ptr - 2) = L; + *(ptr - 1) = R; + } while (ptr < &data.ctx.s[3][0xFF]); + + do { + int done; + + for (i = 0; i < _BLOWFISH_ROUNDS + 2; i += 2) { + data.ctx.p[i] ^= data.expanded_key[i]; + data.ctx.p[i + 1] ^= data.expanded_key[i + 1]; + } + + done = 0; + do { + L = R = 0; + ptr = data.ctx.p; + do { + ptr += 2; + encrypt(&data.ctx, &L, &R); + *(ptr - 2) = L; + *(ptr - 1) = R; + } while (ptr < &data.ctx.p[_BLOWFISH_ROUNDS + 2]); + + ptr = data.ctx.s[0]; + do { + ptr += 2; + encrypt(&data.ctx, &L, &R); + *(ptr - 2) = L; + *(ptr - 1) = R; + } while (ptr < &data.ctx.s[3][0xFF]); + + if (done) + break; + done = 1; + + tmp1 = data.binary.salt[0]; + tmp2 = data.binary.salt[1]; + tmp3 = data.binary.salt[2]; + tmp4 = data.binary.salt[3]; + for (i = 0; i < _BLOWFISH_ROUNDS; i += 4) { + data.ctx.p[i] ^= tmp1; + data.ctx.p[i + 1] ^= tmp2; + data.ctx.p[i + 2] ^= tmp3; + data.ctx.p[i + 3] ^= tmp4; + } + data.ctx.p[16] ^= tmp1; + data.ctx.p[17] ^= tmp2; + } while (1); + } while (--count); + + for (i = 0; i < 6; i += 2) { + L = BF_magic_w[i]; + R = BF_magic_w[i + 1]; + + count = 64; + do { + encrypt(&data.ctx, &L, &R); + } while (--count); + + data.binary.output[i] = L; + data.binary.output[i + 1] = R; + } + + memcpy(output, settings, 7 + 22 - 1); + output[7 + 22 - 1] = BF_itoa64[(int) + BF_atoi64[(int)settings[7 + 22 - 1] - 0x20] & 0x30]; + +/* This has to be bug-compatible with the original implementation, so + * only encode 23 of the 24 bytes. :-) */ + BF_swap(data.binary.output, 6); + BF_encode(&output[7 + 22], data.binary.output, 23); + output[7 + 22 + 31] = '\0'; + + return output; +} + +static int bcrypt_output_magic(const char *settings, char *output, int size) +{ + if (size < 3) + return -1; + + output[0] = '*'; + output[1] = '0'; + output[2] = '\0'; + + if (settings[0] == '*' && settings[1] == '0') + output[1] = '1'; + + return 0; +} + +/* + * Please preserve the runtime self-test. It serves two purposes at once: + * + * 1. We really can't afford the risk of producing incompatible hashes e.g. + * when there's something like gcc bug 26587 again, whereas an application or + * library integrating this code might not also integrate our external tests or + * it might not run them after every build. Even if it does, the miscompile + * might only occur on the production build, but not on a testing build (such + * as because of different optimization settings). It is painful to recover + * from incorrectly-computed hashes - merely fixing whatever broke is not + * enough. Thus, a proactive measure like this self-test is needed. + * + * 2. We don't want to leave sensitive data from our actual password hash + * computation on the stack or in registers. Previous revisions of the code + * would do explicit cleanups, but simply running the self-test after hash + * computation is more reliable. + * + * The performance cost of this quick self-test is around 0.6% at the "$2a$08" + * setting. + */ +uint8_t *blowfish_bcrypt(const uint8_t *key, const uint8_t *settings, + uint8_t *dst, size_t length) +{ + const char *test_pw = "8b \xd0\xc1\xd2\xcf\xcc\xd8"; + const char *test_settings = "$2a$00$abcdefghijklmnopqrstuu"; + static const char * const test_hashes[2] = + {"i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55", /* 'a', 'b', 'y' */ + "VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55"}; /* 'x' */ + const char *test_hash = test_hashes[0]; + uint8_t *retval; + const char *p; + int save_errno, ok; + struct { + char s[7 + 22 + 1]; + char o[7 + 22 + 31 + 1 + 1 + 1]; + } buf; + +/* Hash the supplied password */ + bcrypt_output_magic(settings, dst, length); + retval = BF_crypt(key, settings, dst, length, 16); + save_errno = errno; + +/* + * Do a quick self-test. It is important that we make both calls to BF_crypt() + * from the same scope such that they likely use the same stack locations, + * which makes the second call overwrite the first call's sensitive data on the + * stack and makes it more likely that any alignment related issues would be + * detected by the self-test. + */ + memcpy(buf.s, test_settings, sizeof(buf.s)); + if (retval) { + unsigned int flags = flags_by_subtype[ + (unsigned int)(unsigned char)settings[2] - 'a']; + test_hash = test_hashes[flags & 1]; + buf.s[2] = settings[2]; + } + memset(buf.o, 0x55, sizeof(buf.o)); + buf.o[sizeof(buf.o) - 1] = 0; + p = BF_crypt(test_pw, buf.s, buf.o, sizeof(buf.o) - (1 + 1), 1); + + ok = (p == buf.o && + !memcmp(p, buf.s, 7 + 22) && + !memcmp(p + (7 + 22), test_hash, 31 + 1 + 1 + 1)); + + { + const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"; + BF_key ae, ai, ye, yi; + BF_set_key(k, ae, ai, 2); /* $2a$ */ + BF_set_key(k, ye, yi, 4); /* $2y$ */ + ai[0] ^= 0x10000; /* undo the safety (for comparison) */ + ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 && + !memcmp(ae, ye, sizeof(ae)) && + !memcmp(ai, yi, sizeof(ai)); + } + + __set_errno(save_errno); + if (ok) + return retval; + +/* Should not happen */ + bcrypt_output_magic(settings, dst, length); + __set_errno(EINVAL); /* pretend we don't support this hash type */ + return NULL; +} diff --git a/blowfish.h b/blowfish.h index bcdc7cb6..ae7f5b12 100644 --- a/blowfish.h +++ b/blowfish.h @@ -81,6 +81,11 @@ void blowfish_decrypt(const struct blowfish_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src); +uint8_t * +blowfish_bcrypt(const uint8_t *key, + const uint8_t *settings, + uint8_t *dst, + size_t length);
#ifdef __cplusplus }
nettle-bugs@lists.lysator.liu.se