1 /*
2  * Copyright 2001 Abhijit Menon-Sen <ams@toroid.org>
3  */
4 
5 #include "tea.h"
6 
7 #define strtonl(s) (uint32_t)(*(s)|*(s+1)<<8|*(s+2)<<16|*(s+3)<<24)
8 #define nltostr(l, s) \
9     do {                                    \
10         *(s  )=(unsigned char)((l)      );  \
11         *(s+1)=(unsigned char)((l) >>  8);  \
12         *(s+2)=(unsigned char)((l) >> 16);  \
13         *(s+3)=(unsigned char)((l) >> 24);  \
14     } while (0)
15 
16 /* TEA is a 64-bit symmetric block cipher with a 128-bit key, developed
17    by David J. Wheeler and Roger M. Needham, and described in their
18    paper at <URL:http://www.cl.cam.ac.uk/ftp/users/djw3/tea.ps>.
19 
20    This implementation is based on their code in
21    <URL:http://www.cl.cam.ac.uk/ftp/users/djw3/xtea.ps> */
22 
tea_setup(unsigned char * key,int rounds)23 struct tea *tea_setup(unsigned char *key, int rounds)
24 {
25     struct tea *self = malloc(sizeof(struct tea));
26 
27     if (self) {
28         self->rounds = rounds;
29 
30         self->key[0] = strtonl(key);
31         self->key[1] = strtonl(key+4);
32         self->key[2] = strtonl(key+8);
33         self->key[3] = strtonl(key+12);
34     }
35 
36     return self;
37 }
38 
tea_free(struct tea * self)39 void tea_free(struct tea *self)
40 {
41     free(self);
42 }
43 
tea_crypt(struct tea * self,unsigned char * input,unsigned char * output,int decrypt)44 void tea_crypt(struct tea *self,
45                unsigned char *input, unsigned char *output,
46                int decrypt)
47 {
48     int i, rounds;
49     uint32_t delta = 0x9E3779B9, /* 2^31*(sqrt(5)-1) */
50              *k, y, z, sum = 0;
51 
52     k = self->key;
53     rounds = self->rounds;
54 
55     y = strtonl(input);
56     z = strtonl(input+4);
57 
58     if (!decrypt) {
59         for (i = 0; i < rounds; i++) {
60             y += ((z << 4 ^ z >> 5) + z) ^ (sum + k[sum & 3]);
61             sum += delta;
62             z += ((y << 4 ^ y >> 5) + y) ^ (sum + k[sum >> 11 & 3]);
63         }
64     } else {
65         sum = delta * rounds;
66         for (i = 0; i < rounds; i++) {
67             z -= ((y << 4 ^ y >> 5) + y) ^ (sum + k[sum >> 11 & 3]);
68             sum -= delta;
69             y -= ((z << 4 ^ z >> 5) + z) ^ (sum + k[sum & 3]);
70         }
71     }
72 
73     nltostr(y, output);
74     nltostr(z, output+4);
75 }
76