blowfish.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "blowfish.h"
  2. const char B64[] =
  3. "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  4. /* decode base64 string */
  5. static uint32_t
  6. base64dec (char c)
  7. {
  8. size_t i;
  9. for (i = 0; i < 64; i++)
  10. if (B64[i] == c)
  11. return i;
  12. return 0;
  13. }
  14. static uint32_t
  15. load32_be (const void *p)
  16. {
  17. const unsigned char *in = p;
  18. return (uint32_t) in[0] << 24 |
  19. (uint32_t) in[1] << 16 | (uint32_t) in[2] << 8 | (uint32_t) in[3] << 0;
  20. }
  21. static void
  22. store32_be (void *p, uint32_t v)
  23. {
  24. unsigned char *out = p;
  25. out[0] = v >> 24;
  26. out[1] = v >> 16;
  27. out[2] = v >> 8;
  28. out[3] = v >> 0;
  29. }
  30. /* Returned string must be freed when done with it! */
  31. int
  32. encrypt_string (const char *key, const char *str, char *dest, int len)
  33. {
  34. BF_KEY bf_key;
  35. if (!key || !key[0])
  36. return 0;
  37. BF_set_key (&bf_key, strlen (key), (const unsigned char *) key);
  38. while (len > 0)
  39. {
  40. const size_t blocksize = len < 8 ? len : BF_BLOCK;
  41. unsigned char block[BF_BLOCK] = { 0 }; /* pad with zero */
  42. uint32_t v;
  43. size_t i;
  44. memcpy (block, str, blocksize);
  45. BF_ecb_encrypt (block, block, &bf_key, BF_ENCRYPT);
  46. for (v = load32_be (block + 4), i = 0; i < 6; ++i)
  47. {
  48. *dest++ = B64[v & 0x3f];
  49. v >>= 6;
  50. }
  51. for (v = load32_be (block + 0), i = 0; i < 6; ++i)
  52. {
  53. *dest++ = B64[v & 0x3f];
  54. v >>= 6;
  55. }
  56. len -= blocksize;
  57. str += blocksize;
  58. }
  59. *dest++ = 0;
  60. return 1;
  61. }
  62. int
  63. decrypt_string (const char *key, const char *str, char *dest, int len)
  64. {
  65. BF_KEY bf_key;
  66. uint32_t v;
  67. size_t i;
  68. /* Pad encoded string with 0 bits in case it's bogus */
  69. if (!key || !key[0])
  70. return 0;
  71. /* length must be a multiple of BF_BLOCK encoded in base64 */
  72. if (len % (BF_BLOCK * 6 / 4) != 0)
  73. return 0;
  74. BF_set_key (&bf_key, strlen (key), (const unsigned char *) key);
  75. while (len > 0)
  76. {
  77. unsigned char block[BF_BLOCK] = { 0 };
  78. for (i = v = 0; i < 6; ++i)
  79. v |= base64dec (*str++) << (i * 6);
  80. store32_be (block + 4, v);
  81. for (i = v = 0; i < 6; ++i)
  82. v |= base64dec (*str++) << (i * 6);
  83. store32_be (block + 0, v);
  84. BF_ecb_encrypt (block, block, &bf_key, BF_DECRYPT);
  85. memcpy (dest, block, BF_BLOCK);
  86. dest += BF_BLOCK;
  87. len -= BF_BLOCK * 6 / 4;
  88. }
  89. *dest++ = 0;
  90. return 1;
  91. }
  92. void
  93. encrypt_key (const char *key, char *encryptedKey)
  94. {
  95. static const char prefix[] = "+OK ";
  96. strcpy (encryptedKey, prefix);
  97. encrypt_string (iniKey, key, encryptedKey + strlen (prefix), strlen (key));
  98. }