#include #include #include #include #if CHAR_BIT != 8 #error CHAR_BIT must be 8! #elif ULONG_MAX != 0xFFFFFFFFuL #error 'unsigned long' must be 32 bits! #endif /* * Tiny Encryption Algorithm * * D.J. Wheeler & R.M. Needham */ #define ITERATIONS 32 static void encode(unsigned long *plain, unsigned long *key, unsigned long *enc) { unsigned long y = plain[0]; unsigned long z = plain[1]; unsigned long sum = 0; unsigned long delta = 0x9E3779B9; int i; for (i=0; i < ITERATIONS; ++i) { sum += delta; #if 0 /* The code in the original paper is WRONG WRONG WRONG */ y += ((z << 4) + key[0]) ^ ((z >> 5) + key[1]) ^ (z + sum); z += ((y << 4) + key[2]) ^ ((y >> 5) + key[3]) ^ (y + sum); #else y += (z << 4) + (key[0] ^ z) + (sum ^ (z >> 5)) + key[1]; z += (y << 4) + (key[2] ^ y) + (sum ^ (y >> 5)) + key[3]; #endif } enc[0] = y; enc[1] = z; } static void decode(unsigned long *enc, unsigned long *key, unsigned long *dec) { unsigned long y = enc[0]; unsigned long z = enc[1]; unsigned long delta = 0x9E3779B9; unsigned long sum = delta * ITERATIONS; int i; for (i=0; i < ITERATIONS; ++i) { #if 0 /* The code in the original paper is WRONG WRONG WRONG */ z -= ((y << 4) + key[2]) ^ ((y >> 5) + key[3]) ^ (y + sum); y -= ((z << 4) + key[0]) ^ ((z >> 5) + key[1]) ^ (z + sum); #else z -= (y << 4) + (key[2] ^ y) + (sum ^ (y >> 5)) + key[3]; y -= (z << 4) + (key[0] ^ z) + (sum ^ (z >> 5)) + key[1]; #endif sum -= delta; } dec[0] = y; dec[1] = z; } int TEA_encode(void *plain, void *crypt, size_t len, void *key, size_t keylen) { unsigned long *lplain = plain; unsigned long *lcrypt = crypt; int npairs = len/8; int i; /* Paranoia: check key size */ if (keylen != 16) return -1; for (i=0; i < npairs; ++i) encode(lplain+2*i, key, lcrypt+2*i); if (len % 8) { /* Partial block left over; copy it unencrypted */ memcpy(lcrypt+2*i, lplain+2*i, len%8); } return 0; } int TEA_decode(void *crypt, void *plain, size_t len, void *key, size_t nkey) { unsigned long *lcrypt = crypt; unsigned long *lplain = plain; int npairs = len/8; int i; /* Paranoia: check key size */ if (nkey != 16) return -1; for (i=0; i < npairs; ++i) decode(lcrypt+2*i, key, lplain+2*i); if (len % 8) { /* Partial block left over; copy it undecrypted */ memcpy(lplain+2*i, lcrypt+2*i, len%8); } return 0; } int main(void) { char key[] = "1234567890123456"; char test[] = "Having been some days in preparation\n" "A splendid time is guaranteed for all.\n"; char enc[sizeof test]; char dec[sizeof test]; TEA_encode(test, enc, sizeof test, key, 16); TEA_decode(enc, dec, sizeof test, key, 16); printf("%s\n", test); printf("%s\n", dec); return 0; }