You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
3.7 KiB

11 years ago
11 years ago
  1. #ifdef HAVE_CONFIG_H
  2. #include "config.h"
  3. #endif
  4. #include <stdint.h>
  5. #include "encrypt.h"
  6. #define OFFSET_ROL(p, o) ((u_int64_t)(*(p + o)) << (8 * o))
  7. static void md5(const uint8_t *text, uint8_t *digest) {
  8. md5_state_t state;
  9. md5_init(&state);
  10. md5_append(&state, text, strlen((char*)text));
  11. md5_finish(&state, digest);
  12. }
  13. static int random_compare(const void *_x, const void *_y) {
  14. uint32_t i = enc_conf.ctx.table.salt;
  15. uint64_t a = enc_conf.ctx.table.key;
  16. uint8_t x = *((uint8_t *) _x);
  17. uint8_t y = *((uint8_t*) _y);
  18. return (a % (x + i) - a % (y + i));
  19. }
  20. static void merge(uint8_t *left, int llength, uint8_t *right, int rlength)
  21. {
  22. uint8_t *ltmp = (uint8_t *) malloc(llength * sizeof(uint8_t));
  23. uint8_t *rtmp = (uint8_t *) malloc(rlength * sizeof(uint8_t));
  24. uint8_t *ll = ltmp;
  25. uint8_t *rr = rtmp;
  26. uint8_t *result = left;
  27. memcpy(ltmp, left, llength * sizeof(uint8_t));
  28. memcpy(rtmp, right, rlength * sizeof(uint8_t));
  29. while (llength > 0 && rlength > 0) {
  30. if (random_compare(ll, rr) <= 0) {
  31. *result = *ll;
  32. ++ll;
  33. --llength;
  34. } else {
  35. *result = *rr;
  36. ++rr;
  37. --rlength;
  38. }
  39. ++result;
  40. }
  41. if (llength > 0)
  42. while (llength > 0) {
  43. *result = *ll;
  44. ++result;
  45. ++ll;
  46. --llength;
  47. }
  48. else
  49. while (rlength > 0) {
  50. *result = *rr;
  51. ++result;
  52. ++rr;
  53. --rlength;
  54. }
  55. free(ltmp);
  56. free(rtmp);
  57. }
  58. static void merge_sort(uint8_t array[], int length)
  59. {
  60. uint8_t middle;
  61. uint8_t *left, *right;
  62. int llength;
  63. if (length <= 1)
  64. return;
  65. middle = length / 2;
  66. llength = length - middle;
  67. left = array;
  68. right = array + llength;
  69. merge_sort(left, llength);
  70. merge_sort(right, middle);
  71. merge(left, llength, right, middle);
  72. }
  73. void encrypt_ctx(char *buf, int len, struct rc4_state *ctx) {
  74. if (ctx != NULL) {
  75. rc4_crypt(ctx, (uint8_t*) buf, (uint8_t*) buf, len);
  76. } else {
  77. char *end = buf + len;
  78. while (buf < end) {
  79. *buf = (char)enc_conf.ctx.table.encrypt_table[(uint8_t)*buf];
  80. buf++;
  81. }
  82. }
  83. }
  84. void decrypt_ctx(char *buf, int len, struct rc4_state *ctx) {
  85. if (ctx != NULL) {
  86. rc4_crypt(ctx, (uint8_t*) buf, (uint8_t*) buf, len);
  87. } else {
  88. char *end = buf + len;
  89. while (buf < end) {
  90. *buf = (char)enc_conf.ctx.table.decrypt_table[(uint8_t)*buf];
  91. buf++;
  92. }
  93. }
  94. }
  95. void enc_ctx_init(struct rc4_state *ctx, int enc) {
  96. uint8_t *key = enc_conf.ctx.rc4.key;
  97. int key_len = enc_conf.ctx.rc4.key_len;
  98. rc4_init(ctx, key, key_len);
  99. }
  100. static void enc_rc4_init(const char *pass) {
  101. enc_conf.ctx.rc4.key_len = 16;
  102. enc_conf.ctx.rc4.key = malloc(16);
  103. md5((const uint8_t*)pass, enc_conf.ctx.rc4.key);
  104. }
  105. static void enc_table_init(const char *pass) {
  106. uint8_t *enc_table = malloc(256);
  107. uint8_t *dec_table = malloc(256);
  108. uint8_t digest[16];
  109. uint32_t *salt = &enc_conf.ctx.table.salt;
  110. uint64_t *key = &enc_conf.ctx.table.key;
  111. uint32_t i;
  112. md5((const uint8_t*)pass, digest);
  113. *key = 0;
  114. for (i = 0; i < 8; i++) {
  115. *key += OFFSET_ROL(digest, i);
  116. }
  117. for(i = 0; i < 256; ++i) {
  118. enc_table[i] = i;
  119. }
  120. for(i = 1; i < 1024; ++i) {
  121. *salt = i;
  122. merge_sort(enc_table, 256);
  123. }
  124. for(i = 0; i < 256; ++i) {
  125. // gen decrypt table from encrypt table
  126. dec_table[enc_table[i]] = i;
  127. }
  128. enc_conf.ctx.table.encrypt_table = enc_table;
  129. enc_conf.ctx.table.decrypt_table = dec_table;
  130. }
  131. void enc_conf_init(const char *pass, const char *method) {
  132. enc_conf.method = TABLE;
  133. if (method != NULL && strcmp(method, "rc4") == 0) {
  134. enc_conf.method = RC4;
  135. }
  136. if (enc_conf.method == TABLE) {
  137. enc_table_init(pass);
  138. } else if (enc_conf.method == RC4) {
  139. enc_rc4_init(pass);
  140. }
  141. }