Sin descripción
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.8KB

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