暫無描述
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.

encryption.c 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <stdint.h>
  2. #define LENGTH_OF_BLOCK 8
  3. void xxtea_Encrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4]);
  4. void xxtea_Decrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4]);
  5. /* The data packets are encrypted using the xxtea algorithm. */
  6. void Encrypt(uint32_t * data, uint8_t dataLength, uint64_t salt, const uint32_t key[4])
  7. {
  8. /* This function assumes that the dataLength is a multiple of the length of the
  9. * salt (8)
  10. *
  11. * The data is encrypted using cipher block chaining:
  12. * (https://upload.wikimedia.org/wikipedia/commons/8/80/CBC_encryption.svg)
  13. */
  14. uint8_t i;
  15. uint8_t * previousCipherBlock = (uint8_t*) &salt;
  16. uint8_t * currentPlaintextBlock = (uint8_t*) data;
  17. for (i = 0; i < dataLength/LENGTH_OF_BLOCK; i++)
  18. {
  19. /* XOR of current plain text block and previous cipher block */
  20. //for (j = 0; j < LENGTH_OF_BLOCK; j++)
  21. //{
  22. // currentPlaintextBlock[j] ^= previousCipherBlock[j];
  23. //}
  24. *((uint64_t*) currentPlaintextBlock) ^= *((uint64_t*) previousCipherBlock);
  25. /* Encrypt the block */
  26. xxtea_Encrypt((uint32_t*) currentPlaintextBlock, LENGTH_OF_BLOCK, key);
  27. /* Setup for next block */
  28. previousCipherBlock = currentPlaintextBlock;
  29. currentPlaintextBlock += LENGTH_OF_BLOCK;
  30. }
  31. }
  32. void Decrypt(uint32_t * data, uint8_t dataLength, uint64_t salt, const uint32_t key[4])
  33. {
  34. /* This function assumes that the dataLength is a multiple of the length of the
  35. * salt (8)
  36. *
  37. * The data is encrypted using cipher block chaining:
  38. * (https://upload.wikimedia.org/wikipedia/commons/2/2a/CBC_decryption.svg)
  39. */
  40. /* The data is decrypted from back to front as front to back cannot be done in
  41. * place
  42. */
  43. uint8_t i;
  44. uint8_t * previousCipherBlock = (uint8_t*) data + dataLength - 2 * LENGTH_OF_BLOCK;
  45. uint8_t * currentCipherBlock = (uint8_t*) data + dataLength - LENGTH_OF_BLOCK;
  46. for (i = dataLength/LENGTH_OF_BLOCK; i > 0; i--)
  47. {
  48. /* Decrypt the block */
  49. xxtea_Decrypt((uint32_t*) currentCipherBlock, LENGTH_OF_BLOCK, key);
  50. /* XOR of the decrypted block with cipher block in front of it */
  51. *((uint64_t*) currentCipherBlock) ^= *((uint64_t*) previousCipherBlock);
  52. /* Setup for next block */
  53. currentCipherBlock = previousCipherBlock;
  54. if (previousCipherBlock != (uint8_t*) data + LENGTH_OF_BLOCK)
  55. {
  56. previousCipherBlock -= LENGTH_OF_BLOCK;
  57. }
  58. else
  59. {
  60. previousCipherBlock = (uint8_t*) &salt;
  61. }
  62. }
  63. }
  64. void xxtea_Encrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4])
  65. {
  66. uint32_t sum = 0, z, y, e;
  67. uint8_t i = 6 + 52/(dataLength/4), r;
  68. const int16_t n = dataLength / 4 - 1;
  69. z = data[n]; // left neighbour for the first round
  70. do {
  71. // cycle
  72. sum += 0x9e3779b9ul;
  73. e = (sum >> 2) & 3;
  74. for (r = 0; r <= n; r++) {
  75. // round
  76. y = data[(r+1) % (n + 1)]; // right neighbour
  77. data[r] += ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum^y) + (key[(r^e) & 3] ^ z));
  78. z = data[r]; // left neighbour for the next round
  79. }
  80. } while (--i);
  81. }
  82. void xxtea_Decrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4])
  83. {
  84. uint32_t sum, z, y, e;
  85. int16_t i = 6 + 52/(dataLength/4), r;
  86. const int16_t n = dataLength / 4;
  87. sum = (uint32_t) ((uint64_t) (6 + 52/(dataLength/4)) * 0x9e3779b9ul);
  88. y = data[0];
  89. do {
  90. // cycle
  91. e = sum >> 2;
  92. for (r = n-1; r >= 0; --r) {
  93. // round
  94. z = data[(r+n-1) % n];
  95. data[r] -= ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum^y) + (key[(r^e) & 3] ^ z));
  96. y = data[r];
  97. }
  98. sum -= 0x9e3779b9;
  99. } while (--i);
  100. }