excrypt_des.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include "excrypt.h"
  2. #include "excrypt_des_data.h"
  3. #include <string.h>
  4. #define LODWORD(_qw) ((uint32_t)(_qw))
  5. #define HIDWORD(_qw) ((uint32_t)(((_qw) >> 32) & 0xffffffff))
  6. // DES code based on https://github.com/fffaraz/cppDES
  7. void ExCryptDesParity(const uint8_t* input, uint32_t input_size, uint8_t* output)
  8. {
  9. for (uint32_t i = 0; i < input_size; i++)
  10. {
  11. uint8_t parity = input[i];
  12. parity ^= parity >> 4;
  13. parity ^= parity >> 2;
  14. parity ^= parity >> 1;
  15. output[i] = (input[i] & 0xFE) | (~parity & 1);
  16. }
  17. }
  18. void ExCryptDesKey(EXCRYPT_DES_STATE* state, const uint8_t* key)
  19. {
  20. uint64_t qkey = SWAP64(*(const uint64_t*)key);
  21. // initial key schedule calculation
  22. uint64_t permuted_choice_1 = 0; // 56 bits
  23. for (int i = 0; i < 56; i++)
  24. {
  25. permuted_choice_1 <<= 1;
  26. permuted_choice_1 |= (qkey >> (64 - PC1[i])) & LB64_MASK;
  27. }
  28. // 28 bits
  29. uint32_t C = (uint32_t)((permuted_choice_1 >> 28) & 0x000000000fffffff);
  30. uint32_t D = (uint32_t)(permuted_choice_1 & 0x000000000fffffff);
  31. // Calculation of the 16 keys
  32. for (int i = 0; i < 16; i++)
  33. {
  34. // key schedule, shifting Ci and Di
  35. for (int j = 0; j < ITERATION_SHIFT[i]; j++)
  36. {
  37. C = (0x0fffffff & (C << 1)) | (0x00000001 & (C >> 27));
  38. D = (0x0fffffff & (D << 1)) | (0x00000001 & (D >> 27));
  39. }
  40. uint64_t permuted_choice_2 = (((uint64_t)C) << 28) | (uint64_t)D;
  41. uint64_t sub_key = 0; // 48 bits (2*24)
  42. for (int j = 0; j < 48; j++)
  43. {
  44. sub_key <<= 1;
  45. sub_key |= (permuted_choice_2 >> (56 - PC2[j])) & LB64_MASK;
  46. }
  47. state->keytab[i] = sub_key;
  48. }
  49. }
  50. uint32_t f(uint32_t R, uint64_t k)
  51. {
  52. // applying expansion permutation and returning 48-bit data
  53. uint64_t s_input = 0;
  54. for (int i = 0; i < 48; i++)
  55. {
  56. s_input <<= 1;
  57. s_input |= (uint64_t)((R >> (32 - EXPANSION[i])) & LB32_MASK);
  58. }
  59. // XORing expanded Ri with Ki, the round key
  60. s_input = s_input ^ k;
  61. // applying S-Boxes function and returning 32-bit data
  62. uint32_t s_output = 0;
  63. for (int i = 0; i < 8; i++)
  64. {
  65. // Outer bits
  66. char row = (char)((s_input & (0x0000840000000000 >> 6 * i)) >> (42 - 6 * i));
  67. row = (row >> 4) | (row & 0x01);
  68. // Middle 4 bits of input
  69. char column = (char)((s_input & (0x0000780000000000 >> 6 * i)) >> (43 - 6 * i));
  70. s_output <<= 4;
  71. s_output |= (uint32_t)(SBOX[i][16 * row + column] & 0x0f);
  72. }
  73. // applying the round permutation
  74. uint32_t f_result = 0;
  75. for (int i = 0; i < 32; i++)
  76. {
  77. f_result <<= 1;
  78. f_result |= (s_output >> (32 - PBOX[i])) & LB32_MASK;
  79. }
  80. return f_result;
  81. }
  82. void feistel(uint32_t* L, uint32_t* R, uint32_t F)
  83. {
  84. uint32_t temp = *R;
  85. *R = *L ^ F;
  86. *L = temp;
  87. }
  88. void ExCryptDesEcb(const EXCRYPT_DES_STATE* state, const uint8_t* input, uint8_t* output, uint8_t encrypt)
  89. {
  90. uint64_t block;
  91. memcpy(&block, input, sizeof(uint64_t));
  92. block = SWAP64(block);
  93. //uint64_t block = SWAP64(*(uint64_t*)input)
  94. // initial permutation
  95. uint64_t result = 0;
  96. for (int i = 0; i < 64; i++)
  97. {
  98. result <<= 1;
  99. result |= (block >> (64 - IP[i])) & LB64_MASK;
  100. }
  101. // dividing T' into two 32-bit parts
  102. uint32_t L = HIDWORD(result);
  103. uint32_t R = LODWORD(result);
  104. // 16 rounds
  105. for (int i = 0; i < 16; i++)
  106. {
  107. uint32_t F = !encrypt ? f(R, state->keytab[15 - i]) : f(R, state->keytab[i]);
  108. feistel(&L, &R, F);
  109. }
  110. // swapping the two parts
  111. block = (((uint64_t)R) << 32) | (uint64_t)L;
  112. // inverse initial permutation
  113. result = 0;
  114. for (int i = 0; i < 64; i++)
  115. {
  116. result <<= 1;
  117. result |= (block >> (64 - FP[i])) & LB64_MASK;
  118. }
  119. result = SWAP64(result);
  120. memcpy(output, &result, sizeof(result));
  121. }
  122. void ExCryptDes3Key(EXCRYPT_DES3_STATE* state, const uint64_t* keys)
  123. {
  124. ExCryptDesKey(&state->des_state[0], (const uint8_t*)& keys[0]);
  125. ExCryptDesKey(&state->des_state[1], (const uint8_t*)& keys[1]);
  126. ExCryptDesKey(&state->des_state[2], (const uint8_t*)& keys[2]);
  127. }
  128. void ExCryptDes3Ecb(const EXCRYPT_DES3_STATE* state, const uint8_t* input, uint8_t* output, uint8_t encrypt)
  129. {
  130. if (encrypt)
  131. {
  132. ExCryptDesEcb(&state->des_state[0], input, output, encrypt);
  133. ExCryptDesEcb(&state->des_state[1], output, output, !encrypt);
  134. ExCryptDesEcb(&state->des_state[2], output, output, encrypt);
  135. }
  136. else
  137. {
  138. ExCryptDesEcb(&state->des_state[2], input, output, encrypt);
  139. ExCryptDesEcb(&state->des_state[1], output, output, !encrypt);
  140. ExCryptDesEcb(&state->des_state[0], output, output, encrypt);
  141. }
  142. }
  143. void ExCryptDes3Cbc(const EXCRYPT_DES3_STATE* state, const uint8_t* input, uint32_t input_size, uint8_t* output, uint8_t* feed, uint8_t encrypt)
  144. {
  145. uint64_t last_block = *(uint64_t*)feed;
  146. for (uint32_t i = 0; i < input_size / 8; i++)
  147. {
  148. if (encrypt) {
  149. uint64_t temp;
  150. memcpy(&temp, input, sizeof(temp));
  151. temp = temp ^ last_block;
  152. memcpy(output, &temp, sizeof(temp));
  153. ExCryptDes3Ecb(state, output, output, encrypt);
  154. memcpy(&last_block, output, sizeof(last_block));
  155. }
  156. else
  157. {
  158. ExCryptDes3Ecb(state, input, output, encrypt);
  159. uint64_t temp;
  160. memcpy(&temp, output, sizeof(temp));
  161. temp = temp ^ last_block;
  162. memcpy(output, &temp, sizeof(temp));
  163. memcpy(&last_block, input, sizeof(last_block));
  164. }
  165. input += 8;
  166. output += 8;
  167. }
  168. *(uint64_t*)feed = last_block;
  169. }