[CRYPTO]: Fix XTEA implementation
The XTEA implementation was incorrect due to a misinterpretation of
operator precedence. Because of the wide-spread nature of this
error, the erroneous implementation will be kept, albeit under the
new name of XETA.
Signed-off-by: Aaron Grothe <ajgrothe@yahoo.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 256c0b1..89299f4 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -219,7 +219,7 @@
described in RFC2612.
config CRYPTO_TEA
- tristate "TEA and XTEA cipher algorithms"
+ tristate "TEA, XTEA and XETA cipher algorithms"
depends on CRYPTO
help
TEA cipher algorithm.
@@ -232,6 +232,9 @@
the TEA algorithm to address a potential key weakness
in the TEA algorithm.
+ Xtendend Encryption Tiny Algorithm is a mis-implementation
+ of the XTEA algorithm for compatibility purposes.
+
config CRYPTO_ARC4
tristate "ARC4 cipher algorithm"
depends on CRYPTO
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index bd7524c..6863941 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -72,7 +72,7 @@
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
"arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
- "khazad", "wp512", "wp384", "wp256", "tnepres", NULL
+ "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", NULL
};
static void hexdump(unsigned char *buf, unsigned int len)
@@ -859,6 +859,10 @@
test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
+ //XETA
+ test_cipher ("xeta", MODE_ECB, ENCRYPT, xeta_enc_tv_template, XETA_ENC_TEST_VECTORS);
+ test_cipher ("xeta", MODE_ECB, DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS);
+
test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS);
@@ -1016,6 +1020,11 @@
case 29:
test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS);
break;
+
+ case 30:
+ test_cipher ("xeta", MODE_ECB, ENCRYPT, xeta_enc_tv_template, XETA_ENC_TEST_VECTORS);
+ test_cipher ("xeta", MODE_ECB, DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS);
+ break;
#ifdef CONFIG_CRYPTO_HMAC
case 100:
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index c01a0ce9..522ffd4 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -2211,7 +2211,7 @@
.klen = 16,
.input = { [0 ... 8] = 0x00 },
.ilen = 8,
- .result = { 0xaa, 0x22, 0x96, 0xe5, 0x6c, 0x61, 0xf3, 0x45 },
+ .result = { 0xd8, 0xd4, 0xe9, 0xde, 0xd9, 0x1e, 0x13, 0xf7 },
.rlen = 8,
}, {
.key = { 0x2b, 0x02, 0x05, 0x68, 0x06, 0x14, 0x49, 0x76,
@@ -2219,31 +2219,31 @@
.klen = 16,
.input = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x2e },
.ilen = 8,
- .result = { 0x82, 0x3e, 0xeb, 0x35, 0xdc, 0xdd, 0xd9, 0xc3 },
+ .result = { 0x94, 0xeb, 0xc8, 0x96, 0x84, 0x6a, 0x49, 0xa8 },
.rlen = 8,
}, {
.key = { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
.klen = 16,
- .input = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
+ .input = { 0x3e, 0xce, 0xae, 0x22, 0x60, 0x56, 0xa8, 0x9d,
0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
.ilen = 16,
- .result = { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
+ .result = { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
0x61, 0x35, 0xaa, 0xed, 0xb5, 0xcb, 0x71, 0x2c },
.rlen = 16,
}, {
.key = { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
.klen = 16,
- .input = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
- 0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
- 0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
+ .input = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+ 0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+ 0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
.ilen = 32,
- .result = { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
- 0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
- 0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
- 0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
+ .result = { 0x99, 0x81, 0x9f, 0x5d, 0x6f, 0x4b, 0x31, 0x3a,
+ 0x86, 0xff, 0x6f, 0xd0, 0xe3, 0x87, 0x70, 0x07,
+ 0x4d, 0xb8, 0xcf, 0xf3, 0x99, 0x50, 0xb3, 0xd4,
+ 0x73, 0xa2, 0xfa, 0xc9, 0x16, 0x59, 0x5d, 0x81 },
.rlen = 32,
}
};
@@ -2252,7 +2252,7 @@
{
.key = { [0 ... 15] = 0x00 },
.klen = 16,
- .input = { 0xaa, 0x22, 0x96, 0xe5, 0x6c, 0x61, 0xf3, 0x45 },
+ .input = { 0xd8, 0xd4, 0xe9, 0xde, 0xd9, 0x1e, 0x13, 0xf7 },
.ilen = 8,
.result = { [0 ... 8] = 0x00 },
.rlen = 8,
@@ -2260,7 +2260,7 @@
.key = { 0x2b, 0x02, 0x05, 0x68, 0x06, 0x14, 0x49, 0x76,
0x77, 0x5d, 0x0e, 0x26, 0x6c, 0x28, 0x78, 0x43 },
.klen = 16,
- .input = { 0x82, 0x3e, 0xeb, 0x35, 0xdc, 0xdd, 0xd9, 0xc3 },
+ .input = { 0x94, 0xeb, 0xc8, 0x96, 0x84, 0x6a, 0x49, 0xa8 },
.ilen = 8,
.result = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x2e },
.rlen = 8,
@@ -2268,24 +2268,24 @@
.key = { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
.klen = 16,
- .input = { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
- 0x61, 0x35, 0xaa, 0xed, 0xb5, 0xcb, 0x71, 0x2c },
+ .input = { 0x3e, 0xce, 0xae, 0x22, 0x60, 0x56, 0xa8, 0x9d,
+ 0x77, 0x4d, 0xd4, 0xb4, 0x87, 0x24, 0xe3, 0x9a },
.ilen = 16,
- .result = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
+ .result = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
.rlen = 16,
}, {
.key = { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
.klen = 16,
- .input = { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
- 0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
- 0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
- 0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
+ .input = { 0x99, 0x81, 0x9f, 0x5d, 0x6f, 0x4b, 0x31, 0x3a,
+ 0x86, 0xff, 0x6f, 0xd0, 0xe3, 0x87, 0x70, 0x07,
+ 0x4d, 0xb8, 0xcf, 0xf3, 0x99, 0x50, 0xb3, 0xd4,
+ 0x73, 0xa2, 0xfa, 0xc9, 0x16, 0x59, 0x5d, 0x81 },
.ilen = 32,
- .result = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
- 0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
- 0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
+ .result = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+ 0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+ 0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
.rlen = 32,
}
@@ -2594,6 +2594,98 @@
},
};
+/*
+ * XETA test vectors
+ */
+#define XETA_ENC_TEST_VECTORS 4
+#define XETA_DEC_TEST_VECTORS 4
+
+static struct cipher_testvec xeta_enc_tv_template[] = {
+ {
+ .key = { [0 ... 15] = 0x00 },
+ .klen = 16,
+ .input = { [0 ... 8] = 0x00 },
+ .ilen = 8,
+ .result = { 0xaa, 0x22, 0x96, 0xe5, 0x6c, 0x61, 0xf3, 0x45 },
+ .rlen = 8,
+ }, {
+ .key = { 0x2b, 0x02, 0x05, 0x68, 0x06, 0x14, 0x49, 0x76,
+ 0x77, 0x5d, 0x0e, 0x26, 0x6c, 0x28, 0x78, 0x43 },
+ .klen = 16,
+ .input = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x2e },
+ .ilen = 8,
+ .result = { 0x82, 0x3e, 0xeb, 0x35, 0xdc, 0xdd, 0xd9, 0xc3 },
+ .rlen = 8,
+ }, {
+ .key = { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
+ 0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
+ .klen = 16,
+ .input = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
+ 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
+ .ilen = 16,
+ .result = { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
+ 0x61, 0x35, 0xaa, 0xed, 0xb5, 0xcb, 0x71, 0x2c },
+ .rlen = 16,
+ }, {
+ .key = { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
+ 0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
+ .klen = 16,
+ .input = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+ 0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+ 0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
+ 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
+ .ilen = 32,
+ .result = { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
+ 0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
+ 0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
+ 0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
+ .rlen = 32,
+ }
+};
+
+static struct cipher_testvec xeta_dec_tv_template[] = {
+ {
+ .key = { [0 ... 15] = 0x00 },
+ .klen = 16,
+ .input = { 0xaa, 0x22, 0x96, 0xe5, 0x6c, 0x61, 0xf3, 0x45 },
+ .ilen = 8,
+ .result = { [0 ... 8] = 0x00 },
+ .rlen = 8,
+ }, {
+ .key = { 0x2b, 0x02, 0x05, 0x68, 0x06, 0x14, 0x49, 0x76,
+ 0x77, 0x5d, 0x0e, 0x26, 0x6c, 0x28, 0x78, 0x43 },
+ .klen = 16,
+ .input = { 0x82, 0x3e, 0xeb, 0x35, 0xdc, 0xdd, 0xd9, 0xc3 },
+ .ilen = 8,
+ .result = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x2e },
+ .rlen = 8,
+ }, {
+ .key = { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
+ 0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
+ .klen = 16,
+ .input = { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
+ 0x61, 0x35, 0xaa, 0xed, 0xb5, 0xcb, 0x71, 0x2c },
+ .ilen = 16,
+ .result = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
+ 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
+ .rlen = 16,
+ }, {
+ .key = { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
+ 0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
+ .klen = 16,
+ .input = { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
+ 0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
+ 0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
+ 0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
+ .ilen = 32,
+ .result = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+ 0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+ 0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
+ 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
+ .rlen = 32,
+ }
+};
+
/*
* Compression stuff.
*/
diff --git a/crypto/tea.c b/crypto/tea.c
index 03c23cb..5924efd 100644
--- a/crypto/tea.c
+++ b/crypto/tea.c
@@ -1,11 +1,15 @@
/*
* Cryptographic API.
*
- * TEA and Xtended TEA Algorithms
+ * TEA, XTEA, and XETA crypto alogrithms
*
* The TEA and Xtended TEA algorithms were developed by David Wheeler
* and Roger Needham at the Computer Laboratory of Cambridge University.
*
+ * Due to the order of evaluation in XTEA many people have incorrectly
+ * implemented it. XETA (XTEA in the wrong order), exists for
+ * compatibility with these implementations.
+ *
* Copyright (c) 2004 Aaron Grothe ajgrothe@yahoo.com
*
* This program is free software; you can redistribute it and/or modify
@@ -153,9 +157,9 @@
z = u32_in (src + 4);
while (sum != limit) {
- y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3];
+ y += ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum&3]);
sum += XTEA_DELTA;
- z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3];
+ z += ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 &3]);
}
u32_out (dst, y);
@@ -175,6 +179,51 @@
sum = XTEA_DELTA * XTEA_ROUNDS;
while (sum) {
+ z -= ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 & 3]);
+ sum -= XTEA_DELTA;
+ y -= ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum & 3]);
+ }
+
+ u32_out (dst, y);
+ u32_out (dst + 4, z);
+
+}
+
+
+static void xeta_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
+{
+
+ u32 y, z, sum = 0;
+ u32 limit = XTEA_DELTA * XTEA_ROUNDS;
+
+ struct xtea_ctx *ctx = ctx_arg;
+
+ y = u32_in (src);
+ z = u32_in (src + 4);
+
+ while (sum != limit) {
+ y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3];
+ sum += XTEA_DELTA;
+ z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3];
+ }
+
+ u32_out (dst, y);
+ u32_out (dst + 4, z);
+
+}
+
+static void xeta_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
+{
+
+ u32 y, z, sum;
+ struct tea_ctx *ctx = ctx_arg;
+
+ y = u32_in (src);
+ z = u32_in (src + 4);
+
+ sum = XTEA_DELTA * XTEA_ROUNDS;
+
+ while (sum) {
z -= (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 & 3];
sum -= XTEA_DELTA;
y -= (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum & 3];
@@ -215,6 +264,21 @@
.cia_decrypt = xtea_decrypt } }
};
+static struct crypto_alg xeta_alg = {
+ .cra_name = "xeta",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = XTEA_BLOCK_SIZE,
+ .cra_ctxsize = sizeof (struct xtea_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(xtea_alg.cra_list),
+ .cra_u = { .cipher = {
+ .cia_min_keysize = XTEA_KEY_SIZE,
+ .cia_max_keysize = XTEA_KEY_SIZE,
+ .cia_setkey = xtea_setkey,
+ .cia_encrypt = xeta_encrypt,
+ .cia_decrypt = xeta_decrypt } }
+};
+
static int __init init(void)
{
int ret = 0;
@@ -229,6 +293,13 @@
goto out;
}
+ ret = crypto_register_alg(&xeta_alg);
+ if (ret < 0) {
+ crypto_unregister_alg(&tea_alg);
+ crypto_unregister_alg(&xtea_alg);
+ goto out;
+ }
+
out:
return ret;
}
@@ -237,12 +308,14 @@
{
crypto_unregister_alg(&tea_alg);
crypto_unregister_alg(&xtea_alg);
+ crypto_unregister_alg(&xeta_alg);
}
MODULE_ALIAS("xtea");
+MODULE_ALIAS("xeta");
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("TEA & XTEA Cryptographic Algorithms");
+MODULE_DESCRIPTION("TEA, XTEA & XETA Cryptographic Algorithms");