Doc: Fix broken link
[TortoiseGit.git] / src / TortoisePlink / sshbcrypt.c
blobe16d2f6cf614af08d71f57a5a849f9e812a59cfb
1 /*
2 * 'bcrypt' password hash function, for PuTTY's import/export of
3 * OpenSSH encrypted private key files.
5 * This is not really the same as the original bcrypt; OpenSSH has
6 * modified it in various ways, and of course we have to do the same.
7 */
9 #include <stddef.h>
10 #include <string.h>
11 #include "ssh.h"
12 #include "sshblowf.h"
14 BlowfishContext *bcrypt_setup(const unsigned char *key, int keybytes,
15 const unsigned char *salt, int saltbytes)
17 int i;
18 BlowfishContext *ctx;
20 ctx = blowfish_make_context();
21 blowfish_initkey(ctx);
22 blowfish_expandkey(ctx, key, keybytes, salt, saltbytes);
24 /* Original bcrypt replaces this fixed loop count with the
25 * variable cost. OpenSSH instead iterates the whole thing more
26 * than once if it wants extra rounds. */
27 for (i = 0; i < 64; i++) {
28 blowfish_expandkey(ctx, salt, saltbytes, NULL, 0);
29 blowfish_expandkey(ctx, key, keybytes, NULL, 0);
32 return ctx;
35 void bcrypt_hash(const unsigned char *key, int keybytes,
36 const unsigned char *salt, int saltbytes,
37 unsigned char output[32])
39 BlowfishContext *ctx;
40 int i;
42 ctx = bcrypt_setup(key, keybytes, salt, saltbytes);
43 /* This was quite a nice starting string until it ran into
44 * little-endian Blowfish :-/ */
45 memcpy(output, "cyxOmorhcitawolBhsiftawSanyDetim", 32);
46 for (i = 0; i < 64; i++) {
47 blowfish_lsb_encrypt_ecb(output, 32, ctx);
49 blowfish_free_context(ctx);
52 void bcrypt_genblock(int counter,
53 const unsigned char hashed_passphrase[64],
54 const unsigned char *salt, int saltbytes,
55 unsigned char output[32])
57 SHA512_State shastate;
58 unsigned char hashed_salt[64];
59 unsigned char countbuf[4];
61 /* Hash the input salt with the counter value optionally suffixed
62 * to get our real 32-byte salt */
63 SHA512_Init(&shastate);
64 SHA512_Bytes(&shastate, salt, saltbytes);
65 if (counter) {
66 PUT_32BIT_MSB_FIRST(countbuf, counter);
67 SHA512_Bytes(&shastate, countbuf, 4);
69 SHA512_Final(&shastate, hashed_salt);
71 bcrypt_hash(hashed_passphrase, 64, hashed_salt, 64, output);
73 smemclr(&shastate, sizeof(shastate));
74 smemclr(&hashed_salt, sizeof(hashed_salt));
77 void openssh_bcrypt(const char *passphrase,
78 const unsigned char *salt, int saltbytes,
79 int rounds, unsigned char *out, int outbytes)
81 unsigned char hashed_passphrase[64];
82 unsigned char block[32], outblock[32];
83 const unsigned char *thissalt;
84 int thissaltbytes;
85 int modulus, residue, i, j, round;
87 /* Hash the passphrase to get the bcrypt key material */
88 SHA512_Simple(passphrase, strlen(passphrase), hashed_passphrase);
90 /* We output key bytes in a scattered fashion to meld all output
91 * key blocks into all parts of the output. To do this, we pick a
92 * modulus, and we output the key bytes to indices of out[] in the
93 * following order: first the indices that are multiples of the
94 * modulus, then the ones congruent to 1 mod modulus, etc. Each of
95 * those passes consumes exactly one block output from
96 * bcrypt_genblock, so we must pick a modulus large enough that at
97 * most 32 bytes are used in the pass. */
98 modulus = (outbytes + 31) / 32;
100 for (residue = 0; residue < modulus; residue++) {
101 /* Our output block of data is the XOR of all blocks generated
102 * by bcrypt in the following loop */
103 memset(outblock, 0, sizeof(outblock));
105 thissalt = salt;
106 thissaltbytes = saltbytes;
107 for (round = 0; round < rounds; round++) {
108 bcrypt_genblock(round == 0 ? residue+1 : 0,
109 hashed_passphrase,
110 thissalt, thissaltbytes, block);
111 /* Each subsequent bcrypt call reuses the previous one's
112 * output as its salt */
113 thissalt = block;
114 thissaltbytes = 32;
116 for (i = 0; i < 32; i++)
117 outblock[i] ^= block[i];
120 for (i = residue, j = 0; i < outbytes; i += modulus, j++)
121 out[i] = outblock[j];
123 smemclr(&hashed_passphrase, sizeof(hashed_passphrase));