1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * TEA, XTEA, and XETA crypto alogrithms
7 * The TEA and Xtended TEA algorithms were developed by David Wheeler
8 * and Roger Needham at the Computer Laboratory of Cambridge University.
10 * Due to the order of evaluation in XTEA many people have incorrectly
11 * implemented it. XETA (XTEA in the wrong order), exists for
12 * compatibility with these implementations.
14 * Copyright (c) 2004 Aaron Grothe ajgrothe@yahoo.com
17 #include <linux/init.h>
18 #include <linux/module.h>
20 #include <asm/byteorder.h>
21 #include <linux/crypto.h>
22 #include <linux/types.h>
24 #define TEA_KEY_SIZE 16
25 #define TEA_BLOCK_SIZE 8
27 #define TEA_DELTA 0x9e3779b9
29 #define XTEA_KEY_SIZE 16
30 #define XTEA_BLOCK_SIZE 8
31 #define XTEA_ROUNDS 32
32 #define XTEA_DELTA 0x9e3779b9
42 static int tea_setkey(struct crypto_tfm
*tfm
, const u8
*in_key
,
45 struct tea_ctx
*ctx
= crypto_tfm_ctx(tfm
);
46 const __le32
*key
= (const __le32
*)in_key
;
48 ctx
->KEY
[0] = le32_to_cpu(key
[0]);
49 ctx
->KEY
[1] = le32_to_cpu(key
[1]);
50 ctx
->KEY
[2] = le32_to_cpu(key
[2]);
51 ctx
->KEY
[3] = le32_to_cpu(key
[3]);
57 static void tea_encrypt(struct crypto_tfm
*tfm
, u8
*dst
, const u8
*src
)
61 struct tea_ctx
*ctx
= crypto_tfm_ctx(tfm
);
62 const __le32
*in
= (const __le32
*)src
;
63 __le32
*out
= (__le32
*)dst
;
65 y
= le32_to_cpu(in
[0]);
66 z
= le32_to_cpu(in
[1]);
77 y
+= ((z
<< 4) + k0
) ^ (z
+ sum
) ^ ((z
>> 5) + k1
);
78 z
+= ((y
<< 4) + k2
) ^ (y
+ sum
) ^ ((y
>> 5) + k3
);
81 out
[0] = cpu_to_le32(y
);
82 out
[1] = cpu_to_le32(z
);
85 static void tea_decrypt(struct crypto_tfm
*tfm
, u8
*dst
, const u8
*src
)
89 struct tea_ctx
*ctx
= crypto_tfm_ctx(tfm
);
90 const __le32
*in
= (const __le32
*)src
;
91 __le32
*out
= (__le32
*)dst
;
93 y
= le32_to_cpu(in
[0]);
94 z
= le32_to_cpu(in
[1]);
101 sum
= TEA_DELTA
<< 5;
106 z
-= ((y
<< 4) + k2
) ^ (y
+ sum
) ^ ((y
>> 5) + k3
);
107 y
-= ((z
<< 4) + k0
) ^ (z
+ sum
) ^ ((z
>> 5) + k1
);
111 out
[0] = cpu_to_le32(y
);
112 out
[1] = cpu_to_le32(z
);
115 static int xtea_setkey(struct crypto_tfm
*tfm
, const u8
*in_key
,
116 unsigned int key_len
)
118 struct xtea_ctx
*ctx
= crypto_tfm_ctx(tfm
);
119 const __le32
*key
= (const __le32
*)in_key
;
121 ctx
->KEY
[0] = le32_to_cpu(key
[0]);
122 ctx
->KEY
[1] = le32_to_cpu(key
[1]);
123 ctx
->KEY
[2] = le32_to_cpu(key
[2]);
124 ctx
->KEY
[3] = le32_to_cpu(key
[3]);
130 static void xtea_encrypt(struct crypto_tfm
*tfm
, u8
*dst
, const u8
*src
)
133 u32 limit
= XTEA_DELTA
* XTEA_ROUNDS
;
134 struct xtea_ctx
*ctx
= crypto_tfm_ctx(tfm
);
135 const __le32
*in
= (const __le32
*)src
;
136 __le32
*out
= (__le32
*)dst
;
138 y
= le32_to_cpu(in
[0]);
139 z
= le32_to_cpu(in
[1]);
141 while (sum
!= limit
) {
142 y
+= ((z
<< 4 ^ z
>> 5) + z
) ^ (sum
+ ctx
->KEY
[sum
&3]);
144 z
+= ((y
<< 4 ^ y
>> 5) + y
) ^ (sum
+ ctx
->KEY
[sum
>>11 &3]);
147 out
[0] = cpu_to_le32(y
);
148 out
[1] = cpu_to_le32(z
);
151 static void xtea_decrypt(struct crypto_tfm
*tfm
, u8
*dst
, const u8
*src
)
154 struct tea_ctx
*ctx
= crypto_tfm_ctx(tfm
);
155 const __le32
*in
= (const __le32
*)src
;
156 __le32
*out
= (__le32
*)dst
;
158 y
= le32_to_cpu(in
[0]);
159 z
= le32_to_cpu(in
[1]);
161 sum
= XTEA_DELTA
* XTEA_ROUNDS
;
164 z
-= ((y
<< 4 ^ y
>> 5) + y
) ^ (sum
+ ctx
->KEY
[sum
>>11 & 3]);
166 y
-= ((z
<< 4 ^ z
>> 5) + z
) ^ (sum
+ ctx
->KEY
[sum
& 3]);
169 out
[0] = cpu_to_le32(y
);
170 out
[1] = cpu_to_le32(z
);
174 static void xeta_encrypt(struct crypto_tfm
*tfm
, u8
*dst
, const u8
*src
)
177 u32 limit
= XTEA_DELTA
* XTEA_ROUNDS
;
178 struct xtea_ctx
*ctx
= crypto_tfm_ctx(tfm
);
179 const __le32
*in
= (const __le32
*)src
;
180 __le32
*out
= (__le32
*)dst
;
182 y
= le32_to_cpu(in
[0]);
183 z
= le32_to_cpu(in
[1]);
185 while (sum
!= limit
) {
186 y
+= (z
<< 4 ^ z
>> 5) + (z
^ sum
) + ctx
->KEY
[sum
&3];
188 z
+= (y
<< 4 ^ y
>> 5) + (y
^ sum
) + ctx
->KEY
[sum
>>11 &3];
191 out
[0] = cpu_to_le32(y
);
192 out
[1] = cpu_to_le32(z
);
195 static void xeta_decrypt(struct crypto_tfm
*tfm
, u8
*dst
, const u8
*src
)
198 struct tea_ctx
*ctx
= crypto_tfm_ctx(tfm
);
199 const __le32
*in
= (const __le32
*)src
;
200 __le32
*out
= (__le32
*)dst
;
202 y
= le32_to_cpu(in
[0]);
203 z
= le32_to_cpu(in
[1]);
205 sum
= XTEA_DELTA
* XTEA_ROUNDS
;
208 z
-= (y
<< 4 ^ y
>> 5) + (y
^ sum
) + ctx
->KEY
[sum
>>11 & 3];
210 y
-= (z
<< 4 ^ z
>> 5) + (z
^ sum
) + ctx
->KEY
[sum
& 3];
213 out
[0] = cpu_to_le32(y
);
214 out
[1] = cpu_to_le32(z
);
217 static struct crypto_alg tea_algs
[3] = { {
219 .cra_driver_name
= "tea-generic",
220 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
,
221 .cra_blocksize
= TEA_BLOCK_SIZE
,
222 .cra_ctxsize
= sizeof (struct tea_ctx
),
224 .cra_module
= THIS_MODULE
,
225 .cra_u
= { .cipher
= {
226 .cia_min_keysize
= TEA_KEY_SIZE
,
227 .cia_max_keysize
= TEA_KEY_SIZE
,
228 .cia_setkey
= tea_setkey
,
229 .cia_encrypt
= tea_encrypt
,
230 .cia_decrypt
= tea_decrypt
} }
233 .cra_driver_name
= "xtea-generic",
234 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
,
235 .cra_blocksize
= XTEA_BLOCK_SIZE
,
236 .cra_ctxsize
= sizeof (struct xtea_ctx
),
238 .cra_module
= THIS_MODULE
,
239 .cra_u
= { .cipher
= {
240 .cia_min_keysize
= XTEA_KEY_SIZE
,
241 .cia_max_keysize
= XTEA_KEY_SIZE
,
242 .cia_setkey
= xtea_setkey
,
243 .cia_encrypt
= xtea_encrypt
,
244 .cia_decrypt
= xtea_decrypt
} }
247 .cra_driver_name
= "xeta-generic",
248 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
,
249 .cra_blocksize
= XTEA_BLOCK_SIZE
,
250 .cra_ctxsize
= sizeof (struct xtea_ctx
),
252 .cra_module
= THIS_MODULE
,
253 .cra_u
= { .cipher
= {
254 .cia_min_keysize
= XTEA_KEY_SIZE
,
255 .cia_max_keysize
= XTEA_KEY_SIZE
,
256 .cia_setkey
= xtea_setkey
,
257 .cia_encrypt
= xeta_encrypt
,
258 .cia_decrypt
= xeta_decrypt
} }
261 static int __init
tea_mod_init(void)
263 return crypto_register_algs(tea_algs
, ARRAY_SIZE(tea_algs
));
266 static void __exit
tea_mod_fini(void)
268 crypto_unregister_algs(tea_algs
, ARRAY_SIZE(tea_algs
));
271 MODULE_ALIAS_CRYPTO("tea");
272 MODULE_ALIAS_CRYPTO("xtea");
273 MODULE_ALIAS_CRYPTO("xeta");
275 subsys_initcall(tea_mod_init
);
276 module_exit(tea_mod_fini
);
278 MODULE_LICENSE("GPL");
279 MODULE_DESCRIPTION("TEA, XTEA & XETA Cryptographic Algorithms");