Back to home page

LXR

 
 

    


0001 /* 
0002  * Cryptographic API.
0003  *
0004  * TEA, XTEA, and XETA crypto alogrithms
0005  *
0006  * The TEA and Xtended TEA algorithms were developed by David Wheeler 
0007  * and Roger Needham at the Computer Laboratory of Cambridge University.
0008  *
0009  * Due to the order of evaluation in XTEA many people have incorrectly
0010  * implemented it.  XETA (XTEA in the wrong order), exists for
0011  * compatibility with these implementations.
0012  *
0013  * Copyright (c) 2004 Aaron Grothe ajgrothe@yahoo.com
0014  *
0015  * This program is free software; you can redistribute it and/or modify
0016  * it under the terms of the GNU General Public License as published by
0017  * the Free Software Foundation; either version 2 of the License, or
0018  * (at your option) any later version.
0019  *
0020  */
0021 
0022 #include <linux/init.h>
0023 #include <linux/module.h>
0024 #include <linux/mm.h>
0025 #include <asm/byteorder.h>
0026 #include <linux/crypto.h>
0027 #include <linux/types.h>
0028 
0029 #define TEA_KEY_SIZE        16
0030 #define TEA_BLOCK_SIZE      8
0031 #define TEA_ROUNDS      32
0032 #define TEA_DELTA       0x9e3779b9
0033 
0034 #define XTEA_KEY_SIZE       16
0035 #define XTEA_BLOCK_SIZE     8
0036 #define XTEA_ROUNDS     32
0037 #define XTEA_DELTA      0x9e3779b9
0038 
0039 struct tea_ctx {
0040     u32 KEY[4];
0041 };
0042 
0043 struct xtea_ctx {
0044     u32 KEY[4];
0045 };
0046 
0047 static int tea_setkey(struct crypto_tfm *tfm, const u8 *in_key,
0048               unsigned int key_len)
0049 {
0050     struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
0051     const __le32 *key = (const __le32 *)in_key;
0052 
0053     ctx->KEY[0] = le32_to_cpu(key[0]);
0054     ctx->KEY[1] = le32_to_cpu(key[1]);
0055     ctx->KEY[2] = le32_to_cpu(key[2]);
0056     ctx->KEY[3] = le32_to_cpu(key[3]);
0057 
0058     return 0; 
0059 
0060 }
0061 
0062 static void tea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0063 {
0064     u32 y, z, n, sum = 0;
0065     u32 k0, k1, k2, k3;
0066     struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
0067     const __le32 *in = (const __le32 *)src;
0068     __le32 *out = (__le32 *)dst;
0069 
0070     y = le32_to_cpu(in[0]);
0071     z = le32_to_cpu(in[1]);
0072 
0073     k0 = ctx->KEY[0];
0074     k1 = ctx->KEY[1];
0075     k2 = ctx->KEY[2];
0076     k3 = ctx->KEY[3];
0077 
0078     n = TEA_ROUNDS;
0079 
0080     while (n-- > 0) {
0081         sum += TEA_DELTA;
0082         y += ((z << 4) + k0) ^ (z + sum) ^ ((z >> 5) + k1);
0083         z += ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
0084     }
0085     
0086     out[0] = cpu_to_le32(y);
0087     out[1] = cpu_to_le32(z);
0088 }
0089 
0090 static void tea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0091 {
0092     u32 y, z, n, sum;
0093     u32 k0, k1, k2, k3;
0094     struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
0095     const __le32 *in = (const __le32 *)src;
0096     __le32 *out = (__le32 *)dst;
0097 
0098     y = le32_to_cpu(in[0]);
0099     z = le32_to_cpu(in[1]);
0100 
0101     k0 = ctx->KEY[0];
0102     k1 = ctx->KEY[1];
0103     k2 = ctx->KEY[2];
0104     k3 = ctx->KEY[3];
0105 
0106     sum = TEA_DELTA << 5;
0107 
0108     n = TEA_ROUNDS;
0109 
0110     while (n-- > 0) {
0111         z -= ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
0112         y -= ((z << 4) + k0) ^ (z + sum) ^ ((z >> 5) + k1);
0113         sum -= TEA_DELTA;
0114     }
0115     
0116     out[0] = cpu_to_le32(y);
0117     out[1] = cpu_to_le32(z);
0118 }
0119 
0120 static int xtea_setkey(struct crypto_tfm *tfm, const u8 *in_key,
0121                unsigned int key_len)
0122 {
0123     struct xtea_ctx *ctx = crypto_tfm_ctx(tfm);
0124     const __le32 *key = (const __le32 *)in_key;
0125 
0126     ctx->KEY[0] = le32_to_cpu(key[0]);
0127     ctx->KEY[1] = le32_to_cpu(key[1]);
0128     ctx->KEY[2] = le32_to_cpu(key[2]);
0129     ctx->KEY[3] = le32_to_cpu(key[3]);
0130 
0131     return 0; 
0132 
0133 }
0134 
0135 static void xtea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0136 {
0137     u32 y, z, sum = 0;
0138     u32 limit = XTEA_DELTA * XTEA_ROUNDS;
0139     struct xtea_ctx *ctx = crypto_tfm_ctx(tfm);
0140     const __le32 *in = (const __le32 *)src;
0141     __le32 *out = (__le32 *)dst;
0142 
0143     y = le32_to_cpu(in[0]);
0144     z = le32_to_cpu(in[1]);
0145 
0146     while (sum != limit) {
0147         y += ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum&3]); 
0148         sum += XTEA_DELTA;
0149         z += ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 &3]); 
0150     }
0151     
0152     out[0] = cpu_to_le32(y);
0153     out[1] = cpu_to_le32(z);
0154 }
0155 
0156 static void xtea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0157 {
0158     u32 y, z, sum;
0159     struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
0160     const __le32 *in = (const __le32 *)src;
0161     __le32 *out = (__le32 *)dst;
0162 
0163     y = le32_to_cpu(in[0]);
0164     z = le32_to_cpu(in[1]);
0165 
0166     sum = XTEA_DELTA * XTEA_ROUNDS;
0167 
0168     while (sum) {
0169         z -= ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 & 3]);
0170         sum -= XTEA_DELTA;
0171         y -= ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum & 3]);
0172     }
0173     
0174     out[0] = cpu_to_le32(y);
0175     out[1] = cpu_to_le32(z);
0176 }
0177 
0178 
0179 static void xeta_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0180 {
0181     u32 y, z, sum = 0;
0182     u32 limit = XTEA_DELTA * XTEA_ROUNDS;
0183     struct xtea_ctx *ctx = crypto_tfm_ctx(tfm);
0184     const __le32 *in = (const __le32 *)src;
0185     __le32 *out = (__le32 *)dst;
0186 
0187     y = le32_to_cpu(in[0]);
0188     z = le32_to_cpu(in[1]);
0189 
0190     while (sum != limit) {
0191         y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3];
0192         sum += XTEA_DELTA;
0193         z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3];
0194     }
0195     
0196     out[0] = cpu_to_le32(y);
0197     out[1] = cpu_to_le32(z);
0198 }
0199 
0200 static void xeta_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
0201 {
0202     u32 y, z, sum;
0203     struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
0204     const __le32 *in = (const __le32 *)src;
0205     __le32 *out = (__le32 *)dst;
0206 
0207     y = le32_to_cpu(in[0]);
0208     z = le32_to_cpu(in[1]);
0209 
0210     sum = XTEA_DELTA * XTEA_ROUNDS;
0211 
0212     while (sum) {
0213         z -= (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 & 3];
0214         sum -= XTEA_DELTA;
0215         y -= (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum & 3];
0216     }
0217     
0218     out[0] = cpu_to_le32(y);
0219     out[1] = cpu_to_le32(z);
0220 }
0221 
0222 static struct crypto_alg tea_algs[3] = { {
0223     .cra_name       =   "tea",
0224     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
0225     .cra_blocksize      =   TEA_BLOCK_SIZE,
0226     .cra_ctxsize        =   sizeof (struct tea_ctx),
0227     .cra_alignmask      =   3,
0228     .cra_module     =   THIS_MODULE,
0229     .cra_u          =   { .cipher = {
0230     .cia_min_keysize    =   TEA_KEY_SIZE,
0231     .cia_max_keysize    =   TEA_KEY_SIZE,
0232     .cia_setkey     =   tea_setkey,
0233     .cia_encrypt        =   tea_encrypt,
0234     .cia_decrypt        =   tea_decrypt } }
0235 }, {
0236     .cra_name       =   "xtea",
0237     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
0238     .cra_blocksize      =   XTEA_BLOCK_SIZE,
0239     .cra_ctxsize        =   sizeof (struct xtea_ctx),
0240     .cra_alignmask      =   3,
0241     .cra_module     =   THIS_MODULE,
0242     .cra_u          =   { .cipher = {
0243     .cia_min_keysize    =   XTEA_KEY_SIZE,
0244     .cia_max_keysize    =   XTEA_KEY_SIZE,
0245     .cia_setkey     =   xtea_setkey,
0246     .cia_encrypt        =   xtea_encrypt,
0247     .cia_decrypt        =   xtea_decrypt } }
0248 }, {
0249     .cra_name       =   "xeta",
0250     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
0251     .cra_blocksize      =   XTEA_BLOCK_SIZE,
0252     .cra_ctxsize        =   sizeof (struct xtea_ctx),
0253     .cra_alignmask      =   3,
0254     .cra_module     =   THIS_MODULE,
0255     .cra_u          =   { .cipher = {
0256     .cia_min_keysize    =   XTEA_KEY_SIZE,
0257     .cia_max_keysize    =   XTEA_KEY_SIZE,
0258     .cia_setkey     =   xtea_setkey,
0259     .cia_encrypt        =   xeta_encrypt,
0260     .cia_decrypt        =   xeta_decrypt } }
0261 } };
0262 
0263 static int __init tea_mod_init(void)
0264 {
0265     return crypto_register_algs(tea_algs, ARRAY_SIZE(tea_algs));
0266 }
0267 
0268 static void __exit tea_mod_fini(void)
0269 {
0270     crypto_unregister_algs(tea_algs, ARRAY_SIZE(tea_algs));
0271 }
0272 
0273 MODULE_ALIAS_CRYPTO("tea");
0274 MODULE_ALIAS_CRYPTO("xtea");
0275 MODULE_ALIAS_CRYPTO("xeta");
0276 
0277 module_init(tea_mod_init);
0278 module_exit(tea_mod_fini);
0279 
0280 MODULE_LICENSE("GPL");
0281 MODULE_DESCRIPTION("TEA, XTEA & XETA Cryptographic Algorithms");