diff options
Diffstat (limited to 'crypto/tea.c')
-rw-r--r-- | crypto/tea.c | 81 |
1 files changed, 77 insertions, 4 deletions
diff --git a/crypto/tea.c b/crypto/tea.c index 03c23cbd3afa..5924efdd3a16 100644 --- a/crypto/tea.c +++ b/crypto/tea.c | |||
@@ -1,11 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * Cryptographic API. | 2 | * Cryptographic API. |
3 | * | 3 | * |
4 | * TEA and Xtended TEA Algorithms | 4 | * TEA, XTEA, and XETA crypto alogrithms |
5 | * | 5 | * |
6 | * The TEA and Xtended TEA algorithms were developed by David Wheeler | 6 | * The TEA and Xtended TEA algorithms were developed by David Wheeler |
7 | * and Roger Needham at the Computer Laboratory of Cambridge University. | 7 | * and Roger Needham at the Computer Laboratory of Cambridge University. |
8 | * | 8 | * |
9 | * Due to the order of evaluation in XTEA many people have incorrectly | ||
10 | * implemented it. XETA (XTEA in the wrong order), exists for | ||
11 | * compatibility with these implementations. | ||
12 | * | ||
9 | * Copyright (c) 2004 Aaron Grothe ajgrothe@yahoo.com | 13 | * Copyright (c) 2004 Aaron Grothe ajgrothe@yahoo.com |
10 | * | 14 | * |
11 | * This program is free software; you can redistribute it and/or modify | 15 | * This program is free software; you can redistribute it and/or modify |
@@ -153,9 +157,9 @@ static void xtea_encrypt(void *ctx_arg, u8 *dst, const u8 *src) | |||
153 | z = u32_in (src + 4); | 157 | z = u32_in (src + 4); |
154 | 158 | ||
155 | while (sum != limit) { | 159 | while (sum != limit) { |
156 | y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3]; | 160 | y += ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum&3]); |
157 | sum += XTEA_DELTA; | 161 | sum += XTEA_DELTA; |
158 | z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3]; | 162 | z += ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 &3]); |
159 | } | 163 | } |
160 | 164 | ||
161 | u32_out (dst, y); | 165 | u32_out (dst, y); |
@@ -175,6 +179,51 @@ static void xtea_decrypt(void *ctx_arg, u8 *dst, const u8 *src) | |||
175 | sum = XTEA_DELTA * XTEA_ROUNDS; | 179 | sum = XTEA_DELTA * XTEA_ROUNDS; |
176 | 180 | ||
177 | while (sum) { | 181 | while (sum) { |
182 | z -= ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 & 3]); | ||
183 | sum -= XTEA_DELTA; | ||
184 | y -= ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum & 3]); | ||
185 | } | ||
186 | |||
187 | u32_out (dst, y); | ||
188 | u32_out (dst + 4, z); | ||
189 | |||
190 | } | ||
191 | |||
192 | |||
193 | static void xeta_encrypt(void *ctx_arg, u8 *dst, const u8 *src) | ||
194 | { | ||
195 | |||
196 | u32 y, z, sum = 0; | ||
197 | u32 limit = XTEA_DELTA * XTEA_ROUNDS; | ||
198 | |||
199 | struct xtea_ctx *ctx = ctx_arg; | ||
200 | |||
201 | y = u32_in (src); | ||
202 | z = u32_in (src + 4); | ||
203 | |||
204 | while (sum != limit) { | ||
205 | y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3]; | ||
206 | sum += XTEA_DELTA; | ||
207 | z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3]; | ||
208 | } | ||
209 | |||
210 | u32_out (dst, y); | ||
211 | u32_out (dst + 4, z); | ||
212 | |||
213 | } | ||
214 | |||
215 | static void xeta_decrypt(void *ctx_arg, u8 *dst, const u8 *src) | ||
216 | { | ||
217 | |||
218 | u32 y, z, sum; | ||
219 | struct tea_ctx *ctx = ctx_arg; | ||
220 | |||
221 | y = u32_in (src); | ||
222 | z = u32_in (src + 4); | ||
223 | |||
224 | sum = XTEA_DELTA * XTEA_ROUNDS; | ||
225 | |||
226 | while (sum) { | ||
178 | z -= (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 & 3]; | 227 | z -= (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 & 3]; |
179 | sum -= XTEA_DELTA; | 228 | sum -= XTEA_DELTA; |
180 | y -= (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum & 3]; | 229 | y -= (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum & 3]; |
@@ -215,6 +264,21 @@ static struct crypto_alg xtea_alg = { | |||
215 | .cia_decrypt = xtea_decrypt } } | 264 | .cia_decrypt = xtea_decrypt } } |
216 | }; | 265 | }; |
217 | 266 | ||
267 | static struct crypto_alg xeta_alg = { | ||
268 | .cra_name = "xeta", | ||
269 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
270 | .cra_blocksize = XTEA_BLOCK_SIZE, | ||
271 | .cra_ctxsize = sizeof (struct xtea_ctx), | ||
272 | .cra_module = THIS_MODULE, | ||
273 | .cra_list = LIST_HEAD_INIT(xtea_alg.cra_list), | ||
274 | .cra_u = { .cipher = { | ||
275 | .cia_min_keysize = XTEA_KEY_SIZE, | ||
276 | .cia_max_keysize = XTEA_KEY_SIZE, | ||
277 | .cia_setkey = xtea_setkey, | ||
278 | .cia_encrypt = xeta_encrypt, | ||
279 | .cia_decrypt = xeta_decrypt } } | ||
280 | }; | ||
281 | |||
218 | static int __init init(void) | 282 | static int __init init(void) |
219 | { | 283 | { |
220 | int ret = 0; | 284 | int ret = 0; |
@@ -229,6 +293,13 @@ static int __init init(void) | |||
229 | goto out; | 293 | goto out; |
230 | } | 294 | } |
231 | 295 | ||
296 | ret = crypto_register_alg(&xeta_alg); | ||
297 | if (ret < 0) { | ||
298 | crypto_unregister_alg(&tea_alg); | ||
299 | crypto_unregister_alg(&xtea_alg); | ||
300 | goto out; | ||
301 | } | ||
302 | |||
232 | out: | 303 | out: |
233 | return ret; | 304 | return ret; |
234 | } | 305 | } |
@@ -237,12 +308,14 @@ static void __exit fini(void) | |||
237 | { | 308 | { |
238 | crypto_unregister_alg(&tea_alg); | 309 | crypto_unregister_alg(&tea_alg); |
239 | crypto_unregister_alg(&xtea_alg); | 310 | crypto_unregister_alg(&xtea_alg); |
311 | crypto_unregister_alg(&xeta_alg); | ||
240 | } | 312 | } |
241 | 313 | ||
242 | MODULE_ALIAS("xtea"); | 314 | MODULE_ALIAS("xtea"); |
315 | MODULE_ALIAS("xeta"); | ||
243 | 316 | ||
244 | module_init(init); | 317 | module_init(init); |
245 | module_exit(fini); | 318 | module_exit(fini); |
246 | 319 | ||
247 | MODULE_LICENSE("GPL"); | 320 | MODULE_LICENSE("GPL"); |
248 | MODULE_DESCRIPTION("TEA & XTEA Cryptographic Algorithms"); | 321 | MODULE_DESCRIPTION("TEA, XTEA & XETA Cryptographic Algorithms"); |