Skip to content

Commit 0f2c415

Browse files
committed
add TEA
1 parent 8e044b8 commit 0f2c415

File tree

6 files changed

+246
-1
lines changed

6 files changed

+246
-1
lines changed

src/ciphers/tea.c

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2+
*
3+
* LibTomCrypt is a library that provides various cryptographic
4+
* algorithms in a highly modular and flexible manner.
5+
*
6+
* The library is free for all purposes without any express
7+
* guarantee it works.
8+
*/
9+
10+
/**
11+
@file tea.c
12+
Implementation of TEA, Steffen Jaeckel
13+
*/
14+
#include "tomcrypt_private.h"
15+
16+
#ifdef LTC_TEA
17+
18+
const struct ltc_cipher_descriptor tea_desc =
19+
{
20+
"tea",
21+
26,
22+
16, 16, 8, 32,
23+
&tea_setup,
24+
&tea_ecb_encrypt,
25+
&tea_ecb_decrypt,
26+
&tea_test,
27+
&tea_done,
28+
&tea_keysize,
29+
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
30+
};
31+
32+
#define DELTA 0x9E3779B9uL
33+
#define SUM 0xC6EF3720uL
34+
35+
int tea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
36+
{
37+
LTC_ARGCHK(key != NULL);
38+
LTC_ARGCHK(skey != NULL);
39+
40+
/* check arguments */
41+
if (keylen != 16) {
42+
return CRYPT_INVALID_KEYSIZE;
43+
}
44+
45+
if (num_rounds != 0 && num_rounds != 32) {
46+
return CRYPT_INVALID_ROUNDS;
47+
}
48+
49+
/* load key */
50+
LOAD32H(skey->tea.k[0], key+0);
51+
LOAD32H(skey->tea.k[1], key+4);
52+
LOAD32H(skey->tea.k[2], key+8);
53+
LOAD32H(skey->tea.k[3], key+12);
54+
55+
return CRYPT_OK;
56+
}
57+
58+
/**
59+
Encrypts a block of text with TEA
60+
@param pt The input plaintext (8 bytes)
61+
@param ct The output ciphertext (8 bytes)
62+
@param skey The key as scheduled
63+
@return CRYPT_OK if successful
64+
*/
65+
int tea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
66+
{
67+
ulong32 y, z, sum = 0;
68+
const ulong32 delta = DELTA;
69+
int r;
70+
71+
LTC_ARGCHK(pt != NULL);
72+
LTC_ARGCHK(ct != NULL);
73+
LTC_ARGCHK(skey != NULL);
74+
75+
LOAD32H(y, &pt[0]);
76+
LOAD32H(z, &pt[4]);
77+
for (r = 0; r < 32; r += 4) {
78+
sum += delta;
79+
y += ((z<<4) + skey->tea.k[0]) ^ (z + sum) ^ ((z>>5) + skey->tea.k[1]);
80+
z += ((y<<4) + skey->tea.k[2]) ^ (y + sum) ^ ((y>>5) + skey->tea.k[3]);
81+
}
82+
STORE32H(y, &ct[0]);
83+
STORE32H(z, &ct[4]);
84+
return CRYPT_OK;
85+
}
86+
87+
/**
88+
Decrypts a block of text with TEA
89+
@param ct The input ciphertext (8 bytes)
90+
@param pt The output plaintext (8 bytes)
91+
@param skey The key as scheduled
92+
@return CRYPT_OK if successful
93+
*/
94+
int tea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
95+
{
96+
ulong32 v0, v1, sum = SUM;
97+
const ulong32 delta = DELTA;
98+
int r;
99+
100+
LTC_ARGCHK(pt != NULL);
101+
LTC_ARGCHK(ct != NULL);
102+
LTC_ARGCHK(skey != NULL);
103+
104+
LOAD32H(v0, &ct[0]);
105+
LOAD32H(v1, &ct[4]);
106+
107+
for (r = 0; r < 32; r++) {
108+
v1 -= ((v0 << 4) + skey->tea.k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + skey->tea.k[3]);
109+
v0 -= ((v1 << 4) + skey->tea.k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + skey->tea.k[1]);
110+
sum -= delta;
111+
}
112+
113+
STORE32H(v0, &pt[0]);
114+
STORE32H(v1, &pt[4]);
115+
return CRYPT_OK;
116+
}
117+
118+
/**
119+
Performs a self-test of the TEA block cipher
120+
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
121+
*/
122+
int tea_test(void)
123+
{
124+
#ifndef LTC_TEST
125+
return CRYPT_NOP;
126+
#else
127+
static const struct {
128+
const char *key, *pt, *ct;
129+
} tests[] = {
130+
{
131+
"00000000000000000000000000000000",
132+
"0000000000000000",
133+
"41ea3a0a94baa940"
134+
}, {
135+
"32a1e65408b63bb9214105744ec5d2e2",
136+
"5ada1d89a9c3801a",
137+
"dd46249e28aa0b4b"
138+
}, {
139+
"60388adadf70a1f5d9cb4e097d2c6c57",
140+
"7a6adb4d69c53e0f",
141+
"44b71215cf25368a"
142+
}, {
143+
"4368d2249bd0321eb7c56d5b63a1bfac",
144+
"5a5d7ca2e186c41a",
145+
"91f56dff7281794f"
146+
}, {
147+
"5c60bff27072d01c4513c5eb8f3a38ab",
148+
"80d9c4adcf899635",
149+
"2bb0f1b3c023ed11"
150+
}
151+
};
152+
unsigned char ptct[2][8];
153+
unsigned char tmp[2][8];
154+
unsigned char key[16];
155+
unsigned long l;
156+
symmetric_key skey;
157+
size_t i;
158+
int err, y;
159+
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
160+
zeromem(&skey, sizeof(skey));
161+
162+
l = sizeof(key);
163+
if ((err = base16_decode(tests[i].key, strlen(tests[i].key), key, &l)) != CRYPT) return err;
164+
l = sizeof(ptct[0]);
165+
if ((err = base16_decode(tests[i].pt, strlen(tests[i].pt), ptct[0], &l)) != CRYPT) return err;
166+
l = sizeof(ptct[1]);
167+
if ((err = base16_decode(tests[i].ct, strlen(tests[i].ct), ptct[1], &l)) != CRYPT) return err;
168+
169+
if ((err = tea_setup(key, 16, 0, &skey)) != CRYPT_OK) {
170+
return err;
171+
}
172+
tea_ecb_encrypt(ptct[0], tmp[0], &skey);
173+
tea_ecb_decrypt(tmp[0], tmp[1], &skey);
174+
175+
if (compare_testvector(tmp[0], 8, ptct[0], 8, "TEA Encrypt", i) != 0 ||
176+
compare_testvector(tmp[1], 8, ptct[1], 8, "TEA Decrypt", i) != 0) {
177+
return CRYPT_FAIL_TESTVECTOR;
178+
}
179+
180+
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
181+
for (y = 0; y < 8; y++) tmp[0][y] = 0;
182+
for (y = 0; y < 1000; y++) tea_ecb_encrypt(tmp[0], tmp[0], &skey);
183+
for (y = 0; y < 1000; y++) tea_ecb_decrypt(tmp[0], tmp[0], &skey);
184+
for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
185+
} /* for */
186+
187+
return CRYPT_OK;
188+
#endif
189+
}
190+
191+
/** Terminate the context
192+
@param skey The scheduled key
193+
*/
194+
void tea_done(symmetric_key *skey)
195+
{
196+
LTC_UNUSED_PARAM(skey);
197+
}
198+
199+
/**
200+
Gets suitable key size
201+
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
202+
@return CRYPT_OK if the input key size is acceptable.
203+
*/
204+
int tea_keysize(int *keysize)
205+
{
206+
LTC_ARGCHK(keysize != NULL);
207+
if (*keysize < 16) {
208+
return CRYPT_INVALID_KEYSIZE;
209+
}
210+
*keysize = 16;
211+
return CRYPT_OK;
212+
}
213+
214+
#endif
215+
216+
217+
/* ref: $Format:%D$ */
218+
/* git commit: $Format:%H$ */
219+
/* commit time: $Format:%ai$ */

