From fb4f10ed50f01b0f953068456bfb6e2885921b01 Mon Sep 17 00:00:00 2001 From: Aaron Grothe Date: Thu, 1 Sep 2005 17:42:46 -0700 Subject: [PATCH] [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 Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- Documentation/crypto/api-intro.txt | 1 + crypto/Kconfig | 5 +- crypto/tcrypt.c | 11 ++- crypto/tcrypt.h | 138 ++++++++++++++++++++++++----- crypto/tea.c | 81 ++++++++++++++++- 5 files changed, 207 insertions(+), 29 deletions(-) diff --git a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt index a2d5b4900772..74dffc68ff9f 100644 --- a/Documentation/crypto/api-intro.txt +++ b/Documentation/crypto/api-intro.txt @@ -223,6 +223,7 @@ CAST5 algorithm contributors: TEA/XTEA algorithm contributors: Aaron Grothe + Michael Ringe Khazad algorithm contributors: Aaron Grothe diff --git a/crypto/Kconfig b/crypto/Kconfig index 256c0b1fed10..89299f4ffe12 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -219,7 +219,7 @@ config CRYPTO_CAST6 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 @@ config CRYPTO_TEA 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 bd7524cfff33..68639419c5bd 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -72,7 +72,7 @@ static char *check[] = { "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 @@ static void do_test(void) 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 @@ static void do_test(void) 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 c01a0ce9b40a..522ffd4b6f43 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h @@ -2211,7 +2211,7 @@ static struct cipher_testvec xtea_enc_tv_template[] = { .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 @@ static struct cipher_testvec xtea_enc_tv_template[] = { .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 @@ static struct cipher_testvec xtea_dec_tv_template[] = { { .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 @@ static struct cipher_testvec xtea_dec_tv_template[] = { .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 @@ static struct cipher_testvec xtea_dec_tv_template[] = { .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 @@ static struct cipher_testvec anubis_cbc_dec_tv_template[] = { }, }; +/* + * 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 03c23cbd3afa..5924efdd3a16 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 @@ static void xtea_encrypt(void *ctx_arg, u8 *dst, const u8 *src) 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); @@ -174,6 +178,51 @@ static void xtea_decrypt(void *ctx_arg, u8 *dst, const u8 *src) 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; @@ -215,6 +264,21 @@ static struct crypto_alg xtea_alg = { .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 @@ static int __init init(void) 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 @@ static void __exit fini(void) { 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");