linux/crypto/tea.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* 
   3 * Cryptographic API.
   4 *
   5 * TEA, XTEA, and XETA crypto alogrithms
   6 *
   7 * The TEA and Xtended TEA algorithms were developed by David Wheeler 
   8 * and Roger Needham at the Computer Laboratory of Cambridge University.
   9 *
  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.
  13 *
  14 * Copyright (c) 2004 Aaron Grothe ajgrothe@yahoo.com
  15 */
  16
  17#include <linux/init.h>
  18#include <linux/module.h>
  19#include <linux/mm.h>
  20#include <asm/byteorder.h>
  21#include <linux/crypto.h>
  22#include <linux/types.h>
  23
  24#define TEA_KEY_SIZE            16
  25#define TEA_BLOCK_SIZE          8
  26#define TEA_ROUNDS              32
  27#define TEA_DELTA               0x9e3779b9
  28
  29#define XTEA_KEY_SIZE           16
  30#define XTEA_BLOCK_SIZE         8
  31#define XTEA_ROUNDS             32
  32#define XTEA_DELTA              0x9e3779b9
  33
  34struct tea_ctx {
  35        u32 KEY[4];
  36};
  37
  38struct xtea_ctx {
  39        u32 KEY[4];
  40};
  41
  42static int tea_setkey(struct crypto_tfm *tfm, const u8 *in_key,
  43                      unsigned int key_len)
  44{
  45        struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
  46        const __le32 *key = (const __le32 *)in_key;
  47
  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]);
  52
  53        return 0; 
  54
  55}
  56
  57static void tea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  58{
  59        u32 y, z, n, sum = 0;
  60        u32 k0, k1, k2, k3;
  61        struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
  62        const __le32 *in = (const __le32 *)src;
  63        __le32 *out = (__le32 *)dst;
  64
  65        y = le32_to_cpu(in[0]);
  66        z = le32_to_cpu(in[1]);
  67
  68        k0 = ctx->KEY[0];
  69        k1 = ctx->KEY[1];
  70        k2 = ctx->KEY[2];
  71        k3 = ctx->KEY[3];
  72
  73        n = TEA_ROUNDS;
  74
  75        while (n-- > 0) {
  76                sum += TEA_DELTA;
  77                y += ((z << 4) + k0) ^ (z + sum) ^ ((z >> 5) + k1);
  78                z += ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
  79        }
  80        
  81        out[0] = cpu_to_le32(y);
  82        out[1] = cpu_to_le32(z);
  83}
  84
  85static void tea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  86{
  87        u32 y, z, n, sum;
  88        u32 k0, k1, k2, k3;
  89        struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
  90        const __le32 *in = (const __le32 *)src;
  91        __le32 *out = (__le32 *)dst;
  92
  93        y = le32_to_cpu(in[0]);
  94        z = le32_to_cpu(in[1]);
  95
  96        k0 = ctx->KEY[0];
  97        k1 = ctx->KEY[1];
  98        k2 = ctx->KEY[2];
  99        k3 = ctx->KEY[3];
 100
 101        sum = TEA_DELTA << 5;
 102
 103        n = TEA_ROUNDS;
 104
 105        while (n-- > 0) {
 106                z -= ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
 107                y -= ((z << 4) + k0) ^ (z + sum) ^ ((z >> 5) + k1);
 108                sum -= TEA_DELTA;
 109        }
 110        
 111        out[0] = cpu_to_le32(y);
 112        out[1] = cpu_to_le32(z);
 113}
 114
 115static int xtea_setkey(struct crypto_tfm *tfm, const u8 *in_key,
 116                       unsigned int key_len)
 117{
 118        struct xtea_ctx *ctx = crypto_tfm_ctx(tfm);
 119        const __le32 *key = (const __le32 *)in_key;
 120
 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]);
 125
 126        return 0; 
 127
 128}
 129
 130static void xtea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 131{
 132        u32 y, z, sum = 0;
 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;
 137
 138        y = le32_to_cpu(in[0]);
 139        z = le32_to_cpu(in[1]);
 140
 141        while (sum != limit) {
 142                y += ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum&3]); 
 143                sum += XTEA_DELTA;
 144                z += ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 &3]); 
 145        }
 146        
 147        out[0] = cpu_to_le32(y);
 148        out[1] = cpu_to_le32(z);
 149}
 150
 151static void xtea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 152{
 153        u32 y, z, sum;
 154        struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
 155        const __le32 *in = (const __le32 *)src;
 156        __le32 *out = (__le32 *)dst;
 157
 158        y = le32_to_cpu(in[0]);
 159        z = le32_to_cpu(in[1]);
 160
 161        sum = XTEA_DELTA * XTEA_ROUNDS;
 162
 163        while (sum) {
 164                z -= ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 & 3]);
 165                sum -= XTEA_DELTA;
 166                y -= ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum & 3]);
 167        }
 168        
 169        out[0] = cpu_to_le32(y);
 170        out[1] = cpu_to_le32(z);
 171}
 172
 173
 174static void xeta_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 175{
 176        u32 y, z, sum = 0;
 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;
 181
 182        y = le32_to_cpu(in[0]);
 183        z = le32_to_cpu(in[1]);
 184
 185        while (sum != limit) {
 186                y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3];
 187                sum += XTEA_DELTA;
 188                z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3];
 189        }
 190        
 191        out[0] = cpu_to_le32(y);
 192        out[1] = cpu_to_le32(z);
 193}
 194
 195static void xeta_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 196{
 197        u32 y, z, sum;
 198        struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
 199        const __le32 *in = (const __le32 *)src;
 200        __le32 *out = (__le32 *)dst;
 201
 202        y = le32_to_cpu(in[0]);
 203        z = le32_to_cpu(in[1]);
 204
 205        sum = XTEA_DELTA * XTEA_ROUNDS;
 206
 207        while (sum) {
 208                z -= (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 & 3];
 209                sum -= XTEA_DELTA;
 210                y -= (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum & 3];
 211        }
 212        
 213        out[0] = cpu_to_le32(y);
 214        out[1] = cpu_to_le32(z);
 215}
 216
 217static struct crypto_alg tea_algs[3] = { {
 218        .cra_name               =       "tea",
 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),
 223        .cra_alignmask          =       3,
 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 } }
 231}, {
 232        .cra_name               =       "xtea",
 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),
 237        .cra_alignmask          =       3,
 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 } }
 245}, {
 246        .cra_name               =       "xeta",
 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),
 251        .cra_alignmask          =       3,
 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 } }
 259} };
 260
 261static int __init tea_mod_init(void)
 262{
 263        return crypto_register_algs(tea_algs, ARRAY_SIZE(tea_algs));
 264}
 265
 266static void __exit tea_mod_fini(void)
 267{
 268        crypto_unregister_algs(tea_algs, ARRAY_SIZE(tea_algs));
 269}
 270
 271MODULE_ALIAS_CRYPTO("tea");
 272MODULE_ALIAS_CRYPTO("xtea");
 273MODULE_ALIAS_CRYPTO("xeta");
 274
 275subsys_initcall(tea_mod_init);
 276module_exit(tea_mod_fini);
 277
 278MODULE_LICENSE("GPL");
 279MODULE_DESCRIPTION("TEA, XTEA & XETA Cryptographic Algorithms");
 280