| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | 
							- /*
 
-  * '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 <stddef.h>
 
- #include <string.h>
 
- #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));
 
- }
 
 
  |