src/ciphers/xtea.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
/**
1111
@file xtea.c
12-
Implementation of LTC_XTEA, Tom St Denis
12+
Implementation of eXtended TEA, Tom St Denis
1313
*/
1414
#include "tomcrypt_private.h"
1515

src/headers/tomcrypt_cipher.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ struct serpent_key {
171171
};
172172
#endif
173173

174+
#ifdef LTC_TEA
175+
struct tea_key {
176+
ulong32 k[4];
177+
};
178+
#endif
179+
174180
typedef union Symmetric_key {
175181
#ifdef LTC_DES
176182
struct des_key des;
@@ -235,6 +241,9 @@ typedef union Symmetric_key {
235241
#endif
236242
#ifdef LTC_SERPENT
237243
struct serpent_key serpent;
244+
#endif
245+
#ifdef LTC_TEA
246+
struct tea_key tea;
238247
#endif
239248
void *data;
240249
} symmetric_key;
@@ -859,6 +868,16 @@ int serpent_keysize(int *keysize);
859868
extern const struct ltc_cipher_descriptor serpent_desc;
860869
#endif
861870

871+
#ifdef LTC_TEA
872+
int tea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
873+
int tea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
874+
int tea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);
875+
int tea_test(void);
876+
void tea_done(symmetric_key *skey);
877+
int tea_keysize(int *keysize);
878+
extern const struct ltc_cipher_descriptor tea_desc;
879+
#endif
880+
862881
#ifdef LTC_ECB_MODE
863882
int ecb_start(int cipher, const unsigned char *key,
864883
int keylen, int num_rounds, symmetric_ECB *ecb);

src/headers/tomcrypt_custom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@
207207
#define LTC_CAMELLIA
208208
#define LTC_IDEA
209209
#define LTC_SERPENT
210+
#define LTC_TEA
210211

211212
/* stream ciphers */
212213
#define LTC_CHACHA

src/misc/crypt/crypt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ const char *crypt_build_settings =
127127
#endif
128128
#if defined(LTC_SERPENT)
129129
" Serpent\n"
130+
#endif
131+
#if defined(LTC_TEA)
132+
" TEA\n"
130133
#endif
131134
"Stream ciphers built-in:\n"
132135
#if defined(LTC_CHACHA)

src/misc/crypt/crypt_register_all_ciphers.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ int register_all_ciphers(void)
9797
#endif
9898
#ifdef LTC_SERPENT
9999
REGISTER_CIPHER(&serpent_desc);
100+
#endif
101+
#ifdef LTC_TEA
102+
REGISTER_CIPHER(&tea_desc);
100103
#endif
101104
return CRYPT_OK;
102105
}

0 commit comments

Comments
 (0)