sshbcrypt.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. unsigned char hashed_salt[64];
  50. /* Hash the input salt with the counter value optionally suffixed
  51. * to get our real 32-byte salt */
  52. ssh_hash *h = ssh_hash_new(&ssh_sha512);
  53. put_data(h, salt, saltbytes);
  54. if (counter)
  55. put_uint32(h, counter);
  56. ssh_hash_final(h, hashed_salt);
  57. bcrypt_hash(hashed_passphrase, 64, hashed_salt, 64, output);
  58. smemclr(&hashed_salt, sizeof(hashed_salt));
  59. }
  60. void openssh_bcrypt(const char *passphrase,
  61. const unsigned char *salt, int saltbytes,
  62. int rounds, unsigned char *out, int outbytes)
  63. {
  64. unsigned char hashed_passphrase[64];
  65. unsigned char block[32], outblock[32];
  66. const unsigned char *thissalt;
  67. int thissaltbytes;
  68. int modulus, residue, i, j, round;
  69. /* Hash the passphrase to get the bcrypt key material */
  70. hash_simple(&ssh_sha512, ptrlen_from_asciz(passphrase), hashed_passphrase);
  71. /* We output key bytes in a scattered fashion to meld all output
  72. * key blocks into all parts of the output. To do this, we pick a
  73. * modulus, and we output the key bytes to indices of out[] in the
  74. * following order: first the indices that are multiples of the
  75. * modulus, then the ones congruent to 1 mod modulus, etc. Each of
  76. * those passes consumes exactly one block output from
  77. * bcrypt_genblock, so we must pick a modulus large enough that at
  78. * most 32 bytes are used in the pass. */
  79. modulus = (outbytes + 31) / 32;
  80. for (residue = 0; residue < modulus; residue++) {
  81. /* Our output block of data is the XOR of all blocks generated
  82. * by bcrypt in the following loop */
  83. memset(outblock, 0, sizeof(outblock));
  84. thissalt = salt;
  85. thissaltbytes = saltbytes;
  86. for (round = 0; round < rounds; round++) {
  87. bcrypt_genblock(round == 0 ? residue+1 : 0,
  88. hashed_passphrase,
  89. thissalt, thissaltbytes, block);
  90. /* Each subsequent bcrypt call reuses the previous one's
  91. * output as its salt */
  92. thissalt = block;
  93. thissaltbytes = 32;
  94. for (i = 0; i < 32; i++)
  95. outblock[i] ^= block[i];
  96. }
  97. for (i = residue, j = 0; i < outbytes; i += modulus, j++)
  98. out[i] = outblock[j];
  99. }
  100. smemclr(&hashed_passphrase, sizeof(hashed_passphrase));
  101. }