/* * 'bcrypt' password hash function, for PuTTY's import/export of * OpenSSH encrypted private key files. * * This is not really the same as the original bcrypt; OpenSSH has * modified it in various ways, and of course we have to do the same. */ #include #include #include "ssh.h" #include "sshblowf.h" BlowfishContext *bcrypt_setup(const unsigned char *key, int keybytes, const unsigned char *salt, int saltbytes) { int i; BlowfishContext *ctx; ctx = blowfish_make_context(); blowfish_initkey(ctx); blowfish_expandkey(ctx, key, keybytes, salt, saltbytes); /* Original bcrypt replaces this fixed loop count with the * variable cost. OpenSSH instead iterates the whole thing more * than once if it wants extra rounds. */ for (i = 0; i < 64; i++) { blowfish_expandkey(ctx, salt, saltbytes, NULL, 0); blowfish_expandkey(ctx, key, keybytes, NULL, 0); } return ctx; } void bcrypt_hash(const unsigned char *key, int keybytes, const unsigned char *salt, int saltbytes, unsigned char output[32]) { BlowfishContext *ctx; int i; ctx = bcrypt_setup(key, keybytes, salt, saltbytes); /* This was quite a nice starting string until it ran into * little-endian Blowfish :-/ */ memcpy(output, "cyxOmorhcitawolBhsiftawSanyDetim", 32); for (i = 0; i < 64; i++) { blowfish_lsb_encrypt_ecb(output, 32, ctx); } blowfish_free_context(ctx); } void bcrypt_genblock(int counter, const unsigned char hashed_passphrase[64], const unsigned char *salt, int saltbytes, unsigned char output[32]) { SHA512_State shastate; unsigned char hashed_salt[64]; unsigned char countbuf[4]; /* Hash the input salt with the counter value optionally suffixed * to get our real 32-byte salt */ SHA512_Init(&shastate); SHA512_Bytes(&shastate, salt, saltbytes); if (counter) { PUT_32BIT_MSB_FIRST(countbuf, counter); SHA512_Bytes(&shastate, countbuf, 4); } SHA512_Final(&shastate, hashed_salt); bcrypt_hash(hashed_passphrase, 64, hashed_salt, 64, output); smemclr(&shastate, sizeof(shastate)); smemclr(&hashed_salt, sizeof(hashed_salt)); } void openssh_bcrypt(const char *passphrase, const unsigned char *salt, int saltbytes, int rounds, unsigned char *out, int outbytes) { unsigned char hashed_passphrase[64]; unsigned char block[32], outblock[32]; const unsigned char *thissalt; int thissaltbytes; int modulus, residue, i, j, round; /* Hash the passphrase to get the bcrypt key material */ SHA512_Simple(passphrase, strlen(passphrase), hashed_passphrase); /* We output key bytes in a scattered fashion to meld all output * key blocks into all parts of the output. To do this, we pick a * modulus, and we output the key bytes to indices of out[] in the * following order: first the indices that are multiples of the * modulus, then the ones congruent to 1 mod modulus, etc. Each of * those passes consumes exactly one block output from * bcrypt_genblock, so we must pick a modulus large enough that at * most 32 bytes are used in the pass. */ modulus = (outbytes + 31) / 32; for (residue = 0; residue < modulus; residue++) { /* Our output block of data is the XOR of all blocks generated * by bcrypt in the following loop */ memset(outblock, 0, sizeof(outblock)); thissalt = salt; thissaltbytes = saltbytes; for (round = 0; round < rounds; round++) { bcrypt_genblock(round == 0 ? residue+1 : 0, hashed_passphrase, thissalt, thissaltbytes, block); /* Each subsequent bcrypt call reuses the previous one's * output as its salt */ thissalt = block; thissaltbytes = 32; for (i = 0; i < 32; i++) outblock[i] ^= block[i]; } for (i = residue, j = 0; i < outbytes; i += modulus, j++) out[i] = outblock[j]; } smemclr(&hashed_passphrase, sizeof(hashed_passphrase)); }