1 // SPDX-License-Identifier: GPL-2.0-or-later 1 2 /* 3 * Cryptographic API. 4 * 5 * TEA, XTEA, and XETA crypto alogrithms 6 * 7 * The TEA and Xtended TEA algorithms were dev 8 * and Roger Needham at the Computer Laborator 9 * 10 * Due to the order of evaluation in XTEA many 11 * implemented it. XETA (XTEA in the wrong or 12 * compatibility with these implementations. 13 * 14 * Copyright (c) 2004 Aaron Grothe ajgrothe@ya 15 */ 16 17 #include <crypto/algapi.h> 18 #include <linux/init.h> 19 #include <linux/module.h> 20 #include <linux/mm.h> 21 #include <asm/byteorder.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 34 struct tea_ctx { 35 u32 KEY[4]; 36 }; 37 38 struct xtea_ctx { 39 u32 KEY[4]; 40 }; 41 42 static int tea_setkey(struct crypto_tfm *tfm, 43 unsigned int key_len) 44 { 45 struct tea_ctx *ctx = crypto_tfm_ctx(t 46 const __le32 *key = (const __le32 *)in 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 57 static void tea_encrypt(struct crypto_tfm *tfm 58 { 59 u32 y, z, n, sum = 0; 60 u32 k0, k1, k2, k3; 61 struct tea_ctx *ctx = crypto_tfm_ctx(t 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 + su 78 z += ((y << 4) + k2) ^ (y + su 79 } 80 81 out[0] = cpu_to_le32(y); 82 out[1] = cpu_to_le32(z); 83 } 84 85 static void tea_decrypt(struct crypto_tfm *tfm 86 { 87 u32 y, z, n, sum; 88 u32 k0, k1, k2, k3; 89 struct tea_ctx *ctx = crypto_tfm_ctx(t 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 + su 107 y -= ((z << 4) + k0) ^ (z + su 108 sum -= TEA_DELTA; 109 } 110 111 out[0] = cpu_to_le32(y); 112 out[1] = cpu_to_le32(z); 113 } 114 115 static int xtea_setkey(struct crypto_tfm *tfm, 116 unsigned int key_len) 117 { 118 struct xtea_ctx *ctx = crypto_tfm_ctx( 119 const __le32 *key = (const __le32 *)in 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 130 static void xtea_encrypt(struct crypto_tfm *tf 131 { 132 u32 y, z, sum = 0; 133 u32 limit = XTEA_DELTA * XTEA_ROUNDS; 134 struct xtea_ctx *ctx = crypto_tfm_ctx( 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) ^ 143 sum += XTEA_DELTA; 144 z += ((y << 4 ^ y >> 5) + y) ^ 145 } 146 147 out[0] = cpu_to_le32(y); 148 out[1] = cpu_to_le32(z); 149 } 150 151 static void xtea_decrypt(struct crypto_tfm *tf 152 { 153 u32 y, z, sum; 154 struct tea_ctx *ctx = crypto_tfm_ctx(t 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) ^ 165 sum -= XTEA_DELTA; 166 y -= ((z << 4 ^ z >> 5) + z) ^ 167 } 168 169 out[0] = cpu_to_le32(y); 170 out[1] = cpu_to_le32(z); 171 } 172 173 174 static void xeta_encrypt(struct crypto_tfm *tf 175 { 176 u32 y, z, sum = 0; 177 u32 limit = XTEA_DELTA * XTEA_ROUNDS; 178 struct xtea_ctx *ctx = crypto_tfm_ctx( 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 ^ 187 sum += XTEA_DELTA; 188 z += (y << 4 ^ y >> 5) + (y ^ 189 } 190 191 out[0] = cpu_to_le32(y); 192 out[1] = cpu_to_le32(z); 193 } 194 195 static void xeta_decrypt(struct crypto_tfm *tf 196 { 197 u32 y, z, sum; 198 struct tea_ctx *ctx = crypto_tfm_ctx(t 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 ^ 209 sum -= XTEA_DELTA; 210 y -= (z << 4 ^ z >> 5) + (z ^ 211 } 212 213 out[0] = cpu_to_le32(y); 214 out[1] = cpu_to_le32(z); 215 } 216 217 static struct crypto_alg tea_algs[3] = { { 218 .cra_name = "tea", 219 .cra_driver_name = "tea-g 220 .cra_flags = CRYPTO 221 .cra_blocksize = TEA_BL 222 .cra_ctxsize = sizeof 223 .cra_alignmask = 3, 224 .cra_module = THIS_M 225 .cra_u = { .cip 226 .cia_min_keysize = TEA_KE 227 .cia_max_keysize = TEA_KE 228 .cia_setkey = tea_se 229 .cia_encrypt = tea_en 230 .cia_decrypt = tea_de 231 }, { 232 .cra_name = "xtea" 233 .cra_driver_name = "xtea- 234 .cra_flags = CRYPTO 235 .cra_blocksize = XTEA_B 236 .cra_ctxsize = sizeof 237 .cra_alignmask = 3, 238 .cra_module = THIS_M 239 .cra_u = { .cip 240 .cia_min_keysize = XTEA_K 241 .cia_max_keysize = XTEA_K 242 .cia_setkey = xtea_s 243 .cia_encrypt = xtea_e 244 .cia_decrypt = xtea_d 245 }, { 246 .cra_name = "xeta" 247 .cra_driver_name = "xeta- 248 .cra_flags = CRYPTO 249 .cra_blocksize = XTEA_B 250 .cra_ctxsize = sizeof 251 .cra_alignmask = 3, 252 .cra_module = THIS_M 253 .cra_u = { .cip 254 .cia_min_keysize = XTEA_K 255 .cia_max_keysize = XTEA_K 256 .cia_setkey = xtea_s 257 .cia_encrypt = xeta_e 258 .cia_decrypt = xeta_d 259 } }; 260 261 static int __init tea_mod_init(void) 262 { 263 return crypto_register_algs(tea_algs, 264 } 265 266 static void __exit tea_mod_fini(void) 267 { 268 crypto_unregister_algs(tea_algs, ARRAY 269 } 270 271 MODULE_ALIAS_CRYPTO("tea"); 272 MODULE_ALIAS_CRYPTO("xtea"); 273 MODULE_ALIAS_CRYPTO("xeta"); 274 275 subsys_initcall(tea_mod_init); 276 module_exit(tea_mod_fini); 277 278 MODULE_LICENSE("GPL"); 279 MODULE_DESCRIPTION("TEA, XTEA & XETA Cryptogra 280
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.