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.

187 lines
4.6 KiB

  1. #ifdef HAVE_CONFIG_H
  2. #include "config.h"
  3. #endif
  4. #include <stdint.h>
  5. #include "encrypt.h"
  6. #ifdef BIGENDIAN
  7. #include <endian.h>
  8. #elif LITTLEENDIAN
  9. #define htole64(x) (x)
  10. #endif
  11. static int random_compare(const void *_x, const void *_y) {
  12. uint32_t i = _i;
  13. uint64_t a = _a;
  14. uint8_t x = *((uint8_t *) _x);
  15. uint8_t y = *((uint8_t*) _y);
  16. return (a % (x + i) - a % (y + i));
  17. }
  18. static void merge(uint8_t *left, int llength, uint8_t *right, int rlength)
  19. {
  20. /* Temporary memory locations for the 2 segments of the array to merge. */
  21. uint8_t *ltmp = (uint8_t *) malloc(llength * sizeof(uint8_t));
  22. uint8_t *rtmp = (uint8_t *) malloc(rlength * sizeof(uint8_t));
  23. /*
  24. * Pointers to the elements being sorted in the temporary memory locations.
  25. */
  26. uint8_t *ll = ltmp;
  27. uint8_t *rr = rtmp;
  28. uint8_t *result = left;
  29. /*
  30. * Copy the segment of the array to be merged into the temporary memory
  31. * locations.
  32. */
  33. memcpy(ltmp, left, llength * sizeof(uint8_t));
  34. memcpy(rtmp, right, rlength * sizeof(uint8_t));
  35. while (llength > 0 && rlength > 0) {
  36. if (random_compare(ll, rr) <= 0) {
  37. /*
  38. * Merge the first element from the left back into the main array
  39. * if it is smaller or equal to the one on the right.
  40. */
  41. *result = *ll;
  42. ++ll;
  43. --llength;
  44. } else {
  45. /*
  46. * Merge the first element from the right back into the main array
  47. * if it is smaller than the one on the left.
  48. */
  49. *result = *rr;
  50. ++rr;
  51. --rlength;
  52. }
  53. ++result;
  54. }
  55. /*
  56. * All the elements from either the left or the right temporary array
  57. * segment have been merged back into the main array. Append the remaining
  58. * elements from the other temporary array back into the main array.
  59. */
  60. if (llength > 0)
  61. while (llength > 0) {
  62. /* Appending the rest of the left temporary array. */
  63. *result = *ll;
  64. ++result;
  65. ++ll;
  66. --llength;
  67. }
  68. else
  69. while (rlength > 0) {
  70. /* Appending the rest of the right temporary array. */
  71. *result = *rr;
  72. ++result;
  73. ++rr;
  74. --rlength;
  75. }
  76. /* Release the memory used for the temporary arrays. */
  77. free(ltmp);
  78. free(rtmp);
  79. }
  80. static void merge_sort(uint8_t array[], int length)
  81. {
  82. /* This is the middle index and also the length of the right array. */
  83. uint8_t middle;
  84. /*
  85. * Pointers to the beginning of the left and right segment of the array
  86. * to be merged.
  87. */
  88. uint8_t *left, *right;
  89. /* Length of the left segment of the array to be merged. */
  90. int llength;
  91. if (length <= 1)
  92. return;
  93. /* Let integer division truncate the value. */
  94. middle = length / 2;
  95. llength = length - middle;
  96. /*
  97. * Set the pointers to the appropriate segments of the array to be merged.
  98. */
  99. left = array;
  100. right = array + llength;
  101. merge_sort(left, llength);
  102. merge_sort(right, middle);
  103. merge(left, llength, right, middle);
  104. }
  105. void encrypt_ctx(char *buf, int len, EVP_CIPHER_CTX *ctx) {
  106. if (ctx != NULL) {
  107. int outlen;
  108. unsigned char mybuf[BUF_SIZE];
  109. EVP_CipherUpdate(ctx, mybuf, &outlen, (unsigned char*)buf, len);
  110. memcpy(buf, mybuf, len);
  111. } else {
  112. char *end = buf + len;
  113. while (buf < end) {
  114. *buf = (char)encrypt_table[(uint8_t)*buf];
  115. buf++;
  116. }
  117. }
  118. }
  119. void decrypt_ctx(char *buf, int len, EVP_CIPHER_CTX *ctx) {
  120. if (ctx != NULL) {
  121. int outlen;
  122. unsigned char mybuf[BUF_SIZE];
  123. EVP_CipherUpdate(ctx, mybuf, &outlen, (unsigned char*) buf, len);
  124. memcpy(buf, mybuf, len);
  125. } else {
  126. char *end = buf + len;
  127. while (buf < end) {
  128. *buf = (char)decrypt_table[(uint8_t)*buf];
  129. buf++;
  130. }
  131. }
  132. }
  133. void enc_ctx_init(EVP_CIPHER_CTX *ctx, const char *pass, int enc) {
  134. unsigned char key[EVP_MAX_KEY_LENGTH];
  135. unsigned char iv[EVP_MAX_IV_LENGTH];
  136. int key_len = EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, (unsigned char*) pass,
  137. strlen(pass), 1, key, iv);
  138. EVP_CIPHER_CTX_init(ctx);
  139. EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, NULL, NULL, enc);
  140. if (!EVP_CIPHER_CTX_set_key_length(ctx, key_len)) {
  141. LOGE("Invalid key length: %d", key_len);
  142. EVP_CIPHER_CTX_cleanup(ctx);
  143. exit(EXIT_FAILURE);
  144. }
  145. EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc);
  146. }
  147. void get_table(const char *pass) {
  148. uint8_t *table = encrypt_table;
  149. uint8_t *tmp_hash = MD5((unsigned char *) pass, strlen(pass), NULL);
  150. _a = htole64(*(uint64_t *) tmp_hash);
  151. uint32_t i;
  152. for(i = 0; i < 256; ++i) {
  153. table[i] = i;
  154. }
  155. for(i = 1; i < 1024; ++i) {
  156. _i = i;
  157. merge_sort(table, 256);
  158. }
  159. for(i = 0; i < 256; ++i) {
  160. // gen decrypt table from encrypt table
  161. decrypt_table[encrypt_table[i]] = i;
  162. }
  163. }