| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- #include <stdint.h>
-
- #define LENGTH_OF_BLOCK 8
-
- void xxtea_Encrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4]);
- void xxtea_Decrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4]);
-
- /* The data packets are encrypted using the xxtea algorithm. */
- void Encrypt(uint32_t * data, uint8_t dataLength, uint64_t salt, const uint32_t key[4])
- {
- /* This function assumes that the dataLength is a multiple of the length of the
- * salt (8)
- *
- * The data is encrypted using cipher block chaining:
- * (https://upload.wikimedia.org/wikipedia/commons/8/80/CBC_encryption.svg)
- */
-
- uint8_t i;
- uint8_t * previousCipherBlock = (uint8_t*) &salt;
- uint8_t * currentPlaintextBlock = (uint8_t*) data;
-
- for (i = 0; i < dataLength/LENGTH_OF_BLOCK; i++)
- {
- /* XOR of current plain text block and previous cipher block */
- //for (j = 0; j < LENGTH_OF_BLOCK; j++)
- //{
- // currentPlaintextBlock[j] ^= previousCipherBlock[j];
- //}
- *((uint64_t*) currentPlaintextBlock) ^= *((uint64_t*) previousCipherBlock);
-
- /* Encrypt the block */
- xxtea_Encrypt((uint32_t*) currentPlaintextBlock, LENGTH_OF_BLOCK, key);
-
- /* Setup for next block */
- previousCipherBlock = currentPlaintextBlock;
- currentPlaintextBlock += LENGTH_OF_BLOCK;
- }
-
- }
-
-
- void Decrypt(uint32_t * data, uint8_t dataLength, uint64_t salt, const uint32_t key[4])
- {
- /* This function assumes that the dataLength is a multiple of the length of the
- * salt (8)
- *
- * The data is encrypted using cipher block chaining:
- * (https://upload.wikimedia.org/wikipedia/commons/2/2a/CBC_decryption.svg)
- */
-
- /* The data is decrypted from back to front as front to back cannot be done in
- * place
- */
- uint8_t i;
- uint8_t * previousCipherBlock = (uint8_t*) data + dataLength - 2 * LENGTH_OF_BLOCK;
- uint8_t * currentCipherBlock = (uint8_t*) data + dataLength - LENGTH_OF_BLOCK;
-
- for (i = dataLength/LENGTH_OF_BLOCK; i > 0; i--)
- {
- /* Decrypt the block */
- xxtea_Decrypt((uint32_t*) currentCipherBlock, LENGTH_OF_BLOCK, key);
-
- /* XOR of the decrypted block with cipher block in front of it */
- *((uint64_t*) currentCipherBlock) ^= *((uint64_t*) previousCipherBlock);
-
- /* Setup for next block */
- currentCipherBlock = previousCipherBlock;
- if (previousCipherBlock != (uint8_t*) data + LENGTH_OF_BLOCK)
- {
- previousCipherBlock -= LENGTH_OF_BLOCK;
- }
- else
- {
- previousCipherBlock = (uint8_t*) &salt;
- }
- }
- }
-
- void xxtea_Encrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4])
- {
- uint32_t sum = 0, z, y, e;
- uint8_t i = 6 + 52/(dataLength/4), r;
- const int16_t n = dataLength / 4 - 1;
-
- z = data[n]; // left neighbour for the first round
- do {
- // cycle
- sum += 0x9e3779b9ul;
- e = (sum >> 2) & 3;
- for (r = 0; r <= n; r++) {
- // round
- y = data[(r+1) % (n + 1)]; // right neighbour
- data[r] += ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum^y) + (key[(r^e) & 3] ^ z));
- z = data[r]; // left neighbour for the next round
- }
- } while (--i);
- }
-
- void xxtea_Decrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4])
- {
- uint32_t sum, z, y, e;
- int16_t i = 6 + 52/(dataLength/4), r;
- const int16_t n = dataLength / 4;
-
- sum = (uint32_t) ((uint64_t) (6 + 52/(dataLength/4)) * 0x9e3779b9ul);
- y = data[0];
- do {
- // cycle
- e = sum >> 2;
- for (r = n-1; r >= 0; --r) {
- // round
- z = data[(r+n-1) % n];
- data[r] -= ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum^y) + (key[(r^e) & 3] ^ z));
- y = data[r];
- }
- sum -= 0x9e3779b9;
- } while (--i);
- }
|