sshbcrypt.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * 'bcrypt' password hash function, for PuTTY's import/export of
  3. * OpenSSH encrypted private key files.
  4. *
  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. */
  8. #include <stddef.h>
  9. #include <string.h>
  10. #include "ssh.h"
  11. #include "sshblowf.h"
  12. BlowfishContext *bcrypt_setup(const unsigned char *key, int keybytes,
  13. const unsigned char *salt, int saltbytes)
  14. {
  15. int i;
  16. BlowfishContext *ctx;
  17. ctx = blowfish_make_context();
  18. blowfish_initkey(ctx);
  19. blowfish_expandkey(ctx, key, keybytes, salt, saltbytes);
  20. /* Original bcrypt replaces this fixed loop count with the
  21. * variable cost. OpenSSH instead iterates the whole thing more
  22. * than once if it wants extra rounds. */
  23. for (i = 0; i < 64; i++) {
  24. blowfish_expandkey(ctx, salt, saltbytes, NULL, 0);
  25. blowfish_expandkey(ctx, key, keybytes, NULL, 0);
  26. }
  27. return ctx;
  28. }
  29. void bcrypt_hash(const unsigned char *key, int keybytes,
  30. const unsigned char *salt, int saltbytes,
  31. unsigned char output[32])
  32. {
  33. BlowfishContext *ctx;
  34. int i;
  35. ctx = bcrypt_setup(key, keybytes, salt, saltbytes);
  36. /* This was quite a nice starting string until it ran into
  37. * little-endian Blowfish :-/ */
  38. memcpy(output, "cyxOmorhcitawolBhsiftawSanyDetim", 32);
  39. for (i = 0; i < 64; i++) {
  40. blowfish_lsb_encrypt_ecb(output, 32, ctx);
  41. }
  42. blowfish_free_context(ctx);
  43. }
  44. void bcrypt_genblock(int counter,
  45. const unsigned char hashed_passphrase[64],
  46. const unsigned char *salt, int saltbytes,
  47. unsigned char output[32])
  48. {
  49. SHA512_State shastate;
  50. unsigned char hashed_salt[64];
  51. /* Hash the input salt with the counter value optionally suffixed
  52. * to get our real 32-byte salt */
  53. SHA512_Init(&shastate);
  54. put_data(&shastate, salt, saltbytes);
  55. if (counter)
  56. put_uint32(&shastate, counter);
  57. SHA512_Final(&shastate, hashed_salt);
  58. bcrypt_hash(hashed_passphrase, 64, hashed_salt, 64, output);
  59. smemclr(&shastate, sizeof(shastate));
  60. smemclr(&hashed_salt, sizeof(hashed_salt));
  61. }
  62. void openssh_bcrypt(const char *passphrase,
  63. const unsigned char *salt, int saltbytes,
  64. int rounds, unsigned char *out, int outbytes)
  65. {
  66. unsigned char hashed_passphrase[64];
  67. unsigned char block[32], outblock[32];
  68. const unsigned char *thissalt;
  69. int thissaltbytes;
  70. int modulus, residue, i, j, round;
  71. /* Hash the passphrase to get the bcrypt key material */
  72. SHA512_Simple(passphrase, strlen(passphrase), hashed_passphrase);
  73. /* We output key bytes in a scattered fashion to meld all output
  74. * key blocks into all parts of the output. To do this, we pick a
  75. * modulus, and we output the key bytes to indices of out[] in the
  76. * following order: first the indices that are multiples of the
  77. * modulus, then the ones congruent to 1 mod modulus, etc. Each of
  78. * those passes consumes exactly one block output from
  79. * bcrypt_genblock, so we must pick a modulus large enough that at
  80. * most 32 bytes are used in the pass. */
  81. modulus = (outbytes + 31) / 32;
  82. for (residue = 0; residue < modulus; residue++) {
  83. /* Our output block of data is the XOR of all blocks generated
  84. * by bcrypt in the following loop */
  85. memset(outblock, 0, sizeof(outblock));
  86. thissalt = salt;
  87. thissaltbytes = saltbytes;
  88. for (round = 0; round < rounds; round++) {
  89. bcrypt_genblock(round == 0 ? residue+1 : 0,
  90. hashed_passphrase,
  91. thissalt, thissaltbytes, block);
  92. /* Each subsequent bcrypt call reuses the previous one's
  93. * output as its salt */
  94. thissalt = block;
  95. thissaltbytes = 32;
  96. for (i = 0; i < 32; i++)
  97. outblock[i] ^= block[i];
  98. }
  99. for (i = residue, j = 0; i < outbytes; i += modulus, j++)
  100. out[i] = outblock[j];
  101. }
  102. smemclr(&hashed_passphrase, sizeof(hashed_passphrase));
  103. }